deeper-cli 1.0.5 → 1.2.0
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/index.js +1266 -334
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/chat-repl.ts +1264 -965
- package/src/model/DeepSeekClient.ts +39 -39
- package/src/model/RetryManager.ts +54 -7
- package/src/model/StreamHandler.ts +117 -21
- package/src/model/types.ts +25 -6
- package/src/tools/tool-types.ts +1 -0
package/dist/cli/index.js
CHANGED
|
@@ -1831,10 +1831,10 @@ var init_token_count = __esm({
|
|
|
1831
1831
|
const messagesJson = params.messages;
|
|
1832
1832
|
let content = "";
|
|
1833
1833
|
if (filePath) {
|
|
1834
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
1834
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
1835
1835
|
const { resolve: resolve48 } = await import("path");
|
|
1836
1836
|
const abs = resolve48(filePath);
|
|
1837
|
-
if (!
|
|
1837
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
1838
1838
|
content = readFileSync38(abs, "utf-8");
|
|
1839
1839
|
} else if (text) {
|
|
1840
1840
|
content = text;
|
|
@@ -3271,6 +3271,651 @@ var init_MCPClient = __esm({
|
|
|
3271
3271
|
}
|
|
3272
3272
|
});
|
|
3273
3273
|
|
|
3274
|
+
// src/model/RetryManager.ts
|
|
3275
|
+
var RetryManager;
|
|
3276
|
+
var init_RetryManager = __esm({
|
|
3277
|
+
"src/model/RetryManager.ts"() {
|
|
3278
|
+
"use strict";
|
|
3279
|
+
RetryManager = class {
|
|
3280
|
+
maxRetries;
|
|
3281
|
+
baseDelayMs;
|
|
3282
|
+
maxDelayMs;
|
|
3283
|
+
constructor(maxRetries = 3, baseDelayMs = 1e3, maxDelayMs = 3e4) {
|
|
3284
|
+
this.maxRetries = maxRetries;
|
|
3285
|
+
this.baseDelayMs = baseDelayMs;
|
|
3286
|
+
this.maxDelayMs = maxDelayMs;
|
|
3287
|
+
}
|
|
3288
|
+
async execute(fn, shouldRetry, options) {
|
|
3289
|
+
let lastError;
|
|
3290
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
3291
|
+
try {
|
|
3292
|
+
return await fn();
|
|
3293
|
+
} catch (error) {
|
|
3294
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
3295
|
+
if (attempt === this.maxRetries) {
|
|
3296
|
+
break;
|
|
3297
|
+
}
|
|
3298
|
+
if (shouldRetry && !shouldRetry(lastError, attempt)) {
|
|
3299
|
+
break;
|
|
3300
|
+
}
|
|
3301
|
+
if (!shouldRetry && this.isDefaultNonRetryable(lastError)) {
|
|
3302
|
+
break;
|
|
3303
|
+
}
|
|
3304
|
+
const delay = this.calculateDelay(attempt);
|
|
3305
|
+
if (options?.onRetry) {
|
|
3306
|
+
options.onRetry(lastError, attempt, delay);
|
|
3307
|
+
}
|
|
3308
|
+
await this.sleep(delay);
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
throw lastError ?? new Error("Max retries exceeded");
|
|
3312
|
+
}
|
|
3313
|
+
withTimeout(fn, timeoutMs, signal) {
|
|
3314
|
+
const controller = new AbortController();
|
|
3315
|
+
return new Promise((resolve48, reject) => {
|
|
3316
|
+
const timer = setTimeout(() => {
|
|
3317
|
+
controller.abort();
|
|
3318
|
+
reject(new Error(`Request timed out after ${timeoutMs}ms`));
|
|
3319
|
+
}, timeoutMs);
|
|
3320
|
+
const onAbort = () => {
|
|
3321
|
+
clearTimeout(timer);
|
|
3322
|
+
controller.abort();
|
|
3323
|
+
reject(new Error("Request was aborted"));
|
|
3324
|
+
};
|
|
3325
|
+
if (signal) {
|
|
3326
|
+
if (signal.aborted) {
|
|
3327
|
+
clearTimeout(timer);
|
|
3328
|
+
controller.abort();
|
|
3329
|
+
reject(new Error("Request was aborted"));
|
|
3330
|
+
return;
|
|
3331
|
+
}
|
|
3332
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3333
|
+
}
|
|
3334
|
+
fn().then((result) => {
|
|
3335
|
+
clearTimeout(timer);
|
|
3336
|
+
if (signal) {
|
|
3337
|
+
signal.removeEventListener("abort", onAbort);
|
|
3338
|
+
}
|
|
3339
|
+
resolve48(result);
|
|
3340
|
+
}).catch((error) => {
|
|
3341
|
+
clearTimeout(timer);
|
|
3342
|
+
if (signal) {
|
|
3343
|
+
signal.removeEventListener("abort", onAbort);
|
|
3344
|
+
}
|
|
3345
|
+
reject(error);
|
|
3346
|
+
});
|
|
3347
|
+
});
|
|
3348
|
+
}
|
|
3349
|
+
calculateDelay(attempt) {
|
|
3350
|
+
const exponentialDelay = this.baseDelayMs * Math.pow(2, attempt);
|
|
3351
|
+
const jitter = Math.random() * exponentialDelay;
|
|
3352
|
+
return Math.min(exponentialDelay + jitter, this.maxDelayMs);
|
|
3353
|
+
}
|
|
3354
|
+
isDefaultNonRetryable(error) {
|
|
3355
|
+
const msg = error.message.toLowerCase();
|
|
3356
|
+
if (msg.includes("400") && !msg.includes("429")) return true;
|
|
3357
|
+
if (msg.includes("401") || msg.includes("unauthorized")) return true;
|
|
3358
|
+
if (msg.includes("403") || msg.includes("forbidden")) return true;
|
|
3359
|
+
if (msg.includes("404") || msg.includes("not found")) return true;
|
|
3360
|
+
return false;
|
|
3361
|
+
}
|
|
3362
|
+
sleep(ms, signal) {
|
|
3363
|
+
return new Promise((resolve48, reject) => {
|
|
3364
|
+
const timer = setTimeout(resolve48, ms);
|
|
3365
|
+
if (signal) {
|
|
3366
|
+
const onAbort = () => {
|
|
3367
|
+
clearTimeout(timer);
|
|
3368
|
+
reject(new Error("Retry sleep was aborted"));
|
|
3369
|
+
};
|
|
3370
|
+
if (signal.aborted) {
|
|
3371
|
+
clearTimeout(timer);
|
|
3372
|
+
reject(new Error("Retry sleep was aborted"));
|
|
3373
|
+
return;
|
|
3374
|
+
}
|
|
3375
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3376
|
+
}
|
|
3377
|
+
});
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
}
|
|
3381
|
+
});
|
|
3382
|
+
|
|
3383
|
+
// src/model/StreamHandler.ts
|
|
3384
|
+
var StreamHandler;
|
|
3385
|
+
var init_StreamHandler = __esm({
|
|
3386
|
+
"src/model/StreamHandler.ts"() {
|
|
3387
|
+
"use strict";
|
|
3388
|
+
StreamHandler = class {
|
|
3389
|
+
textBuffer;
|
|
3390
|
+
thinkingBuffer;
|
|
3391
|
+
toolCallBuffer;
|
|
3392
|
+
finished;
|
|
3393
|
+
lastYieldedIndex;
|
|
3394
|
+
constructor() {
|
|
3395
|
+
this.textBuffer = "";
|
|
3396
|
+
this.thinkingBuffer = "";
|
|
3397
|
+
this.toolCallBuffer = /* @__PURE__ */ new Map();
|
|
3398
|
+
this.finished = false;
|
|
3399
|
+
this.lastYieldedIndex = -1;
|
|
3400
|
+
}
|
|
3401
|
+
reset() {
|
|
3402
|
+
this.textBuffer = "";
|
|
3403
|
+
this.thinkingBuffer = "";
|
|
3404
|
+
this.toolCallBuffer.clear();
|
|
3405
|
+
this.finished = false;
|
|
3406
|
+
this.lastYieldedIndex = -1;
|
|
3407
|
+
}
|
|
3408
|
+
handleEvent(event, data) {
|
|
3409
|
+
if (event === "error") {
|
|
3410
|
+
return { type: "error", error: data || "SSE error event" };
|
|
3411
|
+
}
|
|
3412
|
+
if (event === "[DONE]" || data === "[DONE]") {
|
|
3413
|
+
const results = this.finalizePendingToolCalls();
|
|
3414
|
+
this.finished = true;
|
|
3415
|
+
if (results.length > 0) {
|
|
3416
|
+
return [...results, { type: "done" }];
|
|
3417
|
+
}
|
|
3418
|
+
return { type: "done" };
|
|
3419
|
+
}
|
|
3420
|
+
if (!data) {
|
|
3421
|
+
return null;
|
|
3422
|
+
}
|
|
3423
|
+
try {
|
|
3424
|
+
const parsed = JSON.parse(data);
|
|
3425
|
+
const choices = parsed.choices;
|
|
3426
|
+
if (!choices || choices.length === 0) {
|
|
3427
|
+
return null;
|
|
3428
|
+
}
|
|
3429
|
+
const choice = choices[0];
|
|
3430
|
+
const delta = choice.delta;
|
|
3431
|
+
if (!delta) {
|
|
3432
|
+
const finishReason2 = choice.finish_reason;
|
|
3433
|
+
if (finishReason2 === "stop" || finishReason2 === "length" || finishReason2 === "tool_calls") {
|
|
3434
|
+
const results = this.finalizePendingToolCalls();
|
|
3435
|
+
this.finished = true;
|
|
3436
|
+
if (results.length > 0) {
|
|
3437
|
+
return [...results, { type: "done" }];
|
|
3438
|
+
}
|
|
3439
|
+
return { type: "done" };
|
|
3440
|
+
}
|
|
3441
|
+
return null;
|
|
3442
|
+
}
|
|
3443
|
+
if (delta.reasoning_content) {
|
|
3444
|
+
const thinkingChunk = delta.reasoning_content;
|
|
3445
|
+
this.thinkingBuffer += thinkingChunk;
|
|
3446
|
+
if (this.thinkingBuffer.length > 1e5) {
|
|
3447
|
+
this.thinkingBuffer = this.thinkingBuffer.slice(-8e4);
|
|
3448
|
+
}
|
|
3449
|
+
return {
|
|
3450
|
+
type: "thinking",
|
|
3451
|
+
content: thinkingChunk
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
if (delta.tool_calls) {
|
|
3455
|
+
return this.handleToolCallsDelta(delta.tool_calls);
|
|
3456
|
+
}
|
|
3457
|
+
if (delta.content) {
|
|
3458
|
+
const textChunk = delta.content;
|
|
3459
|
+
this.textBuffer += textChunk;
|
|
3460
|
+
if (this.textBuffer.length > 5e5) {
|
|
3461
|
+
this.textBuffer = this.textBuffer.slice(-4e5);
|
|
3462
|
+
}
|
|
3463
|
+
return {
|
|
3464
|
+
type: "text",
|
|
3465
|
+
content: textChunk
|
|
3466
|
+
};
|
|
3467
|
+
}
|
|
3468
|
+
const finishReason = choice.finish_reason;
|
|
3469
|
+
if (finishReason === "stop" || finishReason === "length" || finishReason === "tool_calls") {
|
|
3470
|
+
const results = this.finalizePendingToolCalls();
|
|
3471
|
+
this.finished = true;
|
|
3472
|
+
if (results.length > 0) {
|
|
3473
|
+
return [...results, { type: "done" }];
|
|
3474
|
+
}
|
|
3475
|
+
return { type: "done" };
|
|
3476
|
+
}
|
|
3477
|
+
} catch {
|
|
3478
|
+
return {
|
|
3479
|
+
type: "error",
|
|
3480
|
+
error: `Failed to parse SSE data: ${data.slice(0, 200)}`
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3483
|
+
return null;
|
|
3484
|
+
}
|
|
3485
|
+
getAccumulatedText() {
|
|
3486
|
+
return this.textBuffer;
|
|
3487
|
+
}
|
|
3488
|
+
getAccumulatedThinking() {
|
|
3489
|
+
return this.thinkingBuffer;
|
|
3490
|
+
}
|
|
3491
|
+
getToolCalls() {
|
|
3492
|
+
const result = [];
|
|
3493
|
+
const indices = [...this.toolCallBuffer.keys()].sort((a, b2) => a - b2);
|
|
3494
|
+
for (const idx of indices) {
|
|
3495
|
+
const pending = this.toolCallBuffer.get(idx);
|
|
3496
|
+
if (pending) {
|
|
3497
|
+
result.push({
|
|
3498
|
+
id: pending.id,
|
|
3499
|
+
name: pending.name,
|
|
3500
|
+
arguments: this.parseArgsStr(pending.argsStr),
|
|
3501
|
+
index: pending.index
|
|
3502
|
+
});
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
return result;
|
|
3506
|
+
}
|
|
3507
|
+
isFinished() {
|
|
3508
|
+
return this.finished;
|
|
3509
|
+
}
|
|
3510
|
+
handleToolCallsDelta(toolCalls) {
|
|
3511
|
+
const results = [];
|
|
3512
|
+
for (const tc of toolCalls) {
|
|
3513
|
+
const index = tc.index;
|
|
3514
|
+
const id = tc.id;
|
|
3515
|
+
const fn = tc.function;
|
|
3516
|
+
if (!this.toolCallBuffer.has(index)) {
|
|
3517
|
+
this.toolCallBuffer.set(index, {
|
|
3518
|
+
id: id ?? "",
|
|
3519
|
+
name: fn?.name ?? "",
|
|
3520
|
+
argsStr: "",
|
|
3521
|
+
index,
|
|
3522
|
+
started: false
|
|
3523
|
+
});
|
|
3524
|
+
}
|
|
3525
|
+
const existing = this.toolCallBuffer.get(index);
|
|
3526
|
+
if (id) {
|
|
3527
|
+
existing.id = id;
|
|
3528
|
+
}
|
|
3529
|
+
if (fn?.name) {
|
|
3530
|
+
existing.name = fn.name;
|
|
3531
|
+
}
|
|
3532
|
+
if (fn?.arguments) {
|
|
3533
|
+
existing.argsStr += fn.arguments;
|
|
3534
|
+
}
|
|
3535
|
+
if (!existing.started) {
|
|
3536
|
+
existing.started = true;
|
|
3537
|
+
if (this.lastYieldedIndex >= 0) {
|
|
3538
|
+
const prev = this.toolCallBuffer.get(this.lastYieldedIndex);
|
|
3539
|
+
if (prev && prev !== existing) {
|
|
3540
|
+
results.push({
|
|
3541
|
+
type: "tool_call_end",
|
|
3542
|
+
tool_call: {
|
|
3543
|
+
id: prev.id,
|
|
3544
|
+
name: prev.name,
|
|
3545
|
+
arguments: this.parseArgsStr(prev.argsStr),
|
|
3546
|
+
index: prev.index
|
|
3547
|
+
}
|
|
3548
|
+
});
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
this.lastYieldedIndex = index;
|
|
3552
|
+
results.push({
|
|
3553
|
+
type: "tool_call_start",
|
|
3554
|
+
tool_call: { id: existing.id, name: existing.name, index: existing.index }
|
|
3555
|
+
});
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
return results;
|
|
3559
|
+
}
|
|
3560
|
+
finalizePendingToolCalls() {
|
|
3561
|
+
const results = [];
|
|
3562
|
+
if (this.lastYieldedIndex >= 0) {
|
|
3563
|
+
const last = this.toolCallBuffer.get(this.lastYieldedIndex);
|
|
3564
|
+
if (last) {
|
|
3565
|
+
results.push({
|
|
3566
|
+
type: "tool_call_end",
|
|
3567
|
+
tool_call: {
|
|
3568
|
+
id: last.id,
|
|
3569
|
+
name: last.name,
|
|
3570
|
+
arguments: this.parseArgsStr(last.argsStr),
|
|
3571
|
+
index: last.index
|
|
3572
|
+
}
|
|
3573
|
+
});
|
|
3574
|
+
}
|
|
3575
|
+
this.lastYieldedIndex = -1;
|
|
3576
|
+
}
|
|
3577
|
+
return results;
|
|
3578
|
+
}
|
|
3579
|
+
parseArgsStr(argsStr) {
|
|
3580
|
+
if (!argsStr) return {};
|
|
3581
|
+
try {
|
|
3582
|
+
return JSON.parse(argsStr);
|
|
3583
|
+
} catch {
|
|
3584
|
+
const trimmed = argsStr.trim();
|
|
3585
|
+
if (trimmed.startsWith("{") && !trimmed.endsWith("}")) {
|
|
3586
|
+
try {
|
|
3587
|
+
return JSON.parse(trimmed + "}");
|
|
3588
|
+
} catch {
|
|
3589
|
+
try {
|
|
3590
|
+
return JSON.parse(trimmed + "}}");
|
|
3591
|
+
} catch {
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
return {};
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
}
|
|
3600
|
+
});
|
|
3601
|
+
|
|
3602
|
+
// src/core/logger.ts
|
|
3603
|
+
import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
|
|
3604
|
+
import { join as join7, dirname as dirname2 } from "path";
|
|
3605
|
+
var LOG_LEVEL_RANK, Logger, logger;
|
|
3606
|
+
var init_logger = __esm({
|
|
3607
|
+
"src/core/logger.ts"() {
|
|
3608
|
+
"use strict";
|
|
3609
|
+
init_constants();
|
|
3610
|
+
LOG_LEVEL_RANK = {
|
|
3611
|
+
debug: 0,
|
|
3612
|
+
info: 1,
|
|
3613
|
+
warn: 2,
|
|
3614
|
+
error: 3
|
|
3615
|
+
};
|
|
3616
|
+
Logger = class {
|
|
3617
|
+
level;
|
|
3618
|
+
logDir;
|
|
3619
|
+
currentLogFile;
|
|
3620
|
+
constructor(level = "info", logDir) {
|
|
3621
|
+
this.level = level;
|
|
3622
|
+
this.logDir = logDir ?? DEEPER_LOGS_DIR;
|
|
3623
|
+
this.currentLogFile = this.generateLogFileName();
|
|
3624
|
+
this.ensureLogDir();
|
|
3625
|
+
}
|
|
3626
|
+
setLevel(level) {
|
|
3627
|
+
this.level = level;
|
|
3628
|
+
}
|
|
3629
|
+
debug(message, data) {
|
|
3630
|
+
this.log("debug", message, data);
|
|
3631
|
+
}
|
|
3632
|
+
info(message, data) {
|
|
3633
|
+
this.log("info", message, data);
|
|
3634
|
+
}
|
|
3635
|
+
warn(message, data) {
|
|
3636
|
+
this.log("warn", message, data);
|
|
3637
|
+
}
|
|
3638
|
+
error(message, data) {
|
|
3639
|
+
this.log("error", message, data);
|
|
3640
|
+
}
|
|
3641
|
+
log(level, message, data) {
|
|
3642
|
+
if (LOG_LEVEL_RANK[level] < LOG_LEVEL_RANK[this.level]) {
|
|
3643
|
+
return;
|
|
3644
|
+
}
|
|
3645
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3646
|
+
const formatted = this.formatMessage(level, timestamp, message, data);
|
|
3647
|
+
switch (level) {
|
|
3648
|
+
case "error":
|
|
3649
|
+
console.error(formatted);
|
|
3650
|
+
break;
|
|
3651
|
+
case "warn":
|
|
3652
|
+
console.warn(formatted);
|
|
3653
|
+
break;
|
|
3654
|
+
default:
|
|
3655
|
+
console.log(formatted);
|
|
3656
|
+
break;
|
|
3657
|
+
}
|
|
3658
|
+
try {
|
|
3659
|
+
appendFileSync(this.currentLogFile, this.stripAnsi(formatted) + "\n", "utf-8");
|
|
3660
|
+
} catch {
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
formatMessage(level, timestamp, message, data) {
|
|
3664
|
+
const levelUpper = level.toUpperCase();
|
|
3665
|
+
const base = `[${timestamp}] [${levelUpper}] ${message}`;
|
|
3666
|
+
if (data !== void 0) {
|
|
3667
|
+
if (typeof data === "string") {
|
|
3668
|
+
return `${base} ${data}`;
|
|
3669
|
+
}
|
|
3670
|
+
if (data instanceof Error) {
|
|
3671
|
+
return `${base} ${data.message}
|
|
3672
|
+
${data.stack ?? ""}`;
|
|
3673
|
+
}
|
|
3674
|
+
try {
|
|
3675
|
+
return `${base} ${JSON.stringify(data)}`;
|
|
3676
|
+
} catch {
|
|
3677
|
+
return `${base} [Unserializable data]`;
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
return base;
|
|
3681
|
+
}
|
|
3682
|
+
stripAnsi(text) {
|
|
3683
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
3684
|
+
}
|
|
3685
|
+
generateLogFileName() {
|
|
3686
|
+
const now = /* @__PURE__ */ new Date();
|
|
3687
|
+
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, "");
|
|
3688
|
+
return join7(this.logDir, `deeper-${dateStr}.log`);
|
|
3689
|
+
}
|
|
3690
|
+
ensureLogDir() {
|
|
3691
|
+
const dir = dirname2(this.currentLogFile);
|
|
3692
|
+
if (!existsSync8(dir)) {
|
|
3693
|
+
mkdirSync5(dir, { recursive: true });
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
};
|
|
3697
|
+
logger = new Logger();
|
|
3698
|
+
}
|
|
3699
|
+
});
|
|
3700
|
+
|
|
3701
|
+
// src/model/DeepSeekClient.ts
|
|
3702
|
+
var DEFAULT_TIMEOUT_MS, MAX_RETRIES, isRetryable, DeepSeekClient;
|
|
3703
|
+
var init_DeepSeekClient = __esm({
|
|
3704
|
+
"src/model/DeepSeekClient.ts"() {
|
|
3705
|
+
"use strict";
|
|
3706
|
+
init_RetryManager();
|
|
3707
|
+
init_StreamHandler();
|
|
3708
|
+
init_logger();
|
|
3709
|
+
DEFAULT_TIMEOUT_MS = 12e4;
|
|
3710
|
+
MAX_RETRIES = 3;
|
|
3711
|
+
isRetryable = (error, _attempt) => {
|
|
3712
|
+
const msg = error.message.toLowerCase();
|
|
3713
|
+
if (msg.includes("429") || msg.includes("rate limit")) return true;
|
|
3714
|
+
if (msg.includes("500") || msg.includes("502") || msg.includes("503") || msg.includes("504")) return true;
|
|
3715
|
+
if (msg.includes("timeout") || msg.includes("abort")) return _attempt < 2;
|
|
3716
|
+
if (msg.includes("econnreset") || msg.includes("econnrefused")) return true;
|
|
3717
|
+
return false;
|
|
3718
|
+
};
|
|
3719
|
+
DeepSeekClient = class {
|
|
3720
|
+
config;
|
|
3721
|
+
retryManager;
|
|
3722
|
+
constructor(config) {
|
|
3723
|
+
this.config = config;
|
|
3724
|
+
this.retryManager = new RetryManager(MAX_RETRIES);
|
|
3725
|
+
}
|
|
3726
|
+
async chat(messages, tools, overrides) {
|
|
3727
|
+
const cfg = this.mergeConfig(overrides);
|
|
3728
|
+
const body = this.buildRequestBody(messages, tools, cfg, false);
|
|
3729
|
+
const response = await this.retryManager.execute(async () => {
|
|
3730
|
+
return this.retryManager.withTimeout(
|
|
3731
|
+
() => this.makeRequest(cfg, body),
|
|
3732
|
+
DEFAULT_TIMEOUT_MS,
|
|
3733
|
+
cfg.signal
|
|
3734
|
+
);
|
|
3735
|
+
}, isRetryable);
|
|
3736
|
+
const data = await response.json();
|
|
3737
|
+
if (!data.choices || data.choices.length === 0) {
|
|
3738
|
+
throw new Error("No choices returned from API");
|
|
3739
|
+
}
|
|
3740
|
+
const choice = data.choices[0];
|
|
3741
|
+
const message = choice.message;
|
|
3742
|
+
const result = {
|
|
3743
|
+
role: "assistant",
|
|
3744
|
+
content: message.content
|
|
3745
|
+
};
|
|
3746
|
+
if (message.tool_calls) {
|
|
3747
|
+
result.tool_calls = message.tool_calls.map((tc) => ({
|
|
3748
|
+
id: tc.id,
|
|
3749
|
+
name: tc.function.name,
|
|
3750
|
+
arguments: this.parseArguments(tc.function.arguments)
|
|
3751
|
+
}));
|
|
3752
|
+
}
|
|
3753
|
+
if (message.reasoning_content) {
|
|
3754
|
+
result.reasoning_content = message.reasoning_content;
|
|
3755
|
+
}
|
|
3756
|
+
return result;
|
|
3757
|
+
}
|
|
3758
|
+
async chatStream(messages, tools, overrides) {
|
|
3759
|
+
const cfg = this.mergeConfig(overrides);
|
|
3760
|
+
const body = this.buildRequestBody(messages, tools, cfg, true);
|
|
3761
|
+
const response = await this.retryManager.execute(async () => {
|
|
3762
|
+
return this.retryManager.withTimeout(
|
|
3763
|
+
() => this.makeRequest(cfg, body),
|
|
3764
|
+
DEFAULT_TIMEOUT_MS,
|
|
3765
|
+
cfg.signal
|
|
3766
|
+
);
|
|
3767
|
+
}, isRetryable);
|
|
3768
|
+
if (!response.body) {
|
|
3769
|
+
throw new Error("Response body is empty");
|
|
3770
|
+
}
|
|
3771
|
+
return this.createStreamIterable(response.body);
|
|
3772
|
+
}
|
|
3773
|
+
async *createStreamIterable(body) {
|
|
3774
|
+
const handler = new StreamHandler();
|
|
3775
|
+
let buffer = "";
|
|
3776
|
+
const stream = body;
|
|
3777
|
+
for await (const chunk of stream) {
|
|
3778
|
+
const text = typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
|
|
3779
|
+
buffer += text;
|
|
3780
|
+
const lines = buffer.split("\n");
|
|
3781
|
+
buffer = lines.pop() ?? "";
|
|
3782
|
+
for (const line of lines) {
|
|
3783
|
+
const trimmed = line.trim();
|
|
3784
|
+
if (!trimmed || trimmed.startsWith(":")) {
|
|
3785
|
+
continue;
|
|
3786
|
+
}
|
|
3787
|
+
if (trimmed.startsWith("data: ")) {
|
|
3788
|
+
const data = trimmed.slice(6);
|
|
3789
|
+
const result = handler.handleEvent("message", data);
|
|
3790
|
+
if (result) {
|
|
3791
|
+
if (Array.isArray(result)) {
|
|
3792
|
+
for (const r2 of result) yield r2;
|
|
3793
|
+
} else yield result;
|
|
3794
|
+
}
|
|
3795
|
+
} else if (trimmed === "data: [DONE]") {
|
|
3796
|
+
yield { type: "done" };
|
|
3797
|
+
return;
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
if (buffer.trim()) {
|
|
3802
|
+
const trimmed = buffer.trim();
|
|
3803
|
+
if (trimmed.startsWith("data: ")) {
|
|
3804
|
+
const data = trimmed.slice(6);
|
|
3805
|
+
const result = handler.handleEvent("message", data);
|
|
3806
|
+
if (result) {
|
|
3807
|
+
if (Array.isArray(result)) {
|
|
3808
|
+
for (const r2 of result) yield r2;
|
|
3809
|
+
} else yield result;
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
if (!handler.isFinished()) {
|
|
3814
|
+
yield { type: "done" };
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
buildRequestBody(messages, tools, config, stream) {
|
|
3818
|
+
const body = {
|
|
3819
|
+
model: config.model,
|
|
3820
|
+
messages: messages.map((m) => {
|
|
3821
|
+
const msg = {
|
|
3822
|
+
role: m.role,
|
|
3823
|
+
content: m.content
|
|
3824
|
+
};
|
|
3825
|
+
if (m.tool_calls) {
|
|
3826
|
+
msg.tool_calls = m.tool_calls.map((tc) => ({
|
|
3827
|
+
id: tc.id,
|
|
3828
|
+
type: "function",
|
|
3829
|
+
function: {
|
|
3830
|
+
name: tc.name,
|
|
3831
|
+
arguments: JSON.stringify(tc.arguments)
|
|
3832
|
+
}
|
|
3833
|
+
}));
|
|
3834
|
+
}
|
|
3835
|
+
if (m.tool_call_id) {
|
|
3836
|
+
msg.tool_call_id = m.tool_call_id;
|
|
3837
|
+
}
|
|
3838
|
+
if (m.name) {
|
|
3839
|
+
msg.name = m.name;
|
|
3840
|
+
}
|
|
3841
|
+
const rc = m.reasoning_content || m.thinking;
|
|
3842
|
+
if (rc) msg.reasoning_content = rc;
|
|
3843
|
+
return msg;
|
|
3844
|
+
}),
|
|
3845
|
+
temperature: config.temperature,
|
|
3846
|
+
max_tokens: config.maxTokens,
|
|
3847
|
+
stream
|
|
3848
|
+
};
|
|
3849
|
+
if (config.think?.enabled) {
|
|
3850
|
+
body.thinking = {
|
|
3851
|
+
type: "enabled",
|
|
3852
|
+
budget_tokens: config.think.budgetTokens
|
|
3853
|
+
};
|
|
3854
|
+
}
|
|
3855
|
+
if (tools && tools.length > 0) {
|
|
3856
|
+
body.tools = tools.map((tool) => ({
|
|
3857
|
+
type: "function",
|
|
3858
|
+
function: {
|
|
3859
|
+
name: tool.name,
|
|
3860
|
+
description: tool.description,
|
|
3861
|
+
parameters: tool.parameters
|
|
3862
|
+
}
|
|
3863
|
+
}));
|
|
3864
|
+
body.tool_choice = "auto";
|
|
3865
|
+
}
|
|
3866
|
+
return JSON.stringify(body);
|
|
3867
|
+
}
|
|
3868
|
+
async makeRequest(config, body) {
|
|
3869
|
+
const url = `${config.baseUrl}/v1/chat/completions`;
|
|
3870
|
+
logger.debug("DeepSeek API request", { url, model: config.model });
|
|
3871
|
+
const fetchOpts = {
|
|
3872
|
+
method: "POST",
|
|
3873
|
+
headers: {
|
|
3874
|
+
"Content-Type": "application/json",
|
|
3875
|
+
"Authorization": `Bearer ${config.apiKey}`,
|
|
3876
|
+
"Accept": "application/json"
|
|
3877
|
+
},
|
|
3878
|
+
body
|
|
3879
|
+
};
|
|
3880
|
+
if (config.signal) {
|
|
3881
|
+
fetchOpts.signal = config.signal;
|
|
3882
|
+
}
|
|
3883
|
+
const response = await fetch(url, fetchOpts);
|
|
3884
|
+
if (!response.ok) {
|
|
3885
|
+
const errorBody = await response.text().catch(() => "");
|
|
3886
|
+
logger.error("DeepSeek API error", {
|
|
3887
|
+
status: response.status,
|
|
3888
|
+
statusText: response.statusText,
|
|
3889
|
+
body: errorBody.slice(0, 500)
|
|
3890
|
+
});
|
|
3891
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorBody.slice(0, 200)}`);
|
|
3892
|
+
}
|
|
3893
|
+
return response;
|
|
3894
|
+
}
|
|
3895
|
+
parseArguments(argsStr) {
|
|
3896
|
+
try {
|
|
3897
|
+
return JSON.parse(argsStr);
|
|
3898
|
+
} catch {
|
|
3899
|
+
return {};
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
mergeConfig(overrides) {
|
|
3903
|
+
if (!overrides) {
|
|
3904
|
+
return this.config;
|
|
3905
|
+
}
|
|
3906
|
+
return {
|
|
3907
|
+
...this.config,
|
|
3908
|
+
...overrides,
|
|
3909
|
+
think: {
|
|
3910
|
+
...this.config.think,
|
|
3911
|
+
...overrides.think ?? {}
|
|
3912
|
+
}
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
3915
|
+
};
|
|
3916
|
+
}
|
|
3917
|
+
});
|
|
3918
|
+
|
|
3274
3919
|
// src/ui/ansi.ts
|
|
3275
3920
|
import process4 from "process";
|
|
3276
3921
|
function Oflush() {
|
|
@@ -3363,7 +4008,7 @@ var init_ansi = __esm({
|
|
|
3363
4008
|
});
|
|
3364
4009
|
|
|
3365
4010
|
// src/tools/builtin/filesystem/read_file.ts
|
|
3366
|
-
import { readFileSync as readFileSync5, existsSync as
|
|
4011
|
+
import { readFileSync as readFileSync5, existsSync as existsSync9 } from "fs";
|
|
3367
4012
|
import { resolve, normalize } from "path";
|
|
3368
4013
|
var read_file;
|
|
3369
4014
|
var init_read_file = __esm({
|
|
@@ -3387,11 +4032,11 @@ var init_read_file = __esm({
|
|
|
3387
4032
|
async execute(params) {
|
|
3388
4033
|
try {
|
|
3389
4034
|
const filePath = resolve(params.file_path);
|
|
3390
|
-
if (!
|
|
4035
|
+
if (!existsSync9(filePath)) {
|
|
3391
4036
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
3392
4037
|
}
|
|
3393
|
-
const
|
|
3394
|
-
const stat =
|
|
4038
|
+
const statSync13 = await import("fs").then((m) => m.statSync);
|
|
4039
|
+
const stat = statSync13(filePath);
|
|
3395
4040
|
if (stat.isDirectory()) {
|
|
3396
4041
|
return { success: false, error: `\u8DEF\u5F84\u662F\u76EE\u5F55\uFF0C\u4E0D\u662F\u6587\u4EF6: ${filePath}`, output: "" };
|
|
3397
4042
|
}
|
|
@@ -3425,9 +4070,9 @@ var init_read_file = __esm({
|
|
|
3425
4070
|
});
|
|
3426
4071
|
|
|
3427
4072
|
// src/tools/builtin/filesystem/write_file.ts
|
|
3428
|
-
import { existsSync as
|
|
4073
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6 } from "fs";
|
|
3429
4074
|
import { writeFile as writeFile2, appendFile } from "fs/promises";
|
|
3430
|
-
import { dirname as
|
|
4075
|
+
import { dirname as dirname3, resolve as resolve2 } from "path";
|
|
3431
4076
|
var write_file;
|
|
3432
4077
|
var init_write_file = __esm({
|
|
3433
4078
|
"src/tools/builtin/filesystem/write_file.ts"() {
|
|
@@ -3458,8 +4103,8 @@ var init_write_file = __esm({
|
|
|
3458
4103
|
if (!content.trim() && !append) {
|
|
3459
4104
|
return { success: false, error: `\u5185\u5BB9\u4E3A\u7A7A\uFF0C\u8DF3\u8FC7\u5199\u5165: ${filePath}`, output: "" };
|
|
3460
4105
|
}
|
|
3461
|
-
const dir =
|
|
3462
|
-
if (!
|
|
4106
|
+
const dir = dirname3(filePath);
|
|
4107
|
+
if (!existsSync10(dir)) mkdirSync6(dir, { recursive: true });
|
|
3463
4108
|
if (append) {
|
|
3464
4109
|
await appendFile(filePath, content, "utf-8");
|
|
3465
4110
|
} else {
|
|
@@ -3476,7 +4121,7 @@ var init_write_file = __esm({
|
|
|
3476
4121
|
});
|
|
3477
4122
|
|
|
3478
4123
|
// src/tools/builtin/filesystem/edit_file.ts
|
|
3479
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as
|
|
4124
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync11 } from "fs";
|
|
3480
4125
|
import { resolve as resolve3 } from "path";
|
|
3481
4126
|
var edit_file;
|
|
3482
4127
|
var init_edit_file = __esm({
|
|
@@ -3504,7 +4149,7 @@ var init_edit_file = __esm({
|
|
|
3504
4149
|
const oldStr = params.old_str;
|
|
3505
4150
|
const newStr = params.new_str;
|
|
3506
4151
|
const replaceAll = params.replace_all ?? false;
|
|
3507
|
-
if (!
|
|
4152
|
+
if (!existsSync11(filePath)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
3508
4153
|
const content = readFileSync6(filePath, "utf-8");
|
|
3509
4154
|
const index = content.indexOf(oldStr);
|
|
3510
4155
|
if (index === -1) return { success: false, error: "\u672A\u627E\u5230\u5339\u914D\u7684\u5B57\u7B26\u4E32", output: "" };
|
|
@@ -3530,7 +4175,7 @@ var init_edit_file = __esm({
|
|
|
3530
4175
|
});
|
|
3531
4176
|
|
|
3532
4177
|
// src/tools/builtin/filesystem/delete_file.ts
|
|
3533
|
-
import { unlinkSync, existsSync as
|
|
4178
|
+
import { unlinkSync, existsSync as existsSync12 } from "fs";
|
|
3534
4179
|
import { resolve as resolve4 } from "path";
|
|
3535
4180
|
var delete_file;
|
|
3536
4181
|
var init_delete_file = __esm({
|
|
@@ -3552,7 +4197,7 @@ var init_delete_file = __esm({
|
|
|
3552
4197
|
async execute(params) {
|
|
3553
4198
|
try {
|
|
3554
4199
|
const filePath = resolve4(params.file_path);
|
|
3555
|
-
if (!
|
|
4200
|
+
if (!existsSync12(filePath)) {
|
|
3556
4201
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
3557
4202
|
}
|
|
3558
4203
|
unlinkSync(filePath);
|
|
@@ -3566,8 +4211,8 @@ var init_delete_file = __esm({
|
|
|
3566
4211
|
});
|
|
3567
4212
|
|
|
3568
4213
|
// src/tools/builtin/filesystem/list_dir.ts
|
|
3569
|
-
import { readdirSync as readdirSync3, existsSync as
|
|
3570
|
-
import { resolve as resolve5, join as
|
|
4214
|
+
import { readdirSync as readdirSync3, existsSync as existsSync13 } from "fs";
|
|
4215
|
+
import { resolve as resolve5, join as join8 } from "path";
|
|
3571
4216
|
var list_dir;
|
|
3572
4217
|
var init_list_dir = __esm({
|
|
3573
4218
|
"src/tools/builtin/filesystem/list_dir.ts"() {
|
|
@@ -3597,7 +4242,7 @@ var init_list_dir = __esm({
|
|
|
3597
4242
|
const isDir = entry.isDirectory();
|
|
3598
4243
|
lines.push(`${prefix}${isDir ? "\u{1F4C1}" : "\u{1F4C4}"} ${entry.name}`);
|
|
3599
4244
|
if (isDir && recursive) {
|
|
3600
|
-
walk2(
|
|
4245
|
+
walk2(join8(dir, entry.name), depth + 1, prefix + " ");
|
|
3601
4246
|
}
|
|
3602
4247
|
}
|
|
3603
4248
|
} catch {
|
|
@@ -3608,10 +4253,10 @@ var init_list_dir = __esm({
|
|
|
3608
4253
|
const dirPath = resolve5(params.dir_path);
|
|
3609
4254
|
const recursive = params.recursive ?? false;
|
|
3610
4255
|
const maxDepth = params.max_depth ?? 3;
|
|
3611
|
-
if (!
|
|
4256
|
+
if (!existsSync13(dirPath)) {
|
|
3612
4257
|
return { success: false, error: `\u76EE\u5F55\u4E0D\u5B58\u5728: ${dirPath}`, output: "" };
|
|
3613
4258
|
}
|
|
3614
|
-
const { statSync:
|
|
4259
|
+
const { statSync: statSync13 } = await import("fs");
|
|
3615
4260
|
const lines = [];
|
|
3616
4261
|
walk2(dirPath, 1, "");
|
|
3617
4262
|
return { success: true, output: lines.join("\n"), metadata: { path: dirPath, entries: lines.length } };
|
|
@@ -3674,8 +4319,8 @@ var init_glob_find = __esm({
|
|
|
3674
4319
|
});
|
|
3675
4320
|
|
|
3676
4321
|
// src/tools/builtin/filesystem/move_file.ts
|
|
3677
|
-
import { renameSync, existsSync as
|
|
3678
|
-
import { resolve as resolve7, dirname as
|
|
4322
|
+
import { renameSync, existsSync as existsSync14 } from "fs";
|
|
4323
|
+
import { resolve as resolve7, dirname as dirname4 } from "path";
|
|
3679
4324
|
var move_file;
|
|
3680
4325
|
var init_move_file = __esm({
|
|
3681
4326
|
"src/tools/builtin/filesystem/move_file.ts"() {
|
|
@@ -3698,13 +4343,13 @@ var init_move_file = __esm({
|
|
|
3698
4343
|
try {
|
|
3699
4344
|
const source = resolve7(params.source);
|
|
3700
4345
|
const dest = resolve7(params.destination);
|
|
3701
|
-
if (!
|
|
4346
|
+
if (!existsSync14(source)) {
|
|
3702
4347
|
return { success: false, error: `\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728: ${source}`, output: "" };
|
|
3703
4348
|
}
|
|
3704
|
-
const destDir =
|
|
3705
|
-
const { mkdirSync:
|
|
3706
|
-
if (!
|
|
3707
|
-
|
|
4349
|
+
const destDir = dirname4(dest);
|
|
4350
|
+
const { mkdirSync: mkdirSync16 } = await import("fs");
|
|
4351
|
+
if (!existsSync14(destDir)) {
|
|
4352
|
+
mkdirSync16(destDir, { recursive: true });
|
|
3708
4353
|
}
|
|
3709
4354
|
renameSync(source, dest);
|
|
3710
4355
|
return { success: true, output: `\u5DF2\u79FB\u52A8: ${source} -> ${dest}` };
|
|
@@ -3717,8 +4362,8 @@ var init_move_file = __esm({
|
|
|
3717
4362
|
});
|
|
3718
4363
|
|
|
3719
4364
|
// src/tools/builtin/filesystem/copy_file.ts
|
|
3720
|
-
import { copyFileSync, existsSync as
|
|
3721
|
-
import { resolve as resolve8, dirname as
|
|
4365
|
+
import { copyFileSync, existsSync as existsSync15, mkdirSync as mkdirSync7 } from "fs";
|
|
4366
|
+
import { resolve as resolve8, dirname as dirname5 } from "path";
|
|
3722
4367
|
var copy_file;
|
|
3723
4368
|
var init_copy_file = __esm({
|
|
3724
4369
|
"src/tools/builtin/filesystem/copy_file.ts"() {
|
|
@@ -3741,12 +4386,12 @@ var init_copy_file = __esm({
|
|
|
3741
4386
|
try {
|
|
3742
4387
|
const source = resolve8(params.source);
|
|
3743
4388
|
const dest = resolve8(params.destination);
|
|
3744
|
-
if (!
|
|
4389
|
+
if (!existsSync15(source)) {
|
|
3745
4390
|
return { success: false, error: `\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728: ${source}`, output: "" };
|
|
3746
4391
|
}
|
|
3747
|
-
const destDir =
|
|
3748
|
-
if (!
|
|
3749
|
-
|
|
4392
|
+
const destDir = dirname5(dest);
|
|
4393
|
+
if (!existsSync15(destDir)) {
|
|
4394
|
+
mkdirSync7(destDir, { recursive: true });
|
|
3750
4395
|
}
|
|
3751
4396
|
copyFileSync(source, dest);
|
|
3752
4397
|
return { success: true, output: `\u5DF2\u590D\u5236: ${source} -> ${dest}` };
|
|
@@ -3759,7 +4404,7 @@ var init_copy_file = __esm({
|
|
|
3759
4404
|
});
|
|
3760
4405
|
|
|
3761
4406
|
// src/tools/builtin/filesystem/create_dir.ts
|
|
3762
|
-
import { mkdirSync as
|
|
4407
|
+
import { mkdirSync as mkdirSync8, existsSync as existsSync16 } from "fs";
|
|
3763
4408
|
import { resolve as resolve9 } from "path";
|
|
3764
4409
|
var create_dir;
|
|
3765
4410
|
var init_create_dir = __esm({
|
|
@@ -3781,10 +4426,10 @@ var init_create_dir = __esm({
|
|
|
3781
4426
|
async execute(params) {
|
|
3782
4427
|
try {
|
|
3783
4428
|
const dirPath = resolve9(params.dir_path);
|
|
3784
|
-
if (
|
|
4429
|
+
if (existsSync16(dirPath)) {
|
|
3785
4430
|
return { success: true, output: `\u76EE\u5F55\u5DF2\u5B58\u5728: ${dirPath}` };
|
|
3786
4431
|
}
|
|
3787
|
-
|
|
4432
|
+
mkdirSync8(dirPath, { recursive: true });
|
|
3788
4433
|
return { success: true, output: `\u76EE\u5F55\u5DF2\u521B\u5EFA: ${dirPath}` };
|
|
3789
4434
|
} catch (err) {
|
|
3790
4435
|
return { success: false, error: err.message, output: "" };
|
|
@@ -3795,7 +4440,7 @@ var init_create_dir = __esm({
|
|
|
3795
4440
|
});
|
|
3796
4441
|
|
|
3797
4442
|
// src/tools/builtin/filesystem/file_info.ts
|
|
3798
|
-
import { statSync, existsSync as
|
|
4443
|
+
import { statSync, existsSync as existsSync17 } from "fs";
|
|
3799
4444
|
import { resolve as resolve10, basename } from "path";
|
|
3800
4445
|
function formatSize(bytes) {
|
|
3801
4446
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -3823,7 +4468,7 @@ var init_file_info = __esm({
|
|
|
3823
4468
|
async execute(params) {
|
|
3824
4469
|
try {
|
|
3825
4470
|
const filePath = resolve10(params.file_path);
|
|
3826
|
-
if (!
|
|
4471
|
+
if (!existsSync17(filePath)) {
|
|
3827
4472
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
3828
4473
|
}
|
|
3829
4474
|
const stat = statSync(filePath);
|
|
@@ -3852,7 +4497,7 @@ var init_file_info = __esm({
|
|
|
3852
4497
|
});
|
|
3853
4498
|
|
|
3854
4499
|
// src/tools/builtin/filesystem/watch_file.ts
|
|
3855
|
-
import { existsSync as
|
|
4500
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3856
4501
|
import { resolve as resolve11 } from "path";
|
|
3857
4502
|
var watch_file;
|
|
3858
4503
|
var init_watch_file = __esm({
|
|
@@ -3874,7 +4519,7 @@ var init_watch_file = __esm({
|
|
|
3874
4519
|
async execute(params) {
|
|
3875
4520
|
try {
|
|
3876
4521
|
const filePath = resolve11(params.file_path);
|
|
3877
|
-
if (!
|
|
4522
|
+
if (!existsSync18(filePath)) {
|
|
3878
4523
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
3879
4524
|
}
|
|
3880
4525
|
return {
|
|
@@ -3891,7 +4536,7 @@ var init_watch_file = __esm({
|
|
|
3891
4536
|
});
|
|
3892
4537
|
|
|
3893
4538
|
// src/tools/builtin/filesystem/batch_read.ts
|
|
3894
|
-
import { readFileSync as readFileSync7, existsSync as
|
|
4539
|
+
import { readFileSync as readFileSync7, existsSync as existsSync19 } from "fs";
|
|
3895
4540
|
import { resolve as resolve12 } from "path";
|
|
3896
4541
|
var batch_read;
|
|
3897
4542
|
var init_batch_read = __esm({
|
|
@@ -3919,7 +4564,7 @@ var init_batch_read = __esm({
|
|
|
3919
4564
|
for (const p of paths) {
|
|
3920
4565
|
const abs = resolve12(p);
|
|
3921
4566
|
try {
|
|
3922
|
-
if (!
|
|
4567
|
+
if (!existsSync19(abs)) {
|
|
3923
4568
|
results[p] = { content: "", error: "\u6587\u4EF6\u4E0D\u5B58\u5728" };
|
|
3924
4569
|
continue;
|
|
3925
4570
|
}
|
|
@@ -3952,9 +4597,9 @@ ${r2.content}`;
|
|
|
3952
4597
|
});
|
|
3953
4598
|
|
|
3954
4599
|
// src/tools/builtin/filesystem/batch_write.ts
|
|
3955
|
-
import { existsSync as
|
|
4600
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync9 } from "fs";
|
|
3956
4601
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
3957
|
-
import { resolve as resolve13, dirname as
|
|
4602
|
+
import { resolve as resolve13, dirname as dirname6 } from "path";
|
|
3958
4603
|
var batch_write;
|
|
3959
4604
|
var init_batch_write = __esm({
|
|
3960
4605
|
"src/tools/builtin/filesystem/batch_write.ts"() {
|
|
@@ -4001,9 +4646,9 @@ var init_batch_write = __esm({
|
|
|
4001
4646
|
skipped.push(`${abs} (\u5185\u5BB9\u8FC7\u5927)`);
|
|
4002
4647
|
continue;
|
|
4003
4648
|
}
|
|
4004
|
-
const dir =
|
|
4005
|
-
if (!
|
|
4006
|
-
|
|
4649
|
+
const dir = dirname6(abs);
|
|
4650
|
+
if (!existsSync20(dir)) {
|
|
4651
|
+
mkdirSync9(dir, { recursive: true });
|
|
4007
4652
|
}
|
|
4008
4653
|
await writeFile3(abs, content, "utf-8");
|
|
4009
4654
|
results.push(abs);
|
|
@@ -4025,7 +4670,7 @@ var init_batch_write = __esm({
|
|
|
4025
4670
|
});
|
|
4026
4671
|
|
|
4027
4672
|
// src/tools/builtin/filesystem/diff_files.ts
|
|
4028
|
-
import { readFileSync as readFileSync8, existsSync as
|
|
4673
|
+
import { readFileSync as readFileSync8, existsSync as existsSync21 } from "fs";
|
|
4029
4674
|
import { resolve as resolve14 } from "path";
|
|
4030
4675
|
var diff_files;
|
|
4031
4676
|
var init_diff_files = __esm({
|
|
@@ -4051,8 +4696,8 @@ var init_diff_files = __esm({
|
|
|
4051
4696
|
const fileA = resolve14(params.file_a);
|
|
4052
4697
|
const fileB = resolve14(params.file_b);
|
|
4053
4698
|
const contextLines = params.context_lines ?? 3;
|
|
4054
|
-
if (!
|
|
4055
|
-
if (!
|
|
4699
|
+
if (!existsSync21(fileA)) return { success: false, error: `\u6587\u4EF6A\u4E0D\u5B58\u5728: ${fileA}`, output: "" };
|
|
4700
|
+
if (!existsSync21(fileB)) return { success: false, error: `\u6587\u4EF6B\u4E0D\u5B58\u5728: ${fileB}`, output: "" };
|
|
4056
4701
|
const contentA = readFileSync8(fileA, "utf-8");
|
|
4057
4702
|
const contentB = readFileSync8(fileB, "utf-8");
|
|
4058
4703
|
const Diff = await import("diff");
|
|
@@ -4083,7 +4728,7 @@ var init_diff_files = __esm({
|
|
|
4083
4728
|
});
|
|
4084
4729
|
|
|
4085
4730
|
// src/tools/builtin/filesystem/merge_files.ts
|
|
4086
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as
|
|
4731
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as existsSync22 } from "fs";
|
|
4087
4732
|
import { resolve as resolve15 } from "path";
|
|
4088
4733
|
var merge_files;
|
|
4089
4734
|
var init_merge_files = __esm({
|
|
@@ -4112,7 +4757,7 @@ var init_merge_files = __esm({
|
|
|
4112
4757
|
const parts = [];
|
|
4113
4758
|
for (const p of paths) {
|
|
4114
4759
|
const abs = resolve15(p);
|
|
4115
|
-
if (!
|
|
4760
|
+
if (!existsSync22(abs)) {
|
|
4116
4761
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
4117
4762
|
}
|
|
4118
4763
|
parts.push(readFileSync9(abs, "utf-8"));
|
|
@@ -4133,7 +4778,7 @@ var init_merge_files = __esm({
|
|
|
4133
4778
|
});
|
|
4134
4779
|
|
|
4135
4780
|
// src/tools/builtin/search/grep_search.ts
|
|
4136
|
-
import { readFileSync as readFileSync10, existsSync as
|
|
4781
|
+
import { readFileSync as readFileSync10, existsSync as existsSync23, statSync as statSync2 } from "fs";
|
|
4137
4782
|
import { resolve as resolve16 } from "path";
|
|
4138
4783
|
var grep_search;
|
|
4139
4784
|
var init_grep_search = __esm({
|
|
@@ -4198,7 +4843,7 @@ var init_grep_search = __esm({
|
|
|
4198
4843
|
const maxFileSize = 5 * 1024 * 1024;
|
|
4199
4844
|
if (filePath) {
|
|
4200
4845
|
const abs = resolve16(filePath);
|
|
4201
|
-
if (
|
|
4846
|
+
if (existsSync23(abs)) searchFile2(abs);
|
|
4202
4847
|
} else if (dirPath) {
|
|
4203
4848
|
const fg2 = await import("fast-glob");
|
|
4204
4849
|
const pattern2 = glob ? `**/${glob}` : "**/*";
|
|
@@ -4671,7 +5316,7 @@ var init_fuzzy_find = __esm({
|
|
|
4671
5316
|
});
|
|
4672
5317
|
|
|
4673
5318
|
// src/tools/builtin/search/regex_find.ts
|
|
4674
|
-
import { readFileSync as readFileSync16, writeFileSync as writeFileSync6, existsSync as
|
|
5319
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync6, existsSync as existsSync29 } from "fs";
|
|
4675
5320
|
import { resolve as resolve23 } from "path";
|
|
4676
5321
|
var regex_find;
|
|
4677
5322
|
var init_regex_find = __esm({
|
|
@@ -4737,7 +5382,7 @@ var init_regex_find = __esm({
|
|
|
4737
5382
|
}
|
|
4738
5383
|
if (filePath) {
|
|
4739
5384
|
const abs = resolve23(filePath);
|
|
4740
|
-
if (
|
|
5385
|
+
if (existsSync29(abs)) await processFile(abs);
|
|
4741
5386
|
} else if (dirPath) {
|
|
4742
5387
|
const fg2 = await import("fast-glob");
|
|
4743
5388
|
const files = await fg2.default(filePattern, {
|
|
@@ -5315,7 +5960,7 @@ ${stderr}` : ""),
|
|
|
5315
5960
|
});
|
|
5316
5961
|
|
|
5317
5962
|
// src/tools/builtin/shell/shell_script.ts
|
|
5318
|
-
import { existsSync as
|
|
5963
|
+
import { existsSync as existsSync30 } from "fs";
|
|
5319
5964
|
import { exec as execCb2 } from "child_process";
|
|
5320
5965
|
import { promisify as promisify2 } from "util";
|
|
5321
5966
|
import { resolve as resolve24 } from "path";
|
|
@@ -5346,7 +5991,7 @@ var init_shell_script = __esm({
|
|
|
5346
5991
|
const args = params.args ?? [];
|
|
5347
5992
|
const cwd = params.cwd ?? process.cwd();
|
|
5348
5993
|
const timeout = params.timeout_ms ?? 3e4;
|
|
5349
|
-
if (!
|
|
5994
|
+
if (!existsSync30(scriptPath)) {
|
|
5350
5995
|
return { success: false, error: `\u811A\u672C\u6587\u4EF6\u4E0D\u5B58\u5728: ${scriptPath}`, output: "" };
|
|
5351
5996
|
}
|
|
5352
5997
|
const shell = process.platform === "win32" ? process.env.ComSpec || "cmd.exe" : process.env.SHELL || "/bin/sh";
|
|
@@ -6017,8 +6662,8 @@ var init_http_request = __esm({
|
|
|
6017
6662
|
});
|
|
6018
6663
|
|
|
6019
6664
|
// src/tools/builtin/network/download_file.ts
|
|
6020
|
-
import { createWriteStream, existsSync as
|
|
6021
|
-
import { dirname as
|
|
6665
|
+
import { createWriteStream, existsSync as existsSync31, mkdirSync as mkdirSync10 } from "fs";
|
|
6666
|
+
import { dirname as dirname7, resolve as resolve25 } from "path";
|
|
6022
6667
|
import { pipeline } from "stream/promises";
|
|
6023
6668
|
function formatSize2(bytes) {
|
|
6024
6669
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -6049,9 +6694,9 @@ var init_download_file = __esm({
|
|
|
6049
6694
|
const url = params.url;
|
|
6050
6695
|
const filePath = resolve25(params.file_path);
|
|
6051
6696
|
const timeout = params.timeout_ms ?? 6e4;
|
|
6052
|
-
const dir =
|
|
6053
|
-
if (!
|
|
6054
|
-
|
|
6697
|
+
const dir = dirname7(filePath);
|
|
6698
|
+
if (!existsSync31(dir)) {
|
|
6699
|
+
mkdirSync10(dir, { recursive: true });
|
|
6055
6700
|
}
|
|
6056
6701
|
const controller = new AbortController();
|
|
6057
6702
|
const timer = setTimeout(() => controller.abort(), timeout);
|
|
@@ -6631,7 +7276,7 @@ var init_proxy_request = __esm({
|
|
|
6631
7276
|
});
|
|
6632
7277
|
|
|
6633
7278
|
// src/tools/builtin/code/parse_ast.ts
|
|
6634
|
-
import { readFileSync as readFileSync18, existsSync as
|
|
7279
|
+
import { readFileSync as readFileSync18, existsSync as existsSync32 } from "fs";
|
|
6635
7280
|
import { resolve as resolve26 } from "path";
|
|
6636
7281
|
var parse_ast;
|
|
6637
7282
|
var init_parse_ast = __esm({
|
|
@@ -6655,7 +7300,7 @@ var init_parse_ast = __esm({
|
|
|
6655
7300
|
try {
|
|
6656
7301
|
const filePath = resolve26(params.file_path);
|
|
6657
7302
|
const language = params.language ?? "typescript";
|
|
6658
|
-
if (!
|
|
7303
|
+
if (!existsSync32(filePath)) {
|
|
6659
7304
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
6660
7305
|
}
|
|
6661
7306
|
const content = readFileSync18(filePath, "utf-8");
|
|
@@ -6716,7 +7361,7 @@ var init_parse_ast = __esm({
|
|
|
6716
7361
|
});
|
|
6717
7362
|
|
|
6718
7363
|
// src/tools/builtin/code/format_code.ts
|
|
6719
|
-
import { readFileSync as readFileSync19, existsSync as
|
|
7364
|
+
import { readFileSync as readFileSync19, existsSync as existsSync33 } from "fs";
|
|
6720
7365
|
import { resolve as resolve27 } from "path";
|
|
6721
7366
|
var format_code;
|
|
6722
7367
|
var init_format_code = __esm({
|
|
@@ -6740,13 +7385,13 @@ var init_format_code = __esm({
|
|
|
6740
7385
|
try {
|
|
6741
7386
|
const filePath = resolve27(params.file_path);
|
|
6742
7387
|
const language = params.language ?? "typescript";
|
|
6743
|
-
if (!
|
|
7388
|
+
if (!existsSync33(filePath)) {
|
|
6744
7389
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
6745
7390
|
}
|
|
6746
7391
|
try {
|
|
6747
|
-
const { execSync:
|
|
7392
|
+
const { execSync: execSync20 } = await import("child_process");
|
|
6748
7393
|
const ext = filePath.split(".").pop() ?? "ts";
|
|
6749
|
-
|
|
7394
|
+
execSync20(`npx prettier --write "${filePath}"`, {
|
|
6750
7395
|
encoding: "utf-8",
|
|
6751
7396
|
timeout: 3e4,
|
|
6752
7397
|
stdio: "pipe"
|
|
@@ -6964,7 +7609,7 @@ var init_generate_code = __esm({
|
|
|
6964
7609
|
});
|
|
6965
7610
|
|
|
6966
7611
|
// src/tools/builtin/code/refactor_code.ts
|
|
6967
|
-
import { readFileSync as readFileSync20, existsSync as
|
|
7612
|
+
import { readFileSync as readFileSync20, existsSync as existsSync34 } from "fs";
|
|
6968
7613
|
import { resolve as resolve30 } from "path";
|
|
6969
7614
|
function escapeRegex3(s) {
|
|
6970
7615
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -6995,7 +7640,7 @@ var init_refactor_code = __esm({
|
|
|
6995
7640
|
const action = params.action;
|
|
6996
7641
|
const target = params.target;
|
|
6997
7642
|
const newName = params.new_name;
|
|
6998
|
-
if (!
|
|
7643
|
+
if (!existsSync34(filePath)) {
|
|
6999
7644
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
7000
7645
|
}
|
|
7001
7646
|
const content = readFileSync20(filePath, "utf-8");
|
|
@@ -7032,7 +7677,7 @@ var init_refactor_code = __esm({
|
|
|
7032
7677
|
});
|
|
7033
7678
|
|
|
7034
7679
|
// src/tools/builtin/code/extract_function.ts
|
|
7035
|
-
import { readFileSync as readFileSync21, existsSync as
|
|
7680
|
+
import { readFileSync as readFileSync21, existsSync as existsSync35 } from "fs";
|
|
7036
7681
|
import { resolve as resolve31 } from "path";
|
|
7037
7682
|
function escapeRegex4(s) {
|
|
7038
7683
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -7059,7 +7704,7 @@ var init_extract_function = __esm({
|
|
|
7059
7704
|
try {
|
|
7060
7705
|
const filePath = resolve31(params.file_path);
|
|
7061
7706
|
const funcName = params.function_name;
|
|
7062
|
-
if (!
|
|
7707
|
+
if (!existsSync35(filePath)) {
|
|
7063
7708
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
7064
7709
|
}
|
|
7065
7710
|
const content = readFileSync21(filePath, "utf-8");
|
|
@@ -7187,7 +7832,7 @@ var init_analyze_deps = __esm({
|
|
|
7187
7832
|
});
|
|
7188
7833
|
|
|
7189
7834
|
// src/tools/builtin/code/import_organizer.ts
|
|
7190
|
-
import { readFileSync as readFileSync23, existsSync as
|
|
7835
|
+
import { readFileSync as readFileSync23, existsSync as existsSync37 } from "fs";
|
|
7191
7836
|
import { resolve as resolve33 } from "path";
|
|
7192
7837
|
var import_organizer;
|
|
7193
7838
|
var init_import_organizer = __esm({
|
|
@@ -7215,7 +7860,7 @@ var init_import_organizer = __esm({
|
|
|
7215
7860
|
const groupBy = params.group_by ?? "source";
|
|
7216
7861
|
const sort = params.sort ?? true;
|
|
7217
7862
|
const removeUnused = params.remove_unused ?? false;
|
|
7218
|
-
if (!
|
|
7863
|
+
if (!existsSync37(filePath)) {
|
|
7219
7864
|
return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
7220
7865
|
}
|
|
7221
7866
|
const content = readFileSync23(filePath, "utf-8");
|
|
@@ -7390,10 +8035,10 @@ var init_code_metrics = __esm({
|
|
|
7390
8035
|
});
|
|
7391
8036
|
|
|
7392
8037
|
// src/core/bugscan.ts
|
|
7393
|
-
import { existsSync as
|
|
8038
|
+
import { existsSync as existsSync39, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
|
|
7394
8039
|
import { extname, basename as basename3 } from "path";
|
|
7395
8040
|
function analyzeFile(filePath) {
|
|
7396
|
-
if (!
|
|
8041
|
+
if (!existsSync39(filePath)) return [];
|
|
7397
8042
|
try {
|
|
7398
8043
|
if (statSync10(filePath).size > MAX_FILE_SIZE) return [];
|
|
7399
8044
|
} catch {
|
|
@@ -7529,7 +8174,7 @@ var init_bugscan = __esm({
|
|
|
7529
8174
|
|
|
7530
8175
|
// src/tools/builtin/code/bug_scan.ts
|
|
7531
8176
|
import { statSync as statSync11 } from "fs";
|
|
7532
|
-
import { isAbsolute, join as
|
|
8177
|
+
import { isAbsolute, join as join9 } from "path";
|
|
7533
8178
|
import fg from "fast-glob";
|
|
7534
8179
|
var MAX_FILES, EXTENSIONS, SEVERITY_ORDER, bug_scan;
|
|
7535
8180
|
var init_bug_scan = __esm({
|
|
@@ -7559,7 +8204,7 @@ var init_bug_scan = __esm({
|
|
|
7559
8204
|
const target = params.path;
|
|
7560
8205
|
const recursive = params.recursive ?? false;
|
|
7561
8206
|
const minSeverity = params.severity ?? "warning";
|
|
7562
|
-
const absPath = isAbsolute(target) ? target :
|
|
8207
|
+
const absPath = isAbsolute(target) ? target : join9(process.cwd(), target);
|
|
7563
8208
|
let isFile = false;
|
|
7564
8209
|
try {
|
|
7565
8210
|
isFile = statSync11(absPath).isFile();
|
|
@@ -7932,25 +8577,25 @@ var init_db_restore = __esm({
|
|
|
7932
8577
|
try {
|
|
7933
8578
|
const engine = params.engine;
|
|
7934
8579
|
const connection = params.connection;
|
|
7935
|
-
const
|
|
8580
|
+
const backupFile2 = params.backup_file;
|
|
7936
8581
|
let cmd = "";
|
|
7937
8582
|
switch (engine) {
|
|
7938
8583
|
case "sqlite":
|
|
7939
|
-
cmd = `sqlite3 "${connection || "database.db"}" < "${
|
|
8584
|
+
cmd = `sqlite3 "${connection || "database.db"}" < "${backupFile2}"`;
|
|
7940
8585
|
break;
|
|
7941
8586
|
case "mysql":
|
|
7942
|
-
cmd = `mysql ${connection || ""} < "${
|
|
8587
|
+
cmd = `mysql ${connection || ""} < "${backupFile2}"`;
|
|
7943
8588
|
break;
|
|
7944
8589
|
case "postgresql":
|
|
7945
|
-
cmd = `psql ${connection || ""} < "${
|
|
8590
|
+
cmd = `psql ${connection || ""} < "${backupFile2}"`;
|
|
7946
8591
|
break;
|
|
7947
8592
|
default:
|
|
7948
8593
|
return { success: false, error: `\u4E0D\u652F\u6301\u7684\u6570\u636E\u5E93\u5F15\u64CE: ${engine}`, output: "" };
|
|
7949
8594
|
}
|
|
7950
8595
|
try {
|
|
7951
8596
|
const output = execSync9(cmd, { encoding: "utf-8", timeout: 12e4, stdio: "pipe" });
|
|
7952
|
-
return { success: true, output: `\u6062\u590D\u5B8C\u6210: ${
|
|
7953
|
-
${output || ""}`, metadata: { engine, backupFile } };
|
|
8597
|
+
return { success: true, output: `\u6062\u590D\u5B8C\u6210: ${backupFile2}
|
|
8598
|
+
${output || ""}`, metadata: { engine, backupFile: backupFile2 } };
|
|
7954
8599
|
} catch (err) {
|
|
7955
8600
|
const e = err;
|
|
7956
8601
|
return { success: false, error: `\u6062\u590D\u5931\u8D25: ${e.message || String(err)}`, output: "" };
|
|
@@ -8124,10 +8769,10 @@ var init_json_parse = __esm({
|
|
|
8124
8769
|
const query = params.query;
|
|
8125
8770
|
let jsonContent = "";
|
|
8126
8771
|
if (filePath) {
|
|
8127
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
8772
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8128
8773
|
const { resolve: resolve48 } = await import("path");
|
|
8129
8774
|
const abs = resolve48(filePath);
|
|
8130
|
-
if (!
|
|
8775
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8131
8776
|
jsonContent = readFileSync38(abs, "utf-8");
|
|
8132
8777
|
} else if (content) {
|
|
8133
8778
|
jsonContent = content;
|
|
@@ -8181,10 +8826,10 @@ var init_csv_parse = __esm({
|
|
|
8181
8826
|
const delimiter = params.delimiter ?? ",";
|
|
8182
8827
|
const hasHeader = params.has_header ?? true;
|
|
8183
8828
|
if (filePath) {
|
|
8184
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
8829
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8185
8830
|
const { resolve: resolve48 } = await import("path");
|
|
8186
8831
|
const abs = resolve48(filePath);
|
|
8187
|
-
if (!
|
|
8832
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8188
8833
|
csvContent = readFileSync38(abs, "utf-8");
|
|
8189
8834
|
} else if (content) {
|
|
8190
8835
|
csvContent = content;
|
|
@@ -8268,10 +8913,10 @@ var init_xml_parse = __esm({
|
|
|
8268
8913
|
const filePath = params.file_path;
|
|
8269
8914
|
const content = params.content;
|
|
8270
8915
|
if (filePath) {
|
|
8271
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
8916
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8272
8917
|
const { resolve: resolve48 } = await import("path");
|
|
8273
8918
|
const abs = resolve48(filePath);
|
|
8274
|
-
if (!
|
|
8919
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8275
8920
|
xmlContent = readFileSync38(abs, "utf-8");
|
|
8276
8921
|
} else if (content) {
|
|
8277
8922
|
xmlContent = content;
|
|
@@ -8313,10 +8958,10 @@ var init_yaml_parse = __esm({
|
|
|
8313
8958
|
const filePath = params.file_path;
|
|
8314
8959
|
const content = params.content;
|
|
8315
8960
|
if (filePath) {
|
|
8316
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
8961
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8317
8962
|
const { resolve: resolve48 } = await import("path");
|
|
8318
8963
|
const abs = resolve48(filePath);
|
|
8319
|
-
if (!
|
|
8964
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8320
8965
|
yamlContent = readFileSync38(abs, "utf-8");
|
|
8321
8966
|
} else if (content) {
|
|
8322
8967
|
yamlContent = content;
|
|
@@ -8359,10 +9004,10 @@ var init_toml_parse = __esm({
|
|
|
8359
9004
|
const filePath = params.file_path;
|
|
8360
9005
|
let tomlContent = "";
|
|
8361
9006
|
if (filePath) {
|
|
8362
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
9007
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8363
9008
|
const { resolve: resolve48 } = await import("path");
|
|
8364
9009
|
const abs = resolve48(filePath);
|
|
8365
|
-
if (!
|
|
9010
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8366
9011
|
tomlContent = readFileSync38(abs, "utf-8");
|
|
8367
9012
|
} else if (content) {
|
|
8368
9013
|
tomlContent = content;
|
|
@@ -8411,10 +9056,10 @@ var init_data_transform = __esm({
|
|
|
8411
9056
|
const output = params.output;
|
|
8412
9057
|
let inputStr = "";
|
|
8413
9058
|
if (filePath) {
|
|
8414
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
9059
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
8415
9060
|
const { resolve: resolve48 } = await import("path");
|
|
8416
9061
|
const abs = resolve48(filePath);
|
|
8417
|
-
if (!
|
|
9062
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8418
9063
|
inputStr = readFileSync38(abs, "utf-8");
|
|
8419
9064
|
} else if (data) {
|
|
8420
9065
|
inputStr = data;
|
|
@@ -8623,7 +9268,7 @@ var init_data_diff = __esm({
|
|
|
8623
9268
|
});
|
|
8624
9269
|
|
|
8625
9270
|
// src/tools/builtin/data/template_render.ts
|
|
8626
|
-
import { readFileSync as readFileSync26, existsSync as
|
|
9271
|
+
import { readFileSync as readFileSync26, existsSync as existsSync40, writeFileSync as writeFileSync8 } from "fs";
|
|
8627
9272
|
import { resolve as resolve35 } from "path";
|
|
8628
9273
|
function escapeRegex5(s) {
|
|
8629
9274
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -8657,7 +9302,7 @@ var init_template_render = __esm({
|
|
|
8657
9302
|
let template = "";
|
|
8658
9303
|
if (filePath) {
|
|
8659
9304
|
const abs = resolve35(filePath);
|
|
8660
|
-
if (!
|
|
9305
|
+
if (!existsSync40(abs)) return { success: false, error: `\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8661
9306
|
template = readFileSync26(abs, "utf-8");
|
|
8662
9307
|
} else if (templateStr) {
|
|
8663
9308
|
template = templateStr;
|
|
@@ -8833,8 +9478,8 @@ ${results.join("\n")}
|
|
|
8833
9478
|
});
|
|
8834
9479
|
|
|
8835
9480
|
// src/tools/builtin/security/encrypt_file.ts
|
|
8836
|
-
import { readFileSync as readFileSync28, writeFileSync as writeFileSync9, existsSync as
|
|
8837
|
-
import { resolve as resolve37, dirname as
|
|
9481
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync9, existsSync as existsSync42, mkdirSync as mkdirSync11 } from "fs";
|
|
9482
|
+
import { resolve as resolve37, dirname as dirname8 } from "path";
|
|
8838
9483
|
var encrypt_file;
|
|
8839
9484
|
var init_encrypt_file = __esm({
|
|
8840
9485
|
"src/tools/builtin/security/encrypt_file.ts"() {
|
|
@@ -8861,15 +9506,15 @@ var init_encrypt_file = __esm({
|
|
|
8861
9506
|
const output = resolve37(params.output);
|
|
8862
9507
|
const password = params.password;
|
|
8863
9508
|
const algorithm = params.algorithm ?? "aes-256-cbc";
|
|
8864
|
-
if (!
|
|
9509
|
+
if (!existsSync42(filePath)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
8865
9510
|
const crypto = await import("crypto");
|
|
8866
9511
|
const content = readFileSync28(filePath);
|
|
8867
9512
|
const key = crypto.scryptSync(password || "default-secret-key", "salt", algorithm === "aes-256-cbc" ? 32 : 16);
|
|
8868
9513
|
const iv = crypto.randomBytes(16);
|
|
8869
9514
|
const cipher = crypto.createCipheriv(algorithm, key, iv);
|
|
8870
9515
|
const encrypted = Buffer.concat([iv, cipher.update(content), cipher.final()]);
|
|
8871
|
-
const outDir =
|
|
8872
|
-
if (!
|
|
9516
|
+
const outDir = dirname8(output);
|
|
9517
|
+
if (!existsSync42(outDir)) mkdirSync11(outDir, { recursive: true });
|
|
8873
9518
|
writeFileSync9(output, encrypted);
|
|
8874
9519
|
return {
|
|
8875
9520
|
success: true,
|
|
@@ -8885,8 +9530,8 @@ var init_encrypt_file = __esm({
|
|
|
8885
9530
|
});
|
|
8886
9531
|
|
|
8887
9532
|
// src/tools/builtin/security/decrypt_file.ts
|
|
8888
|
-
import { readFileSync as readFileSync29, writeFileSync as writeFileSync10, existsSync as
|
|
8889
|
-
import { resolve as resolve38, dirname as
|
|
9533
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync10, existsSync as existsSync43, mkdirSync as mkdirSync12 } from "fs";
|
|
9534
|
+
import { resolve as resolve38, dirname as dirname9 } from "path";
|
|
8890
9535
|
var decrypt_file;
|
|
8891
9536
|
var init_decrypt_file = __esm({
|
|
8892
9537
|
"src/tools/builtin/security/decrypt_file.ts"() {
|
|
@@ -8913,7 +9558,7 @@ var init_decrypt_file = __esm({
|
|
|
8913
9558
|
const output = resolve38(params.output);
|
|
8914
9559
|
const password = params.password;
|
|
8915
9560
|
const algorithm = params.algorithm ?? "aes-256-cbc";
|
|
8916
|
-
if (!
|
|
9561
|
+
if (!existsSync43(filePath)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, output: "" };
|
|
8917
9562
|
const crypto = await import("crypto");
|
|
8918
9563
|
const encrypted = readFileSync29(filePath);
|
|
8919
9564
|
const iv = encrypted.subarray(0, 16);
|
|
@@ -8921,8 +9566,8 @@ var init_decrypt_file = __esm({
|
|
|
8921
9566
|
const key = crypto.scryptSync(password || "default-secret-key", "salt", algorithm === "aes-256-cbc" ? 32 : 16);
|
|
8922
9567
|
const decipher = crypto.createDecipheriv(algorithm, key, iv);
|
|
8923
9568
|
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
8924
|
-
const outDir =
|
|
8925
|
-
if (!
|
|
9569
|
+
const outDir = dirname9(output);
|
|
9570
|
+
if (!existsSync43(outDir)) mkdirSync12(outDir, { recursive: true });
|
|
8926
9571
|
writeFileSync10(output, decrypted);
|
|
8927
9572
|
return {
|
|
8928
9573
|
success: true,
|
|
@@ -8939,7 +9584,7 @@ var init_decrypt_file = __esm({
|
|
|
8939
9584
|
|
|
8940
9585
|
// src/tools/builtin/security/hash_generate.ts
|
|
8941
9586
|
import { createHash } from "crypto";
|
|
8942
|
-
import { readFileSync as readFileSync30, existsSync as
|
|
9587
|
+
import { readFileSync as readFileSync30, existsSync as existsSync44 } from "fs";
|
|
8943
9588
|
import { resolve as resolve39 } from "path";
|
|
8944
9589
|
var hash_generate;
|
|
8945
9590
|
var init_hash_generate = __esm({
|
|
@@ -8968,7 +9613,7 @@ var init_hash_generate = __esm({
|
|
|
8968
9613
|
let hash;
|
|
8969
9614
|
if (filePath) {
|
|
8970
9615
|
const abs = resolve39(filePath);
|
|
8971
|
-
if (!
|
|
9616
|
+
if (!existsSync44(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
8972
9617
|
const fileContent = readFileSync30(abs);
|
|
8973
9618
|
hash = createHash(algorithm).update(fileContent).digest("hex");
|
|
8974
9619
|
} else if (content) {
|
|
@@ -9254,7 +9899,7 @@ ${output.slice(0, 5e3)}`,
|
|
|
9254
9899
|
|
|
9255
9900
|
// src/tools/builtin/project/build_project.ts
|
|
9256
9901
|
import { execSync as execSync14 } from "child_process";
|
|
9257
|
-
import { readFileSync as readFileSync31, existsSync as
|
|
9902
|
+
import { readFileSync as readFileSync31, existsSync as existsSync45 } from "fs";
|
|
9258
9903
|
import { resolve as resolve40 } from "path";
|
|
9259
9904
|
var build_project;
|
|
9260
9905
|
var init_build_project = __esm({
|
|
@@ -9282,7 +9927,7 @@ var init_build_project = __esm({
|
|
|
9282
9927
|
const tool = params.tool ?? "auto";
|
|
9283
9928
|
let cmd = "";
|
|
9284
9929
|
const pkgPath = resolve40(cwd, "package.json");
|
|
9285
|
-
if (tool === "auto" &&
|
|
9930
|
+
if (tool === "auto" && existsSync45(pkgPath)) {
|
|
9286
9931
|
const pkg = JSON.parse(readFileSync31(pkgPath, "utf-8"));
|
|
9287
9932
|
const scripts = pkg.scripts || {};
|
|
9288
9933
|
if (scripts.build) cmd = `npm run build`;
|
|
@@ -9332,7 +9977,7 @@ ${output.slice(0, 1e4)}`,
|
|
|
9332
9977
|
|
|
9333
9978
|
// src/tools/builtin/project/run_test.ts
|
|
9334
9979
|
import { execSync as execSync15 } from "child_process";
|
|
9335
|
-
import { readFileSync as readFileSync32, existsSync as
|
|
9980
|
+
import { readFileSync as readFileSync32, existsSync as existsSync46 } from "fs";
|
|
9336
9981
|
import { resolve as resolve41 } from "path";
|
|
9337
9982
|
var run_test;
|
|
9338
9983
|
var init_run_test = __esm({
|
|
@@ -9363,7 +10008,7 @@ var init_run_test = __esm({
|
|
|
9363
10008
|
let cmd = "";
|
|
9364
10009
|
if (runner === "auto") {
|
|
9365
10010
|
const pkgPath = resolve41(cwd, "package.json");
|
|
9366
|
-
if (
|
|
10011
|
+
if (existsSync46(pkgPath)) {
|
|
9367
10012
|
const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
|
|
9368
10013
|
const scripts = pkg.scripts || {};
|
|
9369
10014
|
if (scripts.test) cmd = `npm run test`;
|
|
@@ -9482,7 +10127,7 @@ ${output.slice(0, 1e4)}`,
|
|
|
9482
10127
|
});
|
|
9483
10128
|
|
|
9484
10129
|
// src/tools/builtin/project/env_manage.ts
|
|
9485
|
-
import { readFileSync as readFileSync33, writeFileSync as writeFileSync11, existsSync as
|
|
10130
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync11, existsSync as existsSync47 } from "fs";
|
|
9486
10131
|
import { resolve as resolve42 } from "path";
|
|
9487
10132
|
var env_manage;
|
|
9488
10133
|
var init_env_manage = __esm({
|
|
@@ -9514,14 +10159,14 @@ var init_env_manage = __esm({
|
|
|
9514
10159
|
if (action === "list_envs") {
|
|
9515
10160
|
const cwd = process.cwd();
|
|
9516
10161
|
const envs = [".env", ".env.local", ".env.development", ".env.production", ".env.test"];
|
|
9517
|
-
const found = envs.filter((f) =>
|
|
10162
|
+
const found = envs.filter((f) => existsSync47(resolve42(cwd, f)));
|
|
9518
10163
|
return {
|
|
9519
10164
|
success: true,
|
|
9520
10165
|
output: found.join("\n") || "\u672A\u627E\u5230 .env \u6587\u4EF6",
|
|
9521
10166
|
metadata: { files: found }
|
|
9522
10167
|
};
|
|
9523
10168
|
}
|
|
9524
|
-
if (!
|
|
10169
|
+
if (!existsSync47(abs)) {
|
|
9525
10170
|
if (action === "set" && key && value !== void 0) {
|
|
9526
10171
|
writeFileSync11(abs, `${key}=${value}`, "utf-8");
|
|
9527
10172
|
return { success: true, output: `\u5DF2\u521B\u5EFA ${filePath} \u5E76\u8BBE\u7F6E ${key}=${value}` };
|
|
@@ -9568,7 +10213,7 @@ var init_env_manage = __esm({
|
|
|
9568
10213
|
});
|
|
9569
10214
|
|
|
9570
10215
|
// src/tools/builtin/project/config_manage.ts
|
|
9571
|
-
import { readFileSync as readFileSync34, writeFileSync as writeFileSync12, existsSync as
|
|
10216
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync12, existsSync as existsSync48 } from "fs";
|
|
9572
10217
|
import { resolve as resolve43 } from "path";
|
|
9573
10218
|
var config_manage;
|
|
9574
10219
|
var init_config_manage = __esm({
|
|
@@ -9608,7 +10253,7 @@ var init_config_manage = __esm({
|
|
|
9608
10253
|
".prettierrc"
|
|
9609
10254
|
];
|
|
9610
10255
|
const cwd = process.cwd();
|
|
9611
|
-
const found = configs.filter((f) =>
|
|
10256
|
+
const found = configs.filter((f) => existsSync48(resolve43(cwd, f)));
|
|
9612
10257
|
return {
|
|
9613
10258
|
success: true,
|
|
9614
10259
|
output: `\u9879\u76EE\u914D\u7F6E\u6587\u4EF6:
|
|
@@ -9627,7 +10272,7 @@ NODE_ENV=development
|
|
|
9627
10272
|
return { success: false, error: "\u7F3A\u5C11 file_path \u53C2\u6570", output: "" };
|
|
9628
10273
|
}
|
|
9629
10274
|
const abs = resolve43(filePath);
|
|
9630
|
-
if (!
|
|
10275
|
+
if (!existsSync48(abs)) {
|
|
9631
10276
|
return { success: false, error: `\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
9632
10277
|
}
|
|
9633
10278
|
if (action === "read") {
|
|
@@ -9680,7 +10325,7 @@ NODE_ENV=development
|
|
|
9680
10325
|
|
|
9681
10326
|
// src/tools/builtin/project/docker_manage.ts
|
|
9682
10327
|
import { execSync as execSync17 } from "child_process";
|
|
9683
|
-
import { existsSync as
|
|
10328
|
+
import { existsSync as existsSync49 } from "fs";
|
|
9684
10329
|
import { resolve as resolve44 } from "path";
|
|
9685
10330
|
var docker_manage;
|
|
9686
10331
|
var init_docker_manage = __esm({
|
|
@@ -9716,7 +10361,7 @@ var init_docker_manage = __esm({
|
|
|
9716
10361
|
switch (action) {
|
|
9717
10362
|
case "build": {
|
|
9718
10363
|
const dockerfile = resolve44(cwd, "Dockerfile");
|
|
9719
|
-
if (!
|
|
10364
|
+
if (!existsSync49(dockerfile)) {
|
|
9720
10365
|
return { success: false, error: `Dockerfile \u4E0D\u5B58\u5728: ${dockerfile}`, output: "" };
|
|
9721
10366
|
}
|
|
9722
10367
|
cmd = `docker build ${options} -t ${image || "app"} .`;
|
|
@@ -9811,10 +10456,10 @@ var init_context_summarize = __esm({
|
|
|
9811
10456
|
const maxLength = params.max_length ?? 500;
|
|
9812
10457
|
let content = "";
|
|
9813
10458
|
if (filePath) {
|
|
9814
|
-
const { readFileSync: readFileSync38, existsSync:
|
|
10459
|
+
const { readFileSync: readFileSync38, existsSync: existsSync54 } = await import("fs");
|
|
9815
10460
|
const { resolve: resolve48 } = await import("path");
|
|
9816
10461
|
const abs = resolve48(filePath);
|
|
9817
|
-
if (!
|
|
10462
|
+
if (!existsSync54(abs)) return { success: false, error: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
9818
10463
|
content = readFileSync38(abs, "utf-8");
|
|
9819
10464
|
} else if (text) {
|
|
9820
10465
|
content = text;
|
|
@@ -9917,9 +10562,9 @@ ${list.join("\n")}`,
|
|
|
9917
10562
|
});
|
|
9918
10563
|
|
|
9919
10564
|
// src/tools/builtin/ai/skill_create.ts
|
|
9920
|
-
import { mkdirSync as
|
|
10565
|
+
import { mkdirSync as mkdirSync13, existsSync as existsSync50 } from "fs";
|
|
9921
10566
|
import { writeFile as writeFile4 } from "fs/promises";
|
|
9922
|
-
import { join as
|
|
10567
|
+
import { join as join10 } from "path";
|
|
9923
10568
|
var skill_create;
|
|
9924
10569
|
var init_skill_create = __esm({
|
|
9925
10570
|
"src/tools/builtin/ai/skill_create.ts"() {
|
|
@@ -9947,8 +10592,8 @@ var init_skill_create = __esm({
|
|
|
9947
10592
|
const description = params.description || `${name} \u6280\u80FD`;
|
|
9948
10593
|
const prompt = params.prompt;
|
|
9949
10594
|
const triggers = params.triggers || [];
|
|
9950
|
-
const skillDir =
|
|
9951
|
-
if (!
|
|
10595
|
+
const skillDir = join10(DEEPER_SKILLS_DIR, name);
|
|
10596
|
+
if (!existsSync50(skillDir)) mkdirSync13(skillDir, { recursive: true });
|
|
9952
10597
|
const yaml = [
|
|
9953
10598
|
`name: ${name}`,
|
|
9954
10599
|
`description: ${description}`,
|
|
@@ -9962,7 +10607,7 @@ ${yaml}
|
|
|
9962
10607
|
---
|
|
9963
10608
|
|
|
9964
10609
|
${prompt}`;
|
|
9965
|
-
await writeFile4(
|
|
10610
|
+
await writeFile4(join10(skillDir, "skill.md"), md, "utf-8");
|
|
9966
10611
|
return {
|
|
9967
10612
|
success: true,
|
|
9968
10613
|
output: `Skill "${name}" \u5DF2\u521B\u5EFA
|
|
@@ -10036,13 +10681,13 @@ var init_tool_create = __esm({
|
|
|
10036
10681
|
});
|
|
10037
10682
|
|
|
10038
10683
|
// src/tools/builtin/ai/memory_store.ts
|
|
10039
|
-
import { readFileSync as readFileSync35, writeFileSync as writeFileSync13, existsSync as
|
|
10040
|
-
import { join as
|
|
10684
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync13, existsSync as existsSync51, mkdirSync as mkdirSync14 } from "fs";
|
|
10685
|
+
import { join as join11 } from "path";
|
|
10041
10686
|
var MEMORY_DIR, memory_store;
|
|
10042
10687
|
var init_memory_store = __esm({
|
|
10043
10688
|
"src/tools/builtin/ai/memory_store.ts"() {
|
|
10044
10689
|
"use strict";
|
|
10045
|
-
MEMORY_DIR =
|
|
10690
|
+
MEMORY_DIR = join11(process.env.HOME || process.env.USERPROFILE || process.cwd(), ".deepercode", "memories");
|
|
10046
10691
|
memory_store = {
|
|
10047
10692
|
name: "memory_store",
|
|
10048
10693
|
description: "\u6301\u4E45\u5316\u8BB0\u5FC6\u5B58\u50A8",
|
|
@@ -10065,29 +10710,29 @@ var init_memory_store = __esm({
|
|
|
10065
10710
|
const key = params.key;
|
|
10066
10711
|
const value = params.value;
|
|
10067
10712
|
const query = params.query;
|
|
10068
|
-
if (!
|
|
10069
|
-
|
|
10713
|
+
if (!existsSync51(MEMORY_DIR)) {
|
|
10714
|
+
mkdirSync14(MEMORY_DIR, { recursive: true });
|
|
10070
10715
|
}
|
|
10071
10716
|
switch (action) {
|
|
10072
10717
|
case "set": {
|
|
10073
10718
|
if (!key || value === void 0) return { success: false, error: "set \u9700\u8981 key \u548C value \u53C2\u6570", output: "" };
|
|
10074
|
-
const memPath =
|
|
10719
|
+
const memPath = join11(MEMORY_DIR, `${key}.json`);
|
|
10075
10720
|
writeFileSync13(memPath, JSON.stringify({ key, value, timestamp: Date.now() }), "utf-8");
|
|
10076
10721
|
return { success: true, output: `\u8BB0\u5FC6\u5DF2\u4FDD\u5B58: ${key}` };
|
|
10077
10722
|
}
|
|
10078
10723
|
case "get": {
|
|
10079
10724
|
if (!key) return { success: false, error: "get \u9700\u8981 key \u53C2\u6570", output: "" };
|
|
10080
|
-
const memPath =
|
|
10081
|
-
if (!
|
|
10725
|
+
const memPath = join11(MEMORY_DIR, `${key}.json`);
|
|
10726
|
+
if (!existsSync51(memPath)) return { success: false, error: `\u8BB0\u5FC6\u4E0D\u5B58\u5728: ${key}`, output: "" };
|
|
10082
10727
|
const data = JSON.parse(readFileSync35(memPath, "utf-8"));
|
|
10083
10728
|
return { success: true, output: data.value };
|
|
10084
10729
|
}
|
|
10085
10730
|
case "delete": {
|
|
10086
10731
|
if (!key) return { success: false, error: "delete \u9700\u8981 key \u53C2\u6570", output: "" };
|
|
10087
|
-
const memPath =
|
|
10088
|
-
if (!
|
|
10089
|
-
const { unlinkSync:
|
|
10090
|
-
|
|
10732
|
+
const memPath = join11(MEMORY_DIR, `${key}.json`);
|
|
10733
|
+
if (!existsSync51(memPath)) return { success: false, error: `\u8BB0\u5FC6\u4E0D\u5B58\u5728: ${key}`, output: "" };
|
|
10734
|
+
const { unlinkSync: unlinkSync3 } = await import("fs");
|
|
10735
|
+
unlinkSync3(memPath);
|
|
10091
10736
|
return { success: true, output: `\u8BB0\u5FC6\u5DF2\u5220\u9664: ${key}` };
|
|
10092
10737
|
}
|
|
10093
10738
|
case "list": {
|
|
@@ -10106,7 +10751,7 @@ var init_memory_store = __esm({
|
|
|
10106
10751
|
const files = readdirSync5(MEMORY_DIR).filter((f) => f.endsWith(".json"));
|
|
10107
10752
|
const matches = [];
|
|
10108
10753
|
for (const f of files) {
|
|
10109
|
-
const data = JSON.parse(readFileSync35(
|
|
10754
|
+
const data = JSON.parse(readFileSync35(join11(MEMORY_DIR, f), "utf-8"));
|
|
10110
10755
|
if (data.value.includes(query) || data.key.includes(query)) {
|
|
10111
10756
|
matches.push(`${data.key}: ${data.value.slice(0, 200)}`);
|
|
10112
10757
|
}
|
|
@@ -10378,17 +11023,17 @@ var init_notify_user = __esm({
|
|
|
10378
11023
|
const output = `${icons[level] || ""} [${level.toUpperCase()}] ${title}: ${message}`;
|
|
10379
11024
|
try {
|
|
10380
11025
|
if (process.platform === "win32") {
|
|
10381
|
-
const { execSync:
|
|
10382
|
-
|
|
11026
|
+
const { execSync: execSync20 } = await import("child_process");
|
|
11027
|
+
execSync20(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $notify = New-Object System.Windows.Forms.NotifyIcon; $notify.Icon = [System.Drawing.SystemIcons]::Information; $notify.Visible = $true; $notify.ShowBalloonTip(5000, '${title}', '${message}', [System.Windows.Forms.ToolTipIcon]::${level === "error" ? "Error" : "Info"}); Start-Sleep -Seconds 6; $notify.Dispose()"`, {
|
|
10383
11028
|
timeout: 1e4,
|
|
10384
11029
|
stdio: "ignore"
|
|
10385
11030
|
});
|
|
10386
11031
|
} else if (process.platform === "darwin") {
|
|
10387
|
-
const { execSync:
|
|
10388
|
-
|
|
11032
|
+
const { execSync: execSync20 } = await import("child_process");
|
|
11033
|
+
execSync20(`osascript -e 'display notification "${message}" with title "${title}"'`, { stdio: "ignore" });
|
|
10389
11034
|
} else {
|
|
10390
|
-
const { execSync:
|
|
10391
|
-
|
|
11035
|
+
const { execSync: execSync20 } = await import("child_process");
|
|
11036
|
+
execSync20(`notify-send "${title}" "${message}"`, { stdio: "ignore" });
|
|
10392
11037
|
}
|
|
10393
11038
|
return { success: true, output, metadata: { title, level, notified: true } };
|
|
10394
11039
|
} catch {
|
|
@@ -10403,7 +11048,7 @@ var init_notify_user = __esm({
|
|
|
10403
11048
|
});
|
|
10404
11049
|
|
|
10405
11050
|
// src/tools/builtin/system/log_viewer.ts
|
|
10406
|
-
import { readFileSync as readFileSync36, existsSync as
|
|
11051
|
+
import { readFileSync as readFileSync36, existsSync as existsSync52 } from "fs";
|
|
10407
11052
|
import { resolve as resolve47 } from "path";
|
|
10408
11053
|
var log_viewer;
|
|
10409
11054
|
var init_log_viewer = __esm({
|
|
@@ -10434,7 +11079,7 @@ var init_log_viewer = __esm({
|
|
|
10434
11079
|
if (action !== "clear" && !filePath) {
|
|
10435
11080
|
const defaultLogs = ["npm-debug.log", "yarn-error.log", ".log", "logs/"];
|
|
10436
11081
|
const cwd = process.cwd();
|
|
10437
|
-
const found = defaultLogs.filter((f) =>
|
|
11082
|
+
const found = defaultLogs.filter((f) => existsSync52(resolve47(cwd, f)));
|
|
10438
11083
|
return {
|
|
10439
11084
|
success: true,
|
|
10440
11085
|
output: `\u8BF7\u6307\u5B9A file_path\u3002\u9879\u76EE\u76EE\u5F55\u4E2D\u7684\u65E5\u5FD7\u6587\u4EF6:
|
|
@@ -10447,7 +11092,7 @@ ${found.length > 0 ? found.join("\n") : " (\u672A\u627E\u5230)"}`
|
|
|
10447
11092
|
writeFileSync15(abs, "", "utf-8");
|
|
10448
11093
|
return { success: true, output: `\u65E5\u5FD7\u5DF2\u6E05\u7A7A: ${abs}` };
|
|
10449
11094
|
}
|
|
10450
|
-
if (!
|
|
11095
|
+
if (!existsSync52(abs)) {
|
|
10451
11096
|
return { success: false, error: `\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`, output: "" };
|
|
10452
11097
|
}
|
|
10453
11098
|
const content = readFileSync36(abs, "utf-8");
|
|
@@ -10729,8 +11374,28 @@ __export(chat_repl_exports, {
|
|
|
10729
11374
|
});
|
|
10730
11375
|
import readline from "readline";
|
|
10731
11376
|
import process5 from "process";
|
|
10732
|
-
import { existsSync as
|
|
10733
|
-
import { join as
|
|
11377
|
+
import { existsSync as existsSync53, mkdirSync as mkdirSync15, readFileSync as readFileSync37, writeFileSync as writeFileSync14, readdirSync as readdirSync4, statSync as statSync12, copyFileSync as copyFileSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
11378
|
+
import { join as join12, relative as relative6 } from "path";
|
|
11379
|
+
import { execSync as execSync19 } from "child_process";
|
|
11380
|
+
function backupFile(filePath) {
|
|
11381
|
+
if (!existsSync53(filePath)) return;
|
|
11382
|
+
try {
|
|
11383
|
+
if (!existsSync53(BACKUP_DIR)) mkdirSync15(BACKUP_DIR, { recursive: true });
|
|
11384
|
+
const rel = relative6(process5.cwd(), filePath).replace(/[/\\]/g, "_");
|
|
11385
|
+
const ts = Date.now();
|
|
11386
|
+
const backupPath = join12(BACKUP_DIR, `${ts}_${rel}`);
|
|
11387
|
+
copyFileSync2(filePath, backupPath);
|
|
11388
|
+
fileBackupStack.push({ path: filePath, backupPath, timestamp: ts });
|
|
11389
|
+
if (fileBackupStack.length > MAX_BACKUPS) {
|
|
11390
|
+
const old = fileBackupStack.shift();
|
|
11391
|
+
try {
|
|
11392
|
+
unlinkSync2(old.backupPath);
|
|
11393
|
+
} catch {
|
|
11394
|
+
}
|
|
11395
|
+
}
|
|
11396
|
+
} catch {
|
|
11397
|
+
}
|
|
11398
|
+
}
|
|
10734
11399
|
function getSkillSystemPrompt() {
|
|
10735
11400
|
if (!skillEngine) return "";
|
|
10736
11401
|
return skillEngine.getSystemPrompt();
|
|
@@ -10755,7 +11420,7 @@ async function startRepl(opts) {
|
|
|
10755
11420
|
let curTc = null;
|
|
10756
11421
|
let se = null;
|
|
10757
11422
|
try {
|
|
10758
|
-
const stream = await callApi(opts, msgs, tds,
|
|
11423
|
+
const stream = await callApi(opts, msgs, tds, 131072);
|
|
10759
11424
|
GS.api++;
|
|
10760
11425
|
ce = 0;
|
|
10761
11426
|
for await (const chunk of stream) {
|
|
@@ -10767,10 +11432,11 @@ async function startRepl(opts) {
|
|
|
10767
11432
|
const tc = chunk.tool_call;
|
|
10768
11433
|
if (tc) curTc = { id: tc.id, name: tc.name, argsStr: "" };
|
|
10769
11434
|
}
|
|
10770
|
-
if (chunk.type === "tool_call_args" && curTc) curTc.argsStr += chunk.content || "";
|
|
10771
11435
|
if (chunk.type === "tool_call_end" && curTc) {
|
|
11436
|
+
const tcData = chunk.tool_call;
|
|
10772
11437
|
try {
|
|
10773
|
-
|
|
11438
|
+
const args = tcData?.arguments || JSON.parse(curTc.argsStr || "{}");
|
|
11439
|
+
tcs.push({ id: curTc.id, name: curTc.name, args });
|
|
10774
11440
|
} catch {
|
|
10775
11441
|
tcs.push({ id: curTc.id, name: curTc.name, args: {} });
|
|
10776
11442
|
}
|
|
@@ -10807,7 +11473,11 @@ async function startRepl(opts) {
|
|
|
10807
11473
|
continue;
|
|
10808
11474
|
}
|
|
10809
11475
|
try {
|
|
10810
|
-
const
|
|
11476
|
+
const ac = new AbortController();
|
|
11477
|
+
const timeout = TOOL_TIMEOUT_MAP[tc.name] || DEFAULT_TOOL_TIMEOUT;
|
|
11478
|
+
const timer = setTimeout(() => ac.abort(), timeout);
|
|
11479
|
+
const r2 = await tool.execute(tc.args, ac.signal);
|
|
11480
|
+
clearTimeout(timer);
|
|
10811
11481
|
const txt = sanitize(r2.output || "").slice(0, TOOL_RESULT_MAX);
|
|
10812
11482
|
lh.push({ role: "tool", content: r2.success ? txt : `Error: ${r2.error}`, tool_call_id: tc.id });
|
|
10813
11483
|
GS.tc++;
|
|
@@ -10843,7 +11513,7 @@ async function startRepl(opts) {
|
|
|
10843
11513
|
}
|
|
10844
11514
|
});
|
|
10845
11515
|
const history = [];
|
|
10846
|
-
if (!
|
|
11516
|
+
if (!existsSync53(SESSION_DIR)) mkdirSync15(SESSION_DIR, { recursive: true });
|
|
10847
11517
|
const sid = `sess_${Date.now()}`;
|
|
10848
11518
|
setSessionId(sid);
|
|
10849
11519
|
await xmemory.load();
|
|
@@ -10903,13 +11573,14 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
10903
11573
|
};
|
|
10904
11574
|
drawHeader();
|
|
10905
11575
|
let resizeTimer = null;
|
|
10906
|
-
|
|
11576
|
+
const onResize = () => {
|
|
10907
11577
|
if (resizeTimer) return;
|
|
10908
11578
|
resizeTimer = setTimeout(() => {
|
|
10909
11579
|
resizeTimer = null;
|
|
10910
11580
|
Oflush();
|
|
10911
11581
|
}, 200);
|
|
10912
|
-
}
|
|
11582
|
+
};
|
|
11583
|
+
process5.stdout.on("resize", onResize);
|
|
10913
11584
|
let resolveLine = null;
|
|
10914
11585
|
let running = true;
|
|
10915
11586
|
const rl = readline.createInterface({ input: process5.stdin, output: process5.stdout, terminal: true });
|
|
@@ -10944,7 +11615,13 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
10944
11615
|
else showPrompt();
|
|
10945
11616
|
return ok;
|
|
10946
11617
|
};
|
|
10947
|
-
|
|
11618
|
+
const onSigint = () => {
|
|
11619
|
+
if (currentAbortController) {
|
|
11620
|
+
currentAbortController.abort();
|
|
11621
|
+
currentAbortController = null;
|
|
11622
|
+
O(y("\n \u26A1 \u5DF2\u4E2D\u65AD\u5F53\u524D\u8BF7\u6C42\n"));
|
|
11623
|
+
return;
|
|
11624
|
+
}
|
|
10948
11625
|
if (resolveLine) {
|
|
10949
11626
|
const cb = resolveLine;
|
|
10950
11627
|
resolveLine = null;
|
|
@@ -10952,22 +11629,28 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
10952
11629
|
return;
|
|
10953
11630
|
}
|
|
10954
11631
|
Oflush();
|
|
11632
|
+
process5.stdout.removeListener("resize", onResize);
|
|
11633
|
+
process5.removeListener("uncaughtException", onUCE);
|
|
11634
|
+
process5.removeListener("unhandledRejection", onUHR);
|
|
10955
11635
|
xmemory.save().then(() => {
|
|
10956
11636
|
O("\n" + y("\u518D\u89C1\uFF01") + "\n");
|
|
10957
11637
|
running = false;
|
|
10958
11638
|
rl.close();
|
|
10959
11639
|
process5.exit(0);
|
|
10960
11640
|
});
|
|
10961
|
-
}
|
|
10962
|
-
|
|
10963
|
-
|
|
11641
|
+
};
|
|
11642
|
+
rl.on("SIGINT", onSigint);
|
|
11643
|
+
const onUCE = (err) => {
|
|
11644
|
+
if (!err.message?.includes("readline") && !err.message?.includes("abort")) O(r(`
|
|
10964
11645
|
\u26A0 ${err.message}`) + "\n");
|
|
10965
|
-
}
|
|
10966
|
-
process5.on("
|
|
11646
|
+
};
|
|
11647
|
+
process5.on("uncaughtException", onUCE);
|
|
11648
|
+
const onUHR = (reason) => {
|
|
10967
11649
|
const m = reason instanceof Error ? reason.message : String(reason);
|
|
10968
11650
|
if (!m.includes("readline") && !m.includes("Abort") && !m.includes("timeout")) O(r(`
|
|
10969
11651
|
\u26A0 ${m}`) + "\n");
|
|
10970
|
-
}
|
|
11652
|
+
};
|
|
11653
|
+
process5.on("unhandledRejection", onUHR);
|
|
10971
11654
|
while (running) {
|
|
10972
11655
|
currentPrompt = c("\u276F ");
|
|
10973
11656
|
const tasks = getTodos();
|
|
@@ -10995,6 +11678,12 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
10995
11678
|
O(G(" /mcp") + G(" MCP\u670D\u52A1\u5668") + "\n");
|
|
10996
11679
|
O(G(" /plan") + G(" <\u4EFB\u52A1> \u5148\u51FA\u65B9\u6848") + "\n");
|
|
10997
11680
|
O(G(" /spec") + G(" <\u4EFB\u52A1> \u5148\u51FA\u89C4\u683C") + "\n");
|
|
11681
|
+
O(G(" /review") + G(" <\u8DEF\u5F84> \u4EE3\u7801\u5BA1\u67E5") + "\n");
|
|
11682
|
+
O(G(" /fix") + G(" [\u76EE\u6807] \u81EA\u52A8\u4FEE\u590D") + "\n");
|
|
11683
|
+
O(G(" /commit") + G(" \u667A\u80FD\u63D0\u4EA4") + "\n");
|
|
11684
|
+
O(G(" /analyze") + G(" [\u8DEF\u5F84] \u9879\u76EE\u5206\u6790") + "\n");
|
|
11685
|
+
O(G(" /diff") + G(" <\u6587\u4EF6> \u53D8\u66F4\u9884\u89C8") + "\n");
|
|
11686
|
+
O(G(" /undo") + G(" \u64A4\u9500\u64CD\u4F5C") + "\n");
|
|
10998
11687
|
O(G(" /status") + G(" \u5F53\u524D\u72B6\u6001") + "\n");
|
|
10999
11688
|
O(G(" /model") + G(" \u6A21\u578B\u8BBE\u7F6E") + "\n");
|
|
11000
11689
|
O(G(" /config") + G(" \u914D\u7F6E\u7BA1\u7406") + "\n");
|
|
@@ -11089,11 +11778,11 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
11089
11778
|
continue;
|
|
11090
11779
|
}
|
|
11091
11780
|
if (cmd === "/rules") {
|
|
11092
|
-
const projectRules =
|
|
11093
|
-
const globalRules =
|
|
11781
|
+
const projectRules = join12(process5.cwd(), ".deeper", "rules.md");
|
|
11782
|
+
const globalRules = join12(DEEPER_HOME, "rules.md");
|
|
11094
11783
|
O(b(c(" Rules")) + "\n");
|
|
11095
11784
|
const showRules = (label, path) => {
|
|
11096
|
-
if (
|
|
11785
|
+
if (existsSync53(path)) {
|
|
11097
11786
|
const content = readFileSync37(path, "utf-8");
|
|
11098
11787
|
O(G(` ${label}: `) + c(path) + G(` (${content.split("\n").length}\u884C)`) + "\n");
|
|
11099
11788
|
const lines = content.split("\n").slice(0, 8);
|
|
@@ -11111,7 +11800,8 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
11111
11800
|
if (cmd === "/help") {
|
|
11112
11801
|
O(c(" /help /clear /quit /save [name] /load|resume [name] /sessions\n"));
|
|
11113
11802
|
O(c(" /tools [cat] /stats /memory /tasks /model /config /cwd /export /init /mcp /rules\n"));
|
|
11114
|
-
O(c(" /plan <\u4EFB\u52A1> /spec <\u4EFB\u52A1> /
|
|
11803
|
+
O(c(" /plan <\u4EFB\u52A1> /spec <\u4EFB\u52A1> /review <\u8DEF\u5F84> /fix [\u76EE\u6807]\n"));
|
|
11804
|
+
O(c(" /commit /analyze [\u8DEF\u5F84] /diff <\u6587\u4EF6> /undo /status\n\n"));
|
|
11115
11805
|
continue;
|
|
11116
11806
|
}
|
|
11117
11807
|
if (cmd === "/plan") {
|
|
@@ -11155,6 +11845,178 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
11155
11845
|
await runLoop(opts, history, tools, sfdefs, confirm);
|
|
11156
11846
|
continue;
|
|
11157
11847
|
}
|
|
11848
|
+
if (cmd === "/review") {
|
|
11849
|
+
const target = arg || ".";
|
|
11850
|
+
O(b(c(" Review Mode")) + G(` \u2022 ${target}`) + "\n\n");
|
|
11851
|
+
history.push({ role: "system", content: `[Review Mode]
|
|
11852
|
+
\u4F60\u662F\u4E00\u4F4D\u8D44\u6DF1\u4EE3\u7801\u5BA1\u67E5\u4E13\u5BB6\u3002\u8BF7\u5BF9\u6307\u5B9A\u4EE3\u7801\u8FDB\u884C\u5168\u9762\u5BA1\u67E5\uFF1A
|
|
11853
|
+
|
|
11854
|
+
1. \u5148\u7528 read_file / glob_find / grep_search \u8BFB\u53D6\u76F8\u5173\u4EE3\u7801
|
|
11855
|
+
2. \u4ECE\u4EE5\u4E0B\u7EF4\u5EA6\u9010\u9879\u5BA1\u67E5\u5E76\u8BC4\u5206\uFF081-10\uFF09\uFF1A
|
|
11856
|
+
- \u4EE3\u7801\u8D28\u91CF\uFF1A\u53EF\u8BFB\u6027\u3001\u547D\u540D\u3001\u7ED3\u6784
|
|
11857
|
+
- \u5B89\u5168\u6027\uFF1A\u6CE8\u5165\u3001XSS\u3001\u5BC6\u94A5\u6CC4\u9732\u3001\u6743\u9650\u95EE\u9898
|
|
11858
|
+
- \u6027\u80FD\uFF1AN+1\u67E5\u8BE2\u3001\u5185\u5B58\u6CC4\u6F0F\u3001\u4E0D\u5FC5\u8981\u7684\u8BA1\u7B97
|
|
11859
|
+
- \u53EF\u7EF4\u62A4\u6027\uFF1A\u8026\u5408\u5EA6\u3001\u91CD\u590D\u4EE3\u7801\u3001\u6D4B\u8BD5\u8986\u76D6
|
|
11860
|
+
- \u6700\u4F73\u5B9E\u8DF5\uFF1A\u8BBE\u8BA1\u6A21\u5F0F\u3001SOLID\u539F\u5219\u3001\u9519\u8BEF\u5904\u7406
|
|
11861
|
+
3. \u5BF9\u6BCF\u4E2A\u95EE\u9898\u7ED9\u51FA\uFF1A\u6587\u4EF6\u8DEF\u5F84\u3001\u884C\u53F7\u8303\u56F4\u3001\u95EE\u9898\u63CF\u8FF0\u3001\u4FEE\u590D\u5EFA\u8BAE\u3001\u4E25\u91CD\u7A0B\u5EA6(\u{1F534}\u9AD8/\u{1F7E1}\u4E2D/\u{1F7E2}\u4F4E)
|
|
11862
|
+
4. \u6700\u540E\u7ED9\u51FA\u603B\u4F53\u8BC4\u5206\u548C\u6539\u8FDB\u4F18\u5148\u7EA7\u5217\u8868
|
|
11863
|
+
|
|
11864
|
+
\u5BA1\u67E5\u76EE\u6807\uFF1A${target}` });
|
|
11865
|
+
history.push({ role: "user", content: `\u5BA1\u67E5 ${target} \u7684\u4EE3\u7801\u8D28\u91CF` });
|
|
11866
|
+
const rvdefs = toolsToDefs(tools);
|
|
11867
|
+
await runLoop(opts, history, tools, rvdefs, confirm);
|
|
11868
|
+
continue;
|
|
11869
|
+
}
|
|
11870
|
+
if (cmd === "/commit") {
|
|
11871
|
+
O(b(c(" Commit Mode")) + G(" \u2022 \u667A\u80FD\u63D0\u4EA4") + "\n\n");
|
|
11872
|
+
try {
|
|
11873
|
+
const statusOut = execSync19("git status --porcelain", { encoding: "utf-8", timeout: 1e4, cwd: process5.cwd() });
|
|
11874
|
+
if (!statusOut.trim()) {
|
|
11875
|
+
O(y(" \u6CA1\u6709\u672A\u63D0\u4EA4\u7684\u53D8\u66F4\n\n"));
|
|
11876
|
+
continue;
|
|
11877
|
+
}
|
|
11878
|
+
const diffOut = execSync19("git diff --stat", { encoding: "utf-8", timeout: 15e3, cwd: process5.cwd() });
|
|
11879
|
+
const stagedOut = execSync19("git diff --cached --stat", { encoding: "utf-8", timeout: 15e3, cwd: process5.cwd() });
|
|
11880
|
+
const files = statusOut.trim().split("\n").filter(Boolean);
|
|
11881
|
+
O(G(` ${files.length} \u4E2A\u6587\u4EF6\u53D8\u66F4:
|
|
11882
|
+
`));
|
|
11883
|
+
for (const f of files.slice(0, 20)) {
|
|
11884
|
+
const status = f.slice(0, 2).trim();
|
|
11885
|
+
const path = f.slice(3);
|
|
11886
|
+
const icon = status === "M" ? y("M") : status === "A" ? g("A") : status === "D" ? r("D") : status === "?" ? G("?") : c(status);
|
|
11887
|
+
O(G(` ${icon} ${path.slice(0, 60)}`) + "\n");
|
|
11888
|
+
}
|
|
11889
|
+
if (files.length > 20) O(G(` \u2026\u8FD8\u6709 ${files.length - 20} \u4E2A`) + "\n");
|
|
11890
|
+
O("\n");
|
|
11891
|
+
history.push({ role: "system", content: `[Commit Mode]
|
|
11892
|
+
\u5206\u6790 git \u53D8\u66F4\u5E76\u751F\u6210\u63D0\u4EA4\u4FE1\u606F\uFF1A
|
|
11893
|
+
1. \u5148\u7528 run_command \u6267\u884C git diff \u67E5\u770B\u5177\u4F53\u53D8\u66F4\u5185\u5BB9
|
|
11894
|
+
2. \u5206\u6790\u53D8\u66F4\u7C7B\u578B\u548C\u8303\u56F4\uFF0C\u751F\u6210\u7B26\u5408 Conventional Commits \u89C4\u8303\u7684\u63D0\u4EA4\u4FE1\u606F
|
|
11895
|
+
3. \u683C\u5F0F: type(scope): description
|
|
11896
|
+
- type: feat/fix/refactor/docs/style/test/chore/perf
|
|
11897
|
+
- scope: \u53EF\u9009\uFF0C\u5F71\u54CD\u7684\u6A21\u5757
|
|
11898
|
+
4. \u7528 run_command \u6267\u884C git add \u548C git commit
|
|
11899
|
+
5. \u5982\u679C\u53D8\u66F4\u8F83\u591A\uFF0C\u5EFA\u8BAE\u5206\u591A\u6B21\u63D0\u4EA4
|
|
11900
|
+
|
|
11901
|
+
\u5F53\u524D\u53D8\u66F4\u7EDF\u8BA1\uFF1A
|
|
11902
|
+
${diffOut || stagedOut || "\u65E0staged\u53D8\u66F4"}` });
|
|
11903
|
+
history.push({ role: "user", content: "\u5206\u6790\u53D8\u66F4\u5E76\u63D0\u4EA4" });
|
|
11904
|
+
const cmdefs = toolsToDefs(tools);
|
|
11905
|
+
await runLoop(opts, history, tools, cmdefs, confirm);
|
|
11906
|
+
} catch (e) {
|
|
11907
|
+
O(r(` Git \u64CD\u4F5C\u5931\u8D25: ${e instanceof Error ? e.message.slice(0, 80) : String(e).slice(0, 80)}
|
|
11908
|
+
|
|
11909
|
+
`));
|
|
11910
|
+
}
|
|
11911
|
+
continue;
|
|
11912
|
+
}
|
|
11913
|
+
if (cmd === "/analyze") {
|
|
11914
|
+
const target = arg || process5.cwd();
|
|
11915
|
+
O(b(c(" Analyze Mode")) + G(` \u2022 ${target}`) + "\n\n");
|
|
11916
|
+
history.push({ role: "system", content: `[Analyze Mode]
|
|
11917
|
+
\u4F60\u662F\u4E00\u4F4D\u9879\u76EE\u67B6\u6784\u5206\u6790\u5E08\u3002\u8BF7\u5BF9\u9879\u76EE\u8FDB\u884C\u5168\u9762\u5206\u6790\uFF1A
|
|
11918
|
+
|
|
11919
|
+
1. \u7528 glob_find \u626B\u63CF\u9879\u76EE\u76EE\u5F55\u7ED3\u6784
|
|
11920
|
+
2. \u7528 read_file \u8BFB\u53D6 package.json / tsconfig.json / Cargo.toml \u7B49\u914D\u7F6E
|
|
11921
|
+
3. \u7528 grep_search / codebase_search \u5206\u6790\u4EE3\u7801\u6A21\u5F0F
|
|
11922
|
+
4. \u8F93\u51FA\u4EE5\u4E0B\u5206\u6790\u62A5\u544A\uFF1A
|
|
11923
|
+
- \u{1F4C1} \u9879\u76EE\u7ED3\u6784\u6811\uFF08\u5173\u952E\u76EE\u5F55\u548C\u6587\u4EF6\uFF09
|
|
11924
|
+
- \u{1F6E0} \u6280\u672F\u6808\u8BC6\u522B\uFF08\u8BED\u8A00\u3001\u6846\u67B6\u3001\u5E93\u3001\u5DE5\u5177\u94FE\uFF09
|
|
11925
|
+
- \u{1F4CA} \u4EE3\u7801\u7EDF\u8BA1\uFF08\u6587\u4EF6\u6570\u3001\u4EE3\u7801\u884C\u6570\u4F30\u7B97\u3001\u5404\u8BED\u8A00\u5360\u6BD4\uFF09
|
|
11926
|
+
- \u{1F3D7}\uFE0F \u67B6\u6784\u6A21\u5F0F\uFF08MVC/\u5FAE\u670D\u52A1/\u5355\u4F53/\u63D2\u4EF6\u5F0F\u7B49\uFF09
|
|
11927
|
+
- \u{1F517} \u4F9D\u8D56\u5173\u7CFB\uFF08\u6838\u5FC3\u4F9D\u8D56\u3001\u5F00\u53D1\u4F9D\u8D56\u3001\u7248\u672C\u98CE\u9669\uFF09
|
|
11928
|
+
- \u26A0\uFE0F \u6F5C\u5728\u95EE\u9898\uFF08\u8FC7\u65F6\u4F9D\u8D56\u3001\u5B89\u5168\u98CE\u9669\u3001\u4EE3\u7801\u5F02\u5473\uFF09
|
|
11929
|
+
- \u{1F4A1} \u6539\u8FDB\u5EFA\u8BAE\uFF08\u4F18\u5148\u7EA7\u6392\u5E8F\uFF09
|
|
11930
|
+
|
|
11931
|
+
\u5206\u6790\u76EE\u6807\uFF1A${target}` });
|
|
11932
|
+
history.push({ role: "user", content: `\u5206\u6790\u9879\u76EE ${target}` });
|
|
11933
|
+
const andefs = toolsToDefs(tools);
|
|
11934
|
+
await runLoop(opts, history, tools, andefs, confirm);
|
|
11935
|
+
continue;
|
|
11936
|
+
}
|
|
11937
|
+
if (cmd === "/fix") {
|
|
11938
|
+
const target = arg || "";
|
|
11939
|
+
O(b(c(" Fix Mode")) + G(" \u2022 \u81EA\u52A8\u4FEE\u590D") + "\n\n");
|
|
11940
|
+
history.push({ role: "system", content: `[Fix Mode]
|
|
11941
|
+
\u4F60\u662F\u4E00\u4F4D\u81EA\u52A8\u4FEE\u590D\u5DE5\u7A0B\u5E08\u3002\u8BF7\u6267\u884C\u4EE5\u4E0B\u6D41\u7A0B\uFF1A
|
|
11942
|
+
|
|
11943
|
+
1. \u5148\u7528 run_command \u8FD0\u884C\u6784\u5EFA\u547D\u4EE4\uFF08\u5982 npm run build, tsc --noEmit, cargo check \u7B49\uFF09
|
|
11944
|
+
2. \u5982\u679C\u6784\u5EFA\u6210\u529F\uFF0C\u8FD0\u884C\u6D4B\u8BD5\uFF08npm test, cargo test \u7B49\uFF09
|
|
11945
|
+
3. \u5982\u679C\u6709\u9519\u8BEF\uFF1A
|
|
11946
|
+
a. \u4ED4\u7EC6\u5206\u6790\u9519\u8BEF\u4FE1\u606F\uFF0C\u5B9A\u4F4D\u5230\u5177\u4F53\u6587\u4EF6\u548C\u884C\u53F7
|
|
11947
|
+
b. \u7528 read_file \u8BFB\u53D6\u51FA\u9519\u6587\u4EF6\u7684\u76F8\u5173\u4EE3\u7801
|
|
11948
|
+
c. \u7406\u89E3\u9519\u8BEF\u6839\u56E0\uFF0C\u5236\u5B9A\u4FEE\u590D\u65B9\u6848
|
|
11949
|
+
d. \u7528 edit_file \u7CBE\u786E\u4FEE\u590D\uFF08\u4F18\u5148\u7528 edit \u800C\u975E\u91CD\u5199\u6574\u4E2A\u6587\u4EF6\uFF09
|
|
11950
|
+
e. \u91CD\u65B0\u8FD0\u884C\u6784\u5EFA\u9A8C\u8BC1\u4FEE\u590D
|
|
11951
|
+
f. \u91CD\u590D\u76F4\u5230\u6240\u6709\u9519\u8BEF\u6E05\u9664
|
|
11952
|
+
4. \u5982\u679C\u6D4B\u8BD5\u5931\u8D25\uFF0C\u540C\u6837\u5206\u6790\u5E76\u4FEE\u590D
|
|
11953
|
+
5. \u6700\u591A\u5C1D\u8BD5\u4FEE\u590D 5 \u8F6E\uFF0C\u907F\u514D\u65E0\u9650\u5FAA\u73AF
|
|
11954
|
+
6. \u6BCF\u6B21\u4FEE\u590D\u540E\u90FD\u91CD\u65B0\u9A8C\u8BC1
|
|
11955
|
+
|
|
11956
|
+
${target ? `\u4FEE\u590D\u76EE\u6807\uFF1A${target}
|
|
11957
|
+
` : "\u81EA\u52A8\u68C0\u6D4B\u5E76\u4FEE\u590D\u6240\u6709\u6784\u5EFA/\u6D4B\u8BD5\u9519\u8BEF"}` });
|
|
11958
|
+
history.push({ role: "user", content: target || "\u68C0\u6D4B\u5E76\u4FEE\u590D\u9879\u76EE\u9519\u8BEF" });
|
|
11959
|
+
const fxdefs = toolsToDefs(tools);
|
|
11960
|
+
await runLoop(opts, history, tools, fxdefs, confirm);
|
|
11961
|
+
continue;
|
|
11962
|
+
}
|
|
11963
|
+
if (cmd === "/diff") {
|
|
11964
|
+
if (!arg) {
|
|
11965
|
+
O(y(" \u7528\u6CD5: /diff <\u6587\u4EF6\u8DEF\u5F84>\n \u663E\u793A\u6587\u4EF6\u6700\u8FD1\u7684\u53D8\u66F4\n\n"));
|
|
11966
|
+
continue;
|
|
11967
|
+
}
|
|
11968
|
+
const filePath = arg.startsWith("/") || arg.startsWith("\\") || arg.length > 2 ? arg : join12(process5.cwd(), arg);
|
|
11969
|
+
if (fileBackupStack.length === 0) {
|
|
11970
|
+
O(y(" \u6CA1\u6709\u53EF\u7528\u7684\u5907\u4EFD\u8BB0\u5F55\n\n"));
|
|
11971
|
+
continue;
|
|
11972
|
+
}
|
|
11973
|
+
const backups = fileBackupStack.filter((b2) => b2.path === filePath).reverse();
|
|
11974
|
+
if (backups.length === 0) {
|
|
11975
|
+
const allBackups = [...fileBackupStack].reverse();
|
|
11976
|
+
O(G(" \u6700\u8FD1\u7684\u6587\u4EF6\u53D8\u66F4:\n"));
|
|
11977
|
+
for (const b2 of allBackups.slice(0, 10)) {
|
|
11978
|
+
const rel = relative6(process5.cwd(), b2.path);
|
|
11979
|
+
const time = new Date(b2.timestamp).toLocaleTimeString();
|
|
11980
|
+
O(G(` ${time} ${rel.slice(0, 50)}`) + "\n");
|
|
11981
|
+
}
|
|
11982
|
+
O("\n");
|
|
11983
|
+
continue;
|
|
11984
|
+
}
|
|
11985
|
+
const latest = backups[0];
|
|
11986
|
+
try {
|
|
11987
|
+
const currentContent = existsSync53(filePath) ? readFileSync37(filePath, "utf-8") : "(\u6587\u4EF6\u5DF2\u5220\u9664)";
|
|
11988
|
+
const backupContent = readFileSync37(latest.backupPath, "utf-8");
|
|
11989
|
+
const diffResult = computeSimpleDiff(backupContent, currentContent, filePath);
|
|
11990
|
+
O(b(c(" Diff")) + G(` \u2022 ${relative6(process5.cwd(), filePath)}`) + "\n\n");
|
|
11991
|
+
O(diffResult + "\n\n");
|
|
11992
|
+
} catch {
|
|
11993
|
+
O(y(" \u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6\u8FDB\u884C\u5BF9\u6BD4\n\n"));
|
|
11994
|
+
}
|
|
11995
|
+
continue;
|
|
11996
|
+
}
|
|
11997
|
+
if (cmd === "/undo") {
|
|
11998
|
+
if (fileBackupStack.length === 0) {
|
|
11999
|
+
O(y(" \u6CA1\u6709\u53EF\u64A4\u9500\u7684\u64CD\u4F5C\n\n"));
|
|
12000
|
+
continue;
|
|
12001
|
+
}
|
|
12002
|
+
const last = fileBackupStack[fileBackupStack.length - 1];
|
|
12003
|
+
try {
|
|
12004
|
+
const rel = relative6(process5.cwd(), last.path);
|
|
12005
|
+
copyFileSync2(last.backupPath, last.path);
|
|
12006
|
+
fileBackupStack.pop();
|
|
12007
|
+
try {
|
|
12008
|
+
unlinkSync2(last.backupPath);
|
|
12009
|
+
} catch {
|
|
12010
|
+
}
|
|
12011
|
+
O(g(" \u2713 \u5DF2\u64A4\u9500") + G(` ${rel}`) + "\n");
|
|
12012
|
+
O(G(" \u63D0\u793A: \u53EF\u7EE7\u7EED /undo \u64A4\u9500\u66F4\u591A\u64CD\u4F5C\n\n"));
|
|
12013
|
+
} catch (e) {
|
|
12014
|
+
O(r(` \u64A4\u9500\u5931\u8D25: ${e instanceof Error ? e.message.slice(0, 60) : String(e).slice(0, 60)}
|
|
12015
|
+
|
|
12016
|
+
`));
|
|
12017
|
+
}
|
|
12018
|
+
continue;
|
|
12019
|
+
}
|
|
11158
12020
|
O(G(` \u672A\u77E5\u547D\u4EE4: ${cmd} (\u8F93\u5165 /help \u67E5\u770B\u5E2E\u52A9)
|
|
11159
12021
|
|
|
11160
12022
|
`));
|
|
@@ -11169,6 +12031,9 @@ ${prevSummary.slice(0, 800)}` });
|
|
|
11169
12031
|
}
|
|
11170
12032
|
rl.close();
|
|
11171
12033
|
Oflush();
|
|
12034
|
+
process5.stdout.removeListener("resize", onResize);
|
|
12035
|
+
process5.removeListener("uncaughtException", onUCE);
|
|
12036
|
+
process5.removeListener("unhandledRejection", onUHR);
|
|
11172
12037
|
await xmemory.save();
|
|
11173
12038
|
if (mcpClient) mcpClient.disconnectAll();
|
|
11174
12039
|
Oflush();
|
|
@@ -11221,8 +12086,9 @@ async function runLoop(opts, history, tools, toolDefs, confirm) {
|
|
|
11221
12086
|
thinkAnimIv = null;
|
|
11222
12087
|
}
|
|
11223
12088
|
};
|
|
12089
|
+
currentAbortController = new AbortController();
|
|
11224
12090
|
try {
|
|
11225
|
-
const stream = await callApi(opts, msgs, toolDefs,
|
|
12091
|
+
const stream = await callApi(opts, msgs, toolDefs, amax, currentAbortController.signal);
|
|
11226
12092
|
GS.api++;
|
|
11227
12093
|
ce = 0;
|
|
11228
12094
|
const cols = process5.stdout.columns || 80;
|
|
@@ -11261,10 +12127,11 @@ async function runLoop(opts, history, tools, toolDefs, confirm) {
|
|
|
11261
12127
|
const tc = chunk.tool_call;
|
|
11262
12128
|
if (tc) curTc = { id: tc.id, name: tc.name, argsStr: "" };
|
|
11263
12129
|
}
|
|
11264
|
-
if (chunk.type === "tool_call_args" && curTc) curTc.argsStr += chunk.content || "";
|
|
11265
12130
|
if (chunk.type === "tool_call_end" && curTc) {
|
|
12131
|
+
const tcData = chunk.tool_call;
|
|
11266
12132
|
try {
|
|
11267
|
-
|
|
12133
|
+
const args = tcData?.arguments || JSON.parse(curTc.argsStr || "{}");
|
|
12134
|
+
tcs.push({ id: curTc.id, name: curTc.name, args });
|
|
11268
12135
|
} catch {
|
|
11269
12136
|
tcs.push({ id: curTc.id, name: curTc.name, args: {} });
|
|
11270
12137
|
}
|
|
@@ -11278,8 +12145,15 @@ async function runLoop(opts, history, tools, toolDefs, confirm) {
|
|
|
11278
12145
|
}
|
|
11279
12146
|
} catch (e) {
|
|
11280
12147
|
stopStreamAnim();
|
|
11281
|
-
|
|
12148
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
12149
|
+
if (errMsg.includes("abort") || errMsg.includes("cancel")) {
|
|
12150
|
+
se = null;
|
|
12151
|
+
O(y("\n \u26A1 \u8BF7\u6C42\u5DF2\u53D6\u6D88\n"));
|
|
12152
|
+
} else {
|
|
12153
|
+
se = errMsg;
|
|
12154
|
+
}
|
|
11282
12155
|
}
|
|
12156
|
+
currentAbortController = null;
|
|
11283
12157
|
stopStreamAnim();
|
|
11284
12158
|
Oflush();
|
|
11285
12159
|
const remaining = md.flush();
|
|
@@ -11415,14 +12289,19 @@ async function execTool(tc, tools, opts, confirm) {
|
|
|
11415
12289
|
execAnimIv = setInterval(() => {
|
|
11416
12290
|
rawWrite("\r" + thinkingAnimAt(toolName, toolStart));
|
|
11417
12291
|
}, 80);
|
|
11418
|
-
const
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
12292
|
+
const timeout = TOOL_TIMEOUT_MAP[tc.name] || DEFAULT_TOOL_TIMEOUT;
|
|
12293
|
+
const ac = new AbortController();
|
|
12294
|
+
const timer = setTimeout(() => ac.abort(), timeout);
|
|
12295
|
+
if (tc.name === "write_file" || tc.name === "edit_file") {
|
|
12296
|
+
const fp = tc.args.file_path || tc.args.path || tc.args.file || "";
|
|
12297
|
+
if (fp) backupFile(fp);
|
|
12298
|
+
}
|
|
11422
12299
|
let result;
|
|
11423
12300
|
try {
|
|
11424
|
-
result = await
|
|
12301
|
+
result = await tool.execute(tc.args, ac.signal);
|
|
12302
|
+
clearTimeout(timer);
|
|
11425
12303
|
} catch (e) {
|
|
12304
|
+
clearTimeout(timer);
|
|
11426
12305
|
result = { success: false, error: e.message, output: "" };
|
|
11427
12306
|
}
|
|
11428
12307
|
stopToolAnim();
|
|
@@ -11487,56 +12366,71 @@ async function execTool(tc, tools, opts, confirm) {
|
|
|
11487
12366
|
}
|
|
11488
12367
|
function buildMsgs(history) {
|
|
11489
12368
|
const r2 = [];
|
|
11490
|
-
let sysContent = `You are DeeperCode V4-Pro,
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
12369
|
+
let sysContent = `You are DeeperCode V4-Pro, an elite full-stack AI coding agent with autonomous execution capability.
|
|
12370
|
+
|
|
12371
|
+
## Core Principles
|
|
12372
|
+
1. READ BEFORE WRITE \u2014 Always inspect project state before making changes.
|
|
12373
|
+
2. COMPLETE CODE \u2014 Write full files. Never use placeholders like "// ..." or "rest of code".
|
|
12374
|
+
3. ONE CALL = ONE FILE \u2014 Each write_file contains exactly one complete file. Batch independent writes.
|
|
12375
|
+
4. PLAN WITH TODOS \u2014 Use todo_manager for multi-step tasks. Update status as you progress.
|
|
12376
|
+
5. ACT OVER EXPLAIN \u2014 Keep reasoning brief. Prefer tool calls over lengthy explanations.
|
|
12377
|
+
6. VERIFY AFTER WRITE \u2014 After writing code, run type checks, linters, or tests to confirm correctness.
|
|
12378
|
+
7. FIX ERRORS PROACTIVELY \u2014 If a tool returns an error, diagnose and fix it immediately.
|
|
12379
|
+
8. PARALLEL WHEN POSSIBLE \u2014 Execute independent tool calls simultaneously for efficiency.
|
|
12380
|
+
|
|
12381
|
+
## Smart Editing Strategy
|
|
12382
|
+
- For EXISTING files, prefer edit_file over write_file to minimize diff size.
|
|
12383
|
+
- For NEW files, use write_file with complete content.
|
|
12384
|
+
- Before editing, read the file first to understand its current state.
|
|
12385
|
+
- Make targeted, minimal edits rather than rewriting entire files.
|
|
12386
|
+
|
|
12387
|
+
## Auto-Verification Loop
|
|
12388
|
+
After writing or editing code files, ALWAYS verify the changes:
|
|
12389
|
+
1. Run the project's build command (npm run build, tsc --noEmit, cargo check, etc.)
|
|
12390
|
+
2. If build fails, read the error output, fix the issues, and re-verify
|
|
12391
|
+
3. If tests exist, run them to confirm nothing is broken
|
|
12392
|
+
4. Repeat until all checks pass \u2014 do NOT leave the user with broken code
|
|
12393
|
+
|
|
12394
|
+
## Error Recovery
|
|
12395
|
+
- When a tool call fails, analyze the error message carefully before retrying
|
|
12396
|
+
- If the same approach fails twice, try a different strategy
|
|
12397
|
+
- For type errors: read the file, understand the types, fix precisely
|
|
12398
|
+
- For runtime errors: add proper error handling and logging
|
|
12399
|
+
- Never give up after one failure \u2014 adapt and overcome
|
|
12400
|
+
|
|
12401
|
+
## Execution Strategy
|
|
12402
|
+
- Start by reading relevant files and understanding the codebase structure.
|
|
12403
|
+
- Break complex tasks into small, verifiable steps.
|
|
12404
|
+
- After each code change, verify it compiles/passes before moving on.
|
|
12405
|
+
- When stuck, try a different approach rather than repeating the same failed action.
|
|
12406
|
+
- Use subagent for independent subtasks that can run in parallel.
|
|
12407
|
+
|
|
12408
|
+
## Context
|
|
12409
|
+
- cwd=${process5.cwd()} plat=${process5.platform} arch=${process5.arch}
|
|
12410
|
+
- Respond in the same language as the user's input.`;
|
|
11499
12411
|
const ts = todoSummary(4);
|
|
11500
|
-
if (ts) sysContent += "\n[Remaining]\n" + ts;
|
|
12412
|
+
if (ts) sysContent += "\n[Remaining Tasks]\n" + ts;
|
|
11501
12413
|
const lastU = history.filter((m) => m.role === "user").pop();
|
|
11502
12414
|
if (lastU?.content) {
|
|
11503
12415
|
const hints = xmemory.getProceduralHints(lastU.content || "", 3);
|
|
11504
12416
|
if (hints) sysContent += "\n" + hints;
|
|
11505
12417
|
}
|
|
11506
12418
|
const workCtx = xmemory.getWorkingContext(400);
|
|
11507
|
-
if (workCtx) sysContent += "\n[
|
|
12419
|
+
if (workCtx) sysContent += "\n[Recent Work]\n" + workCtx;
|
|
11508
12420
|
const skillPrompt = getSkillSystemPrompt();
|
|
11509
12421
|
if (skillPrompt) sysContent += "\n" + skillPrompt;
|
|
11510
12422
|
r2.push({ role: "system", content: sysContent });
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
try {
|
|
11523
|
-
const rulesFile = join11(process5.cwd(), ".deeper", "rules.md");
|
|
11524
|
-
if (existsSync52(rulesFile)) {
|
|
11525
|
-
const rules = readFileSync37(rulesFile, "utf-8").slice(0, 4e3);
|
|
11526
|
-
if (rules.trim()) r2.push({ role: "system", content: `[\u9879\u76EE\u89C4\u5219 rules.md]
|
|
11527
|
-
${rules}` });
|
|
11528
|
-
}
|
|
11529
|
-
} catch {
|
|
11530
|
-
}
|
|
11531
|
-
try {
|
|
11532
|
-
const globalRules = join11(DEEPER_HOME, "rules.md");
|
|
11533
|
-
if (existsSync52(globalRules)) {
|
|
11534
|
-
const rules = readFileSync37(globalRules, "utf-8").slice(0, 2e3);
|
|
11535
|
-
if (rules.trim()) r2.push({ role: "system", content: `[\u5168\u5C40\u89C4\u5219]
|
|
11536
|
-
${rules}` });
|
|
11537
|
-
}
|
|
11538
|
-
} catch {
|
|
11539
|
-
}
|
|
12423
|
+
const deeperCtx = cachedRead(join12(process5.cwd(), "deeper.md"));
|
|
12424
|
+
if (deeperCtx && deeperCtx.trim() && !deeperCtx.includes("<!-- \u586B\u5199")) {
|
|
12425
|
+
r2.push({ role: "system", content: `[\u9879\u76EE\u4E0A\u4E0B\u6587 deeper.md]
|
|
12426
|
+
${deeperCtx}` });
|
|
12427
|
+
}
|
|
12428
|
+
const projRules = cachedRead(join12(process5.cwd(), ".deeper", "rules.md"));
|
|
12429
|
+
if (projRules && projRules.trim()) r2.push({ role: "system", content: `[\u9879\u76EE\u89C4\u5219 rules.md]
|
|
12430
|
+
${projRules}` });
|
|
12431
|
+
const globalRules = cachedRead(join12(DEEPER_HOME, "rules.md"), 2e3);
|
|
12432
|
+
if (globalRules && globalRules.trim()) r2.push({ role: "system", content: `[\u5168\u5C40\u89C4\u5219]
|
|
12433
|
+
${globalRules}` });
|
|
11540
12434
|
for (const m of history.slice(-30)) {
|
|
11541
12435
|
const e = { role: m.role };
|
|
11542
12436
|
if (m.content != null) e.content = (m.content || "").slice(0, 8e3);
|
|
@@ -11554,27 +12448,62 @@ ${rules}` });
|
|
|
11554
12448
|
function trimHistory(h, max) {
|
|
11555
12449
|
while (h.length > max) h.shift();
|
|
11556
12450
|
}
|
|
12451
|
+
function cachedRead(path, maxLen = 4e3) {
|
|
12452
|
+
if (!existsSync53(path)) return null;
|
|
12453
|
+
try {
|
|
12454
|
+
const st = statSync12(path);
|
|
12455
|
+
const cached = _fileCache.get(path);
|
|
12456
|
+
if (cached && cached.mtime === st.mtimeMs) return cached.content;
|
|
12457
|
+
const content = readFileSync37(path, "utf-8").slice(0, maxLen);
|
|
12458
|
+
_fileCache.set(path, { mtime: st.mtimeMs, content });
|
|
12459
|
+
return content;
|
|
12460
|
+
} catch {
|
|
12461
|
+
return null;
|
|
12462
|
+
}
|
|
12463
|
+
}
|
|
11557
12464
|
function compressHistory(h) {
|
|
11558
12465
|
if (h.length <= 6) return;
|
|
11559
12466
|
const keep = 6;
|
|
11560
12467
|
const old = h.slice(0, h.length - keep);
|
|
11561
12468
|
const recent = h.slice(h.length - keep);
|
|
11562
|
-
|
|
12469
|
+
const sections = [];
|
|
12470
|
+
let userParts = [];
|
|
12471
|
+
let assistantParts = [];
|
|
12472
|
+
let toolParts = [];
|
|
12473
|
+
const flushSection = () => {
|
|
12474
|
+
if (userParts.length > 0) sections.push(`[\u7528\u6237] ${userParts.join(" \u2192 ")}`);
|
|
12475
|
+
if (assistantParts.length > 0) sections.push(`[\u52A9\u624B] ${assistantParts.join(" \u2192 ")}`);
|
|
12476
|
+
if (toolParts.length > 0) sections.push(`[\u5DE5\u5177] ${toolParts.join(", ")}`);
|
|
12477
|
+
userParts = [];
|
|
12478
|
+
assistantParts = [];
|
|
12479
|
+
toolParts = [];
|
|
12480
|
+
};
|
|
11563
12481
|
for (const m of old) {
|
|
12482
|
+
if (m.role === "system") {
|
|
12483
|
+
flushSection();
|
|
12484
|
+
continue;
|
|
12485
|
+
}
|
|
11564
12486
|
if (m.role === "user" && m.content) {
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
} else if (m.role === "assistant"
|
|
11568
|
-
|
|
11569
|
-
|
|
12487
|
+
if (assistantParts.length > 0 || toolParts.length > 0) flushSection();
|
|
12488
|
+
userParts.push(m.content.slice(0, 120));
|
|
12489
|
+
} else if (m.role === "assistant") {
|
|
12490
|
+
if (m.tool_calls && m.tool_calls.length > 0) {
|
|
12491
|
+
const names = m.tool_calls.map((t) => t.name).join(", ");
|
|
12492
|
+
toolParts.push(names);
|
|
12493
|
+
}
|
|
12494
|
+
if (m.content) {
|
|
12495
|
+
assistantParts.push(m.content.slice(0, 150));
|
|
12496
|
+
}
|
|
11570
12497
|
} else if (m.role === "tool" && m.content) {
|
|
11571
|
-
|
|
11572
|
-
|
|
12498
|
+
const isErr = m.content.startsWith("Error:");
|
|
12499
|
+
toolParts.push(isErr ? "\u274C" : "\u2713");
|
|
11573
12500
|
}
|
|
11574
12501
|
}
|
|
12502
|
+
flushSection();
|
|
12503
|
+
const compressed = sections.join("\n").slice(0, 4e3);
|
|
11575
12504
|
h.length = 0;
|
|
11576
12505
|
h.push({ role: "system", content: `[\u4E0A\u4E0B\u6587\u538B\u7F29\xB7${old.length}\u6761\u6458\u8981]
|
|
11577
|
-
${compressed
|
|
12506
|
+
${compressed}` });
|
|
11578
12507
|
h.push(...recent);
|
|
11579
12508
|
}
|
|
11580
12509
|
function sanitize(t) {
|
|
@@ -11584,17 +12513,56 @@ function lastUser(h) {
|
|
|
11584
12513
|
for (let i = h.length - 1; i >= 0; i--) if (h[i].role === "user" && h[i].content) return h[i].content;
|
|
11585
12514
|
return "";
|
|
11586
12515
|
}
|
|
12516
|
+
function computeSimpleDiff(oldText, newText, filePath) {
|
|
12517
|
+
const oldLines = oldText.split("\n");
|
|
12518
|
+
const newLines = newText.split("\n");
|
|
12519
|
+
const maxLines = Math.max(oldLines.length, newLines.length);
|
|
12520
|
+
const result = [];
|
|
12521
|
+
let changeCount = 0;
|
|
12522
|
+
const contextLines = 3;
|
|
12523
|
+
for (let i = 0; i < maxLines; i++) {
|
|
12524
|
+
const oldLine = oldLines[i];
|
|
12525
|
+
const newLine = newLines[i];
|
|
12526
|
+
if (oldLine !== newLine) {
|
|
12527
|
+
changeCount++;
|
|
12528
|
+
const start = Math.max(0, i - contextLines);
|
|
12529
|
+
const end = Math.min(maxLines, i + contextLines + 1);
|
|
12530
|
+
if (result.length === 0 || result[result.length - 1] !== "...") {
|
|
12531
|
+
result.push(G(` @@ line ${i + 1} @@`));
|
|
12532
|
+
}
|
|
12533
|
+
for (let j = start; j < end; j++) {
|
|
12534
|
+
if (j === i) {
|
|
12535
|
+
if (oldLine !== void 0 && newLine !== void 0) {
|
|
12536
|
+
result.push(r(` - ${oldLines[j]}`));
|
|
12537
|
+
result.push(g(` + ${newLines[j]}`));
|
|
12538
|
+
} else if (oldLine !== void 0) {
|
|
12539
|
+
result.push(r(` - ${oldLines[j]}`));
|
|
12540
|
+
} else {
|
|
12541
|
+
result.push(g(` + ${newLines[j]}`));
|
|
12542
|
+
}
|
|
12543
|
+
} else if (j < oldLines.length && j < newLines.length) {
|
|
12544
|
+
result.push(G(` ${oldLines[j]}`));
|
|
12545
|
+
}
|
|
12546
|
+
}
|
|
12547
|
+
result.push(G(" ..."));
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12550
|
+
if (changeCount === 0) return G(" (\u65E0\u53D8\u66F4)");
|
|
12551
|
+
const rel = relative6(process5.cwd(), filePath);
|
|
12552
|
+
return `${G(`\u6587\u4EF6: ${rel} (${changeCount} \u5904\u53D8\u66F4)`)}
|
|
12553
|
+
${result.join("\n")}`;
|
|
12554
|
+
}
|
|
11587
12555
|
function toolsToDefs(tools) {
|
|
11588
12556
|
return tools.map((t) => ({ type: "function", function: { name: t.name, description: t.description, parameters: t.parameters } }));
|
|
11589
12557
|
}
|
|
11590
12558
|
async function saveSession(history, name) {
|
|
11591
12559
|
const label = name || (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
11592
|
-
const file =
|
|
12560
|
+
const file = join12(SESSION_DIR, `sess_${label}.json`);
|
|
11593
12561
|
writeFileSync14(file, JSON.stringify({ savedAt: (/* @__PURE__ */ new Date()).toISOString(), cwd: process5.cwd(), messages: history }, null, 2), "utf-8");
|
|
11594
12562
|
O(g(`\u5DF2\u4FDD\u5B58: sess_${label}`) + "\n\n");
|
|
11595
12563
|
}
|
|
11596
12564
|
async function listSessions() {
|
|
11597
|
-
if (!
|
|
12565
|
+
if (!existsSync53(SESSION_DIR)) {
|
|
11598
12566
|
O(r("\u65E0\u4FDD\u5B58\u7684\u4F1A\u8BDD\n\n"));
|
|
11599
12567
|
return;
|
|
11600
12568
|
}
|
|
@@ -11607,10 +12575,9 @@ async function listSessions() {
|
|
|
11607
12575
|
for (let i = 0; i < Math.min(files.length, 15); i++) {
|
|
11608
12576
|
const f = files[i];
|
|
11609
12577
|
try {
|
|
11610
|
-
const data = JSON.parse(readFileSync37(
|
|
12578
|
+
const data = JSON.parse(readFileSync37(join12(SESSION_DIR, f), "utf-8"));
|
|
11611
12579
|
const label = f.replace(/^sess_|\.json$/g, "");
|
|
11612
12580
|
const msgCount = data.messages?.length || 0;
|
|
11613
|
-
const cwd = data.cwd || "?";
|
|
11614
12581
|
const savedAt = data.savedAt?.slice(0, 16) || "?";
|
|
11615
12582
|
O(G(` ${i + 1}. `) + c(label) + G(` \xB7 ${msgCount}\u6761 \xB7 ${savedAt}`) + "\n");
|
|
11616
12583
|
} catch {
|
|
@@ -11621,8 +12588,8 @@ async function listSessions() {
|
|
|
11621
12588
|
O("\n \u52A0\u8F7D: /load <name> | \u6062\u590D: /resume\n\n");
|
|
11622
12589
|
}
|
|
11623
12590
|
async function loadNamedSession(history, name) {
|
|
11624
|
-
const file =
|
|
11625
|
-
if (!
|
|
12591
|
+
const file = join12(SESSION_DIR, `sess_${name}.json`);
|
|
12592
|
+
if (!existsSync53(file)) {
|
|
11626
12593
|
O(r(`\u4F1A\u8BDD\u4E0D\u5B58\u5728: ${name}
|
|
11627
12594
|
|
|
11628
12595
|
`));
|
|
@@ -11635,7 +12602,7 @@ async function loadNamedSession(history, name) {
|
|
|
11635
12602
|
O(g(`\u5DF2\u52A0\u8F7D: ${name}`) + "\n\n");
|
|
11636
12603
|
}
|
|
11637
12604
|
async function loadLatestSession(history) {
|
|
11638
|
-
if (!
|
|
12605
|
+
if (!existsSync53(SESSION_DIR)) {
|
|
11639
12606
|
O(r("\u65E0\u4FDD\u5B58\u7684\u4F1A\u8BDD\n\n"));
|
|
11640
12607
|
return;
|
|
11641
12608
|
}
|
|
@@ -11644,7 +12611,7 @@ async function loadLatestSession(history) {
|
|
|
11644
12611
|
O(r("\u65E0\u4FDD\u5B58\u7684\u4F1A\u8BDD\n\n"));
|
|
11645
12612
|
return;
|
|
11646
12613
|
}
|
|
11647
|
-
const file =
|
|
12614
|
+
const file = join12(SESSION_DIR, files[0]);
|
|
11648
12615
|
const data = JSON.parse(readFileSync37(file, "utf-8"));
|
|
11649
12616
|
const label = files[0].replace(/^sess_|\.json$/g, "");
|
|
11650
12617
|
history.push({ role: "system", content: `[\u5DF2\u52A0\u8F7D: ${label} (${data.messages?.length || 0} \u6761)]` });
|
|
@@ -11653,13 +12620,13 @@ async function loadLatestSession(history) {
|
|
|
11653
12620
|
O(g(`\u5DF2\u52A0\u8F7D: ${label}`) + "\n\n");
|
|
11654
12621
|
}
|
|
11655
12622
|
async function exportHistory(history) {
|
|
11656
|
-
const file =
|
|
12623
|
+
const file = join12(process5.cwd(), `deeper-export-${Date.now()}.json`);
|
|
11657
12624
|
writeFileSync14(file, JSON.stringify(history, null, 2), "utf-8");
|
|
11658
12625
|
O(g(`\u5DF2\u5BFC\u51FA: ${file}`) + "\n\n");
|
|
11659
12626
|
}
|
|
11660
12627
|
async function initProject() {
|
|
11661
|
-
const file =
|
|
11662
|
-
if (
|
|
12628
|
+
const file = join12(process5.cwd(), "deeper.md");
|
|
12629
|
+
if (existsSync53(file)) {
|
|
11663
12630
|
O(y(" deeper.md \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\n\n"));
|
|
11664
12631
|
return;
|
|
11665
12632
|
}
|
|
@@ -11785,99 +12752,34 @@ async function loadBuiltinTools() {
|
|
|
11785
12752
|
const { builtinTools: builtinTools2 } = await Promise.resolve().then(() => (init_builtin(), builtin_exports));
|
|
11786
12753
|
return builtinTools2;
|
|
11787
12754
|
}
|
|
11788
|
-
async function callApi(opts, msgs, tools,
|
|
11789
|
-
const
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
}
|
|
11815
|
-
throw new Error(`HTTP ${resp.status}: ${et.slice(0, 200)}`);
|
|
11816
|
-
}
|
|
11817
|
-
if (!resp.body) throw new Error("\u7A7A\u54CD\u5E94");
|
|
11818
|
-
return sseIter(resp.body);
|
|
11819
|
-
} catch (e) {
|
|
11820
|
-
const m = (e instanceof Error ? e.message : String(e)).toLowerCase();
|
|
11821
|
-
if ((m.includes("timeout") || m.includes("abort") || m.includes("econn")) && retry < MR) {
|
|
11822
|
-
const d2 = Math.min(1e3 * (retry + 1), 5e3);
|
|
11823
|
-
await new Promise((r2) => setTimeout(r2, d2));
|
|
11824
|
-
return callApi(opts, msgs, tools, retry + 1, cmt);
|
|
11825
|
-
}
|
|
11826
|
-
throw e;
|
|
11827
|
-
} finally {
|
|
11828
|
-
clearTimeout(t);
|
|
11829
|
-
}
|
|
11830
|
-
}
|
|
11831
|
-
async function* sseIter(body) {
|
|
11832
|
-
const reader = body.getReader();
|
|
11833
|
-
const dec = new TextDecoder();
|
|
11834
|
-
let buf = "";
|
|
11835
|
-
try {
|
|
11836
|
-
while (true) {
|
|
11837
|
-
const { done, value } = await reader.read();
|
|
11838
|
-
if (done) break;
|
|
11839
|
-
buf += dec.decode(value, { stream: true });
|
|
11840
|
-
if (buf.length > 65536) buf = buf.slice(-32768);
|
|
11841
|
-
const lines = buf.split("\n");
|
|
11842
|
-
buf = lines.pop() || "";
|
|
11843
|
-
for (const line of lines) {
|
|
11844
|
-
const tr = line.trim();
|
|
11845
|
-
if (!tr || tr.startsWith(":")) continue;
|
|
11846
|
-
if (!tr.startsWith("data: ")) continue;
|
|
11847
|
-
const d2 = tr.slice(6).trim();
|
|
11848
|
-
if (d2 === "[DONE]") {
|
|
11849
|
-
yield { type: "done" };
|
|
11850
|
-
return;
|
|
11851
|
-
}
|
|
11852
|
-
try {
|
|
11853
|
-
const p = JSON.parse(d2);
|
|
11854
|
-
const ch = p.choices?.[0];
|
|
11855
|
-
if (!ch) continue;
|
|
11856
|
-
const dl = ch.delta;
|
|
11857
|
-
if (dl?.content) yield { type: "text", content: dl.content };
|
|
11858
|
-
if (dl?.reasoning_content) yield { type: "thinking", content: dl.reasoning_content };
|
|
11859
|
-
if (dl?.tool_calls) for (const tc of dl.tool_calls) {
|
|
11860
|
-
if (tc.id) yield { type: "tool_call_start", tool_call: { id: tc.id, name: tc.function?.name || "" } };
|
|
11861
|
-
if (tc.function?.arguments) yield { type: "tool_call_args", content: tc.function.arguments };
|
|
11862
|
-
if (tc.id && tc.function?.arguments) yield { type: "tool_call_end" };
|
|
11863
|
-
}
|
|
11864
|
-
if (ch.finish_reason === "tool_calls") yield { type: "tool_call_end" };
|
|
11865
|
-
} catch {
|
|
11866
|
-
}
|
|
11867
|
-
}
|
|
11868
|
-
}
|
|
11869
|
-
} catch (e) {
|
|
11870
|
-
if (e instanceof Error && e.name === "AbortError") {
|
|
11871
|
-
} else yield { type: "error", error: e instanceof Error ? e.message : String(e) };
|
|
11872
|
-
} finally {
|
|
11873
|
-
try {
|
|
11874
|
-
reader.releaseLock();
|
|
11875
|
-
} catch {
|
|
11876
|
-
}
|
|
11877
|
-
}
|
|
11878
|
-
yield { type: "done" };
|
|
12755
|
+
async function callApi(opts, msgs, tools, cmt = 8192, signal) {
|
|
12756
|
+
const client = new DeepSeekClient({
|
|
12757
|
+
apiKey: opts.apiKey || "",
|
|
12758
|
+
model: opts.model || "deepseek-chat",
|
|
12759
|
+
baseUrl: opts.baseUrl || "https://api.deepseek.com",
|
|
12760
|
+
temperature: opts.temperature ?? 0,
|
|
12761
|
+
maxTokens: cmt,
|
|
12762
|
+
think: { enabled: true, budgetTokens: cmt },
|
|
12763
|
+
signal
|
|
12764
|
+
});
|
|
12765
|
+
const chatMsgs = msgs.map((m) => ({
|
|
12766
|
+
role: m.role || "user",
|
|
12767
|
+
content: m.content != null ? String(m.content) : null,
|
|
12768
|
+
tool_calls: m.tool_calls,
|
|
12769
|
+
tool_call_id: m.tool_call_id,
|
|
12770
|
+
name: m.name,
|
|
12771
|
+
reasoning_content: m.reasoning_content,
|
|
12772
|
+
thinking: m.thinking
|
|
12773
|
+
}));
|
|
12774
|
+
const stream = await client.chatStream(chatMsgs, tools.map((t) => ({
|
|
12775
|
+
name: t.function.name,
|
|
12776
|
+
description: t.function.description,
|
|
12777
|
+
category: "",
|
|
12778
|
+
parameters: t.function.parameters
|
|
12779
|
+
})));
|
|
12780
|
+
return stream;
|
|
11879
12781
|
}
|
|
11880
|
-
var MAX_HISTORY, CONTEXT_LIMIT, CTX_WARN, TOOL_RESULT_MAX, SESSION_DIR, AUTOSAVE_FILE, GS, skillEngine, mcpClient, validator;
|
|
12782
|
+
var MAX_HISTORY, CONTEXT_LIMIT, CTX_WARN, TOOL_RESULT_MAX, SESSION_DIR, AUTOSAVE_FILE, TOOL_TIMEOUT_MAP, DEFAULT_TOOL_TIMEOUT, GS, skillEngine, mcpClient, validator, currentAbortController, BACKUP_DIR, MAX_BACKUPS, fileBackupStack, _fileCache;
|
|
11881
12783
|
var init_chat_repl = __esm({
|
|
11882
12784
|
"src/cli/chat-repl.ts"() {
|
|
11883
12785
|
"use strict";
|
|
@@ -11890,17 +12792,47 @@ var init_chat_repl = __esm({
|
|
|
11890
12792
|
init_token_count();
|
|
11891
12793
|
init_SkillEngine();
|
|
11892
12794
|
init_MCPClient();
|
|
12795
|
+
init_DeepSeekClient();
|
|
11893
12796
|
init_ansi();
|
|
11894
12797
|
MAX_HISTORY = 60;
|
|
11895
12798
|
CONTEXT_LIMIT = 1048576;
|
|
11896
12799
|
CTX_WARN = 786432;
|
|
11897
12800
|
TOOL_RESULT_MAX = 4e3;
|
|
11898
|
-
SESSION_DIR =
|
|
11899
|
-
AUTOSAVE_FILE =
|
|
12801
|
+
SESSION_DIR = join12(DEEPER_HOME, "sessions");
|
|
12802
|
+
AUTOSAVE_FILE = join12(SESSION_DIR, "_autosave.json");
|
|
12803
|
+
TOOL_TIMEOUT_MAP = {
|
|
12804
|
+
run_command: 12e4,
|
|
12805
|
+
run_async: 12e4,
|
|
12806
|
+
pipe_commands: 12e4,
|
|
12807
|
+
shell_script: 12e4,
|
|
12808
|
+
build_project: 18e4,
|
|
12809
|
+
run_test: 18e4,
|
|
12810
|
+
npm_manage: 12e4,
|
|
12811
|
+
docker_manage: 12e4,
|
|
12812
|
+
project_init: 12e4,
|
|
12813
|
+
web_fetch: 6e4,
|
|
12814
|
+
web_search: 6e4,
|
|
12815
|
+
http_request: 6e4,
|
|
12816
|
+
browser_action: 6e4,
|
|
12817
|
+
screenshot_page: 6e4,
|
|
12818
|
+
sql_query: 6e4,
|
|
12819
|
+
sql_migrate: 12e4,
|
|
12820
|
+
db_backup: 18e4,
|
|
12821
|
+
db_restore: 18e4,
|
|
12822
|
+
secret_scan: 6e4,
|
|
12823
|
+
vulnerability_check: 6e4,
|
|
12824
|
+
subagent: 18e4
|
|
12825
|
+
};
|
|
12826
|
+
DEFAULT_TOOL_TIMEOUT = 3e4;
|
|
11900
12827
|
GS = { tc: 0, api: 0, ch: 0 };
|
|
11901
12828
|
skillEngine = null;
|
|
11902
12829
|
mcpClient = null;
|
|
11903
12830
|
validator = new ToolValidator();
|
|
12831
|
+
currentAbortController = null;
|
|
12832
|
+
BACKUP_DIR = join12(DEEPER_HOME, "backups");
|
|
12833
|
+
MAX_BACKUPS = 50;
|
|
12834
|
+
fileBackupStack = [];
|
|
12835
|
+
_fileCache = /* @__PURE__ */ new Map();
|
|
11904
12836
|
}
|
|
11905
12837
|
});
|
|
11906
12838
|
|