blun-king-cli 7.2.12 → 7.3.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/lib/chat.js +216 -46
  2. package/package.json +1 -1
package/lib/chat.js CHANGED
@@ -276,61 +276,25 @@ function startChat() {
276
276
  printToScrollArea(chalk.yellow(" [SYS] Model: " + parts[1]));
277
277
  drawInputPanel();
278
278
  } else {
279
- // Open inquirer menu
280
- enterMenuMode(function (done) {
281
- var inquirer = require("inquirer");
282
- inquirer.prompt([{
283
- type: "list",
284
- name: "model",
285
- message: chalk.cyan("Select Model"),
286
- choices: [
287
- { name: "Auto (recommended)", value: "auto" },
288
- { name: "Gemma 4", value: "gemma4" },
289
- { name: "Claude", value: "claude" },
290
- { name: "Llama", value: "llama" },
291
- ],
292
- }]).then(function (ans) {
293
- if (ans.model) {
294
- model = ans.model;
295
- settings.model = ans.model;
296
- auth.saveSettings(settings);
297
- printToScrollArea(chalk.yellow(" [SYS] Model: " + ans.model));
298
- }
299
- done();
300
- });
301
- });
279
+ // Cycle model
280
+ var models = ["auto", "gemma4", "claude", "llama"];
281
+ var midx = models.indexOf(settings.model || "auto");
282
+ settings.model = models[(midx + 1) % models.length];
283
+ model = settings.model;
284
+ auth.saveSettings(settings);
285
+ printToScrollArea(chalk.yellow(" [SYS] Model: " + settings.model));
286
+ drawInputPanel();
302
287
  }
303
288
  return;
304
289
  }
305
290
 
306
291
  if (input === "/settings") {
307
- enterMenuMode(function (done) {
308
- openSettingsPanel(done);
309
- });
292
+ openRawSettings();
310
293
  return;
311
294
  }
312
295
 
313
296
  if (input === "/") {
314
- enterMenuMode(function (done) {
315
- var inquirer = require("inquirer");
316
- inquirer.prompt([{
317
- type: "list",
318
- name: "cmd",
319
- message: chalk.cyan("Select command"),
320
- choices: SLASH_COMMANDS.map(function (c) {
321
- return { name: chalk.green(c[0]) + chalk.gray(" " + c[1]), value: c[0] };
322
- }).concat([
323
- new inquirer.Separator(),
324
- { name: chalk.dim("Cancel"), value: "" },
325
- ]),
326
- pageSize: 12,
327
- }]).then(function (ans) {
328
- done();
329
- if (ans.cmd) {
330
- processCommand(ans.cmd);
331
- }
332
- });
333
- });
297
+ openRawCommandPicker();
334
298
  return;
335
299
  }
336
300
 
@@ -413,6 +377,212 @@ function startChat() {
413
377
  });
414
378
  }
415
379
 
