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.
- package/lib/chat.js +216 -46
- 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
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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
|
-
|
|
308
|
-
openSettingsPanel(done);
|
|
309
|
-
});
|
|
292
|
+
openRawSettings();
|
|
310
293
|
return;
|
|
311
294
|
}
|
|
312
295
|
|
|
313
296
|
if (input === "/") {
|
|
314
|
-
|
|
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");
|