blun-king-cli 5.0.1 → 5.0.3
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/blun-cli.js +61 -36
- package/package.json +1 -1
package/blun-cli.js
CHANGED
|
@@ -506,58 +506,83 @@ async function main() {
|
|
|
506
506
|
renderPrompt();
|
|
507
507
|
}
|
|
508
508
|
|
|
509
|
+
// ── Arrow-key menu helper ──
|
|
510
|
+
function arrowMenu(options, count) {
|
|
511
|
+
let sel = 0;
|
|
512
|
+
return new Promise((resolve) => {
|
|
513
|
+
function render() {
|
|
514
|
+
process.stdout.write(`\x1b[${count}A\r`);
|
|
515
|
+
options.forEach((opt, i) => {
|
|
516
|
+
const prefix = i === sel ? "\x1b[32m\x1b[1m \u276F " : " ";
|
|
517
|
+
const color = i === sel ? "\x1b[97m\x1b[1m" : "\x1b[90m";
|
|
518
|
+
process.stdout.write(`\x1b[2K${prefix}${color}${i + 1}. ${opt.label}\x1b[0m\n`);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
for (let i = 0; i < count; i++) console.log("");
|
|
522
|
+
render();
|
|
523
|
+
process.stdin.setRawMode(true);
|
|
524
|
+
process.stdin.resume();
|
|
525
|
+
process.stdin.setEncoding("utf8");
|
|
526
|
+
function onKey(key) {
|
|
527
|
+
if (key === "\x1b[A") { sel = Math.max(0, sel - 1); render(); return; }
|
|
528
|
+
if (key === "\x1b[B") { sel = Math.min(options.length - 1, sel + 1); render(); return; }
|
|
529
|
+
for (let i = 0; i < options.length; i++) {
|
|
530
|
+
if (key === String(i + 1)) { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(options[i]); return; }
|
|
531
|
+
}
|
|
532
|
+
if (key === "\r" || key === "\n") { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(options[sel]); return; }
|
|
533
|
+
if (key === "\x03") { process.exit(0); }
|
|
534
|
+
}
|
|
535
|
+
process.stdin.on("data", onKey);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
|
|
509
539
|
// ── Trust Prompt ──
|
|
510
540
|
const TRUST_FILE = path.join(HOME, "trusted.json");
|
|
511
541
|
let trustedDirs = [];
|
|
512
542
|
try { if (fs.existsSync(TRUST_FILE)) trustedDirs = JSON.parse(fs.readFileSync(TRUST_FILE, "utf8")); } catch {}
|
|
513
543
|
const isTrusted = trustedDirs.includes(workdir) || process.argv.includes("--trust");
|
|
514
544
|
|
|
515
|
-
|
|
545
|
+
const isTTY = process.stdin.isTTY || process.stdout.isTTY || process.platform === "win32";
|
|
546
|
+
if (!isTrusted && isTTY) {
|
|
516
547
|
console.log("");
|
|
517
|
-
console.log(` \u{1F4C1} Working in: ${workdir}`);
|
|
518
|
-
console.log("
|
|
548
|
+
console.log(` \x1b[33m\u{1F4C1} Working in: \x1b[97m${workdir}\x1b[0m`);
|
|
549
|
+
console.log(" \x1b[90mDo you trust this folder? BLUN King will read/write files here.\x1b[0m");
|
|
519
550
|
console.log("");
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if (
|
|
551
|
+
const trustChoice = await arrowMenu([
|
|
552
|
+
{ label: "Yes, trust this folder", action: "trust" },
|
|
553
|
+
{ label: "Always trust this folder", action: "always" },
|
|
554
|
+
{ label: "Choose another folder", action: "choose" }
|
|
555
|
+
], 3);
|
|
556
|
+
|
|
557
|
+
if (trustChoice.action === "always") {
|
|
527
558
|
trustedDirs.push(workdir);
|
|
528
559
|
fs.writeFileSync(TRUST_FILE, JSON.stringify(trustedDirs, null, 2));
|
|
529
|
-
console.log(" Folder trusted permanently
|
|
530
|
-
} else if (
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
560
|
+
console.log(" \x1b[32m\u2713 Folder trusted permanently.\x1b[0m");
|
|
561
|
+
} else if (trustChoice.action === "choose") {
|
|
562
|
+
if (process.platform === "win32") {
|
|
563
|
+
try {
|
|
564
|
+
const 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\' }"';
|
|
565
|
+
const newDir = require("child_process").execSync(psCmd, { encoding: "utf8", timeout: 60000 }).trim();
|
|
566
|
+
if (newDir && newDir !== "CANCELLED" && fs.existsSync(newDir)) {
|
|
567
|
+
process.chdir(newDir);
|
|
568
|
+
console.log(` \x1b[32m\u2713 Workspace: ${newDir}\x1b[0m`);
|
|
569
|
+
}
|
|
570
|
+
} catch {}
|
|
539
571
|
}
|
|
540
572
|
}
|
|
541
573
|
console.log("");
|
|
542
574
|
}
|
|
543
575
|
|
|
544
576
|
// ── Mode Selection ──
|
|
545
|
-
if (!process.argv.includes("--agent") && !process.argv.includes("--chat") &&
|
|
546
|
-
console.log("
|
|
547
|
-
console.log(" [1] Chat — talk back and forth");
|
|
548
|
-
console.log(" [2] Agent — give a goal, I do the rest autonomously");
|
|
577
|
+
if (!process.argv.includes("--agent") && !process.argv.includes("--chat") && isTTY) {
|
|
578
|
+
console.log(" \x1b[97m\x1b[1mHow do you want to work?\x1b[0m");
|
|
549
579
|
console.log("");
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
mode = "chat";
|
|
557
|
-
} else {
|
|
558
|
-
mode = "agent";
|
|
559
|
-
}
|
|
560
|
-
console.log(` Mode: ${mode}`);
|
|
580
|
+
const modeChoice = await arrowMenu([
|
|
581
|
+
{ label: "Chat \u2014 talk back and forth", mode: "chat" },
|
|
582
|
+
{ label: "Agent \u2014 give a goal, I do the rest autonomously", mode: "agent" }
|
|
583
|
+
], 2);
|
|
584
|
+
mode = modeChoice.mode;
|
|
585
|
+
console.log(` \x1b[32m\u2713 Mode: ${mode === "agent" ? "Agent (autonomous)" : "Chat (interactive)"}\x1b[0m`);
|
|
561
586
|
console.log("");
|
|
562
587
|
}
|
|
563
588
|
if (process.argv.includes("--chat")) mode = "chat";
|
|
@@ -571,7 +596,7 @@ async function main() {
|
|
|
571
596
|
}
|
|
572
597
|
|
|
573
598
|
console.log("");
|
|
574
|
-
console.log(" BLUN KING CLI v5.0.
|
|
599
|
+
console.log(" BLUN KING CLI v5.0.3");
|
|
575
600
|
console.log(` API: ${cfg.apiUrl}`);
|
|
576
601
|
console.log(` Dir: ${workdir}`);
|
|
577
602
|
console.log(" Chat input stays available while jobs run.");
|