@noobdemon/noob-cli 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/repl.js +25 -15
- package/src/sessions.js +16 -4
package/package.json
CHANGED
package/src/repl.js
CHANGED
|
@@ -282,7 +282,7 @@ export async function startRepl(opts = {}) {
|
|
|
282
282
|
console.log("");
|
|
283
283
|
}
|
|
284
284
|
async function pickSession() {
|
|
285
|
-
const items = sessions.list(20);
|
|
285
|
+
const items = sessions.list(20, process.cwd()); // chỉ phiên của workspace hiện tại
|
|
286
286
|
if (!items.length) {
|
|
287
287
|
console.log(c.dim(" " + t.sessionEmpty) + "\n");
|
|
288
288
|
return null;
|
|
@@ -307,7 +307,7 @@ export async function startRepl(opts = {}) {
|
|
|
307
307
|
return full;
|
|
308
308
|
}
|
|
309
309
|
function listSessions() {
|
|
310
|
-
const items = sessions.list(20);
|
|
310
|
+
const items = sessions.list(20, process.cwd()); // chỉ phiên của workspace hiện tại
|
|
311
311
|
if (!items.length) return console.log(c.dim(" " + t.sessionEmpty));
|
|
312
312
|
console.log("\n" + chalk.bold(" " + t.sessionListTitle));
|
|
313
313
|
items.forEach((s) =>
|
|
@@ -457,7 +457,7 @@ Tự đánh giá: còn THIẾU gì để đạt mục tiêu? Chọn 1 nhiệm v
|
|
|
457
457
|
|
|
458
458
|
// Khôi phục phiên theo cờ dòng lệnh, hoặc mở phiên mới.
|
|
459
459
|
if (opts.continue) {
|
|
460
|
-
const s = sessions.latest();
|
|
460
|
+
const s = sessions.latest(process.cwd()); // phiên gần nhất CỦA workspace này
|
|
461
461
|
if (s) await restore(s);
|
|
462
462
|
else {
|
|
463
463
|
startFresh();
|
|
@@ -663,18 +663,28 @@ Tự đánh giá: còn THIẾU gì để đạt mục tiêu? Chọn 1 nhiệm v
|
|
|
663
663
|
// "tự tắt" trước đây) — thì KHÔNG coi là từ chối: xếp nó vào hàng đợi tin
|
|
664
664
|
// nhắn rồi HỎI LẠI. Nhờ vậy không thao tác nào bị quyết định bởi rác.
|
|
665
665
|
async function askPermission(name) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
666
|
+
// Tắt spinner "đang chạy" trong lúc chờ duyệt. Nếu để nguyên, thanh dưới hiện
|
|
667
|
+
// "đang chạy · Ctrl+C để dừng" → người dùng tưởng đang bận, không biết phải gõ
|
|
668
|
+
// y/n nên lượt TREO. Báo bằng 1 dòng cố định (vào scrollback, không bị vẽ đè)
|
|
669
|
+
// + bỏ spinner để prompt nổi bật. finally khôi phục trạng thái chạy.
|
|
670
|
+
tui.setBusy(false);
|
|
671
|
+
console.log(c.tool(" ⏸ Cần quyền: " + name) + c.dim(" — gõ y (đồng ý) / n (từ chối) / a (luôn cho phép)"));
|
|
672
|
+
try {
|
|
673
|
+
while (true) {
|
|
674
|
+
const raw = await ask(c.tool(" cho phép? ") + c.dim("[y] có / [n] không / [a] luôn " + name + " › "));
|
|
675
|
+
if (raw == null) return "n"; // stdin đóng thật
|
|
676
|
+
const a = raw.trim().toLowerCase();
|
|
677
|
+
if (a === "" || a === "y" || a === "yes" || a === "có") return "y";
|
|
678
|
+
if (a === "n" || a === "no" || a === "không") return "n";
|
|
679
|
+
if (a === "a" || a === "always" || a === "luôn") return "a";
|
|
680
|
+
if (raw.trim().length > 3) {
|
|
681
|
+
pending.push(raw); // tin nhắn lạc → xếp hàng, gửi sau khi xong lượt
|
|
682
|
+
console.log(c.dim(" " + t.queued(pending.length, truncate(raw, 60))));
|
|
683
|
+
}
|
|
684
|
+
console.log(c.dim(" " + t.permRetry));
|
|
676
685
|
}
|
|
677
|
-
|
|
686
|
+
} finally {
|
|
687
|
+
tui.setBusy(true, t.thinking); // khôi phục "đang chạy" cho phần còn lại của lượt
|
|
678
688
|
}
|
|
679
689
|
}
|
|
680
690
|
|
|
@@ -926,7 +936,7 @@ function printError(err) {
|
|
|
926
936
|
}
|
|
927
937
|
|
|
928
938
|
function printUsage(u) {
|
|
929
|
-
const planName = { pro: "Pro", proplus: "Pro+", admin: "Admin", trial: "Trial" }[u.plan] || u.plan;
|
|
939
|
+
const planName = { pro: "Pro", proplus: "Pro+", ultra: "Ultra", admin: "Admin", trial: "Trial" }[u.plan] || u.plan;
|
|
930
940
|
const lines = [
|
|
931
941
|
chalk.bold(t.usageTitle),
|
|
932
942
|
` ${t.plan}: ${chalk.bold(planName)} ${t.status}: ${u.status === "active" ? c.ok(u.status) : c.err(u.status)}`,
|
package/src/sessions.js
CHANGED
|
@@ -63,9 +63,20 @@ export function load(id) {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
// Chuẩn hoá thư mục workspace để so khớp: resolve + lowercase trên Windows nên
|
|
67
|
+
// "D:\x", "D:\x\" và "d:\x" coi là một.
|
|
68
|
+
const normDir = (p) => {
|
|
69
|
+
const r = path.resolve(p || "");
|
|
70
|
+
return process.platform === "win32" ? r.toLowerCase() : r;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Tóm tắt nhẹ (không tải toàn bộ history vào view), sắp xếp mới nhất trước.
|
|
75
|
+
* cwd != null → chỉ trả phiên thuộc đúng thư mục workspace đó (resume theo dự án).
|
|
76
|
+
*/
|
|
77
|
+
export function list(limit = 30, cwd = null) {
|
|
68
78
|
ensure();
|
|
79
|
+
const want = cwd != null ? normDir(cwd) : null;
|
|
69
80
|
let files;
|
|
70
81
|
try {
|
|
71
82
|
files = fs.readdirSync(DIR).filter((f) => f.endsWith(".json"));
|
|
@@ -76,6 +87,7 @@ export function list(limit = 30) {
|
|
|
76
87
|
for (const f of files) {
|
|
77
88
|
try {
|
|
78
89
|
const s = JSON.parse(fs.readFileSync(path.join(DIR, f), "utf8"));
|
|
90
|
+
if (want != null && normDir(s.cwd) !== want) continue; // khác workspace → bỏ
|
|
79
91
|
out.push({
|
|
80
92
|
id: s.id,
|
|
81
93
|
updatedAt: s.updatedAt || s.createdAt || 0,
|
|
@@ -92,8 +104,8 @@ export function list(limit = 30) {
|
|
|
92
104
|
return out.slice(0, limit);
|
|
93
105
|
}
|
|
94
106
|
|
|
95
|
-
export function latest() {
|
|
96
|
-
const l = list(1);
|
|
107
|
+
export function latest(cwd = null) {
|
|
108
|
+
const l = list(1, cwd);
|
|
97
109
|
return l.length ? load(l[0].id) : null;
|
|
98
110
|
}
|
|
99
111
|
|