blun-king-cli 5.1.3 → 5.1.5
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 +83 -28
- package/package.json +1 -1
package/blun-cli.js
CHANGED
|
@@ -2608,20 +2608,36 @@ async function main() {
|
|
|
2608
2608
|
console.log(C.gray + " Do you trust this folder? BLUN King will read/write files here." + C.reset);
|
|
2609
2609
|
console.log("");
|
|
2610
2610
|
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2611
|
+
var trustOptions = [
|
|
2612
|
+
{ label: "Yes, trust this folder", action: "trust" },
|
|
2613
|
+
{ label: "Always trust this folder", action: "always" },
|
|
2614
|
+
{ label: "Choose another folder", action: "choose" }
|
|
2615
|
+
];
|
|
2616
|
+
var trustSel = 0;
|
|
2617
|
+
var trustResult = await new Promise(function(resolve) {
|
|
2618
|
+
function render() {
|
|
2619
|
+
process.stdout.write("\x1b[3A\r");
|
|
2620
|
+
trustOptions.forEach(function(opt, i) {
|
|
2621
|
+
var prefix = i === trustSel ? "\x1b[32m\x1b[1m \u276F " : " ";
|
|
2622
|
+
var color = i === trustSel ? "\x1b[97m\x1b[1m" : "\x1b[90m";
|
|
2623
|
+
process.stdout.write("\x1b[2K" + prefix + color + (i + 1) + ". " + opt.label + "\x1b[0m\n");
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
console.log(""); console.log(""); console.log("");
|
|
2627
|
+
render();
|
|
2628
|
+
process.stdin.setRawMode(true);
|
|
2629
|
+
process.stdin.resume();
|
|
2630
|
+
process.stdin.setEncoding("utf8");
|
|
2631
|
+
function onKey(key) {
|
|
2632
|
+
if (key === "\x1b[A") { trustSel = Math.max(0, trustSel - 1); render(); return; }
|
|
2633
|
+
if (key === "\x1b[B") { trustSel = Math.min(2, trustSel + 1); render(); return; }
|
|
2634
|
+
if (key === "1" || key === "2" || key === "3") { trustSel = parseInt(key) - 1; process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(trustOptions[trustSel]); return; }
|
|
2635
|
+
if (key === "\r" || key === "\n") { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(trustOptions[trustSel]); return; }
|
|
2636
|
+
if (key === "\x03") { process.exit(0); }
|
|
2637
|
+
}
|
|
2638
|
+
process.stdin.on("data", onKey);
|
|
2624
2639
|
});
|
|
2640
|
+
var trustChoice = trustResult.action;
|
|
2625
2641
|
|
|
2626
2642
|
if (trustChoice === "always") {
|
|
2627
2643
|
trustedDirs.push(process.cwd());
|
|
@@ -2663,25 +2679,45 @@ async function main() {
|
|
|
2663
2679
|
printHeader();
|
|
2664
2680
|
checkForUpdates();
|
|
2665
2681
|
|
|
2666
|
-
// API Key check — prompt if missing
|
|
2667
|
-
if (!config.api.key && !process.argv.includes("--api-key")) {
|
|
2682
|
+
// API Key check — prompt if missing (uses raw stdin since readline may not work after setRawMode)
|
|
2683
|
+
if (!config.api.key && !config.auth.api_key && !process.argv.includes("--api-key")) {
|
|
2668
2684
|
console.log("");
|
|
2669
2685
|
console.log(C.yellow + " " + BOX.bot + " No API key configured." + C.reset);
|
|
2670
2686
|
console.log(C.gray + " Enter your BLUN King API key (or press Enter to skip):" + C.reset);
|
|
2687
|
+
process.stdout.write(C.brightBlue + " API Key: " + C.reset);
|
|
2671
2688
|
var apiKeyAnswer = await new Promise(function(resolve) {
|
|
2672
|
-
var
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2689
|
+
var buf = "";
|
|
2690
|
+
process.stdin.setRawMode(true);
|
|
2691
|
+
process.stdin.resume();
|
|
2692
|
+
process.stdin.setEncoding("utf8");
|
|
2693
|
+
function onKeyApi(key) {
|
|
2694
|
+
if (key === "\x03") { process.exit(0); }
|
|
2695
|
+
if (key === "\r" || key === "\n") {
|
|
2696
|
+
process.stdin.removeListener("data", onKeyApi);
|
|
2697
|
+
process.stdin.setRawMode(false);
|
|
2698
|
+
process.stdout.write("\n");
|
|
2699
|
+
resolve(buf.trim());
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
if (key === "\x7f" || key === "\b") {
|
|
2703
|
+
if (buf.length > 0) { buf = buf.slice(0, -1); process.stdout.write("\b \b"); }
|
|
2704
|
+
return;
|
|
2705
|
+
}
|
|
2706
|
+
buf += key;
|
|
2707
|
+
process.stdout.write("*");
|
|
2708
|
+
}
|
|
2709
|
+
process.stdin.on("data", onKeyApi);
|
|
2677
2710
|
});
|
|
2678
2711
|
if (apiKeyAnswer) {
|
|
2679
2712
|
config.api.key = apiKeyAnswer;
|
|
2713
|
+
config.auth.api_key = apiKeyAnswer;
|
|
2680
2714
|
var cfgFile = path.join(CONFIG_DIR, "config.json");
|
|
2681
2715
|
var cfgData = {};
|
|
2682
2716
|
if (fs.existsSync(cfgFile)) { try { cfgData = JSON.parse(fs.readFileSync(cfgFile, "utf8")); } catch(e) {} }
|
|
2683
2717
|
if (!cfgData.api) cfgData.api = {};
|
|
2718
|
+
if (!cfgData.auth) cfgData.auth = {};
|
|
2684
2719
|
cfgData.api.key = apiKeyAnswer;
|
|
2720
|
+
cfgData.auth.api_key = apiKeyAnswer;
|
|
2685
2721
|
fs.writeFileSync(cfgFile, JSON.stringify(cfgData, null, 2));
|
|
2686
2722
|
printSuccess("API key saved.");
|
|
2687
2723
|
}
|
|
@@ -2707,15 +2743,34 @@ async function main() {
|
|
|
2707
2743
|
console.log("");
|
|
2708
2744
|
console.log(C.brightWhite + C.bold + " How do you want to work?" + C.reset);
|
|
2709
2745
|
console.log("");
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2746
|
+
var modeOptions = [
|
|
2747
|
+
{ label: "Chat \u2014 talk back and forth", mode: "chat" },
|
|
2748
|
+
{ label: "Agent \u2014 give a goal, I do the rest autonomously", mode: "agent" }
|
|
2749
|
+
];
|
|
2750
|
+
var modeSel = 0;
|
|
2713
2751
|
var modeChoice = await new Promise(function(resolve) {
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2752
|
+
function render() {
|
|
2753
|
+
process.stdout.write("\x1b[2A\r");
|
|
2754
|
+
modeOptions.forEach(function(opt, i) {
|
|
2755
|
+
var prefix = i === modeSel ? "\x1b[32m\x1b[1m \u276F " : " ";
|
|
2756
|
+
var color = i === modeSel ? "\x1b[97m\x1b[1m" : "\x1b[90m";
|
|
2757
|
+
process.stdout.write("\x1b[2K" + prefix + color + (i + 1) + ". " + opt.label + "\x1b[0m\n");
|
|
2758
|
+
});
|
|
2759
|
+
}
|
|
2760
|
+
console.log(""); console.log("");
|
|
2761
|
+
render();
|
|
2762
|
+
process.stdin.setRawMode(true);
|
|
2763
|
+
process.stdin.resume();
|
|
2764
|
+
process.stdin.setEncoding("utf8");
|
|
2765
|
+
function onKey(key) {
|
|
2766
|
+
if (key === "\x1b[A") { modeSel = 0; render(); return; }
|
|
2767
|
+
if (key === "\x1b[B") { modeSel = 1; render(); return; }
|
|
2768
|
+
if (key === "1") { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve("chat"); return; }
|
|
2769
|
+
if (key === "2") { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve("agent"); return; }
|
|
2770
|
+
if (key === "\r" || key === "\n") { process.stdin.removeListener("data", onKey); process.stdin.setRawMode(false); resolve(modeOptions[modeSel].mode); return; }
|
|
2771
|
+
if (key === "\x03") { process.exit(0); }
|
|
2772
|
+
}
|
|
2773
|
+
process.stdin.on("data", onKey);
|
|
2719
2774
|
});
|
|
2720
2775
|
sessionMode = modeChoice;
|
|
2721
2776
|
printSuccess("Mode: " + (sessionMode === "agent" ? "Agent (autonomous)" : "Chat (interactive)"));
|