@rennii/deepseek-cli 1.0.0 → 1.0.1
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/deepseek-cli.js +39 -3
- package/package.json +1 -1
- package/test-deepseek-cli.js +16 -0
package/deepseek-cli.js
CHANGED
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
readFileSync,
|
|
12
12
|
readdirSync,
|
|
13
13
|
renameSync,
|
|
14
|
+
unlinkSync,
|
|
14
15
|
writeFileSync,
|
|
15
16
|
} = require("node:fs");
|
|
16
17
|
const { dirname, join } = require("node:path");
|
|
@@ -46,6 +47,7 @@ const COMMAND_SUGGESTIONS = [
|
|
|
46
47
|
["/logout", "xóa token đã lưu"],
|
|
47
48
|
["/new", "phiên mới"],
|
|
48
49
|
["/resume", "mở phiên đã lưu"],
|
|
50
|
+
["/remove", "xóa phiên đã lưu"],
|
|
49
51
|
["/agent", "bật/tắt terminal"],
|
|
50
52
|
["/clear", "xóa màn hình"],
|
|
51
53
|
["/help", "trợ giúp"],
|
|
@@ -221,6 +223,17 @@ class SessionStore {
|
|
|
221
223
|
for (const session of sessions) saveJson(this.sessionPath(session), session);
|
|
222
224
|
}
|
|
223
225
|
|
|
226
|
+
remove(session) {
|
|
227
|
+
if (!session?.id) throw new Error("Phiên không có mã định danh để xóa");
|
|
228
|
+
let removed = false;
|
|
229
|
+
for (const path of this.sessionFiles(this.sessionDir)) {
|
|
230
|
+
if (readJson(path, null)?.id !== session.id) continue;
|
|
231
|
+
unlinkSync(path);
|
|
232
|
+
removed = true;
|
|
233
|
+
}
|
|
234
|
+
return removed;
|
|
235
|
+
}
|
|
236
|
+
|
|
224
237
|
sessionPath(session) {
|
|
225
238
|
const timestamp = new Date(session.created_at || session.updated_at || nowIso());
|
|
226
239
|
const date = Number.isNaN(timestamp.getTime()) ? new Date() : timestamp;
|
|
@@ -332,6 +345,7 @@ class TerminalUI {
|
|
|
332
345
|
` ${CYAN}/logout${RESET} Xóa token DeepSeek đã lưu`,
|
|
333
346
|
` ${CYAN}/new${RESET} Tạo phiên mới`,
|
|
334
347
|
` ${CYAN}/resume${RESET} Chọn phiên đã lưu để tiếp tục`,
|
|
348
|
+
` ${CYAN}/remove${RESET} Chọn và xóa một phiên đã lưu`,
|
|
335
349
|
` ${CYAN}/agent${RESET} Bật/tắt chế độ chạy lệnh terminal`,
|
|
336
350
|
` ${CYAN}/clear${RESET} Xóa nội dung khỏi màn hình`,
|
|
337
351
|
` ${CYAN}/help${RESET} Hiện trợ giúp`,
|
|
@@ -461,7 +475,7 @@ class TerminalUI {
|
|
|
461
475
|
}
|
|
462
476
|
}
|
|
463
477
|
|
|
464
|
-
async selectSession(sessions) {
|
|
478
|
+
async selectSession(sessions, { title = "Tiếp tục phiên", action = "mở" } = {}) {
|
|
465
479
|
if (!sessions.length) {
|
|
466
480
|
this.notice("Chưa có phiên nào được lưu.");
|
|
467
481
|
return null;
|
|
@@ -478,8 +492,8 @@ class TerminalUI {
|
|
|
478
492
|
const visibleRows = Math.max(1, (process.stdout.rows || 24) - 4);
|
|
479
493
|
const first = Math.min(Math.max(0, selected - visibleRows + 1), Math.max(0, sessions.length - visibleRows));
|
|
480
494
|
this.write("\x1b[2J\x1b[H");
|
|
481
|
-
console.log(`${BOLD}${BLUE}
|
|
482
|
-
console.log(`${DIM}↑ ↓ để chọn · Enter để
|
|
495
|
+
console.log(`${BOLD}${BLUE}${title}${RESET}`);
|
|
496
|
+
console.log(`${DIM}↑ ↓ để chọn · Enter để ${action} · Esc để hủy${RESET}\n`);
|
|
483
497
|
for (let index = first; index < Math.min(first + visibleRows, sessions.length); index += 1) {
|
|
484
498
|
console.log(sessionPickerLine(sessions[index], index, selected, columns));
|
|
485
499
|
}
|
|
@@ -491,6 +505,16 @@ class TerminalUI {
|
|
|
491
505
|
if (/^[1-9]$/.test(key) && Number(key) <= sessions.length) selected = Number(key) - 1;
|
|
492
506
|
}
|
|
493
507
|
}
|
|
508
|
+
|
|
509
|
+
async confirmSessionRemoval(session) {
|
|
510
|
+
const title = sessionPreview(session, 48);
|
|
511
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
512
|
+
const answer = await readline.createInterface({ input: process.stdin, output: process.stdout }).question(`Xóa "${title}"? (y/N): `);
|
|
513
|
+
return answer.trim().toLowerCase() === "y";
|
|
514
|
+
}
|
|
515
|
+
this.write(`\x1b[2J\x1b[H${BOLD}${RED}Xóa phiên${RESET}\n${DIM}${title}${RESET}\n\n${DIM}Enter để xóa · Esc để hủy${RESET}`);
|
|
516
|
+
return (await this.readKey()) === "ENTER";
|
|
517
|
+
}
|
|
494
518
|
}
|
|
495
519
|
|
|
496
520
|
class DeepSeekCLI {
|
|
@@ -693,6 +717,17 @@ class DeepSeekCLI {
|
|
|
693
717
|
this.ui.notice("Đã tiếp tục phiên đã chọn.");
|
|
694
718
|
}
|
|
695
719
|
|
|
720
|
+
async removeSession() {
|
|
721
|
+
const session = await this.ui.selectSession(this.savedSessions, { title: "Xóa phiên", action: "chọn" });
|
|
722
|
+
if (!session) { this.ui.clear(this.activeSession); return; }
|
|
723
|
+
if (!await this.ui.confirmSessionRemoval(session)) { this.ui.clear(this.activeSession); return; }
|
|
724
|
+
if (!this.store.remove(session)) { this.ui.error("Không tìm thấy tệp phiên để xóa."); return; }
|
|
725
|
+
this.savedSessions = this.store.load();
|
|
726
|
+
if (this.activeSession.id === session.id) this.newSession();
|
|
727
|
+
this.ui.clear(this.activeSession);
|
|
728
|
+
this.ui.notice("Đã xóa phiên đã chọn.");
|
|
729
|
+
}
|
|
730
|
+
|
|
696
731
|
async handleCommand(prompt) {
|
|
697
732
|
const command = prompt.toLowerCase();
|
|
698
733
|
if (["/exit", "exit", "quit", "q"].includes(command)) return false;
|
|
@@ -702,6 +737,7 @@ class DeepSeekCLI {
|
|
|
702
737
|
else if (command === "/clear") this.ui.clear(this.activeSession);
|
|
703
738
|
else if (command === "/new") { this.newSession(); this.ui.clear(this.activeSession); this.ui.notice("Đã tạo phiên mới."); }
|
|
704
739
|
else if (command === "/resume") await this.resumeSession();
|
|
740
|
+
else if (command === "/remove") await this.removeSession();
|
|
705
741
|
else if (command === "/agent") { this.agentEnabled = !this.agentEnabled; this.ui.notice(`Chế độ terminal: ${this.agentEnabled ? "bật" : "tắt"}`); }
|
|
706
742
|
else if (command.startsWith("/")) this.ui.error("Lệnh không hợp lệ. Dùng /help để xem danh sách lệnh.");
|
|
707
743
|
else return null;
|
package/package.json
CHANGED
package/test-deepseek-cli.js
CHANGED
|
@@ -84,6 +84,22 @@ test("persists a local session", () => {
|
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
test("removes every saved file for the selected session", () => {
|
|
88
|
+
const directory = mkdtempSync(join(tmpdir(), "deepseek-cli-"));
|
|
89
|
+
try {
|
|
90
|
+
const store = new SessionStore(join(directory, "sessions"), []);
|
|
91
|
+
const session = newLocalSession();
|
|
92
|
+
session.id = "remove-me";
|
|
93
|
+
session.created_at = "2026-08-30T19:45:10.000Z";
|
|
94
|
+
store.save([session]);
|
|
95
|
+
assert.equal(store.remove(session), true);
|
|
96
|
+
assert.deepEqual(store.load(), []);
|
|
97
|
+
assert.equal(store.remove(session), false);
|
|
98
|
+
} finally {
|
|
99
|
+
rmSync(directory, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
87
103
|
test("migrates flat session history into one file per dated session", () => {
|
|
88
104
|
const directory = mkdtempSync(join(tmpdir(), "deepseek-cli-"));
|
|
89
105
|
try {
|