bashio 2.0.0 → 2.1.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/LICENSE +217 -21
- package/README.md +48 -3
- package/dist/{App-SRRDMIMW.js → App-MVOM7NMT.js} +304 -430
- package/dist/App-MVOM7NMT.js.map +1 -0
- package/dist/{chunk-PYTBTPZN.js → chunk-6OLRZLFB.js} +6 -37
- package/dist/chunk-6OLRZLFB.js.map +1 -0
- package/dist/index.js +33 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/App-SRRDMIMW.js.map +0 -1
- package/dist/chunk-PYTBTPZN.js.map +0 -1
|
@@ -9,18 +9,17 @@ import {
|
|
|
9
9
|
OPENROUTER_MODELS,
|
|
10
10
|
THEMES,
|
|
11
11
|
configExists,
|
|
12
|
-
copyToClipboard,
|
|
13
12
|
createProvider,
|
|
14
13
|
getThemeByName,
|
|
15
14
|
loadConfig,
|
|
16
15
|
runAuthSetup,
|
|
17
16
|
saveConfig
|
|
18
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-6OLRZLFB.js";
|
|
19
18
|
|
|
20
19
|
// src/chat/App.tsx
|
|
21
20
|
import { MouseProvider } from "@ink-tools/ink-mouse";
|
|
22
|
-
import { Box as
|
|
23
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo5, useRef as
|
|
21
|
+
import { Box as Box10, render, Text as Text10, useApp, useInput as useInput6, useStdout as useStdout4 } from "ink";
|
|
22
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef7, useState as useState6 } from "react";
|
|
24
23
|
|
|
25
24
|
// src/chat/components/InputBox.tsx
|
|
26
25
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
@@ -31,21 +30,39 @@ var SLASH_COMMANDS = [
|
|
|
31
30
|
{
|
|
32
31
|
name: "models",
|
|
33
32
|
description: "Switch AI model",
|
|
34
|
-
action: "openModelSwitcher"
|
|
33
|
+
action: "openModelSwitcher",
|
|
34
|
+
shortcut: "Ctrl+P"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
name: "sessions",
|
|
38
38
|
description: "Browse chat sessions",
|
|
39
|
-
action: "openSessionPicker"
|
|
39
|
+
action: "openSessionPicker",
|
|
40
|
+
shortcut: "Ctrl+O"
|
|
40
41
|
},
|
|
41
42
|
{
|
|
42
43
|
name: "theme",
|
|
43
44
|
description: "Change color theme",
|
|
44
|
-
action: "openThemePicker"
|
|
45
|
+
action: "openThemePicker",
|
|
46
|
+
shortcut: "Ctrl+T"
|
|
45
47
|
},
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
{
|
|
49
|
+
name: "new",
|
|
50
|
+
description: "Start new chat session",
|
|
51
|
+
action: "newSession",
|
|
52
|
+
shortcut: "Ctrl+N"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "clear",
|
|
56
|
+
description: "Clear current chat",
|
|
57
|
+
action: "clearChat",
|
|
58
|
+
shortcut: "Ctrl+L"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "exit",
|
|
62
|
+
description: "Exit chat",
|
|
63
|
+
action: "exitChat",
|
|
64
|
+
shortcut: "Ctrl+C"
|
|
65
|
+
}
|
|
49
66
|
];
|
|
50
67
|
function filterCommands(query) {
|
|
51
68
|
const normalizedQuery = query.toLowerCase().replace(/^\//, "");
|
|
@@ -81,9 +98,10 @@ var MenuItem = memo(function MenuItem2({
|
|
|
81
98
|
}) {
|
|
82
99
|
const rowRef = useRef(null);
|
|
83
100
|
const nameColWidth = 15;
|
|
101
|
+
const shortcutWidth = cmd.shortcut ? cmd.shortcut.length + 2 : 0;
|
|
84
102
|
const nameText = `/${cmd.name}`.padEnd(nameColWidth);
|
|
85
|
-
const descWidth = width - nameColWidth - 6;
|
|
86
|
-
const descText = cmd.description.length > descWidth ? `${cmd.description.slice(0, descWidth - 3)}...` : cmd.description;
|
|
103
|
+
const descWidth = width - nameColWidth - shortcutWidth - 6;
|
|
104
|
+
const descText = cmd.description.length > descWidth ? `${cmd.description.slice(0, descWidth - 3)}...` : cmd.description.padEnd(descWidth);
|
|
87
105
|
useOnMouseMove(rowRef, () => {
|
|
88
106
|
onHover(index);
|
|
89
107
|
});
|
|
@@ -91,14 +109,16 @@ var MenuItem = memo(function MenuItem2({
|
|
|
91
109
|
onClick(index);
|
|
92
110
|
});
|
|
93
111
|
if (isSelected) {
|
|
94
|
-
return /* @__PURE__ */
|
|
95
|
-
nameText,
|
|
96
|
-
descText
|
|
97
|
-
|
|
112
|
+
return /* @__PURE__ */ jsxs(Box, { ref: rowRef, backgroundColor: accent, paddingX: 1, children: [
|
|
113
|
+
/* @__PURE__ */ jsx(Text, { color: "white", bold: true, children: nameText }),
|
|
114
|
+
/* @__PURE__ */ jsx(Text, { color: "white", bold: true, children: descText }),
|
|
115
|
+
cmd.shortcut && /* @__PURE__ */ jsx(Text, { color: "white", bold: true, children: cmd.shortcut })
|
|
116
|
+
] });
|
|
98
117
|
}
|
|
99
118
|
return /* @__PURE__ */ jsxs(Box, { ref: rowRef, paddingX: 1, children: [
|
|
100
119
|
/* @__PURE__ */ jsx(Text, { color: textPrimary, children: nameText }),
|
|
101
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: descText })
|
|
120
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: descText }),
|
|
121
|
+
cmd.shortcut && /* @__PURE__ */ jsx(Text, { dimColor: true, children: cmd.shortcut })
|
|
102
122
|
] });
|
|
103
123
|
});
|
|
104
124
|
var SlashCommandMenu = memo(function SlashCommandMenu2({
|
|
@@ -411,137 +431,21 @@ ${v.slice(cursorPos)}`);
|
|
|
411
431
|
});
|
|
412
432
|
|
|
413
433
|
// src/chat/components/MessageList.tsx
|
|
414
|
-
import { useOnClick as useOnClick3, useOnWheel } from "@ink-tools/ink-mouse";
|
|
415
434
|
import { highlight } from "cli-highlight";
|
|
416
|
-
import { Box as
|
|
435
|
+
import { Box as Box3, Text as Text3, useInput as useInput2 } from "ink";
|
|
417
436
|
import { ScrollView } from "ink-scroll-view";
|
|
418
437
|
import Spinner from "ink-spinner";
|
|
419
438
|
import {
|
|
420
439
|
forwardRef,
|
|
421
|
-
memo as
|
|
440
|
+
memo as memo3,
|
|
422
441
|
useCallback,
|
|
423
442
|
useEffect,
|
|
424
443
|
useImperativeHandle,
|
|
425
444
|
useMemo as useMemo3,
|
|
426
|
-
useRef as
|
|
427
|
-
useState as
|
|
445
|
+
useRef as useRef3,
|
|
446
|
+
useState as useState2
|
|
428
447
|
} from "react";
|
|
429
|
-
|
|
430
|
-
// src/chat/components/MessageContextMenu.tsx
|
|
431
|
-
import { useOnClick as useOnClick2, useOnMouseMove as useOnMouseMove2 } from "@ink-tools/ink-mouse";
|
|
432
|
-
import { Box as Box3, Text as Text3, useInput as useInput2 } from "ink";
|
|
433
|
-
import { memo as memo3, useRef as useRef3, useState as useState2 } from "react";
|
|
434
448
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
435
|
-
var menuItems = [
|
|
436
|
-
{ label: "Copy", description: "message text to clipboard", action: "copy" },
|
|
437
|
-
{ label: "Exit", description: "close this menu", action: "exit" }
|
|
438
|
-
];
|
|
439
|
-
var MenuItemRow = memo3(function MenuItemRow2({
|
|
440
|
-
item,
|
|
441
|
-
index,
|
|
442
|
-
isSelected,
|
|
443
|
-
rowWidth,
|
|
444
|
-
accent,
|
|
445
|
-
onHover,
|
|
446
|
-
onClick
|
|
447
|
-
}) {
|
|
448
|
-
const rowRef = useRef3(null);
|
|
449
|
-
useOnMouseMove2(rowRef, () => {
|
|
450
|
-
onHover(index);
|
|
451
|
-
});
|
|
452
|
-
useOnClick2(rowRef, () => {
|
|
453
|
-
onClick(item.action);
|
|
454
|
-
});
|
|
455
|
-
return /* @__PURE__ */ jsxs3(
|
|
456
|
-
Box3,
|
|
457
|
-
{
|
|
458
|
-
ref: rowRef,
|
|
459
|
-
backgroundColor: isSelected ? accent : void 0,
|
|
460
|
-
width: rowWidth,
|
|
461
|
-
justifyContent: "space-between",
|
|
462
|
-
paddingX: 1,
|
|
463
|
-
children: [
|
|
464
|
-
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "white" : "white", bold: isSelected, children: item.label }),
|
|
465
|
-
isSelected ? /* @__PURE__ */ jsx3(Text3, { color: "white", children: item.description }) : /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: item.description })
|
|
466
|
-
]
|
|
467
|
-
}
|
|
468
|
-
);
|
|
469
|
-
});
|
|
470
|
-
var MessageContextMenu = memo3(function MessageContextMenu2({
|
|
471
|
-
onSelect,
|
|
472
|
-
onClose,
|
|
473
|
-
width = 50
|
|
474
|
-
}) {
|
|
475
|
-
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
476
|
-
useInput2((input, key) => {
|
|
477
|
-
if (key.escape) {
|
|
478
|
-
onClose();
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
if (key.return) {
|
|
482
|
-
const selected = menuItems[selectedIndex];
|
|
483
|
-
if (selected) {
|
|
484
|
-
if (selected.action === "exit") {
|
|
485
|
-
onClose();
|
|
486
|
-
} else {
|
|
487
|
-
onSelect(selected.action);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
if (key.upArrow || input === "k") {
|
|
493
|
-
setSelectedIndex((i) => Math.max(0, i - 1));
|
|
494
|
-
}
|
|
495
|
-
if (key.downArrow || input === "j") {
|
|
496
|
-
setSelectedIndex((i) => Math.min(menuItems.length - 1, i + 1));
|
|
497
|
-
}
|
|
498
|
-
});
|
|
499
|
-
const handleHover = (index) => {
|
|
500
|
-
setSelectedIndex(index);
|
|
501
|
-
};
|
|
502
|
-
const handleClick = (action) => {
|
|
503
|
-
if (action === "exit") {
|
|
504
|
-
onClose();
|
|
505
|
-
} else {
|
|
506
|
-
onSelect(action);
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
const theme = useTheme();
|
|
510
|
-
const menuWidth = Math.min(width, 50);
|
|
511
|
-
return /* @__PURE__ */ jsxs3(
|
|
512
|
-
Box3,
|
|
513
|
-
{
|
|
514
|
-
flexDirection: "column",
|
|
515
|
-
width: menuWidth,
|
|
516
|
-
borderStyle: "round",
|
|
517
|
-
borderColor: theme.accent,
|
|
518
|
-
backgroundColor: theme.background,
|
|
519
|
-
children: [
|
|
520
|
-
/* @__PURE__ */ jsxs3(Box3, { paddingX: 1, justifyContent: "space-between", children: [
|
|
521
|
-
/* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.textPrimary, children: "Message Actions" }),
|
|
522
|
-
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "esc" })
|
|
523
|
-
] }),
|
|
524
|
-
/* @__PURE__ */ jsx3(Box3, { paddingX: 1, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2500".repeat(menuWidth - 4) }) }),
|
|
525
|
-
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", paddingBottom: 1, children: menuItems.map((item, index) => /* @__PURE__ */ jsx3(
|
|
526
|
-
MenuItemRow,
|
|
527
|
-
{
|
|
528
|
-
item,
|
|
529
|
-
index,
|
|
530
|
-
isSelected: index === selectedIndex,
|
|
531
|
-
rowWidth: menuWidth - 2,
|
|
532
|
-
accent: theme.accent,
|
|
533
|
-
onHover: handleHover,
|
|
534
|
-
onClick: handleClick
|
|
535
|
-
},
|
|
536
|
-
item.action
|
|
537
|
-
)) })
|
|
538
|
-
]
|
|
539
|
-
}
|
|
540
|
-
);
|
|
541
|
-
});
|
|
542
|
-
|
|
543
|
-
// src/chat/components/MessageList.tsx
|
|
544
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
545
449
|
function parseInlineMarkdown(text, keyPrefix) {
|
|
546
450
|
const nodes = [];
|
|
547
451
|
const inlineRegex = /(\*\*|__)(.+?)\1|(\*|_)(.+?)\3|`([^`]+)`/g;
|
|
@@ -555,15 +459,15 @@ function parseInlineMarkdown(text, keyPrefix) {
|
|
|
555
459
|
}
|
|
556
460
|
if (match[2]) {
|
|
557
461
|
nodes.push(
|
|
558
|
-
/* @__PURE__ */
|
|
462
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, children: match[2] }, `${keyPrefix}-b-${idx++}`)
|
|
559
463
|
);
|
|
560
464
|
} else if (match[4]) {
|
|
561
465
|
nodes.push(
|
|
562
|
-
/* @__PURE__ */
|
|
466
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: match[4] }, `${keyPrefix}-i-${idx++}`)
|
|
563
467
|
);
|
|
564
468
|
} else if (match[5]) {
|
|
565
469
|
nodes.push(
|
|
566
|
-
/* @__PURE__ */
|
|
470
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: match[5] }, `${keyPrefix}-c-${idx++}`)
|
|
567
471
|
);
|
|
568
472
|
}
|
|
569
473
|
lastIndex = match.index + match[0].length;
|
|
@@ -586,19 +490,19 @@ function parseLine(line, keyIndex, _maxWidth) {
|
|
|
586
490
|
const headerText = headerMatch[2];
|
|
587
491
|
const parsed2 = parseInlineMarkdown(headerText, `h-${keyIndex}`);
|
|
588
492
|
if (level === 1) {
|
|
589
|
-
return /* @__PURE__ */
|
|
493
|
+
return /* @__PURE__ */ jsx3(Text3, { bold: true, color: "yellow", children: parsed2 }, keyIndex);
|
|
590
494
|
}
|
|
591
495
|
if (level === 2) {
|
|
592
|
-
return /* @__PURE__ */
|
|
496
|
+
return /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: parsed2 }, keyIndex);
|
|
593
497
|
}
|
|
594
|
-
return /* @__PURE__ */
|
|
498
|
+
return /* @__PURE__ */ jsx3(Text3, { bold: true, children: parsed2 }, keyIndex);
|
|
595
499
|
}
|
|
596
500
|
const bulletMatch = trimmed.match(/^[-*]\s+(.+)$/);
|
|
597
501
|
if (bulletMatch) {
|
|
598
502
|
const bulletText = bulletMatch[1];
|
|
599
503
|
const parsed2 = parseInlineMarkdown(bulletText, `li-${keyIndex}`);
|
|
600
|
-
return /* @__PURE__ */
|
|
601
|
-
/* @__PURE__ */
|
|
504
|
+
return /* @__PURE__ */ jsx3(Box3, { paddingLeft: indent, children: /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
505
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "\u2022" }),
|
|
602
506
|
" ",
|
|
603
507
|
parsed2
|
|
604
508
|
] }) }, keyIndex);
|
|
@@ -608,8 +512,8 @@ function parseLine(line, keyIndex, _maxWidth) {
|
|
|
608
512
|
const num = numberedMatch[1];
|
|
609
513
|
const itemText = numberedMatch[2];
|
|
610
514
|
const parsed2 = parseInlineMarkdown(itemText, `ol-${keyIndex}`);
|
|
611
|
-
return /* @__PURE__ */
|
|
612
|
-
/* @__PURE__ */
|
|
515
|
+
return /* @__PURE__ */ jsx3(Box3, { paddingLeft: indent, children: /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
516
|
+
/* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
|
|
613
517
|
num,
|
|
614
518
|
"."
|
|
615
519
|
] }),
|
|
@@ -621,17 +525,17 @@ function parseLine(line, keyIndex, _maxWidth) {
|
|
|
621
525
|
if (quoteMatch) {
|
|
622
526
|
const quoteText = quoteMatch[1];
|
|
623
527
|
const parsed2 = parseInlineMarkdown(quoteText, `q-${keyIndex}`);
|
|
624
|
-
return /* @__PURE__ */
|
|
625
|
-
/* @__PURE__ */
|
|
528
|
+
return /* @__PURE__ */ jsx3(Box3, { paddingLeft: 1, children: /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
529
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: "\u2502" }),
|
|
626
530
|
" ",
|
|
627
|
-
/* @__PURE__ */
|
|
531
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: parsed2 })
|
|
628
532
|
] }) }, keyIndex);
|
|
629
533
|
}
|
|
630
534
|
if (trimmed.length === 0) {
|
|
631
|
-
return /* @__PURE__ */
|
|
535
|
+
return /* @__PURE__ */ jsx3(Text3, { children: " " }, keyIndex);
|
|
632
536
|
}
|
|
633
537
|
const parsed = parseInlineMarkdown(line, `p-${keyIndex}`);
|
|
634
|
-
return /* @__PURE__ */
|
|
538
|
+
return /* @__PURE__ */ jsx3(Text3, { wrap: "wrap", children: parsed }, keyIndex);
|
|
635
539
|
}
|
|
636
540
|
var BOX = {
|
|
637
541
|
topLeft: "\u250C",
|
|
@@ -713,24 +617,24 @@ function parseTable(lines, startKey, maxWidth) {
|
|
|
713
617
|
topBorder += c < numCols - 1 ? BOX.topMid : BOX.topRight;
|
|
714
618
|
}
|
|
715
619
|
tableRows.push(
|
|
716
|
-
/* @__PURE__ */
|
|
620
|
+
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: topBorder }) }, `top-${keyIdx++}`)
|
|
717
621
|
);
|
|
718
622
|
const wrappedHeaders = headers.map((h, idx) => wrapText(h, colWidths[idx]));
|
|
719
623
|
const headerLineCount = Math.max(...wrappedHeaders.map((w) => w.length));
|
|
720
624
|
for (let lineIdx = 0; lineIdx < headerLineCount; lineIdx++) {
|
|
721
625
|
tableRows.push(
|
|
722
|
-
/* @__PURE__ */
|
|
723
|
-
/* @__PURE__ */
|
|
626
|
+
/* @__PURE__ */ jsxs3(Box3, { children: [
|
|
627
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: BOX.vertical }),
|
|
724
628
|
headers.map((_, colIdx) => {
|
|
725
629
|
const wrappedLines = wrappedHeaders[colIdx];
|
|
726
630
|
const lineText = wrappedLines[lineIdx] || "";
|
|
727
|
-
return /* @__PURE__ */
|
|
728
|
-
/* @__PURE__ */
|
|
631
|
+
return /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
632
|
+
/* @__PURE__ */ jsxs3(Text3, { bold: true, color: "yellow", children: [
|
|
729
633
|
" ",
|
|
730
634
|
lineText.padEnd(colWidths[colIdx]),
|
|
731
635
|
" "
|
|
732
636
|
] }),
|
|
733
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: BOX.vertical })
|
|
734
638
|
] }, `h-${colIdx}-${lineIdx}`);
|
|
735
639
|
})
|
|
736
640
|
] }, `header-${keyIdx++}-${lineIdx}`)
|
|
@@ -742,7 +646,7 @@ function parseTable(lines, startKey, maxWidth) {
|
|
|
742
646
|
headerSep += c < numCols - 1 ? BOX.midMid : BOX.rightMid;
|
|
743
647
|
}
|
|
744
648
|
tableRows.push(
|
|
745
|
-
/* @__PURE__ */
|
|
649
|
+
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: headerSep }) }, `sep-${keyIdx++}`)
|
|
746
650
|
);
|
|
747
651
|
for (let rowIdx = 0; rowIdx < dataRows.length; rowIdx++) {
|
|
748
652
|
const row = dataRows[rowIdx];
|
|
@@ -753,8 +657,8 @@ function parseTable(lines, startKey, maxWidth) {
|
|
|
753
657
|
const maxLines = Math.max(...wrappedCells.map((w) => w.length));
|
|
754
658
|
for (let lineIdx = 0; lineIdx < maxLines; lineIdx++) {
|
|
755
659
|
tableRows.push(
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
660
|
+
/* @__PURE__ */ jsxs3(Box3, { children: [
|
|
661
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: BOX.vertical }),
|
|
758
662
|
headers.map((_, colIdx) => {
|
|
759
663
|
const wrappedLines = wrappedCells[colIdx];
|
|
760
664
|
const lineText = wrappedLines[lineIdx] || "";
|
|
@@ -763,11 +667,11 @@ function parseTable(lines, startKey, maxWidth) {
|
|
|
763
667
|
paddedText,
|
|
764
668
|
`cell-${rowIdx}-${colIdx}-${lineIdx}`
|
|
765
669
|
);
|
|
766
|
-
return /* @__PURE__ */
|
|
670
|
+
return /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
767
671
|
" ",
|
|
768
672
|
parsed,
|
|
769
673
|
" ",
|
|
770
|
-
/* @__PURE__ */
|
|
674
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: BOX.vertical })
|
|
771
675
|
] }, `c-${colIdx}-${rowIdx}-${lineIdx}`);
|
|
772
676
|
})
|
|
773
677
|
] }, `row-${keyIdx++}-${rowIdx}-${lineIdx}`)
|
|
@@ -780,10 +684,10 @@ function parseTable(lines, startKey, maxWidth) {
|
|
|
780
684
|
bottomBorder += c < numCols - 1 ? BOX.bottomMid : BOX.bottomRight;
|
|
781
685
|
}
|
|
782
686
|
tableRows.push(
|
|
783
|
-
/* @__PURE__ */
|
|
687
|
+
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: bottomBorder }) }, `bottom-${keyIdx++}`)
|
|
784
688
|
);
|
|
785
689
|
return {
|
|
786
|
-
node: /* @__PURE__ */
|
|
690
|
+
node: /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: tableRows }, startKey),
|
|
787
691
|
linesConsumed: i
|
|
788
692
|
};
|
|
789
693
|
}
|
|
@@ -839,32 +743,32 @@ function parseContent(content, maxWidth) {
|
|
|
839
743
|
try {
|
|
840
744
|
const highlighted = highlight(code, { language, ignoreIllegals: true });
|
|
841
745
|
parts.push(
|
|
842
|
-
/* @__PURE__ */
|
|
843
|
-
|
|
746
|
+
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", width: maxWidth - 4, children: /* @__PURE__ */ jsxs3(
|
|
747
|
+
Box3,
|
|
844
748
|
{
|
|
845
749
|
borderStyle: "single",
|
|
846
750
|
borderColor: "gray",
|
|
847
751
|
paddingX: 1,
|
|
848
752
|
flexDirection: "column",
|
|
849
753
|
children: [
|
|
850
|
-
/* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
754
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: language }),
|
|
755
|
+
/* @__PURE__ */ jsx3(Text3, { children: highlighted })
|
|
852
756
|
]
|
|
853
757
|
}
|
|
854
758
|
) }, keyIndex++)
|
|
855
759
|
);
|
|
856
760
|
} catch {
|
|
857
761
|
parts.push(
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
|
|
762
|
+
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", width: maxWidth - 4, children: /* @__PURE__ */ jsxs3(
|
|
763
|
+
Box3,
|
|
860
764
|
{
|
|
861
765
|
borderStyle: "single",
|
|
862
766
|
borderColor: "gray",
|
|
863
767
|
paddingX: 1,
|
|
864
768
|
flexDirection: "column",
|
|
865
769
|
children: [
|
|
866
|
-
/* @__PURE__ */
|
|
867
|
-
/* @__PURE__ */
|
|
770
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: language }),
|
|
771
|
+
/* @__PURE__ */ jsx3(Text3, { children: code })
|
|
868
772
|
]
|
|
869
773
|
}
|
|
870
774
|
) }, keyIndex++)
|
|
@@ -880,39 +784,30 @@ function parseContent(content, maxWidth) {
|
|
|
880
784
|
parts.push(...result.parts);
|
|
881
785
|
}
|
|
882
786
|
return parts.length > 0 ? parts : [
|
|
883
|
-
/* @__PURE__ */
|
|
787
|
+
/* @__PURE__ */ jsx3(Text3, { wrap: "wrap", children: content }, 0)
|
|
884
788
|
];
|
|
885
789
|
}
|
|
886
|
-
var Message =
|
|
790
|
+
var Message = memo3(function Message2({
|
|
887
791
|
message,
|
|
888
792
|
width,
|
|
889
|
-
|
|
890
|
-
accent,
|
|
891
|
-
onMessageClick
|
|
793
|
+
accent
|
|
892
794
|
}) {
|
|
893
795
|
const isUser = message.role === "user";
|
|
894
|
-
const messageRef = useRef4(null);
|
|
895
796
|
const parsedContent = useMemo3(
|
|
896
797
|
() => parseContent(message.content, width - 4),
|
|
897
798
|
[message.content, width]
|
|
898
799
|
);
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
!isUser && onMessageClick ? () => {
|
|
902
|
-
onMessageClick(messageIndex, message.content);
|
|
903
|
-
} : null
|
|
904
|
-
);
|
|
905
|
-
return /* @__PURE__ */ jsxs4(Box4, { ref: messageRef, flexDirection: "column", marginY: 1, width, children: [
|
|
906
|
-
/* @__PURE__ */ jsx4(Box4, { children: /* @__PURE__ */ jsxs4(Text4, { bold: true, color: isUser ? accent : "yellow", children: [
|
|
800
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginY: 1, width, children: [
|
|
801
|
+
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsxs3(Text3, { bold: true, color: isUser ? accent : "yellow", children: [
|
|
907
802
|
isUser ? "You" : "Bashio",
|
|
908
803
|
":"
|
|
909
804
|
] }) }),
|
|
910
|
-
/* @__PURE__ */
|
|
805
|
+
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", paddingLeft: 2, children: parsedContent })
|
|
911
806
|
] });
|
|
912
807
|
});
|
|
913
|
-
var EmptyState =
|
|
914
|
-
return /* @__PURE__ */
|
|
915
|
-
|
|
808
|
+
var EmptyState = memo3(function EmptyState2({ height }) {
|
|
809
|
+
return /* @__PURE__ */ jsxs3(
|
|
810
|
+
Box3,
|
|
916
811
|
{
|
|
917
812
|
flexDirection: "column",
|
|
918
813
|
height,
|
|
@@ -920,37 +815,17 @@ var EmptyState = memo4(function EmptyState2({ height }) {
|
|
|
920
815
|
justifyContent: "center",
|
|
921
816
|
alignItems: "center",
|
|
922
817
|
children: [
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Start a conversation by typing a message below." }),
|
|
819
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Type / for commands or Ctrl+P to switch models." })
|
|
925
820
|
]
|
|
926
821
|
}
|
|
927
822
|
);
|
|
928
823
|
});
|
|
929
|
-
var MessageList =
|
|
824
|
+
var MessageList = memo3(
|
|
930
825
|
forwardRef(function MessageList2({ messages, currentResponse, isLoading, height, width, slashModeRef }, ref) {
|
|
931
826
|
const theme = useTheme();
|
|
932
|
-
const scrollRef =
|
|
933
|
-
const
|
|
934
|
-
const [followOutput, setFollowOutput] = useState3(true);
|
|
935
|
-
const [contextMenu, setContextMenu] = useState3(null);
|
|
936
|
-
const handleMessageClick = useCallback(
|
|
937
|
-
(messageIndex, content) => {
|
|
938
|
-
setContextMenu({ messageIndex, content });
|
|
939
|
-
},
|
|
940
|
-
[]
|
|
941
|
-
);
|
|
942
|
-
const handleContextMenuSelect = useCallback(
|
|
943
|
-
async (action) => {
|
|
944
|
-
if (action === "copy" && contextMenu) {
|
|
945
|
-
await copyToClipboard(contextMenu.content);
|
|
946
|
-
}
|
|
947
|
-
setContextMenu(null);
|
|
948
|
-
},
|
|
949
|
-
[contextMenu]
|
|
950
|
-
);
|
|
951
|
-
const handleContextMenuClose = useCallback(() => {
|
|
952
|
-
setContextMenu(null);
|
|
953
|
-
}, []);
|
|
827
|
+
const scrollRef = useRef3(null);
|
|
828
|
+
const [followOutput, setFollowOutput] = useState2(true);
|
|
954
829
|
const boundedScrollBy = useCallback((delta) => {
|
|
955
830
|
const sv = scrollRef.current;
|
|
956
831
|
if (!sv) return;
|
|
@@ -984,7 +859,7 @@ var MessageList = memo4(
|
|
|
984
859
|
}, 10);
|
|
985
860
|
return () => clearTimeout(timer);
|
|
986
861
|
}, [messagesCount, hasResponse, boundedScrollToBottom, followOutput]);
|
|
987
|
-
|
|
862
|
+
useInput2((input, key) => {
|
|
988
863
|
if (slashModeRef.current) return;
|
|
989
864
|
if (input.startsWith("\x1B[<")) {
|
|
990
865
|
return;
|
|
@@ -1009,13 +884,6 @@ var MessageList = memo4(
|
|
|
1009
884
|
if (input === "k" && key.meta) boundedScrollBy(-3);
|
|
1010
885
|
if (input === "j" && key.meta) boundedScrollBy(3);
|
|
1011
886
|
});
|
|
1012
|
-
useOnWheel(mouseRef, (event) => {
|
|
1013
|
-
if (event.button === "wheel-up") {
|
|
1014
|
-
boundedScrollBy(-3);
|
|
1015
|
-
} else if (event.button === "wheel-down") {
|
|
1016
|
-
boundedScrollBy(3);
|
|
1017
|
-
}
|
|
1018
|
-
});
|
|
1019
887
|
useEffect(() => {
|
|
1020
888
|
if (followOutput) return;
|
|
1021
889
|
const sv = scrollRef.current;
|
|
@@ -1031,69 +899,47 @@ var MessageList = memo4(
|
|
|
1031
899
|
[currentResponse, width]
|
|
1032
900
|
);
|
|
1033
901
|
if (messages.length === 0 && !currentResponse) {
|
|
1034
|
-
return /* @__PURE__ */
|
|
902
|
+
return /* @__PURE__ */ jsx3(EmptyState, { height });
|
|
1035
903
|
}
|
|
1036
|
-
return /* @__PURE__ */
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
Message,
|
|
1040
|
-
{
|
|
1041
|
-
message: msg,
|
|
1042
|
-
width,
|
|
1043
|
-
messageIndex: i,
|
|
1044
|
-
accent: theme.accent,
|
|
1045
|
-
onMessageClick: contextMenu === null ? handleMessageClick : void 0
|
|
1046
|
-
},
|
|
1047
|
-
`msg-${i}-${msg.role}`
|
|
1048
|
-
)),
|
|
1049
|
-
streamingContent && /* @__PURE__ */ jsxs4(
|
|
1050
|
-
Box4,
|
|
1051
|
-
{
|
|
1052
|
-
flexDirection: "column",
|
|
1053
|
-
marginY: 1,
|
|
1054
|
-
width,
|
|
1055
|
-
children: [
|
|
1056
|
-
/* @__PURE__ */ jsx4(Box4, { children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: "Bashio:" }) }),
|
|
1057
|
-
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingLeft: 2, children: [
|
|
1058
|
-
streamingContent,
|
|
1059
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "|" })
|
|
1060
|
-
] })
|
|
1061
|
-
]
|
|
1062
|
-
},
|
|
1063
|
-
"streaming"
|
|
1064
|
-
),
|
|
1065
|
-
isLoading && !currentResponse && /* @__PURE__ */ jsxs4(Box4, { marginY: 1, children: [
|
|
1066
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.accent, children: /* @__PURE__ */ jsx4(Spinner, { type: "dots" }) }),
|
|
1067
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.accent, children: " Thinking..." })
|
|
1068
|
-
] }, "loading")
|
|
1069
|
-
] }) }),
|
|
1070
|
-
contextMenu !== null && /* @__PURE__ */ jsx4(
|
|
1071
|
-
Box4,
|
|
904
|
+
return /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", height, width, children: /* @__PURE__ */ jsx3(Box3, { height, paddingX: 1, overflow: "hidden", children: /* @__PURE__ */ jsxs3(ScrollView, { ref: scrollRef, height, children: [
|
|
905
|
+
messages.map((msg, i) => /* @__PURE__ */ jsx3(
|
|
906
|
+
Message,
|
|
1072
907
|
{
|
|
1073
|
-
|
|
908
|
+
message: msg,
|
|
1074
909
|
width,
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
910
|
+
accent: theme.accent
|
|
911
|
+
},
|
|
912
|
+
`msg-${i}-${msg.role}`
|
|
913
|
+
)),
|
|
914
|
+
streamingContent && /* @__PURE__ */ jsxs3(
|
|
915
|
+
Box3,
|
|
916
|
+
{
|
|
917
|
+
flexDirection: "column",
|
|
918
|
+
marginY: 1,
|
|
919
|
+
width,
|
|
920
|
+
children: [
|
|
921
|
+
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "yellow", children: "Bashio:" }) }),
|
|
922
|
+
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingLeft: 2, children: [
|
|
923
|
+
streamingContent,
|
|
924
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "|" })
|
|
925
|
+
] })
|
|
926
|
+
]
|
|
927
|
+
},
|
|
928
|
+
"streaming"
|
|
929
|
+
),
|
|
930
|
+
isLoading && !currentResponse && /* @__PURE__ */ jsxs3(Box3, { marginY: 1, children: [
|
|
931
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.accent, children: /* @__PURE__ */ jsx3(Spinner, { type: "dots" }) }),
|
|
932
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.accent, children: " Thinking..." })
|
|
933
|
+
] }, "loading")
|
|
934
|
+
] }) }) });
|
|
1089
935
|
})
|
|
1090
936
|
);
|
|
1091
937
|
|
|
1092
938
|
// src/chat/components/ModelSwitcher.tsx
|
|
1093
|
-
import { useOnClick as
|
|
1094
|
-
import { Box as
|
|
1095
|
-
import { memo as
|
|
1096
|
-
import { jsx as
|
|
939
|
+
import { useOnClick as useOnClick2, useOnMouseMove as useOnMouseMove2 } from "@ink-tools/ink-mouse";
|
|
940
|
+
import { Box as Box4, Text as Text4, useInput as useInput3, useStdout } from "ink";
|
|
941
|
+
import { memo as memo4, useRef as useRef4, useState as useState3 } from "react";
|
|
942
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1097
943
|
var PROVIDER_LABELS = {
|
|
1098
944
|
"claude-subscription": "Claude Pro/Max",
|
|
1099
945
|
"chatgpt-subscription": "ChatGPT Plus/Pro",
|
|
@@ -1103,7 +949,7 @@ var PROVIDER_LABELS = {
|
|
|
1103
949
|
ollama: "Ollama",
|
|
1104
950
|
openrouter: "OpenRouter"
|
|
1105
951
|
};
|
|
1106
|
-
var ModelRow =
|
|
952
|
+
var ModelRow = memo4(function ModelRow2({
|
|
1107
953
|
option,
|
|
1108
954
|
isSelected,
|
|
1109
955
|
isCurrent,
|
|
@@ -1112,15 +958,15 @@ var ModelRow = memo5(function ModelRow2({
|
|
|
1112
958
|
onHover,
|
|
1113
959
|
onClick
|
|
1114
960
|
}) {
|
|
1115
|
-
const rowRef =
|
|
1116
|
-
|
|
1117
|
-
|
|
961
|
+
const rowRef = useRef4(null);
|
|
962
|
+
useOnMouseMove2(rowRef, onHover);
|
|
963
|
+
useOnClick2(rowRef, onClick);
|
|
1118
964
|
const prefix = isSelected ? ">" : isCurrent ? "\u2713" : " ";
|
|
1119
965
|
const labelWithPrefix = ` ${prefix} ${option.label}`;
|
|
1120
966
|
const padding = Math.max(0, rowWidth - labelWithPrefix.length);
|
|
1121
967
|
const fullLine = labelWithPrefix + " ".repeat(padding);
|
|
1122
|
-
return /* @__PURE__ */
|
|
1123
|
-
|
|
968
|
+
return /* @__PURE__ */ jsx4(Box4, { ref: rowRef, children: /* @__PURE__ */ jsx4(
|
|
969
|
+
Text4,
|
|
1124
970
|
{
|
|
1125
971
|
backgroundColor: isSelected ? accent : void 0,
|
|
1126
972
|
color: isSelected ? "#000000" : void 0,
|
|
@@ -1176,7 +1022,7 @@ function ModelSwitcher({
|
|
|
1176
1022
|
const currentIndex = options.findIndex(
|
|
1177
1023
|
(o) => o.provider === currentProvider && o.model === currentModel
|
|
1178
1024
|
);
|
|
1179
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1025
|
+
const [selectedIndex, setSelectedIndex] = useState3(
|
|
1180
1026
|
currentIndex >= 0 ? currentIndex : 0
|
|
1181
1027
|
);
|
|
1182
1028
|
const handleHover = (index) => {
|
|
@@ -1188,7 +1034,7 @@ function ModelSwitcher({
|
|
|
1188
1034
|
onSelect(selected.provider, selected.model);
|
|
1189
1035
|
}
|
|
1190
1036
|
};
|
|
1191
|
-
|
|
1037
|
+
useInput3((input, key) => {
|
|
1192
1038
|
if (key.escape) {
|
|
1193
1039
|
onClose();
|
|
1194
1040
|
return;
|
|
@@ -1216,8 +1062,8 @@ function ModelSwitcher({
|
|
|
1216
1062
|
}
|
|
1217
1063
|
const visibleOptions = options.slice(startIndex, startIndex + listHeight);
|
|
1218
1064
|
let lastProvider = null;
|
|
1219
|
-
return /* @__PURE__ */
|
|
1220
|
-
|
|
1065
|
+
return /* @__PURE__ */ jsx4(
|
|
1066
|
+
Box4,
|
|
1221
1067
|
{
|
|
1222
1068
|
flexDirection: "column",
|
|
1223
1069
|
width,
|
|
@@ -1225,8 +1071,8 @@ function ModelSwitcher({
|
|
|
1225
1071
|
justifyContent: "center",
|
|
1226
1072
|
alignItems: "center",
|
|
1227
1073
|
backgroundColor: theme.background,
|
|
1228
|
-
children: /* @__PURE__ */
|
|
1229
|
-
|
|
1074
|
+
children: /* @__PURE__ */ jsxs4(
|
|
1075
|
+
Box4,
|
|
1230
1076
|
{
|
|
1231
1077
|
flexDirection: "column",
|
|
1232
1078
|
width: boxWidth,
|
|
@@ -1234,35 +1080,35 @@ function ModelSwitcher({
|
|
|
1234
1080
|
borderColor: theme.accent,
|
|
1235
1081
|
paddingX: 1,
|
|
1236
1082
|
children: [
|
|
1237
|
-
/* @__PURE__ */
|
|
1238
|
-
/* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1083
|
+
/* @__PURE__ */ jsxs4(Box4, { marginBottom: 1, justifyContent: "space-between", children: [
|
|
1084
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, color: theme.accent, children: "Model Selector" }),
|
|
1085
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "esc to exit" })
|
|
1240
1086
|
] }),
|
|
1241
|
-
/* @__PURE__ */
|
|
1242
|
-
/* @__PURE__ */
|
|
1243
|
-
/* @__PURE__ */
|
|
1087
|
+
/* @__PURE__ */ jsxs4(Box4, { children: [
|
|
1088
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.accent, children: "Current: " }),
|
|
1089
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1244
1090
|
PROVIDER_LABELS[currentProvider],
|
|
1245
1091
|
" / ",
|
|
1246
1092
|
currentModel
|
|
1247
1093
|
] })
|
|
1248
1094
|
] }),
|
|
1249
|
-
/* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
1095
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u2500".repeat(boxWidth - 4) }),
|
|
1096
|
+
/* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: visibleOptions.map((option, i) => {
|
|
1251
1097
|
const actualIndex = startIndex + i;
|
|
1252
1098
|
const isSelected = actualIndex === selectedIndex;
|
|
1253
1099
|
const isCurrent = option.provider === currentProvider && option.model === currentModel;
|
|
1254
1100
|
const showProviderHeader = option.provider !== lastProvider;
|
|
1255
1101
|
lastProvider = option.provider;
|
|
1256
|
-
return /* @__PURE__ */
|
|
1257
|
-
|
|
1102
|
+
return /* @__PURE__ */ jsxs4(
|
|
1103
|
+
Box4,
|
|
1258
1104
|
{
|
|
1259
1105
|
flexDirection: "column",
|
|
1260
1106
|
children: [
|
|
1261
|
-
showProviderHeader && /* @__PURE__ */
|
|
1107
|
+
showProviderHeader && /* @__PURE__ */ jsxs4(Text4, { bold: true, color: theme.accent, children: [
|
|
1262
1108
|
i > 0 ? "\n" : "",
|
|
1263
1109
|
option.providerLabel
|
|
1264
1110
|
] }),
|
|
1265
|
-
/* @__PURE__ */
|
|
1111
|
+
/* @__PURE__ */ jsx4(
|
|
1266
1112
|
ModelRow,
|
|
1267
1113
|
{
|
|
1268
1114
|
option,
|
|
@@ -1279,17 +1125,17 @@ function ModelSwitcher({
|
|
|
1279
1125
|
`${option.provider}-${option.model}`
|
|
1280
1126
|
);
|
|
1281
1127
|
}) }),
|
|
1282
|
-
/* @__PURE__ */
|
|
1283
|
-
/* @__PURE__ */
|
|
1284
|
-
/* @__PURE__ */
|
|
1285
|
-
options.length > listHeight && /* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u2500".repeat(boxWidth - 4) }),
|
|
1129
|
+
/* @__PURE__ */ jsxs4(Box4, { justifyContent: "space-between", children: [
|
|
1130
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u2191\u2193 navigate" }),
|
|
1131
|
+
options.length > listHeight && /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
1286
1132
|
startIndex + 1,
|
|
1287
1133
|
"-",
|
|
1288
1134
|
Math.min(startIndex + listHeight, options.length),
|
|
1289
1135
|
"/",
|
|
1290
1136
|
options.length
|
|
1291
1137
|
] }),
|
|
1292
|
-
/* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u21B5 select" })
|
|
1293
1139
|
] })
|
|
1294
1140
|
]
|
|
1295
1141
|
}
|
|
@@ -1299,22 +1145,22 @@ function ModelSwitcher({
|
|
|
1299
1145
|
}
|
|
1300
1146
|
|
|
1301
1147
|
// src/chat/components/SessionHeader.tsx
|
|
1302
|
-
import { Box as
|
|
1303
|
-
import { memo as
|
|
1304
|
-
import { jsx as
|
|
1305
|
-
var SessionHeader =
|
|
1148
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
1149
|
+
import { memo as memo5 } from "react";
|
|
1150
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1151
|
+
var SessionHeader = memo5(function SessionHeader2({
|
|
1306
1152
|
sessionTitle,
|
|
1307
1153
|
width
|
|
1308
1154
|
}) {
|
|
1309
1155
|
const theme = useTheme();
|
|
1310
|
-
return /* @__PURE__ */
|
|
1311
|
-
|
|
1156
|
+
return /* @__PURE__ */ jsxs5(
|
|
1157
|
+
Box5,
|
|
1312
1158
|
{
|
|
1313
1159
|
borderStyle: "single",
|
|
1314
|
-
borderLeft:
|
|
1160
|
+
borderLeft: false,
|
|
1315
1161
|
borderRight: false,
|
|
1316
1162
|
borderTop: false,
|
|
1317
|
-
borderBottom:
|
|
1163
|
+
borderBottom: true,
|
|
1318
1164
|
borderColor: theme.accent,
|
|
1319
1165
|
backgroundColor: theme.secondaryBg,
|
|
1320
1166
|
paddingX: 1,
|
|
@@ -1322,17 +1168,17 @@ var SessionHeader = memo6(function SessionHeader2({
|
|
|
1322
1168
|
gap: 1,
|
|
1323
1169
|
width,
|
|
1324
1170
|
children: [
|
|
1325
|
-
/* @__PURE__ */
|
|
1326
|
-
/* @__PURE__ */
|
|
1171
|
+
/* @__PURE__ */ jsx5(Text5, { color: theme.accent, children: "#" }),
|
|
1172
|
+
/* @__PURE__ */ jsx5(Text5, { color: theme.textPrimary, children: sessionTitle })
|
|
1327
1173
|
]
|
|
1328
1174
|
}
|
|
1329
1175
|
);
|
|
1330
1176
|
});
|
|
1331
1177
|
|
|
1332
1178
|
// src/chat/components/SessionPicker.tsx
|
|
1333
|
-
import { useOnClick as
|
|
1334
|
-
import { Box as
|
|
1335
|
-
import { memo as
|
|
1179
|
+
import { useOnClick as useOnClick3, useOnMouseMove as useOnMouseMove3 } from "@ink-tools/ink-mouse";
|
|
1180
|
+
import { Box as Box6, Text as Text6, useInput as useInput4, useStdout as useStdout2 } from "ink";
|
|
1181
|
+
import { memo as memo6, useRef as useRef5, useState as useState4 } from "react";
|
|
1336
1182
|
|
|
1337
1183
|
// src/chat/utils/sessions.ts
|
|
1338
1184
|
import {
|
|
@@ -1443,7 +1289,7 @@ function cleanupOldSessions() {
|
|
|
1443
1289
|
}
|
|
1444
1290
|
|
|
1445
1291
|
// src/chat/components/SessionPicker.tsx
|
|
1446
|
-
import { jsx as
|
|
1292
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1447
1293
|
function formatDate(isoString) {
|
|
1448
1294
|
const date = new Date(isoString);
|
|
1449
1295
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1457,7 +1303,7 @@ function formatDate(isoString) {
|
|
|
1457
1303
|
if (diffDays < 7) return `${diffDays}d ago`;
|
|
1458
1304
|
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
1459
1305
|
}
|
|
1460
|
-
var SessionRow =
|
|
1306
|
+
var SessionRow = memo6(function SessionRow2({
|
|
1461
1307
|
isNew,
|
|
1462
1308
|
session,
|
|
1463
1309
|
isSelected,
|
|
@@ -1468,22 +1314,22 @@ var SessionRow = memo7(function SessionRow2({
|
|
|
1468
1314
|
onHover,
|
|
1469
1315
|
onClick
|
|
1470
1316
|
}) {
|
|
1471
|
-
const rowRef =
|
|
1472
|
-
|
|
1317
|
+
const rowRef = useRef5(null);
|
|
1318
|
+
useOnMouseMove3(rowRef, () => {
|
|
1473
1319
|
onHover(index);
|
|
1474
1320
|
});
|
|
1475
|
-
|
|
1321
|
+
useOnClick3(rowRef, () => {
|
|
1476
1322
|
onClick(index);
|
|
1477
1323
|
});
|
|
1478
1324
|
if (isNew) {
|
|
1479
|
-
return /* @__PURE__ */
|
|
1480
|
-
|
|
1325
|
+
return /* @__PURE__ */ jsx6(
|
|
1326
|
+
Box6,
|
|
1481
1327
|
{
|
|
1482
1328
|
ref: rowRef,
|
|
1483
1329
|
backgroundColor: isSelected ? accent : void 0,
|
|
1484
1330
|
width: rowWidth,
|
|
1485
1331
|
paddingX: 1,
|
|
1486
|
-
children: /* @__PURE__ */
|
|
1332
|
+
children: /* @__PURE__ */ jsxs6(Text6, { color: isSelected ? "white" : "green", bold: isSelected, children: [
|
|
1487
1333
|
isSelected ? " > " : " ",
|
|
1488
1334
|
"+ New Chat"
|
|
1489
1335
|
] })
|
|
@@ -1492,19 +1338,19 @@ var SessionRow = memo7(function SessionRow2({
|
|
|
1492
1338
|
}
|
|
1493
1339
|
if (!session) return null;
|
|
1494
1340
|
const title = session.title.length > titleWidth ? `${session.title.slice(0, titleWidth - 3)}...` : session.title.padEnd(titleWidth);
|
|
1495
|
-
return /* @__PURE__ */
|
|
1496
|
-
|
|
1341
|
+
return /* @__PURE__ */ jsxs6(
|
|
1342
|
+
Box6,
|
|
1497
1343
|
{
|
|
1498
1344
|
ref: rowRef,
|
|
1499
1345
|
backgroundColor: isSelected ? accent : void 0,
|
|
1500
1346
|
width: rowWidth,
|
|
1501
1347
|
paddingX: 1,
|
|
1502
1348
|
children: [
|
|
1503
|
-
/* @__PURE__ */
|
|
1349
|
+
/* @__PURE__ */ jsxs6(Text6, { color: isSelected ? "white" : void 0, bold: isSelected, children: [
|
|
1504
1350
|
isSelected ? " > " : " ",
|
|
1505
1351
|
title
|
|
1506
1352
|
] }),
|
|
1507
|
-
/* @__PURE__ */
|
|
1353
|
+
/* @__PURE__ */ jsxs6(Text6, { color: isSelected ? "white" : void 0, dimColor: !isSelected, children: [
|
|
1508
1354
|
" ",
|
|
1509
1355
|
session.messageCount,
|
|
1510
1356
|
" msgs | ",
|
|
@@ -1518,8 +1364,8 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1518
1364
|
const { stdout } = useStdout2();
|
|
1519
1365
|
const width = stdout?.columns ?? 80;
|
|
1520
1366
|
const height = stdout?.rows ?? 24;
|
|
1521
|
-
const [sessions, setSessions] =
|
|
1522
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1367
|
+
const [sessions, setSessions] = useState4(() => listSessions());
|
|
1368
|
+
const [selectedIndex, setSelectedIndex] = useState4(0);
|
|
1523
1369
|
const totalItems = sessions.length + 1;
|
|
1524
1370
|
const handleSelect = (index) => {
|
|
1525
1371
|
if (index === 0) {
|
|
@@ -1537,7 +1383,7 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1537
1383
|
const handleClick = (index) => {
|
|
1538
1384
|
handleSelect(index);
|
|
1539
1385
|
};
|
|
1540
|
-
|
|
1386
|
+
useInput4((input, key) => {
|
|
1541
1387
|
if (key.escape) {
|
|
1542
1388
|
onClose();
|
|
1543
1389
|
return;
|
|
@@ -1579,8 +1425,8 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1579
1425
|
const theme = useTheme();
|
|
1580
1426
|
const rowWidth = Math.min(76, width - 6);
|
|
1581
1427
|
const titleWidth = Math.min(40, width - 30);
|
|
1582
|
-
return /* @__PURE__ */
|
|
1583
|
-
|
|
1428
|
+
return /* @__PURE__ */ jsx6(
|
|
1429
|
+
Box6,
|
|
1584
1430
|
{
|
|
1585
1431
|
flexDirection: "column",
|
|
1586
1432
|
width,
|
|
@@ -1588,25 +1434,25 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1588
1434
|
justifyContent: "center",
|
|
1589
1435
|
alignItems: "center",
|
|
1590
1436
|
backgroundColor: theme.background,
|
|
1591
|
-
children: /* @__PURE__ */
|
|
1592
|
-
|
|
1437
|
+
children: /* @__PURE__ */ jsxs6(
|
|
1438
|
+
Box6,
|
|
1593
1439
|
{
|
|
1594
1440
|
flexDirection: "column",
|
|
1595
1441
|
width: Math.min(80, width - 4),
|
|
1596
1442
|
borderStyle: "double",
|
|
1597
1443
|
borderColor: theme.accent,
|
|
1598
1444
|
children: [
|
|
1599
|
-
/* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1601
|
-
/* @__PURE__ */
|
|
1445
|
+
/* @__PURE__ */ jsxs6(Box6, { paddingX: 2, paddingY: 1, justifyContent: "space-between", children: [
|
|
1446
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.accent, children: "Chat Sessions" }),
|
|
1447
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Esc: close | Enter: select | Ctrl+D: delete" })
|
|
1602
1448
|
] }),
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ jsx6(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\u2500".repeat(Math.min(76, width - 8)) }) }),
|
|
1450
|
+
/* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
|
|
1605
1451
|
visibleItems.map((item, i) => {
|
|
1606
1452
|
const actualIndex = startIndex + i;
|
|
1607
1453
|
const isSelected = actualIndex === selectedIndex;
|
|
1608
1454
|
if (item.type === "new") {
|
|
1609
|
-
return /* @__PURE__ */
|
|
1455
|
+
return /* @__PURE__ */ jsx6(
|
|
1610
1456
|
SessionRow,
|
|
1611
1457
|
{
|
|
1612
1458
|
isNew: true,
|
|
@@ -1621,7 +1467,7 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1621
1467
|
"new-chat"
|
|
1622
1468
|
);
|
|
1623
1469
|
}
|
|
1624
|
-
return /* @__PURE__ */
|
|
1470
|
+
return /* @__PURE__ */ jsx6(
|
|
1625
1471
|
SessionRow,
|
|
1626
1472
|
{
|
|
1627
1473
|
session: item.session,
|
|
@@ -1636,9 +1482,9 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1636
1482
|
item.session.id
|
|
1637
1483
|
);
|
|
1638
1484
|
}),
|
|
1639
|
-
sessions.length === 0 && /* @__PURE__ */
|
|
1485
|
+
sessions.length === 0 && /* @__PURE__ */ jsx6(Box6, { paddingY: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "No previous sessions" }) })
|
|
1640
1486
|
] }),
|
|
1641
|
-
totalItems > visibleCount && /* @__PURE__ */
|
|
1487
|
+
totalItems > visibleCount && /* @__PURE__ */ jsx6(Box6, { paddingX: 2, paddingBottom: 1, children: /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1642
1488
|
"Showing ",
|
|
1643
1489
|
startIndex + 1,
|
|
1644
1490
|
"-",
|
|
@@ -1654,12 +1500,12 @@ function SessionPicker({ onSelect, onClose }) {
|
|
|
1654
1500
|
}
|
|
1655
1501
|
|
|
1656
1502
|
// src/chat/components/ThemePicker.tsx
|
|
1657
|
-
import { useOnClick as
|
|
1658
|
-
import { Box as
|
|
1659
|
-
import { memo as
|
|
1660
|
-
import { jsx as
|
|
1503
|
+
import { useOnClick as useOnClick4, useOnMouseMove as useOnMouseMove4, useOnWheel } from "@ink-tools/ink-mouse";
|
|
1504
|
+
import { Box as Box7, Text as Text7, useInput as useInput5, useStdout as useStdout3 } from "ink";
|
|
1505
|
+
import { memo as memo7, useRef as useRef6, useState as useState5 } from "react";
|
|
1506
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1661
1507
|
var MAX_VISIBLE_THEMES = 12;
|
|
1662
|
-
var ThemeRow =
|
|
1508
|
+
var ThemeRow = memo7(function ThemeRow2({
|
|
1663
1509
|
theme,
|
|
1664
1510
|
isSelected,
|
|
1665
1511
|
isCurrent,
|
|
@@ -1668,19 +1514,19 @@ var ThemeRow = memo8(function ThemeRow2({
|
|
|
1668
1514
|
onHover,
|
|
1669
1515
|
onClick
|
|
1670
1516
|
}) {
|
|
1671
|
-
const rowRef =
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
return /* @__PURE__ */
|
|
1675
|
-
|
|
1517
|
+
const rowRef = useRef6(null);
|
|
1518
|
+
useOnMouseMove4(rowRef, onHover);
|
|
1519
|
+
useOnClick4(rowRef, onClick);
|
|
1520
|
+
return /* @__PURE__ */ jsx7(
|
|
1521
|
+
Box7,
|
|
1676
1522
|
{
|
|
1677
1523
|
ref: rowRef,
|
|
1678
1524
|
backgroundColor: isSelected ? selectedTheme.accent : void 0,
|
|
1679
1525
|
width: rowWidth,
|
|
1680
1526
|
paddingX: 1,
|
|
1681
|
-
children: /* @__PURE__ */
|
|
1682
|
-
isCurrent && !isSelected && /* @__PURE__ */
|
|
1683
|
-
isCurrent && isSelected && /* @__PURE__ */
|
|
1527
|
+
children: /* @__PURE__ */ jsxs7(Text7, { color: isSelected ? "white" : void 0, bold: isSelected, children: [
|
|
1528
|
+
isCurrent && !isSelected && /* @__PURE__ */ jsx7(Text7, { color: selectedTheme.accent, children: "\u25CF " }),
|
|
1529
|
+
isCurrent && isSelected && /* @__PURE__ */ jsx7(Text7, { color: "white", children: "\u25CF " }),
|
|
1684
1530
|
!isCurrent && " ",
|
|
1685
1531
|
theme.displayName
|
|
1686
1532
|
] })
|
|
@@ -1695,9 +1541,9 @@ function ThemePicker({
|
|
|
1695
1541
|
const { stdout } = useStdout3();
|
|
1696
1542
|
const width = stdout?.columns ?? 80;
|
|
1697
1543
|
const height = stdout?.rows ?? 24;
|
|
1698
|
-
const listRef =
|
|
1544
|
+
const listRef = useRef6(null);
|
|
1699
1545
|
const currentIndex = THEMES.findIndex((t) => t.name === currentTheme);
|
|
1700
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1546
|
+
const [selectedIndex, setSelectedIndex] = useState5(
|
|
1701
1547
|
currentIndex >= 0 ? currentIndex : 0
|
|
1702
1548
|
);
|
|
1703
1549
|
const visibleCount = Math.min(MAX_VISIBLE_THEMES, height - 10);
|
|
@@ -1710,7 +1556,7 @@ function ThemePicker({
|
|
|
1710
1556
|
onSelect(selected.name);
|
|
1711
1557
|
}
|
|
1712
1558
|
};
|
|
1713
|
-
|
|
1559
|
+
useInput5((input, key) => {
|
|
1714
1560
|
if (key.escape) {
|
|
1715
1561
|
onClose();
|
|
1716
1562
|
return;
|
|
@@ -1735,7 +1581,7 @@ function ThemePicker({
|
|
|
1735
1581
|
setSelectedIndex((i) => Math.min(THEMES.length - 1, i + visibleCount));
|
|
1736
1582
|
}
|
|
1737
1583
|
});
|
|
1738
|
-
|
|
1584
|
+
useOnWheel(listRef, (event) => {
|
|
1739
1585
|
if (event.button === "wheel-up") {
|
|
1740
1586
|
setSelectedIndex((i) => Math.max(0, i - 1));
|
|
1741
1587
|
} else if (event.button === "wheel-down") {
|
|
@@ -1753,8 +1599,8 @@ function ThemePicker({
|
|
|
1753
1599
|
const visibleThemes = THEMES.slice(startIndex, startIndex + visibleCount);
|
|
1754
1600
|
const selectedTheme = THEMES[selectedIndex] ?? THEMES[0];
|
|
1755
1601
|
const rowWidth = Math.min(60, width - 8);
|
|
1756
|
-
return /* @__PURE__ */
|
|
1757
|
-
|
|
1602
|
+
return /* @__PURE__ */ jsx7(
|
|
1603
|
+
Box7,
|
|
1758
1604
|
{
|
|
1759
1605
|
flexDirection: "column",
|
|
1760
1606
|
width,
|
|
@@ -1762,22 +1608,22 @@ function ThemePicker({
|
|
|
1762
1608
|
justifyContent: "center",
|
|
1763
1609
|
alignItems: "center",
|
|
1764
1610
|
backgroundColor: selectedTheme.background,
|
|
1765
|
-
children: /* @__PURE__ */
|
|
1766
|
-
|
|
1611
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1612
|
+
Box7,
|
|
1767
1613
|
{
|
|
1768
1614
|
flexDirection: "column",
|
|
1769
1615
|
width: Math.min(64, width - 4),
|
|
1770
1616
|
borderStyle: "round",
|
|
1771
1617
|
borderColor: selectedTheme.accent,
|
|
1772
1618
|
children: [
|
|
1773
|
-
/* @__PURE__ */
|
|
1774
|
-
/* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
1619
|
+
/* @__PURE__ */ jsxs7(Box7, { paddingX: 2, paddingTop: 1, justifyContent: "space-between", children: [
|
|
1620
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, color: selectedTheme.textPrimary, children: "Themes" }),
|
|
1621
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "esc" })
|
|
1776
1622
|
] }),
|
|
1777
|
-
/* @__PURE__ */
|
|
1778
|
-
/* @__PURE__ */
|
|
1623
|
+
/* @__PURE__ */ jsx7(Box7, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\u2500".repeat(Math.min(60, width - 8)) }) }),
|
|
1624
|
+
/* @__PURE__ */ jsx7(Box7, { ref: listRef, flexDirection: "column", paddingY: 1, children: visibleThemes.map((theme, i) => {
|
|
1779
1625
|
const actualIndex = startIndex + i;
|
|
1780
|
-
return /* @__PURE__ */
|
|
1626
|
+
return /* @__PURE__ */ jsx7(
|
|
1781
1627
|
ThemeRow,
|
|
1782
1628
|
{
|
|
1783
1629
|
theme,
|
|
@@ -1791,9 +1637,9 @@ function ThemePicker({
|
|
|
1791
1637
|
theme.name
|
|
1792
1638
|
);
|
|
1793
1639
|
}) }),
|
|
1794
|
-
/* @__PURE__ */
|
|
1795
|
-
/* @__PURE__ */
|
|
1796
|
-
THEMES.length > visibleCount && /* @__PURE__ */
|
|
1640
|
+
/* @__PURE__ */ jsxs7(Box7, { paddingX: 2, paddingBottom: 1, justifyContent: "space-between", children: [
|
|
1641
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "j/k or arrows to navigate" }),
|
|
1642
|
+
THEMES.length > visibleCount && /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1797
1643
|
startIndex + 1,
|
|
1798
1644
|
"-",
|
|
1799
1645
|
Math.min(startIndex + visibleCount, THEMES.length),
|
|
@@ -1809,13 +1655,13 @@ function ThemePicker({
|
|
|
1809
1655
|
}
|
|
1810
1656
|
|
|
1811
1657
|
// src/chat/components/WelcomeScreen.tsx
|
|
1812
|
-
import { Box as
|
|
1813
|
-
import { memo as
|
|
1658
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
1659
|
+
import { memo as memo9 } from "react";
|
|
1814
1660
|
|
|
1815
1661
|
// src/chat/components/CatIcon.tsx
|
|
1816
|
-
import { Box as
|
|
1817
|
-
import { memo as
|
|
1818
|
-
import { jsx as
|
|
1662
|
+
import { Box as Box8, Text as Text8 } from "ink";
|
|
1663
|
+
import { memo as memo8, useMemo as useMemo4 } from "react";
|
|
1664
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1819
1665
|
var CAT_LINES = [
|
|
1820
1666
|
" \u2588\u2588 \u2588\u2588 ",
|
|
1821
1667
|
" \u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2588\u2591\u2591\u2588\u2588 ",
|
|
@@ -1826,7 +1672,7 @@ var CAT_LINES = [
|
|
|
1826
1672
|
" \u2588\u2588\u2591\u2592\u2592\u2592\u2592\u2592\u2592\u2591\u2588\u2588 ",
|
|
1827
1673
|
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "
|
|
1828
1674
|
];
|
|
1829
|
-
var CatIcon =
|
|
1675
|
+
var CatIcon = memo8(function CatIcon2() {
|
|
1830
1676
|
const theme = useTheme();
|
|
1831
1677
|
const colors = useMemo4(
|
|
1832
1678
|
() => ({
|
|
@@ -1837,23 +1683,23 @@ var CatIcon = memo9(function CatIcon2() {
|
|
|
1837
1683
|
}),
|
|
1838
1684
|
[theme.accent]
|
|
1839
1685
|
);
|
|
1840
|
-
return /* @__PURE__ */
|
|
1686
|
+
return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", alignItems: "center", children: CAT_LINES.map((line, i) => (
|
|
1841
1687
|
// biome-ignore lint/suspicious/noArrayIndexKey: Static ASCII art
|
|
1842
|
-
/* @__PURE__ */
|
|
1688
|
+
/* @__PURE__ */ jsx8(Text8, { children: line.split("").map((char, j) => {
|
|
1843
1689
|
const color = colors[char];
|
|
1844
1690
|
if (color) {
|
|
1845
1691
|
return (
|
|
1846
1692
|
// biome-ignore lint/suspicious/noArrayIndexKey: Static char
|
|
1847
|
-
/* @__PURE__ */
|
|
1693
|
+
/* @__PURE__ */ jsx8(Text8, { color, children: "\u2588" }, `char-${i}-${j}`)
|
|
1848
1694
|
);
|
|
1849
1695
|
}
|
|
1850
|
-
return /* @__PURE__ */
|
|
1696
|
+
return /* @__PURE__ */ jsx8(Text8, { children: " " }, `char-${i}-${j}`);
|
|
1851
1697
|
}) }, `line-${i}`)
|
|
1852
1698
|
)) });
|
|
1853
1699
|
});
|
|
1854
1700
|
|
|
1855
1701
|
// src/chat/components/WelcomeScreen.tsx
|
|
1856
|
-
import { jsx as
|
|
1702
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1857
1703
|
var BASHIO_ASCII = `
|
|
1858
1704
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
1859
1705
|
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557
|
|
@@ -1862,15 +1708,15 @@ var BASHIO_ASCII = `
|
|
|
1862
1708
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
1863
1709
|
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1864
1710
|
`.trim();
|
|
1865
|
-
var WelcomeScreen =
|
|
1711
|
+
var WelcomeScreen = memo9(function WelcomeScreen2({
|
|
1866
1712
|
width,
|
|
1867
1713
|
height,
|
|
1868
1714
|
children
|
|
1869
1715
|
}) {
|
|
1870
1716
|
const lines = BASHIO_ASCII.split("\n");
|
|
1871
1717
|
const theme = useTheme();
|
|
1872
|
-
return /* @__PURE__ */
|
|
1873
|
-
|
|
1718
|
+
return /* @__PURE__ */ jsx9(
|
|
1719
|
+
Box9,
|
|
1874
1720
|
{
|
|
1875
1721
|
flexDirection: "column",
|
|
1876
1722
|
width,
|
|
@@ -1878,20 +1724,20 @@ var WelcomeScreen = memo10(function WelcomeScreen2({
|
|
|
1878
1724
|
justifyContent: "center",
|
|
1879
1725
|
alignItems: "center",
|
|
1880
1726
|
backgroundColor: theme.background,
|
|
1881
|
-
children: /* @__PURE__ */
|
|
1882
|
-
|
|
1727
|
+
children: /* @__PURE__ */ jsxs8(
|
|
1728
|
+
Box9,
|
|
1883
1729
|
{
|
|
1884
1730
|
flexDirection: "column",
|
|
1885
1731
|
alignItems: "center",
|
|
1886
1732
|
backgroundColor: theme.background,
|
|
1887
1733
|
children: [
|
|
1888
|
-
/* @__PURE__ */
|
|
1889
|
-
/* @__PURE__ */
|
|
1734
|
+
/* @__PURE__ */ jsx9(CatIcon, {}),
|
|
1735
|
+
/* @__PURE__ */ jsx9(Box9, { paddingTop: 1, backgroundColor: theme.background }),
|
|
1890
1736
|
lines.map((line, i) => (
|
|
1891
1737
|
// biome-ignore lint/suspicious/noArrayIndexKey: Static ASCII art lines
|
|
1892
|
-
/* @__PURE__ */
|
|
1738
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.textPrimary, bold: true, children: line }, `ascii-${i}`)
|
|
1893
1739
|
)),
|
|
1894
|
-
children && /* @__PURE__ */
|
|
1740
|
+
children && /* @__PURE__ */ jsx9(Box9, { paddingTop: 2, backgroundColor: theme.background, children })
|
|
1895
1741
|
]
|
|
1896
1742
|
}
|
|
1897
1743
|
)
|
|
@@ -1953,18 +1799,18 @@ function createSyncOutputStream(stdout) {
|
|
|
1953
1799
|
}
|
|
1954
1800
|
|
|
1955
1801
|
// src/chat/App.tsx
|
|
1956
|
-
import { jsx as
|
|
1802
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1957
1803
|
function ChatApp() {
|
|
1958
1804
|
const { exit } = useApp();
|
|
1959
1805
|
const { stdout } = useStdout4();
|
|
1960
|
-
const [height, setHeight] =
|
|
1961
|
-
const [width, setWidth] =
|
|
1962
|
-
const messageListRef =
|
|
1963
|
-
const slashModeRef =
|
|
1964
|
-
const [config, setConfig] =
|
|
1965
|
-
const [provider, setProvider] =
|
|
1966
|
-
const [currentSession, setCurrentSession] =
|
|
1967
|
-
const [state, setState] =
|
|
1806
|
+
const [height, setHeight] = useState6(stdout?.rows ?? 24);
|
|
1807
|
+
const [width, setWidth] = useState6(stdout?.columns ?? 80);
|
|
1808
|
+
const messageListRef = useRef7(null);
|
|
1809
|
+
const slashModeRef = useRef7(false);
|
|
1810
|
+
const [config, setConfig] = useState6(null);
|
|
1811
|
+
const [provider, setProvider] = useState6(null);
|
|
1812
|
+
const [currentSession, setCurrentSession] = useState6(null);
|
|
1813
|
+
const [state, setState] = useState6({
|
|
1968
1814
|
messages: [],
|
|
1969
1815
|
isLoading: false,
|
|
1970
1816
|
currentResponse: "",
|
|
@@ -2017,8 +1863,8 @@ function ChatApp() {
|
|
|
2017
1863
|
if (key.ctrl && input === "c") {
|
|
2018
1864
|
exit();
|
|
2019
1865
|
}
|
|
2020
|
-
if (!slashModeRef.current && noPickerOpen) {
|
|
2021
|
-
if (key.ctrl && input === "
|
|
1866
|
+
if (!slashModeRef.current && noPickerOpen && !state.isLoading) {
|
|
1867
|
+
if (key.ctrl && input === "p") {
|
|
2022
1868
|
setState((s) => ({ ...s, showModelSwitcher: true }));
|
|
2023
1869
|
}
|
|
2024
1870
|
if (key.ctrl && input === "o") {
|
|
@@ -2027,6 +1873,31 @@ function ChatApp() {
|
|
|
2027
1873
|
if (key.ctrl && input === "t") {
|
|
2028
1874
|
setState((s) => ({ ...s, showThemePicker: true }));
|
|
2029
1875
|
}
|
|
1876
|
+
if (key.ctrl && input === "n") {
|
|
1877
|
+
if (config) {
|
|
1878
|
+
const activeProvider2 = config.activeProvider;
|
|
1879
|
+
const model = config.providers[activeProvider2]?.model ?? "unknown";
|
|
1880
|
+
const session = createSession(model, activeProvider2);
|
|
1881
|
+
setCurrentSession(session);
|
|
1882
|
+
setState((s) => ({
|
|
1883
|
+
...s,
|
|
1884
|
+
messages: [],
|
|
1885
|
+
error: null
|
|
1886
|
+
}));
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
if (key.ctrl && input === "l") {
|
|
1890
|
+
setState((s) => ({ ...s, messages: [], error: null }));
|
|
1891
|
+
if (currentSession) {
|
|
1892
|
+
const clearedSession = {
|
|
1893
|
+
...currentSession,
|
|
1894
|
+
messages: [],
|
|
1895
|
+
messageCount: 0
|
|
1896
|
+
};
|
|
1897
|
+
saveSession(clearedSession);
|
|
1898
|
+
setCurrentSession(clearedSession);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
2030
1901
|
}
|
|
2031
1902
|
if (key.escape) {
|
|
2032
1903
|
if (state.showModelSwitcher) {
|
|
@@ -2045,10 +1916,13 @@ function ChatApp() {
|
|
|
2045
1916
|
noPickerOpen,
|
|
2046
1917
|
state.showModelSwitcher,
|
|
2047
1918
|
state.showSessionPicker,
|
|
2048
|
-
state.showThemePicker
|
|
1919
|
+
state.showThemePicker,
|
|
1920
|
+
state.isLoading,
|
|
1921
|
+
config,
|
|
1922
|
+
currentSession
|
|
2049
1923
|
]
|
|
2050
1924
|
);
|
|
2051
|
-
|
|
1925
|
+
useInput6(handleGlobalInput);
|
|
2052
1926
|
const handleSubmit = useCallback2(
|
|
2053
1927
|
async (message) => {
|
|
2054
1928
|
if (!provider || !message.trim()) return;
|
|
@@ -2229,19 +2103,19 @@ function ChatApp() {
|
|
|
2229
2103
|
[currentThemeName]
|
|
2230
2104
|
);
|
|
2231
2105
|
if (!config || !provider) {
|
|
2232
|
-
return /* @__PURE__ */
|
|
2233
|
-
|
|
2106
|
+
return /* @__PURE__ */ jsx10(
|
|
2107
|
+
Box10,
|
|
2234
2108
|
{
|
|
2235
2109
|
width,
|
|
2236
2110
|
height,
|
|
2237
2111
|
justifyContent: "center",
|
|
2238
2112
|
alignItems: "center",
|
|
2239
|
-
children: /* @__PURE__ */
|
|
2113
|
+
children: /* @__PURE__ */ jsx10(Text10, { children: "Loading..." })
|
|
2240
2114
|
}
|
|
2241
2115
|
);
|
|
2242
2116
|
}
|
|
2243
2117
|
if (state.showThemePicker) {
|
|
2244
|
-
return /* @__PURE__ */
|
|
2118
|
+
return /* @__PURE__ */ jsx10(
|
|
2245
2119
|
ThemePicker,
|
|
2246
2120
|
{
|
|
2247
2121
|
currentTheme: currentThemeName,
|
|
@@ -2251,7 +2125,7 @@ function ChatApp() {
|
|
|
2251
2125
|
);
|
|
2252
2126
|
}
|
|
2253
2127
|
if (state.showSessionPicker) {
|
|
2254
|
-
return /* @__PURE__ */
|
|
2128
|
+
return /* @__PURE__ */ jsx10(ThemeProvider, { value: theme, children: /* @__PURE__ */ jsx10(
|
|
2255
2129
|
SessionPicker,
|
|
2256
2130
|
{
|
|
2257
2131
|
onSelect: handleSessionSelect,
|
|
@@ -2260,7 +2134,7 @@ function ChatApp() {
|
|
|
2260
2134
|
) });
|
|
2261
2135
|
}
|
|
2262
2136
|
if (state.showModelSwitcher) {
|
|
2263
|
-
return /* @__PURE__ */
|
|
2137
|
+
return /* @__PURE__ */ jsx10(ThemeProvider, { value: theme, children: /* @__PURE__ */ jsx10(
|
|
2264
2138
|
ModelSwitcher,
|
|
2265
2139
|
{
|
|
2266
2140
|
config,
|
|
@@ -2273,14 +2147,14 @@ function ChatApp() {
|
|
|
2273
2147
|
const currentModel = config.providers[activeProvider]?.model ?? "unknown";
|
|
2274
2148
|
const isEmptyChat = state.messages.length === 0 && !state.currentResponse;
|
|
2275
2149
|
if (isEmptyChat) {
|
|
2276
|
-
return /* @__PURE__ */
|
|
2277
|
-
|
|
2150
|
+
return /* @__PURE__ */ jsx10(ThemeProvider, { value: theme, children: /* @__PURE__ */ jsx10(
|
|
2151
|
+
Box10,
|
|
2278
2152
|
{
|
|
2279
2153
|
flexDirection: "column",
|
|
2280
2154
|
width,
|
|
2281
2155
|
height,
|
|
2282
2156
|
backgroundColor: theme.background,
|
|
2283
|
-
children: /* @__PURE__ */
|
|
2157
|
+
children: /* @__PURE__ */ jsx10(WelcomeScreen, { width, height, children: /* @__PURE__ */ jsx10(
|
|
2284
2158
|
InputBox,
|
|
2285
2159
|
{
|
|
2286
2160
|
onSubmit: handleSubmit,
|
|
@@ -2301,22 +2175,22 @@ function ChatApp() {
|
|
|
2301
2175
|
5,
|
|
2302
2176
|
height - inputBoxHeight - sessionHeaderHeight - 2
|
|
2303
2177
|
);
|
|
2304
|
-
return /* @__PURE__ */
|
|
2305
|
-
|
|
2178
|
+
return /* @__PURE__ */ jsx10(ThemeProvider, { value: theme, children: /* @__PURE__ */ jsxs9(
|
|
2179
|
+
Box10,
|
|
2306
2180
|
{
|
|
2307
2181
|
flexDirection: "column",
|
|
2308
2182
|
width,
|
|
2309
2183
|
height,
|
|
2310
2184
|
backgroundColor: theme.background,
|
|
2311
2185
|
children: [
|
|
2312
|
-
/* @__PURE__ */
|
|
2186
|
+
/* @__PURE__ */ jsx10(Box10, { paddingX: 1, marginTop: 1, children: /* @__PURE__ */ jsx10(
|
|
2313
2187
|
SessionHeader,
|
|
2314
2188
|
{
|
|
2315
2189
|
sessionTitle: currentSession?.title ?? "New Chat",
|
|
2316
2190
|
width: width - 2
|
|
2317
2191
|
}
|
|
2318
2192
|
) }),
|
|
2319
|
-
/* @__PURE__ */
|
|
2193
|
+
/* @__PURE__ */ jsx10(Box10, { flexDirection: "column", height: messageListHeight, children: /* @__PURE__ */ jsx10(
|
|
2320
2194
|
MessageList,
|
|
2321
2195
|
{
|
|
2322
2196
|
ref: messageListRef,
|
|
@@ -2328,11 +2202,11 @@ function ChatApp() {
|
|
|
2328
2202
|
slashModeRef
|
|
2329
2203
|
}
|
|
2330
2204
|
) }),
|
|
2331
|
-
state.error && /* @__PURE__ */
|
|
2205
|
+
state.error && /* @__PURE__ */ jsx10(Box10, { paddingX: 1, children: /* @__PURE__ */ jsxs9(Text10, { color: "red", children: [
|
|
2332
2206
|
"Error: ",
|
|
2333
2207
|
state.error
|
|
2334
2208
|
] }) }),
|
|
2335
|
-
/* @__PURE__ */
|
|
2209
|
+
/* @__PURE__ */ jsx10(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx10(
|
|
2336
2210
|
InputBox,
|
|
2337
2211
|
{
|
|
2338
2212
|
onSubmit: handleSubmit,
|
|
@@ -2360,7 +2234,7 @@ async function runChat() {
|
|
|
2360
2234
|
process.stdout.write("\x1B[?25l");
|
|
2361
2235
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
2362
2236
|
const instance = render(
|
|
2363
|
-
/* @__PURE__ */
|
|
2237
|
+
/* @__PURE__ */ jsx10(MouseProvider, { autoEnable: false, children: /* @__PURE__ */ jsx10(ChatApp, {}) }),
|
|
2364
2238
|
{
|
|
2365
2239
|
exitOnCtrlC: false,
|
|
2366
2240
|
stdout: syncOutput
|
|
@@ -2375,4 +2249,4 @@ async function runChat() {
|
|
|
2375
2249
|
export {
|
|
2376
2250
|
runChat
|
|
2377
2251
|
};
|
|
2378
|
-
//# sourceMappingURL=App-
|
|
2252
|
+
//# sourceMappingURL=App-MVOM7NMT.js.map
|