blun-king-cli 2.5.1 → 2.6.0

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.
Files changed (2) hide show
  1. package/bin/blun.js +84 -17
  2. package/package.json +1 -1
package/bin/blun.js CHANGED
@@ -2228,6 +2228,24 @@ async function main() {
2228
2228
  }
2229
2229
  }
2230
2230
 
2231
+ // Restore last workdir if still in home/default dir
2232
+ var lastWdFile = path.join(CONFIG_DIR, "last-workdir.json");
2233
+ if (!dirIdx || dirIdx === -1) {
2234
+ try {
2235
+ if (fs.existsSync(lastWdFile)) {
2236
+ var lastWd = JSON.parse(fs.readFileSync(lastWdFile, "utf8"));
2237
+ if (lastWd.dir && fs.existsSync(lastWd.dir) && config.workdir === process.cwd()) {
2238
+ // Only auto-restore if user didn't explicitly cd somewhere
2239
+ var homeDir = require("os").homedir();
2240
+ if (config.workdir === homeDir || config.workdir === homeDir.replace(/\\/g, "/")) {
2241
+ config.workdir = lastWd.dir;
2242
+ process.chdir(config.workdir);
2243
+ }
2244
+ }
2245
+ }
2246
+ } catch(e) {}
2247
+ }
2248
+
2231
2249
  if (!process.argv.includes("--no-workdir-prompt") && !process.argv.includes("--trust")) {
2232
2250
  var trustedDirs = [];
2233
2251
  var trustFile = path.join(CONFIG_DIR, "trusted.json");
@@ -2240,35 +2258,82 @@ async function main() {
2240
2258
  console.log("");
2241
2259
  console.log(C.yellow + " " + BOX.bot + " Working in: " + C.brightWhite + process.cwd() + C.reset);
2242
2260
  console.log(C.gray + " Do you trust this folder? BLUN King will read/write files here." + C.reset);
2243
- console.log(C.gray + " [y] Yes, trust [n] Choose another folder [a] Always trust" + C.reset);
2261
+ console.log("");
2262
+
2263
+ var trustOptions = [
2264
+ { label: "Yes, trust this folder", action: "trust" },
2265
+ { label: "Always trust this folder", action: "always" },
2266
+ { label: "Choose another folder", action: "choose" }
2267
+ ];
2268
+ var trustSel = 0;
2269
+
2270
+ // Arrow key menu for trust selection
2271
+ var trustChoice = await new Promise(function(resolve) {
2272
+ function renderTrustMenu() {
2273
+ // Move up and clear previous menu
2274
+ if (trustSel >= 0) process.stdout.write("\x1b[3A\r");
2275
+ trustOptions.forEach(function(opt, i) {
2276
+ var prefix = i === trustSel ? C.green + C.bold + " \u276F " : " ";
2277
+ var color = i === trustSel ? C.brightWhite + C.bold : C.gray;
2278
+ process.stdout.write("\x1b[2K" + prefix + color + (i + 1) + ". " + opt.label + C.reset + "\n");
2279
+ });
2280
+ }
2281
+ // Initial render
2282
+ console.log(""); console.log(""); console.log("");
2283
+ renderTrustMenu();
2244
2284
 
2245
- var trustAnswer = await new Promise(function(resolve) {
2246
2285
  process.stdin.setRawMode(true);
2247
2286
  process.stdin.resume();
2248
2287
  process.stdin.setEncoding("utf8");
2249
- process.stdin.once("data", function(key) {
2250
- process.stdin.setRawMode(false);
2251
- resolve(key.toLowerCase());
2252
- });
2288
+ function onKey(key) {
2289
+ if (key === "\x1b[A") { trustSel = Math.max(0, trustSel - 1); renderTrustMenu(); return; }
2290
+ if (key === "\x1b[B") { trustSel = Math.min(2, trustSel + 1); renderTrustMenu(); return; }
2291
+ if (key === "1") { trustSel = 0; process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(trustOptions[0].action); return; }
2292
+ if (key === "2") { trustSel = 1; process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(trustOptions[1].action); return; }
2293
+ if (key === "3") { trustSel = 2; process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(trustOptions[2].action); return; }
2294
+ if (key === "\r" || key === "\n") {
2295
+ process.stdin.removeListener("data", onKey);
2296
+ process.stdin.setRawMode(false);
2297
+ resolve(trustOptions[trustSel].action);
2298
+ return;
2299
+ }
2300
+ }
2301
+ process.stdin.on("data", onKey);
2253
2302
  });
2254
2303
 
2255
- if (trustAnswer === "a") {
2304
+ if (trustChoice === "always") {
2256
2305
  trustedDirs.push(process.cwd());
2257
2306
  fs.writeFileSync(trustFile, JSON.stringify(trustedDirs, null, 2));
2258
2307
  printSuccess("Folder trusted permanently.");
2259
- } else if (trustAnswer === "n") {
2260
- var rlDir = readline.createInterface({ input: process.stdin, output: process.stdout });
2261
- var newDir = await new Promise(function(resolve) {
2262
- rlDir.question(C.brightBlue + " Enter path: " + C.reset, resolve);
2263
- });
2264
- rlDir.close();
2265
- if (newDir.trim() && fs.existsSync(newDir.trim())) {
2266
- config.workdir = newDir.trim();
2267
- } else {
2308
+ } else if (trustChoice === "choose") {
2309
+ // Open Windows folder picker if available
2310
+ var newDir = null;
2311
+ if (process.platform === "win32") {
2312
+ try {
2313
+ printInfo("Opening folder picker...");
2314
+ var psCmd = 'powershell -NoProfile -Command "Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.FolderBrowserDialog; $f.Description = \'Choose BLUN King workspace\'; $f.ShowNewFolderButton = $true; if($f.ShowDialog() -eq \'OK\'){ Write-Output $f.SelectedPath } else { Write-Output \'CANCELLED\' }"';
2315
+ newDir = require("child_process").execSync(psCmd, { encoding: "utf8", timeout: 60000 }).trim();
2316
+ if (newDir === "CANCELLED") newDir = null;
2317
+ } catch(e) { newDir = null; }
2318
+ }
2319
+ // Fallback to text input
2320
+ if (!newDir) {
2321
+ var rlDir = readline.createInterface({ input: process.stdin, output: process.stdout });
2322
+ newDir = await new Promise(function(resolve) {
2323
+ rlDir.question(C.brightBlue + " Enter path: " + C.reset, resolve);
2324
+ });
2325
+ rlDir.close();
2326
+ newDir = newDir ? newDir.trim() : null;
2327
+ }
2328
+ if (newDir && fs.existsSync(newDir)) {
2329
+ config.workdir = newDir;
2330
+ try { fs.writeFileSync(path.join(CONFIG_DIR, "last-workdir.json"), JSON.stringify({ dir: config.workdir, ts: new Date().toISOString() })); } catch(e) {}
2331
+ printSuccess("Workspace: " + config.workdir);
2332
+ } else if (newDir) {
2268
2333
  printError("Invalid path, using current directory.");
2269
2334
  }
2270
2335
  }
2271
- // y or anything else = trust for this session
2336
+ // trust = trust for this session only
2272
2337
  console.log("");
2273
2338
  }
2274
2339
  }
@@ -2568,6 +2633,8 @@ async function main() {
2568
2633
  if (key === "\x03" || key === "\x04") {
2569
2634
  session.history = chatHistory.slice(-50);
2570
2635
  saveSessionHistory(session);
2636
+ // Save last workdir for next session
2637
+ try { fs.writeFileSync(path.join(CONFIG_DIR, "last-workdir.json"), JSON.stringify({ dir: config.workdir, ts: new Date().toISOString() })); } catch(e) {}
2571
2638
  eraseUI();
2572
2639
  console.log(C.dim + "\nBye." + C.reset);
2573
2640
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "2.5.1",
3
+ "version": "2.6.0",
4
4
  "description": "BLUN King CLI — Premium KI Console",
5
5
  "bin": {
6
6
  "blun": "./bin/blun.js"