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.
Files changed (2) hide show
  1. package/blun-cli.js +83 -28
  2. 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
- console.log(C.green + C.bold + " ❯ " + C.brightWhite + "1. Yes, trust this folder" + C.reset);
2612
- console.log(" " + C.gray + "2. Always trust this folder" + C.reset);
2613
- console.log(" " + C.gray + "3. Choose another folder" + C.reset);
2614
- console.log("");
2615
- var trustChoice = await new Promise(function(resolve) {
2616
- var rlTrust = readline.createInterface({ input: process.stdin, output: process.stdout });
2617
- rlTrust.question(C.brightBlue + " Choice (1/2/3): " + C.reset, function(answer) {
2618
- rlTrust.close();
2619
- var n = answer.trim();
2620
- if (n === "2") resolve("always");
2621
- else if (n === "3") resolve("choose");
2622
- else resolve("trust");
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 rlKey = readline.createInterface({ input: process.stdin, output: process.stdout });
2673
- rlKey.question(C.brightBlue + " API Key: " + C.reset, function(answer) {
2674
- rlKey.close();
2675
- resolve(answer.trim());
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
- console.log(C.green + C.bold + " ❯ " + C.brightWhite + "1. Chat — talk back and forth" + C.reset);
2711
- console.log(" " + C.gray + "2. Agent give a goal, I do the rest autonomously" + C.reset);
2712
- console.log("");
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
- var rlMode = readline.createInterface({ input: process.stdin, output: process.stdout });
2715
- rlMode.question(C.brightBlue + " Choice (1/2): " + C.reset, function(answer) {
2716
- rlMode.close();
2717
- resolve(answer.trim() === "2" ? "agent" : "chat");
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)"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "5.1.3",
3
+ "version": "5.1.5",
4
4
  "description": "BLUN King CLI — Your local AI assistant powered by Gemma4",
5
5
  "type": "commonjs",
6
6
  "bin": {