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.
- package/bin/blun.js +84 -17
- 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(
|
|
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
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
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 (
|
|
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 (
|
|
2260
|
-
|
|
2261
|
-
var newDir =
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
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
|
-
//
|
|
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);
|