@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noobdemon/noob-cli",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
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
- while (true) {
667
- const raw = await ask(c.tool(" cho phép? ") + c.dim("[y] / [n] không / [a] luôn " + name + " › "));
668
- if (raw == null) return "n"; // stdin đóng thật
669
- const a = raw.trim().toLowerCase();
670
- if (a === "" || a === "y" || a === "yes" || a === "có") return "y";
671
- if (a === "n" || a === "no" || a === "không") return "n";
672
- if (a === "a" || a === "always" || a === "luôn") return "a";
673
- if (raw.trim().length > 3) {
674
- pending.push(raw); // tin nhắn lạc xếp hàng, gửi sau khi xong lượt
675
- console.log(c.dim(" " + t.queued(pending.length, truncate(raw, 60))));
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
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(" 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] / [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
- console.log(c.dim(" " + t.permRetry));
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
- /** 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. */
67
- export function list(limit = 30) {
66
+ // Chuẩn hoá thư mục workspace để so khớp: resolve + lowercase trên Windows nên
67
+ // "D:\x", "D:\x\" "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