380
+ // ── Raw-Mode Settings Panel (no inquirer needed) ──────
381
+ function openRawSettings() {
382
+ var settingsActive = true;
383
+ var selectedField = 0;
384
+ var fields = ui.SETTINGS_FIELDS;
385
+
386
+ function drawSettings() {
387
+ var rows = getRows();
388
+ var cols = getCols();
389
+ var t = ui.getTheme();
390
+ var panelTop = rows - INPUT_PANEL_HEIGHT + 1;
391
+
392
+ // Draw settings over the input panel area
393
+ process.stdout.write(saveCursor());
394
+
395
+ // Clear panel area
396
+ for (var r = panelTop; r <= panelTop + 4; r++) {
397
+ process.stdout.write(cursorTo(r, 1) + clearLine());
398
+ }
399
+
400
+ // Also use scroll area bottom for more space
401
+ var settingsTop = panelTop - fields.length - 3;
402
+ if (settingsTop < 2) settingsTop = 2;
403
+
404
+ // Header
405
+ process.stdout.write(cursorTo(settingsTop, 1) + clearLine());
406
+ process.stdout.write(t.frame(" ╭─ Settings ") + t.frame("─".repeat(Math.max(1, cols - 16))) + t.frame("╮"));
407
+
408
+ // Fields
409
+ for (var i = 0; i < fields.length; i++) {
410
+ var row = settingsTop + 1 + i;
411
+ process.stdout.write(cursorTo(row, 1) + clearLine());
412
+ var marker = i === selectedField ? chalk.cyan(" ▸ ") : " ";
413
+ var label = fields[i].label;
414
+ var value = ui.formatSettingValue(fields[i], settings[fields[i].key]);
415
+ var help = i === selectedField ? chalk.dim(" ← → change") : "";
416
+ process.stdout.write(t.frame(" │") + marker + chalk.white(label) + " ".repeat(Math.max(1, 16 - label.length)) + value + help);
417
+ process.stdout.write(cursorTo(row, cols) + t.frame("│"));
418
+ }
419
+
420
+ // Footer
421
+ var footerRow = settingsTop + 1 + fields.length;
422
+ process.stdout.write(cursorTo(footerRow, 1) + clearLine());
423
+ process.stdout.write(t.frame(" │") + chalk.dim(" ↑↓ select ← → change Enter/Esc close"));
424
+ process.stdout.write(cursorTo(footerRow, cols) + t.frame("│"));
425
+
426
+ process.stdout.write(cursorTo(footerRow + 1, 1) + clearLine());
427
+ process.stdout.write(t.frame(" ╰") + t.frame("─".repeat(Math.max(1, cols - 4))) + t.frame("╯"));
428
+
429
+ process.stdout.write(restoreCursor());
430
+ }
431
+
432
+ // Replace data listener temporarily
433
+ process.stdin.removeAllListeners("data");
434
+
435
+ function onSettingsKey(key) {
436
+ if (!settingsActive) return;
437
+
438
+ // Escape or Enter — close settings
439
+ if (key === "\u001b" && key.length === 1 || key === "\r" || key === "\n") {
440
+ settingsActive = false;
441
+ process.stdin.removeAllListeners("data");
442
+ // Redraw normal UI
443
+ var rows = getRows();
444
+ var settingsTop = rows - INPUT_PANEL_HEIGHT + 1 - fields.length - 3;
445
+ if (settingsTop < 2) settingsTop = 2;
446
+ for (var r = settingsTop; r <= rows; r++) {
447
+ process.stdout.write(cursorTo(r, 1) + clearLine());
448
+ }
449
+ drawInputPanel();
450
+ startRawInput();
451
+ return;
452
+ }
453
+
454
+ // Up arrow
455
+ if (key === "\u001b[A") {
456
+ selectedField = (selectedField - 1 + fields.length) % fields.length;
457
+ drawSettings();
458
+ return;
459
+ }
460
+
461
+ // Down arrow
462
+ if (key === "\u001b[B") {
463
+ selectedField = (selectedField + 1) % fields.length;
464
+ drawSettings();
465
+ return;
466
+ }
467
+
468
+ // Left/Right arrow — cycle value
469
+ if (key === "\u001b[D" || key === "\u001b[C") {
470
+ var field = fields[selectedField];
471
+ var values = field.values;
472
+ var curIdx = values.indexOf(settings[field.key]);
473
+ if (curIdx < 0) curIdx = 0;
474
+ var dir = key === "\u001b[C" ? 1 : -1;
475
+ var newIdx = (curIdx + dir + values.length) % values.length;
476
+ settings[field.key] = values[newIdx];
477
+ if (field.key === "theme") ui.setTheme(settings.theme);
478
+ auth.saveSettings(settings);
479
+ drawSettings();
480
+ return;
481
+ }
482
+
483
+ // Ctrl+C
484
+ if (key === "\u0003") {
485
+ settingsActive = false;
486
+ process.stdin.removeAllListeners("data");
487
+ drawInputPanel();
488
+ startRawInput();
489
+ return;
490
+ }
491
+ }
492
+
493
+ process.stdin.on("data", onSettingsKey);
494
+ drawSettings();
495
+ }
496
+
497
+ // ── Raw Command Picker ─────────────────────────────────
498
+ function openRawCommandPicker() {
499
+ var pickerActive = true;
500
+ var selectedCmd = 0;
501
+
502
+ function drawPicker() {
503
+ var rows = getRows();
504
+ var cols = getCols();
505
+ var t = ui.getTheme();
506
+ var panelTop = rows - INPUT_PANEL_HEIGHT + 1;
507
+ var pickerTop = panelTop - SLASH_COMMANDS.length - 3;
508
+ if (pickerTop < 2) pickerTop = 2;
509
+
510
+ process.stdout.write(saveCursor());
511
+
512
+ // Header
513
+ process.stdout.write(cursorTo(pickerTop, 1) + clearLine());
514
+ process.stdout.write(t.frame(" ╭─ Commands ") + t.frame("─".repeat(Math.max(1, cols - 16))) + t.frame("╮"));
515
+
516
+ for (var i = 0; i < SLASH_COMMANDS.length; i++) {
517
+ var row = pickerTop + 1 + i;
518
+ process.stdout.write(cursorTo(row, 1) + clearLine());
519
+ var marker = i === selectedCmd ? chalk.cyan(" ▸ ") : " ";
520
+ process.stdout.write(t.frame(" │") + marker + chalk.green(SLASH_COMMANDS[i][0]) + " ".repeat(Math.max(1, 14 - SLASH_COMMANDS[i][0].length)) + chalk.gray(SLASH_COMMANDS[i][1]));
521
+ process.stdout.write(cursorTo(row, cols) + t.frame("│"));
522
+ }
523
+
524
+ var footerRow = pickerTop + 1 + SLASH_COMMANDS.length;
525
+ process.stdout.write(cursorTo(footerRow, 1) + clearLine());
526
+ process.stdout.write(t.frame(" │") + chalk.dim(" ↑↓ select Enter run Esc close"));
527
+ process.stdout.write(cursorTo(footerRow, cols) + t.frame("│"));
528
+ process.stdout.write(cursorTo(footerRow + 1, 1) + clearLine());
529
+ process.stdout.write(t.frame(" ╰") + t.frame("─".repeat(Math.max(1, cols - 4))) + t.frame("╯"));
530
+
531
+ process.stdout.write(restoreCursor());
532
+ }
533
+
534
+ process.stdin.removeAllListeners("data");
535
+
536
+ function onPickerKey(key) {
537
+ if (!pickerActive) return;
538
+
539
+ if (key === "\u001b" && key.length === 1 || key === "\u0003") {
540
+ pickerActive = false;
541
+ process.stdin.removeAllListeners("data");
542
+ var rows = getRows();
543
+ var pickerTop = rows - INPUT_PANEL_HEIGHT + 1 - SLASH_COMMANDS.length - 3;
544
+ if (pickerTop < 2) pickerTop = 2;
545
+ for (var r = pickerTop; r <= rows; r++) {
546
+ process.stdout.write(cursorTo(r, 1) + clearLine());
547
+ }
548
+ drawInputPanel();
549
+ startRawInput();
550
+ return;
551
+ }
552
+
553
+ if (key === "\u001b[A") {
554
+ selectedCmd = (selectedCmd - 1 + SLASH_COMMANDS.length) % SLASH_COMMANDS.length;
555
+ drawPicker();
556
+ return;
557
+ }
558
+
559
+ if (key === "\u001b[B") {
560
+ selectedCmd = (selectedCmd + 1) % SLASH_COMMANDS.length;
561
+ drawPicker();
562
+ return;
563
+ }
564
+
565
+ if (key === "\r" || key === "\n") {
566
+ pickerActive = false;
567
+ process.stdin.removeAllListeners("data");
568
+ var cmd = SLASH_COMMANDS[selectedCmd][0];
569
+ var rows = getRows();
570
+ var pickerTop = rows - INPUT_PANEL_HEIGHT + 1 - SLASH_COMMANDS.length - 3;
571
+ if (pickerTop < 2) pickerTop = 2;
572
+ for (var r = pickerTop; r <= rows; r++) {
573
+ process.stdout.write(cursorTo(r, 1) + clearLine());
574
+ }
575
+ drawInputPanel();
576
+ startRawInput();
577
+ processCommand(cmd);
578
+ return;
579
+ }
580
+ }
581
+
582
+ process.stdin.on("data", onPickerKey);
583
+ drawPicker();
584
+ }
585
+
416
586
  // ── Settings Panel (inquirer) ─────────────────────────
417
587
  function openSettingsPanel(done) {
418
588
  var inquirer = require("inquirer");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "7.2.12",
3
+ "version": "7.3.0",
4
4
  "description": "BLUN AI Assistant - Command Line Interface",
5
5
  "bin": {
6
6
  "blun": "./bin/blun.js"