@noobdemon/noob-cli 1.5.0 → 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/agent.js +2 -0
- package/src/repl.js +25 -15
- package/src/sessions.js +16 -4
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -29,6 +29,8 @@ Available tools:
|
|
|
29
29
|
|
|
30
30
|
# Rules
|
|
31
31
|
- GROUND TRUTH = the filesystem, NOT your memory of this chat. A file was created/changed ONLY if a write_file/edit_file TOOL RESULT confirms it (see the FILES CHANGED list). Saying "I created/updated X" in prose does NOT change any file — you must emit the tool call. If the user says a file is missing or asks its state, read_file/list_dir to check reality first; never claim a file "was reverted" or "should be there" from memory.
|
|
32
|
+
- NO FABRICATED VERIFICATION. Never claim a result you did not actually get from a real TOOL RESULT in THIS conversation. Do NOT say "tests pass" / "300/300" / "verified" / "done" / "100%" / "it works" unless a run_command TOOL RESULT above truly shows it. Do NOT reference or quote output that does not appear above — if you have not run the check, say so and RUN it; never narrate a result you only imagine.
|
|
33
|
+
- BEFORE any "finished/summary" message, RE-CHECK reality against the FILES CHANGED list: every file you are about to say you created/edited MUST appear there. If it is not there, you did NOT write it — emit the write_file/edit_file (or list_dir/read_file to confirm) NOW instead of claiming completion. When in doubt, list_dir/read_file the workspace and verify before asserting — do not assert from memory.
|
|
32
34
|
- Investigate before editing: read the relevant files first; never invent file contents.
|
|
33
35
|
- Make the smallest change that fully solves the task. Match the surrounding code style.
|
|
34
36
|
- Prefer edit_file over write_file for existing files.
|
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
|
|