@noobdemon/noob-cli 1.0.3 → 1.0.4
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/package.json +1 -1
- package/src/i18n.js +2 -1
- package/src/repl.js +37 -7
- package/src/update.js +5 -0
package/package.json
CHANGED
package/src/i18n.js
CHANGED
|
@@ -55,7 +55,8 @@ export const t = {
|
|
|
55
55
|
cmdLogin: "/login <key> đăng nhập bằng API key",
|
|
56
56
|
cmdLogout: "/logout đăng xuất",
|
|
57
57
|
cmdUsage: "/usage xem hạn mức key còn lại",
|
|
58
|
-
cmdStatus: "/status xem mô hình
|
|
58
|
+
cmdStatus: "/status xem mô hình, version, trạng thái yolo, thư mục",
|
|
59
|
+
cmdVersion: "/version /v xem version hiện tại + trạng thái yolo",
|
|
59
60
|
cmdExit: "/exit /quit thoát",
|
|
60
61
|
tip1: "• Mô tả việc cần làm; noob sẽ đọc/sửa file & chạy lệnh giúp bạn.",
|
|
61
62
|
tip2: "• Thao tác nguy hiểm sẽ hỏi phép, trừ khi bật yolo (Shift+Tab).",
|
package/src/repl.js
CHANGED
|
@@ -88,6 +88,20 @@ export async function startRepl(opts = {}) {
|
|
|
88
88
|
rl.prompt(true);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
+
// Đừng để một lỗi bất ngờ làm "tự động tắt" CLI. Nguyên nhân hay gặp:
|
|
92
|
+
// tiến trình cập nhật nền (spawn npm) phát sự kiện 'error' không ai bắt,
|
|
93
|
+
// hoặc lỗi async trong một lượt → Node thoát ngay. Ở đây bắt lại, in ra,
|
|
94
|
+
// rồi vẽ lại prompt để phiên làm việc vẫn sống.
|
|
95
|
+
process.on("uncaughtException", (err) => {
|
|
96
|
+
if (abort) { abort.abort(); abort = null; }
|
|
97
|
+
console.log(c.err("\n ✗ lỗi: " + (err?.message || err)));
|
|
98
|
+
if (!closed) rl.prompt(true);
|
|
99
|
+
});
|
|
100
|
+
process.on("unhandledRejection", (err) => {
|
|
101
|
+
console.log(c.err("\n ✗ lỗi nền: " + (err?.message || err)));
|
|
102
|
+
if (!closed) rl.prompt(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
91
105
|
banner();
|
|
92
106
|
printStatus(state);
|
|
93
107
|
if (!config.apiKey) console.log("\n" + c.tool(" " + t.notLoggedIn) + "\n");
|
|
@@ -112,18 +126,26 @@ export async function startRepl(opts = {}) {
|
|
|
112
126
|
|
|
113
127
|
// Main loop — runs until /exit, double Ctrl+C, or EOF. Never exits after a task.
|
|
114
128
|
while (true) {
|
|
115
|
-
const raw = await ask(c.user("\n" + t.promptYou) + c.dim("› "));
|
|
129
|
+
const raw = await ask(c.user("\n" + t.promptYou) + (state.yolo ? c.err("⚡ ") : "") + c.dim("› "));
|
|
116
130
|
if (raw == null) break; // stdin fully closed and drained
|
|
117
131
|
const input = raw.trim();
|
|
118
132
|
if (!input) continue;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
// Bọc cả lượt: một lỗi trong xử lý lệnh/agent không được phép thoát ra
|
|
134
|
+
// ngoài vòng lặp (sẽ rơi vào .catch ở bin/noob.js → process.exit(1) =
|
|
135
|
+
// "tự động tắt"). Bắt ở đây, in lỗi, rồi tiếp tục vòng lặp.
|
|
136
|
+
try {
|
|
137
|
+
if (input.startsWith("/")) {
|
|
138
|
+
const done = await command(input);
|
|
139
|
+
if (done) break;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
await handle(input);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
printError(err);
|
|
123
145
|
}
|
|
124
|
-
await handle(input);
|
|
125
146
|
}
|
|
126
147
|
rl.close();
|
|
148
|
+
process.exit(0);
|
|
127
149
|
|
|
128
150
|
// ── turn handler ─────────────────────────────────────────────────────────
|
|
129
151
|
async function handle(text) {
|
|
@@ -277,6 +299,10 @@ export async function startRepl(opts = {}) {
|
|
|
277
299
|
case "status":
|
|
278
300
|
printStatus(state);
|
|
279
301
|
break;
|
|
302
|
+
case "version":
|
|
303
|
+
case "v":
|
|
304
|
+
console.log(c.dim(" noob ") + c.accent("v" + CURRENT) + (state.yolo ? c.err(" ⚡ yolo: BẬT") : c.dim(" yolo: tắt")));
|
|
305
|
+
break;
|
|
280
306
|
case "exit":
|
|
281
307
|
case "quit":
|
|
282
308
|
case "q":
|
|
@@ -337,7 +363,10 @@ export async function startRepl(opts = {}) {
|
|
|
337
363
|
const mode =
|
|
338
364
|
s.mode === "merge" ? c.tool("Merge AI") : s.mode === "search" ? c.accent("Tìm web") : modelBadge(s.model);
|
|
339
365
|
const key = config.apiKey ? c.ok(" 🔑") : c.err(" 🔒");
|
|
340
|
-
|
|
366
|
+
const yolo = s.yolo ? c.err(" ⚡ yolo: BẬT") : c.dim(" yolo: tắt");
|
|
367
|
+
console.log(
|
|
368
|
+
" " + mode + key + yolo + c.dim(" v" + CURRENT) + c.dim(" thư mục: " + shortCwd()),
|
|
369
|
+
);
|
|
341
370
|
}
|
|
342
371
|
}
|
|
343
372
|
|
|
@@ -399,6 +428,7 @@ function printHelp() {
|
|
|
399
428
|
" " + t.cmdUpdate,
|
|
400
429
|
" " + t.cmdClear,
|
|
401
430
|
" " + t.cmdStatus,
|
|
431
|
+
" " + t.cmdVersion,
|
|
402
432
|
" " + t.cmdExit,
|
|
403
433
|
"",
|
|
404
434
|
chalk.bold(t.helpTips),
|
package/src/update.js
CHANGED
|
@@ -61,6 +61,11 @@ export function runUpdate({ background = false } = {}) {
|
|
|
61
61
|
}
|
|
62
62
|
if (background) {
|
|
63
63
|
const child = spawn(cmd, args, { detached: true, stdio: "ignore", env, shell: isWin });
|
|
64
|
+
// QUAN TRỌNG: nếu spawn lỗi (vd npm không có trong PATH, hoặc shell trục
|
|
65
|
+
// trặc trên Windows) mà không có listener 'error', Node sẽ ném
|
|
66
|
+
// uncaughtException → tiến trình tự tắt ngay sau khi khởi động. Nuốt lỗi ở
|
|
67
|
+
// đây vì cập nhật nền chỉ là "best effort".
|
|
68
|
+
child.on("error", () => {});
|
|
64
69
|
child.unref();
|
|
65
70
|
return Promise.resolve(true);
|
|
66
71
|
}
|