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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bashio",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"pnpm": {
|
|
5
5
|
"onlyBuiltDependencies": [
|
|
6
6
|
"better-sqlite3"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"bugs": {
|
|
45
45
|
"url": "https://github.com/VrandaaGarg/bashio/issues"
|
|
46
46
|
},
|
|
47
|
-
"license": "
|
|
47
|
+
"license": "Apache-2.0",
|
|
48
48
|
"packageManager": "pnpm@10.17.1",
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=20.12.0"
|
package/dist/App-SRRDMIMW.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chat/App.tsx","../src/chat/components/InputBox.tsx","../src/chat/utils/slashCommands.ts","../src/chat/utils/ThemeContext.tsx","../src/chat/components/SlashCommandMenu.tsx","../src/chat/components/MessageList.tsx","../src/chat/components/MessageContextMenu.tsx","../src/chat/components/ModelSwitcher.tsx","../src/chat/components/SessionHeader.tsx","../src/chat/components/SessionPicker.tsx","../src/chat/utils/sessions.ts","../src/chat/components/ThemePicker.tsx","../src/chat/components/WelcomeScreen.tsx","../src/chat/components/CatIcon.tsx","../src/chat/utils/syncOutput.ts"],"sourcesContent":["import { MouseProvider } from '@ink-tools/ink-mouse';\nimport { Box, render, Text, useApp, useInput, useStdout } from 'ink';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { runAuthSetup } from '../core/auth.js';\nimport { configExists, loadConfig, saveConfig } from '../core/config.js';\nimport type { ConfigV2, ProviderName } from '../core/types.js';\nimport type { AIProvider, ChatMessage } from '../providers/base.js';\nimport { createProvider } from '../providers/index.js';\nimport { InputBox } from './components/InputBox.js';\nimport {\n MessageList,\n type MessageListHandle,\n} from './components/MessageList.js';\nimport { ModelSwitcher } from './components/ModelSwitcher.js';\nimport { SessionHeader } from './components/SessionHeader.js';\nimport { SessionPicker } from './components/SessionPicker.js';\nimport { ThemePicker } from './components/ThemePicker.js';\nimport { WelcomeScreen } from './components/WelcomeScreen.js';\nimport {\n createSession,\n loadSession,\n type Session,\n saveSession,\n} from './utils/sessions.js';\nimport type { SlashCommandAction } from './utils/slashCommands.js';\nimport { createSyncOutputStream } from './utils/syncOutput.js';\nimport { ThemeProvider } from './utils/ThemeContext.js';\nimport { getThemeByName } from './utils/themes.js';\n\nexport type { ChatMessage };\n\ninterface AppState {\n messages: ChatMessage[];\n isLoading: boolean;\n currentResponse: string;\n showModelSwitcher: boolean;\n showSessionPicker: boolean;\n showThemePicker: boolean;\n error: string | null;\n}\n\nfunction ChatApp() {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const [height, setHeight] = useState(stdout?.rows ?? 24);\n const [width, setWidth] = useState(stdout?.columns ?? 80);\n const messageListRef = useRef<MessageListHandle>(null);\n const slashModeRef = useRef(false);\n\n const [config, setConfig] = useState<ConfigV2 | null>(null);\n const [provider, setProvider] = useState<AIProvider | null>(null);\n const [currentSession, setCurrentSession] = useState<Session | null>(null);\n const [state, setState] = useState<AppState>({\n messages: [],\n isLoading: false,\n currentResponse: '',\n showModelSwitcher: false,\n showSessionPicker: false,\n showThemePicker: false,\n error: null,\n });\n\n useEffect(() => {\n const handleResize = () => {\n if (stdout) {\n setHeight(stdout.rows);\n setWidth(stdout.columns);\n }\n };\n stdout?.on('resize', handleResize);\n return () => {\n stdout?.off('resize', handleResize);\n };\n }, [stdout]);\n\n useEffect(() => {\n // Auth is already checked in runChat() before entering alternate screen\n // So config should always exist at this point\n const loadedConfig = loadConfig();\n if (loadedConfig) {\n setConfig(loadedConfig);\n setProvider(createProvider(loadedConfig));\n\n const activeProvider = loadedConfig.activeProvider;\n const model = loadedConfig.providers[activeProvider]?.model ?? 'unknown';\n const session = createSession(model, activeProvider);\n setCurrentSession(session);\n } else {\n // This shouldn't happen, but handle gracefully\n exit();\n }\n }, [exit]);\n\n const messagesLength = state.messages.length;\n const isLoading = state.isLoading;\n // biome-ignore lint/correctness/useExhaustiveDependencies: save only when message count changes\n useEffect(() => {\n if (currentSession && messagesLength > 0 && !isLoading) {\n const updatedSession: Session = {\n ...currentSession,\n messages: state.messages,\n messageCount: messagesLength,\n };\n saveSession(updatedSession);\n setCurrentSession(updatedSession);\n }\n }, [messagesLength, isLoading]);\n\n const noPickerOpen =\n !state.showModelSwitcher &&\n !state.showSessionPicker &&\n !state.showThemePicker;\n\n const handleGlobalInput = useCallback(\n (input: string, key: { ctrl: boolean; escape: boolean }) => {\n if (key.ctrl && input === 'c') {\n exit();\n }\n if (!slashModeRef.current && noPickerOpen) {\n if ((key.ctrl && input === 'm') || (key.ctrl && input === 'p')) {\n setState((s) => ({ ...s, showModelSwitcher: true }));\n }\n if (key.ctrl && input === 'o') {\n setState((s) => ({ ...s, showSessionPicker: true }));\n }\n if (key.ctrl && input === 't') {\n setState((s) => ({ ...s, showThemePicker: true }));\n }\n }\n if (key.escape) {\n if (state.showModelSwitcher) {\n setState((s) => ({ ...s, showModelSwitcher: false }));\n }\n if (state.showSessionPicker) {\n setState((s) => ({ ...s, showSessionPicker: false }));\n }\n if (state.showThemePicker) {\n setState((s) => ({ ...s, showThemePicker: false }));\n }\n }\n },\n [\n exit,\n noPickerOpen,\n state.showModelSwitcher,\n state.showSessionPicker,\n state.showThemePicker,\n ],\n );\n\n useInput(handleGlobalInput);\n\n const handleSubmit = useCallback(\n async (message: string) => {\n if (!provider || !message.trim()) return;\n\n const userMessage: ChatMessage = {\n role: 'user',\n content: message.trim(),\n };\n\n // Get current messages and add user message\n let messagesWithUser: ChatMessage[] = [];\n setState((s) => {\n if (s.isLoading) return s;\n messagesWithUser = [...s.messages, userMessage];\n return {\n ...s,\n messages: messagesWithUser,\n isLoading: true,\n currentResponse: '',\n error: null,\n };\n });\n\n // If already loading, messagesWithUser will be empty, so return\n if (messagesWithUser.length === 0) return;\n\n try {\n if (provider.streamChat) {\n await provider.streamChat(messagesWithUser, (chunk: string) => {\n setState((s) => ({\n ...s,\n currentResponse: s.currentResponse + chunk,\n }));\n });\n setState((s) => ({\n ...s,\n messages: [\n ...s.messages,\n { role: 'assistant', content: s.currentResponse },\n ],\n isLoading: false,\n currentResponse: '',\n }));\n } else {\n setState((s) => ({\n ...s,\n messages: [\n ...s.messages,\n {\n role: 'assistant',\n content: 'Streaming not supported for this provider.',\n },\n ],\n isLoading: false,\n }));\n }\n } catch (err) {\n setState((s) => ({\n ...s,\n isLoading: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n }));\n }\n },\n [provider],\n );\n\n const handleModelSelect = useCallback(\n (providerName: ProviderName, model: string) => {\n if (!config) return;\n const newConfig = { ...config, activeProvider: providerName };\n const providerSettings = newConfig.providers[providerName];\n if (providerSettings) {\n providerSettings.model = model;\n }\n setConfig(newConfig);\n setProvider(createProvider(newConfig));\n setState((s) => ({ ...s, showModelSwitcher: false }));\n\n if (currentSession) {\n setCurrentSession({\n ...currentSession,\n model,\n provider: providerName,\n });\n }\n },\n [config, currentSession],\n );\n\n const handleModelSwitcherClose = useCallback(() => {\n setState((s) => ({ ...s, showModelSwitcher: false }));\n }, []);\n\n const handleSessionSelect = useCallback(\n (sessionId: string | null) => {\n if (!config) return;\n\n if (sessionId === null) {\n const activeProvider = config.activeProvider;\n const model = config.providers[activeProvider]?.model ?? 'unknown';\n const session = createSession(model, activeProvider);\n setCurrentSession(session);\n setState((s) => ({\n ...s,\n messages: [],\n showSessionPicker: false,\n error: null,\n }));\n } else {\n const session = loadSession(sessionId);\n if (session) {\n setCurrentSession(session);\n setState((s) => ({\n ...s,\n messages: session.messages,\n showSessionPicker: false,\n error: null,\n }));\n }\n }\n },\n [config],\n );\n\n const handleSessionPickerClose = useCallback(() => {\n setState((s) => ({ ...s, showSessionPicker: false }));\n }, []);\n\n const handleThemeSelect = useCallback(\n (themeName: string) => {\n if (!config) return;\n const cs = config.settings;\n const newConfig: ConfigV2 = {\n ...config,\n settings: {\n confirmBeforeExecute: cs?.confirmBeforeExecute ?? true,\n historyEnabled: cs?.historyEnabled ?? true,\n historyRetentionDays: cs?.historyRetentionDays ?? 30,\n historyMaxEntries: cs?.historyMaxEntries ?? 2000,\n autoConfirmShortcuts: cs?.autoConfirmShortcuts ?? false,\n theme: themeName,\n },\n };\n setConfig(newConfig);\n saveConfig(newConfig);\n setState((s) => ({ ...s, showThemePicker: false }));\n },\n [config],\n );\n\n const handleThemePickerClose = useCallback(() => {\n setState((s) => ({ ...s, showThemePicker: false }));\n }, []);\n\n const handleSlashCommand = useCallback(\n (action: SlashCommandAction) => {\n switch (action) {\n case 'openModelSwitcher':\n setState((s) => ({ ...s, showModelSwitcher: true }));\n break;\n case 'openSessionPicker':\n setState((s) => ({ ...s, showSessionPicker: true }));\n break;\n case 'openThemePicker':\n setState((s) => ({ ...s, showThemePicker: true }));\n break;\n case 'newSession':\n handleSessionSelect(null);\n break;\n case 'clearChat':\n setState((s) => ({ ...s, messages: [], error: null }));\n if (currentSession) {\n const clearedSession: Session = {\n ...currentSession,\n messages: [],\n messageCount: 0,\n };\n saveSession(clearedSession);\n setCurrentSession(clearedSession);\n }\n break;\n case 'exitChat':\n exit();\n break;\n }\n },\n [handleSessionSelect, currentSession, exit],\n );\n\n const currentThemeName = config?.settings?.theme ?? 'bashio';\n const theme = useMemo(\n () => getThemeByName(currentThemeName),\n [currentThemeName],\n );\n\n if (!config || !provider) {\n return (\n <Box\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Text>Loading...</Text>\n </Box>\n );\n }\n\n if (state.showThemePicker) {\n return (\n <ThemePicker\n currentTheme={currentThemeName}\n onSelect={handleThemeSelect}\n onClose={handleThemePickerClose}\n />\n );\n }\n\n if (state.showSessionPicker) {\n return (\n <ThemeProvider value={theme}>\n <SessionPicker\n onSelect={handleSessionSelect}\n onClose={handleSessionPickerClose}\n />\n </ThemeProvider>\n );\n }\n\n if (state.showModelSwitcher) {\n return (\n <ThemeProvider value={theme}>\n <ModelSwitcher\n config={config}\n onSelect={handleModelSelect}\n onClose={handleModelSwitcherClose}\n />\n </ThemeProvider>\n );\n }\n\n const activeProvider = config.activeProvider;\n const currentModel = config.providers[activeProvider]?.model ?? 'unknown';\n const isEmptyChat = state.messages.length === 0 && !state.currentResponse;\n\n // Welcome screen layout (centered)\n if (isEmptyChat) {\n return (\n <ThemeProvider value={theme}>\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n backgroundColor={theme.background}\n >\n <WelcomeScreen width={width} height={height}>\n <InputBox\n onSubmit={handleSubmit}\n onSlashCommand={handleSlashCommand}\n slashModeRef={slashModeRef}\n modelName={currentModel}\n disabled={state.isLoading}\n width={Math.min(width - 4, 80)}\n placeholder=\"Ask anything...\"\n />\n </WelcomeScreen>\n </Box>\n </ThemeProvider>\n );\n }\n\n // Chat view layout (with messages)\n const inputBoxHeight = 6; // Input box + footer + margins\n const sessionHeaderHeight = 4; // Header with paddingY + margins\n const messageListHeight = Math.max(\n 5,\n height - inputBoxHeight - sessionHeaderHeight - 2,\n );\n\n return (\n <ThemeProvider value={theme}>\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n backgroundColor={theme.background}\n >\n {/* Session Header */}\n <Box paddingX={1} marginTop={1}>\n <SessionHeader\n sessionTitle={currentSession?.title ?? 'New Chat'}\n width={width - 2}\n />\n </Box>\n\n {/* Message List */}\n <Box flexDirection=\"column\" height={messageListHeight}>\n <MessageList\n ref={messageListRef}\n messages={state.messages}\n currentResponse={state.currentResponse}\n isLoading={state.isLoading}\n height={messageListHeight}\n width={width - 2}\n slashModeRef={slashModeRef}\n />\n </Box>\n\n {/* Error display */}\n {state.error && (\n <Box paddingX={1}>\n <Text color=\"red\">Error: {state.error}</Text>\n </Box>\n )}\n\n {/* Input Box */}\n <Box paddingX={1}>\n <InputBox\n onSubmit={handleSubmit}\n onSlashCommand={handleSlashCommand}\n slashModeRef={slashModeRef}\n modelName={currentModel}\n disabled={state.isLoading}\n width={width - 2}\n />\n </Box>\n </Box>\n </ThemeProvider>\n );\n}\n\nexport async function runChat(): Promise<number> {\n // Check auth BEFORE entering alternate screen buffer\n // This allows the welcome banner and auth prompts to display properly\n if (!configExists()) {\n const success = await runAuthSetup();\n if (!success) {\n return 1;\n }\n console.log(); // Add spacing before entering chat\n }\n\n const syncOutput = createSyncOutputStream(process.stdout);\n\n // Now enter alternate screen buffer for the chat UI\n process.stdout.write('\\x1b[?1049h');\n process.stdout.write('\\x1b[?25l');\n process.stdout.write('\\x1b[2J\\x1b[H');\n\n const instance = render(\n <MouseProvider>\n <ChatApp />\n </MouseProvider>,\n {\n exitOnCtrlC: false,\n stdout: syncOutput,\n },\n );\n\n await instance.waitUntilExit();\n\n syncOutput._flushSyncOutput?.();\n\n process.stdout.write('\\x1b[?25h');\n process.stdout.write('\\x1b[?1049l');\n\n return 0;\n}\n","import { Box, Text, useInput } from 'ink';\nimport type React from 'react';\nimport { memo, useMemo, useRef, useState } from 'react';\nimport {\n filterCommands,\n type SlashCommandAction,\n} from '../utils/slashCommands.js';\nimport { useTheme } from '../utils/ThemeContext.js';\nimport { SlashCommandMenu } from './SlashCommandMenu.js';\n\ninterface InputBoxProps {\n onSubmit: (value: string) => void;\n onSlashCommand: (action: SlashCommandAction) => void;\n slashModeRef: React.MutableRefObject<boolean>;\n modelName: string;\n disabled?: boolean;\n width?: number;\n placeholder?: string;\n}\n\nexport const InputBox = memo(function InputBox({\n onSubmit,\n onSlashCommand,\n slashModeRef,\n modelName,\n disabled = false,\n width = 50,\n placeholder = 'Ask anything...',\n}: InputBoxProps) {\n const [value, setValue] = useState('');\n const [cursorPos, setCursorPos] = useState(0);\n const [menuIndex, setMenuIndex] = useState(0);\n\n const isSlashMode = value.startsWith('/') && !value.includes('\\n');\n const filteredCommands = useMemo(\n () => (isSlashMode ? filterCommands(value) : []),\n [isSlashMode, value],\n );\n\n const prevSlashMode = useRef(false);\n if (prevSlashMode.current !== isSlashMode) {\n prevSlashMode.current = isSlashMode;\n slashModeRef.current = isSlashMode;\n }\n\n useInput(\n (input, key) => {\n if (disabled) return;\n\n const normalizedInput = input\n .replaceAll('\\u001b[200~', '')\n .replaceAll('\\u001b[201~', '')\n .replaceAll('\\r', '');\n\n if (isSlashMode && filteredCommands.length > 0) {\n if (key.upArrow) {\n setMenuIndex((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setMenuIndex((i) => Math.min(filteredCommands.length - 1, i + 1));\n return;\n }\n if (key.tab) {\n const selected = filteredCommands[menuIndex];\n if (selected) {\n setValue(`/${selected.name}`);\n setCursorPos(selected.name.length + 1);\n }\n return;\n }\n if (key.return && !key.shift) {\n const selected = filteredCommands[menuIndex];\n if (selected) {\n onSlashCommand(selected.action);\n setValue('');\n setCursorPos(0);\n setMenuIndex(0);\n }\n return;\n }\n }\n\n if (key.return && !key.shift) {\n if (value.trim()) {\n onSubmit(value);\n setValue('');\n setCursorPos(0);\n setMenuIndex(0);\n }\n return;\n }\n\n if (key.escape && isSlashMode) {\n setValue('');\n setCursorPos(0);\n setMenuIndex(0);\n return;\n }\n\n if ((key.return && key.shift) || (key.ctrl && input === 'j')) {\n setValue((v) => `${v.slice(0, cursorPos)}\\n${v.slice(cursorPos)}`);\n setCursorPos((p) => p + 1);\n return;\n }\n\n const isControlSequence =\n normalizedInput.length > 1 &&\n (/^\\[<?\\d+;/.test(normalizedInput) ||\n /^\\[[0-9;]*[A-Za-z~]$/.test(normalizedInput));\n\n if (isControlSequence) {\n return;\n }\n\n if (\n normalizedInput.length > 1 &&\n !key.ctrl &&\n !key.meta &&\n !normalizedInput.includes('\\u001b')\n ) {\n setValue(\n (v) => v.slice(0, cursorPos) + normalizedInput + v.slice(cursorPos),\n );\n setCursorPos((p) => p + normalizedInput.length);\n setMenuIndex(0);\n return;\n }\n\n if (key.backspace || key.delete) {\n if (cursorPos > 0) {\n setValue((v) => v.slice(0, cursorPos - 1) + v.slice(cursorPos));\n setCursorPos((p) => p - 1);\n setMenuIndex(0);\n }\n return;\n }\n\n if (key.leftArrow) {\n if (key.ctrl) {\n const before = value.slice(0, cursorPos);\n const match = before.match(/\\S+\\s*$/);\n setCursorPos((p) => (match ? p - match[0].length : 0));\n } else {\n setCursorPos((p) => Math.max(0, p - 1));\n }\n return;\n }\n\n if (key.rightArrow) {\n if (key.ctrl) {\n const after = value.slice(cursorPos);\n const match = after.match(/^\\s*\\S+/);\n setCursorPos((p) => (match ? p + match[0].length : value.length));\n } else {\n setCursorPos((p) => Math.min(value.length, p + 1));\n }\n return;\n }\n\n if (key.ctrl && input === 'a') {\n setCursorPos(0);\n return;\n }\n\n if (key.ctrl && input === 'e') {\n setCursorPos(value.length);\n return;\n }\n\n if (key.ctrl && input === 'u') {\n setValue('');\n setCursorPos(0);\n setMenuIndex(0);\n return;\n }\n\n if (\n normalizedInput &&\n !key.ctrl &&\n !key.meta &&\n normalizedInput.length === 1\n ) {\n const charCode = normalizedInput.charCodeAt(0);\n if (charCode >= 32) {\n setValue(\n (v) => v.slice(0, cursorPos) + normalizedInput + v.slice(cursorPos),\n );\n setCursorPos((p) => p + 1);\n setMenuIndex(0);\n }\n }\n },\n { isActive: !disabled },\n );\n\n const beforeCursor = value.slice(0, cursorPos);\n const atCursor = value[cursorPos] || ' ';\n const afterCursor = value.slice(cursorPos + 1);\n const isEmpty = value.length === 0;\n\n const menuHeight =\n filteredCommands.length > 0 ? Math.min(filteredCommands.length, 5) + 2 : 3;\n\n const cursor = '▋';\n const theme = useTheme();\n\n const handleMenuHover = (index: number) => {\n setMenuIndex(index);\n };\n\n const handleMenuSelect = (index: number) => {\n const selected = filteredCommands[index];\n if (selected) {\n onSlashCommand(selected.action);\n setValue('');\n setCursorPos(0);\n setMenuIndex(0);\n }\n };\n\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n backgroundColor={theme.background}\n >\n {isSlashMode && (\n <Box position=\"absolute\" marginTop={-menuHeight} marginLeft={0}>\n <SlashCommandMenu\n commands={filteredCommands}\n selectedIndex={menuIndex}\n width={width - 2}\n onHover={handleMenuHover}\n onSelect={handleMenuSelect}\n />\n </Box>\n )}\n {/* Wrapper with background to fill the gap above the border */}\n <Box\n flexDirection=\"column\"\n paddingTop={1}\n backgroundColor={theme.background}\n >\n {/* Input area with border on all sides */}\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.accent}\n backgroundColor={theme.secondaryBg}\n paddingX={2}\n paddingY={1}\n >\n {/* Input line */}\n <Box>\n {isEmpty && !disabled ? (\n <Text>\n <Text color={theme.textPrimary}>{cursor}</Text>\n <Text dimColor>{placeholder}</Text>\n </Text>\n ) : (\n <Text\n color={\n disabled\n ? 'gray'\n : isSlashMode\n ? theme.accent\n : theme.textPrimary\n }\n >\n {beforeCursor}\n {!disabled && <Text color={theme.textPrimary}>{cursor}</Text>}\n {atCursor !== ' ' && atCursor}\n {afterCursor.replace(/\\n/g, '↵')}\n </Text>\n )}\n </Box>\n </Box>\n </Box>\n {/* Footer: Model name on left, shortcuts on right */}\n <Box\n justifyContent=\"space-between\"\n paddingX={1}\n backgroundColor={theme.background}\n >\n <Box>\n <Text color={theme.accent}>◆ </Text>\n <Text color={theme.textPrimary}>{modelName}</Text>\n </Box>\n <Box>\n <Text color={theme.textPrimary} bold>\n /\n </Text>\n <Text dimColor> commands </Text>\n <Text color={theme.textPrimary} bold>\n ctrl+c\n </Text>\n <Text dimColor> exit</Text>\n </Box>\n </Box>\n </Box>\n );\n});\n","export type SlashCommandAction =\n | 'openModelSwitcher'\n | 'openSessionPicker'\n | 'openThemePicker'\n | 'newSession'\n | 'clearChat'\n | 'exitChat';\n\nexport interface SlashCommand {\n name: string;\n description: string;\n action: SlashCommandAction;\n}\n\nexport const SLASH_COMMANDS: SlashCommand[] = [\n {\n name: 'models',\n description: 'Switch AI model',\n action: 'openModelSwitcher',\n },\n {\n name: 'sessions',\n description: 'Browse chat sessions',\n action: 'openSessionPicker',\n },\n {\n name: 'theme',\n description: 'Change color theme',\n action: 'openThemePicker',\n },\n { name: 'new', description: 'Start new chat session', action: 'newSession' },\n { name: 'clear', description: 'Clear current chat', action: 'clearChat' },\n { name: 'exit', description: 'Exit chat', action: 'exitChat' },\n];\n\nexport function filterCommands(query: string): SlashCommand[] {\n const normalizedQuery = query.toLowerCase().replace(/^\\//, '');\n if (!normalizedQuery) return SLASH_COMMANDS;\n return SLASH_COMMANDS.filter(\n (cmd) =>\n cmd.name.toLowerCase().startsWith(normalizedQuery) ||\n cmd.description.toLowerCase().includes(normalizedQuery),\n );\n}\n","import { createContext, useContext } from 'react';\nimport { THEMES, type Theme } from './themes.js';\n\nconst ThemeContext = createContext<Theme>(THEMES[0]);\n\nexport const ThemeProvider = ThemeContext.Provider;\n\nexport function useTheme(): Theme {\n return useContext(ThemeContext);\n}\n","import { useOnClick, useOnMouseMove } from '@ink-tools/ink-mouse';\nimport { Box, type DOMElement, Text } from 'ink';\nimport { memo, useMemo, useRef } from 'react';\nimport type { SlashCommand } from '../utils/slashCommands.js';\nimport { useTheme } from '../utils/ThemeContext.js';\n\nconst VISIBLE_ROWS = 5;\n\ninterface MenuItemProps {\n cmd: SlashCommand;\n isSelected: boolean;\n width: number;\n index: number;\n accent: string;\n textPrimary: string;\n onHover: (index: number) => void;\n onClick: (index: number) => void;\n}\n\nconst MenuItem = memo(function MenuItem({\n cmd,\n isSelected,\n width,\n index,\n accent,\n textPrimary,\n onHover,\n onClick,\n}: MenuItemProps) {\n const rowRef = useRef<DOMElement>(null);\n const nameColWidth = 15;\n const nameText = `/${cmd.name}`.padEnd(nameColWidth);\n const descWidth = width - nameColWidth - 6;\n const descText =\n cmd.description.length > descWidth\n ? `${cmd.description.slice(0, descWidth - 3)}...`\n : cmd.description;\n\n useOnMouseMove(rowRef, () => {\n onHover(index);\n });\n\n useOnClick(rowRef, () => {\n onClick(index);\n });\n\n if (isSelected) {\n return (\n <Box ref={rowRef} backgroundColor={accent} paddingX={1}>\n <Text color=\"white\" bold>\n {nameText}\n {descText}\n </Text>\n </Box>\n );\n }\n\n return (\n <Box ref={rowRef} paddingX={1}>\n <Text color={textPrimary}>{nameText}</Text>\n <Text dimColor>{descText}</Text>\n </Box>\n );\n});\n\ninterface SlashCommandMenuProps {\n commands: SlashCommand[];\n selectedIndex: number;\n width: number;\n onHover?: (index: number) => void;\n onSelect?: (index: number) => void;\n}\n\nexport const SlashCommandMenu = memo(function SlashCommandMenu({\n commands,\n selectedIndex,\n width,\n onHover,\n onSelect,\n}: SlashCommandMenuProps) {\n const theme = useTheme();\n const menuWidth = width;\n\n const { visibleCommands, startIndex } = useMemo(() => {\n let start = 0;\n if (commands.length > VISIBLE_ROWS) {\n start = Math.max(\n 0,\n Math.min(\n selectedIndex - Math.floor(VISIBLE_ROWS / 2),\n commands.length - VISIBLE_ROWS,\n ),\n );\n }\n return {\n visibleCommands: commands.slice(start, start + VISIBLE_ROWS),\n startIndex: start,\n };\n }, [commands, selectedIndex]);\n\n const handleHover = (index: number) => {\n onHover?.(index);\n };\n\n const handleClick = (index: number) => {\n onSelect?.(index);\n };\n\n if (commands.length === 0) {\n return (\n <Box\n borderStyle=\"round\"\n borderColor=\"gray\"\n paddingX={1}\n width={menuWidth}\n flexDirection=\"column\"\n >\n <Text dimColor>No matching commands</Text>\n </Box>\n );\n }\n\n return (\n <Box\n borderStyle=\"round\"\n borderColor={theme.accent}\n backgroundColor={theme.secondaryBg}\n flexDirection=\"column\"\n width={menuWidth}\n >\n {visibleCommands.map((cmd, i) => (\n <MenuItem\n key={cmd.name}\n cmd={cmd}\n isSelected={startIndex + i === selectedIndex}\n width={menuWidth}\n index={startIndex + i}\n accent={theme.accent}\n textPrimary={theme.textPrimary}\n onHover={handleHover}\n onClick={handleClick}\n />\n ))}\n </Box>\n );\n});\n","import { useOnClick, useOnWheel } from '@ink-tools/ink-mouse';\nimport { highlight } from 'cli-highlight';\nimport { Box, type DOMElement, Text, useInput } from 'ink';\nimport { ScrollView, type ScrollViewRef } from 'ink-scroll-view';\nimport Spinner from 'ink-spinner';\nimport type React from 'react';\nimport {\n forwardRef,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { ChatMessage } from '../../providers/base.js';\nimport { copyToClipboard } from '../../utils/clipboard.js';\nimport { useTheme } from '../utils/ThemeContext.js';\nimport { MessageContextMenu } from './MessageContextMenu.js';\n\ninterface MessageListProps {\n messages: ChatMessage[];\n currentResponse: string;\n isLoading: boolean;\n height: number;\n width: number;\n slashModeRef: React.MutableRefObject<boolean>;\n}\n\nexport interface MessageListHandle {\n scrollBy: (delta: number) => void;\n scrollToBottom: () => void;\n}\n\n// Parse inline markdown (bold, italic, code) within a line\nfunction parseInlineMarkdown(\n text: string,\n keyPrefix: string,\n): React.ReactNode[] {\n const nodes: React.ReactNode[] = [];\n // Match: **bold**, *italic*, `code`, __bold__, _italic_\n const inlineRegex = /(\\*\\*|__)(.+?)\\1|(\\*|_)(.+?)\\3|`([^`]+)`/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n let idx = 0;\n\n match = inlineRegex.exec(text);\n while (match !== null) {\n // Add text before match\n if (match.index > lastIndex) {\n nodes.push(text.slice(lastIndex, match.index));\n }\n\n if (match[2]) {\n // **bold** or __bold__\n nodes.push(\n <Text key={`${keyPrefix}-b-${idx++}`} bold>\n {match[2]}\n </Text>,\n );\n } else if (match[4]) {\n // *italic* or _italic_\n nodes.push(\n <Text key={`${keyPrefix}-i-${idx++}`} dimColor>\n {match[4]}\n </Text>,\n );\n } else if (match[5]) {\n // `inline code`\n nodes.push(\n <Text key={`${keyPrefix}-c-${idx++}`} color=\"yellow\">\n {match[5]}\n </Text>,\n );\n }\n\n lastIndex = match.index + match[0].length;\n match = inlineRegex.exec(text);\n }\n\n // Add remaining text\n if (lastIndex < text.length) {\n nodes.push(text.slice(lastIndex));\n }\n\n return nodes.length > 0 ? nodes : [text];\n}\n\n// Parse a single line and return appropriate React node\nfunction parseLine(\n line: string,\n keyIndex: number,\n _maxWidth: number,\n): React.ReactNode {\n const trimmed = line.trimStart();\n const indent = line.length - trimmed.length;\n\n // Horizontal rule: --- or *** or ___ - skip completely (no extra space)\n if (/^(-{3,}|\\*{3,}|_{3,})$/.test(trimmed)) {\n return null;\n }\n\n // Headers: # H1, ## H2, ### H3, etc.\n const headerMatch = trimmed.match(/^(#{1,6})\\s+(.+)$/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const headerText = headerMatch[2];\n const parsed = parseInlineMarkdown(headerText, `h-${keyIndex}`);\n\n if (level === 1) {\n return (\n <Text key={keyIndex} bold color=\"yellow\">\n {parsed}\n </Text>\n );\n }\n if (level === 2) {\n return (\n <Text key={keyIndex} bold color=\"white\">\n {parsed}\n </Text>\n );\n }\n // H3 and below\n return (\n <Text key={keyIndex} bold>\n {parsed}\n </Text>\n );\n }\n\n // Bullet list: - item or * item\n const bulletMatch = trimmed.match(/^[-*]\\s+(.+)$/);\n if (bulletMatch) {\n const bulletText = bulletMatch[1];\n const parsed = parseInlineMarkdown(bulletText, `li-${keyIndex}`);\n return (\n <Box key={keyIndex} paddingLeft={indent}>\n <Text>\n <Text color=\"yellow\">•</Text> {parsed}\n </Text>\n </Box>\n );\n }\n\n // Numbered list: 1. item, 2. item, etc.\n const numberedMatch = trimmed.match(/^(\\d+)\\.\\s+(.+)$/);\n if (numberedMatch) {\n const num = numberedMatch[1];\n const itemText = numberedMatch[2];\n const parsed = parseInlineMarkdown(itemText, `ol-${keyIndex}`);\n return (\n <Box key={keyIndex} paddingLeft={indent}>\n <Text>\n <Text color=\"yellow\">{num}.</Text> {parsed}\n </Text>\n </Box>\n );\n }\n\n // Blockquote: > text\n const quoteMatch = trimmed.match(/^>\\s*(.*)$/);\n if (quoteMatch) {\n const quoteText = quoteMatch[1];\n const parsed = parseInlineMarkdown(quoteText, `q-${keyIndex}`);\n return (\n <Box key={keyIndex} paddingLeft={1}>\n <Text>\n <Text color=\"gray\">│</Text> <Text dimColor>{parsed}</Text>\n </Text>\n </Box>\n );\n }\n\n // Regular text with inline markdown\n if (trimmed.length === 0) {\n return <Text key={keyIndex}> </Text>;\n }\n\n const parsed = parseInlineMarkdown(line, `p-${keyIndex}`);\n return (\n <Text key={keyIndex} wrap=\"wrap\">\n {parsed}\n </Text>\n );\n}\n\n// Box drawing characters\nconst BOX = {\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n horizontal: '─',\n vertical: '│',\n topMid: '┬',\n bottomMid: '┴',\n leftMid: '├',\n rightMid: '┤',\n midMid: '┼',\n};\n\n// Wrap text to fit within a given width\nfunction wrapText(text: string, maxWidth: number): string[] {\n if (text.length <= maxWidth) {\n return [text];\n }\n\n const words = text.split(' ');\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n\n if (testLine.length <= maxWidth) {\n currentLine = testLine;\n } else {\n if (currentLine) {\n lines.push(currentLine);\n }\n // If single word is longer than maxWidth, split it\n if (word.length > maxWidth) {\n let remaining = word;\n while (remaining.length > maxWidth) {\n lines.push(remaining.slice(0, maxWidth));\n remaining = remaining.slice(maxWidth);\n }\n currentLine = remaining;\n } else {\n currentLine = word;\n }\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines.length > 0 ? lines : [''];\n}\n\n// Parse markdown table and render it\nfunction parseTable(\n lines: string[],\n startKey: number,\n maxWidth: number,\n): { node: React.ReactNode; linesConsumed: number } {\n // Parse header row\n const headerLine = lines[0];\n const headers = headerLine\n .split('|')\n .map((h) => h.trim())\n .filter((h) => h.length > 0);\n\n if (headers.length === 0) {\n return { node: null, linesConsumed: 0 };\n }\n\n // Skip separator line (|---|---|)\n const separatorLine = lines[1];\n if (!separatorLine || !/^\\|?[\\s-:|]+\\|?$/.test(separatorLine)) {\n return { node: null, linesConsumed: 0 };\n }\n\n // Parse data rows\n const dataRows: string[][] = [];\n let i = 2;\n while (i < lines.length && lines[i].includes('|')) {\n const row = lines[i]\n .split('|')\n .map((c) => c.trim())\n .filter((_, idx, arr) => {\n // Filter out empty first/last elements from | at start/end\n if (idx === 0 && arr[idx] === '') return false;\n if (idx === arr.length - 1 && arr[idx] === '') return false;\n return true;\n });\n if (row.length > 0) {\n dataRows.push(row);\n }\n i++;\n }\n\n // Calculate column widths - distribute available space\n const numCols = headers.length;\n const availableWidth = maxWidth - (numCols + 1) - numCols * 2; // borders and padding\n const colWidth = Math.max(Math.floor(availableWidth / numCols), 15);\n\n const colWidths = headers.map(() => colWidth);\n\n // Render table\n const tableRows: React.ReactNode[] = [];\n let keyIdx = startKey;\n\n // Top border: ┌───┬───┬───┐\n let topBorder = BOX.topLeft;\n for (let c = 0; c < numCols; c++) {\n topBorder += BOX.horizontal.repeat(colWidths[c] + 2);\n topBorder += c < numCols - 1 ? BOX.topMid : BOX.topRight;\n }\n tableRows.push(\n <Box key={`top-${keyIdx++}`}>\n <Text dimColor>{topBorder}</Text>\n </Box>,\n );\n\n // Header row (with wrapping): │ Col1 │ Col2 │\n const wrappedHeaders = headers.map((h, idx) => wrapText(h, colWidths[idx]));\n const headerLineCount = Math.max(...wrappedHeaders.map((w) => w.length));\n\n for (let lineIdx = 0; lineIdx < headerLineCount; lineIdx++) {\n tableRows.push(\n <Box key={`header-${keyIdx++}-${lineIdx}`}>\n <Text dimColor>{BOX.vertical}</Text>\n {headers.map((_, colIdx) => {\n const wrappedLines = wrappedHeaders[colIdx];\n const lineText = wrappedLines[lineIdx] || '';\n return (\n <Text key={`h-${colIdx}-${lineIdx}`}>\n <Text bold color=\"yellow\">\n {' '}\n {lineText.padEnd(colWidths[colIdx])}{' '}\n </Text>\n <Text dimColor>{BOX.vertical}</Text>\n </Text>\n );\n })}\n </Box>,\n );\n }\n\n // Header separator: ├───┼───┼───┤\n let headerSep = BOX.leftMid;\n for (let c = 0; c < numCols; c++) {\n headerSep += BOX.horizontal.repeat(colWidths[c] + 2);\n headerSep += c < numCols - 1 ? BOX.midMid : BOX.rightMid;\n }\n tableRows.push(\n <Box key={`sep-${keyIdx++}`}>\n <Text dimColor>{headerSep}</Text>\n </Box>,\n );\n\n // Data rows with text wrapping: │ val1 │ val2 │\n for (let rowIdx = 0; rowIdx < dataRows.length; rowIdx++) {\n const row = dataRows[rowIdx];\n\n // Wrap each cell\n const wrappedCells = headers.map((_, colIdx) => {\n const cell = row[colIdx] || '';\n return wrapText(cell, colWidths[colIdx]);\n });\n\n // Find max lines needed for this row\n const maxLines = Math.max(...wrappedCells.map((w) => w.length));\n\n // Render each line of the row\n for (let lineIdx = 0; lineIdx < maxLines; lineIdx++) {\n tableRows.push(\n <Box key={`row-${keyIdx++}-${rowIdx}-${lineIdx}`}>\n <Text dimColor>{BOX.vertical}</Text>\n {headers.map((_, colIdx) => {\n const wrappedLines = wrappedCells[colIdx];\n const lineText = wrappedLines[lineIdx] || '';\n const paddedText = lineText.padEnd(colWidths[colIdx]);\n const parsed = parseInlineMarkdown(\n paddedText,\n `cell-${rowIdx}-${colIdx}-${lineIdx}`,\n );\n return (\n <Text key={`c-${colIdx}-${rowIdx}-${lineIdx}`}>\n {' '}\n {parsed} <Text dimColor>{BOX.vertical}</Text>\n </Text>\n );\n })}\n </Box>,\n );\n }\n }\n\n // Bottom border: └───┴───┴───┘\n let bottomBorder = BOX.bottomLeft;\n for (let c = 0; c < numCols; c++) {\n bottomBorder += BOX.horizontal.repeat(colWidths[c] + 2);\n bottomBorder += c < numCols - 1 ? BOX.bottomMid : BOX.bottomRight;\n }\n tableRows.push(\n <Box key={`bottom-${keyIdx++}`}>\n <Text dimColor>{bottomBorder}</Text>\n </Box>,\n );\n\n return {\n node: (\n <Box key={startKey} flexDirection=\"column\">\n {tableRows}\n </Box>\n ),\n linesConsumed: i,\n };\n}\n\n// Check if a line looks like a table row\nfunction isTableRow(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.startsWith('|') && trimmed.endsWith('|') && trimmed.length > 2;\n}\n\n// Process lines, detecting tables\nfunction processLines(\n lines: string[],\n startKeyIndex: number,\n maxWidth: number,\n): { parts: React.ReactNode[]; keyIndex: number } {\n const parts: React.ReactNode[] = [];\n let keyIndex = startKeyIndex;\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // Check if this could be the start of a table\n if (isTableRow(line) && i + 1 < lines.length) {\n const nextLine = lines[i + 1];\n // Check if next line is a separator (|---|---|)\n if (/^\\|?[\\s-:|]+\\|?$/.test(nextLine.trim())) {\n // This is a table, parse it\n const tableLines = lines.slice(i);\n const { node, linesConsumed } = parseTable(\n tableLines,\n keyIndex,\n maxWidth,\n );\n if (node && linesConsumed > 0) {\n parts.push(node);\n keyIndex++;\n i += linesConsumed;\n continue;\n }\n }\n }\n\n // Regular line\n parts.push(parseLine(line, keyIndex++, maxWidth));\n i++;\n }\n\n return { parts, keyIndex };\n}\n\nfunction parseContent(content: string, maxWidth: number): React.ReactNode[] {\n const parts: React.ReactNode[] = [];\n const codeBlockRegex = /```(\\w+)?\\n([\\s\\S]*?)```/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n let keyIndex = 0;\n\n match = codeBlockRegex.exec(content);\n while (match !== null) {\n // Process text before code block\n if (match.index > lastIndex) {\n const text = content.slice(lastIndex, match.index);\n const lines = text.split('\\n');\n const result = processLines(lines, keyIndex, maxWidth);\n parts.push(...result.parts);\n keyIndex = result.keyIndex;\n }\n\n // Process code block\n const language = match[1] || 'bash';\n const code = match[2].trim();\n\n try {\n const highlighted = highlight(code, { language, ignoreIllegals: true });\n parts.push(\n <Box key={keyIndex++} flexDirection=\"column\" width={maxWidth - 4}>\n <Box\n borderStyle=\"single\"\n borderColor=\"gray\"\n paddingX={1}\n flexDirection=\"column\"\n >\n <Text dimColor>{language}</Text>\n <Text>{highlighted}</Text>\n </Box>\n </Box>,\n );\n } catch {\n parts.push(\n <Box key={keyIndex++} flexDirection=\"column\" width={maxWidth - 4}>\n <Box\n borderStyle=\"single\"\n borderColor=\"gray\"\n paddingX={1}\n flexDirection=\"column\"\n >\n <Text dimColor>{language}</Text>\n <Text>{code}</Text>\n </Box>\n </Box>,\n );\n }\n\n lastIndex = match.index + match[0].length;\n match = codeBlockRegex.exec(content);\n }\n\n // Process remaining text after last code block\n if (lastIndex < content.length) {\n const text = content.slice(lastIndex);\n const lines = text.split('\\n');\n const result = processLines(lines, keyIndex, maxWidth);\n parts.push(...result.parts);\n }\n\n return parts.length > 0\n ? parts\n : [\n <Text key={0} wrap=\"wrap\">\n {content}\n </Text>,\n ];\n}\n\nconst Message = memo(function Message({\n message,\n width,\n messageIndex,\n accent,\n onMessageClick,\n}: {\n message: ChatMessage;\n width: number;\n messageIndex: number;\n accent: string;\n onMessageClick?: (messageIndex: number, content: string) => void;\n}) {\n const isUser = message.role === 'user';\n const messageRef = useRef<DOMElement>(null);\n const parsedContent = useMemo(\n () => parseContent(message.content, width - 4),\n [message.content, width],\n );\n\n // Handle click on assistant messages only\n useOnClick(\n messageRef,\n !isUser && onMessageClick\n ? () => {\n onMessageClick(messageIndex, message.content);\n }\n : null,\n );\n\n return (\n <Box ref={messageRef} flexDirection=\"column\" marginY={1} width={width}>\n <Box>\n <Text bold color={isUser ? accent : 'yellow'}>\n {isUser ? 'You' : 'Bashio'}:\n </Text>\n </Box>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {parsedContent}\n </Box>\n </Box>\n );\n});\n\nconst EmptyState = memo(function EmptyState({ height }: { height: number }) {\n return (\n <Box\n flexDirection=\"column\"\n height={height}\n paddingX={1}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Text dimColor>Start a conversation by typing a message below.</Text>\n <Text dimColor>Type / for commands or Ctrl+P to switch models.</Text>\n </Box>\n );\n});\n\nexport const MessageList = memo(\n forwardRef<MessageListHandle, MessageListProps>(function MessageList(\n { messages, currentResponse, isLoading, height, width, slashModeRef },\n ref,\n ) {\n const theme = useTheme();\n const scrollRef = useRef<ScrollViewRef>(null);\n const mouseRef = useRef<DOMElement>(null);\n const [followOutput, setFollowOutput] = useState(true);\n const [contextMenu, setContextMenu] = useState<{\n messageIndex: number;\n content: string;\n } | null>(null);\n\n const handleMessageClick = useCallback(\n (messageIndex: number, content: string) => {\n setContextMenu({ messageIndex, content });\n },\n [],\n );\n\n const handleContextMenuSelect = useCallback(\n async (action: string) => {\n if (action === 'copy' && contextMenu) {\n // Only copy to clipboard - do NOT execute anything\n await copyToClipboard(contextMenu.content);\n }\n setContextMenu(null);\n },\n [contextMenu],\n );\n\n const handleContextMenuClose = useCallback(() => {\n setContextMenu(null);\n }, []);\n\n const boundedScrollBy = useCallback((delta: number) => {\n const sv = scrollRef.current;\n if (!sv) return;\n const currentOffset = sv.getScrollOffset();\n const maxOffset = sv.getBottomOffset();\n const newOffset = Math.max(0, Math.min(maxOffset, currentOffset + delta));\n sv.scrollTo(newOffset);\n setFollowOutput(newOffset >= maxOffset);\n }, []);\n\n const boundedScrollToBottom = useCallback(() => {\n const sv = scrollRef.current;\n if (!sv) return;\n const maxOffset = sv.getBottomOffset();\n sv.scrollTo(Math.max(0, maxOffset));\n setFollowOutput(true);\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollBy: boundedScrollBy,\n scrollToBottom: boundedScrollToBottom,\n }),\n [boundedScrollBy, boundedScrollToBottom],\n );\n\n const messagesCount = messages.length;\n const hasResponse = Boolean(currentResponse);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally re-run on content changes\n useEffect(() => {\n if (!followOutput) return;\n const timer = setTimeout(() => {\n boundedScrollToBottom();\n }, 10);\n return () => clearTimeout(timer);\n }, [messagesCount, hasResponse, boundedScrollToBottom, followOutput]);\n\n // Scroll input - reads ref directly, no re-render when slash mode changes\n useInput((input, key) => {\n // Skip scrolling when slash menu is open (read from ref)\n if (slashModeRef.current) return;\n\n if (input.startsWith('\\u001b[<')) {\n return;\n }\n\n const isUpSequence = input === '\\u001b[A';\n const isDownSequence = input === '\\u001b[B';\n const isPageUpSequence = input === '\\u001b[5~';\n const isPageDownSequence = input === '\\u001b[6~';\n\n if (key.ctrl && input === 'l') {\n boundedScrollToBottom();\n return;\n }\n\n // Arrow keys for scrolling\n if (key.upArrow || isUpSequence) boundedScrollBy(-1);\n if (key.downArrow || isDownSequence) boundedScrollBy(1);\n\n // Page up/down for faster scrolling\n if (key.pageUp || isPageUpSequence) {\n boundedScrollBy(-Math.floor(height / 2));\n }\n if (key.pageDown || isPageDownSequence) {\n boundedScrollBy(Math.floor(height / 2));\n }\n\n // Vim-style: Ctrl+K/J for scrolling (3 lines at a time)\n if (input === 'k' && key.ctrl) boundedScrollBy(-3);\n // Note: Ctrl+J is used for newline in InputBox, so use Alt or just k/j\n\n // Simple j/k for scrolling when not typing (meta key as modifier)\n if (input === 'k' && key.meta) boundedScrollBy(-3);\n if (input === 'j' && key.meta) boundedScrollBy(3);\n });\n\n // Mouse wheel scrolling\n useOnWheel(mouseRef, (event) => {\n if (event.button === 'wheel-up') {\n boundedScrollBy(-3);\n } else if (event.button === 'wheel-down') {\n boundedScrollBy(3);\n }\n });\n\n useEffect(() => {\n if (followOutput) return;\n const sv = scrollRef.current;\n if (!sv) return;\n const currentOffset = sv.getScrollOffset();\n const maxOffset = sv.getBottomOffset();\n if (maxOffset === 0 || currentOffset >= maxOffset) {\n setFollowOutput(true);\n }\n }, [followOutput]);\n\n const streamingContent = useMemo(\n () => (currentResponse ? parseContent(currentResponse, width - 4) : null),\n [currentResponse, width],\n );\n\n if (messages.length === 0 && !currentResponse) {\n return <EmptyState height={height} />;\n }\n\n return (\n <Box flexDirection=\"column\" height={height} width={width}>\n {/* Messages list */}\n <Box ref={mouseRef} height={height} paddingX={1} overflow=\"hidden\">\n <ScrollView ref={scrollRef} height={height}>\n {messages.map((msg, i) => (\n <Message\n key={`msg-${i}-${msg.role}`}\n message={msg}\n width={width}\n messageIndex={i}\n accent={theme.accent}\n onMessageClick={\n contextMenu === null ? handleMessageClick : undefined\n }\n />\n ))}\n\n {streamingContent && (\n <Box\n key=\"streaming\"\n flexDirection=\"column\"\n marginY={1}\n width={width}\n >\n <Box>\n <Text bold color=\"yellow\">\n Bashio:\n </Text>\n </Box>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {streamingContent}\n <Text color=\"yellow\">|</Text>\n </Box>\n </Box>\n )}\n\n {isLoading && !currentResponse && (\n <Box key=\"loading\" marginY={1}>\n <Text color={theme.accent}>\n <Spinner type=\"dots\" />\n </Text>\n <Text color={theme.accent}> Thinking...</Text>\n </Box>\n )}\n </ScrollView>\n </Box>\n\n {/* Context menu overlay - positioned absolutely on top, centered */}\n {contextMenu !== null && (\n <Box\n position=\"absolute\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <MessageContextMenu\n onSelect={handleContextMenuSelect}\n onClose={handleContextMenuClose}\n width={Math.min(width - 4, 50)}\n />\n </Box>\n )}\n </Box>\n );\n }),\n);\n","import { useOnClick, useOnMouseMove } from '@ink-tools/ink-mouse';\nimport { Box, type DOMElement, Text, useInput } from 'ink';\nimport { memo, useRef, useState } from 'react';\nimport { useTheme } from '../utils/ThemeContext.js';\n\ninterface MenuItem {\n label: string;\n description: string;\n action: string;\n}\n\ninterface MessageContextMenuProps {\n onSelect: (action: string) => void;\n onClose: () => void;\n width?: number;\n}\n\nconst menuItems: MenuItem[] = [\n { label: 'Copy', description: 'message text to clipboard', action: 'copy' },\n { label: 'Exit', description: 'close this menu', action: 'exit' },\n];\n\ninterface MenuItemRowProps {\n item: MenuItem;\n index: number;\n isSelected: boolean;\n rowWidth: number;\n accent: string;\n onHover: (index: number) => void;\n onClick: (action: string) => void;\n}\n\nconst MenuItemRow = memo(function MenuItemRow({\n item,\n index,\n isSelected,\n rowWidth,\n accent,\n onHover,\n onClick,\n}: MenuItemRowProps) {\n const rowRef = useRef<DOMElement>(null);\n\n useOnMouseMove(rowRef, () => {\n onHover(index);\n });\n\n useOnClick(rowRef, () => {\n onClick(item.action);\n });\n\n return (\n <Box\n ref={rowRef}\n backgroundColor={isSelected ? accent : undefined}\n width={rowWidth}\n justifyContent=\"space-between\"\n paddingX={1}\n >\n <Text color={isSelected ? 'white' : 'white'} bold={isSelected}>\n {item.label}\n </Text>\n {isSelected ? (\n <Text color=\"white\">{item.description}</Text>\n ) : (\n <Text dimColor>{item.description}</Text>\n )}\n </Box>\n );\n});\n\nexport const MessageContextMenu = memo(function MessageContextMenu({\n onSelect,\n onClose,\n width = 50,\n}: MessageContextMenuProps) {\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) {\n onClose();\n return;\n }\n\n if (key.return) {\n const selected = menuItems[selectedIndex];\n if (selected) {\n if (selected.action === 'exit') {\n onClose();\n } else {\n onSelect(selected.action);\n }\n }\n return;\n }\n\n if (key.upArrow || input === 'k') {\n setSelectedIndex((i) => Math.max(0, i - 1));\n }\n\n if (key.downArrow || input === 'j') {\n setSelectedIndex((i) => Math.min(menuItems.length - 1, i + 1));\n }\n });\n\n const handleHover = (index: number) => {\n setSelectedIndex(index);\n };\n\n const handleClick = (action: string) => {\n if (action === 'exit') {\n onClose();\n } else {\n onSelect(action);\n }\n };\n\n const theme = useTheme();\n const menuWidth = Math.min(width, 50);\n\n return (\n <Box\n flexDirection=\"column\"\n width={menuWidth}\n borderStyle=\"round\"\n borderColor={theme.accent}\n backgroundColor={theme.background}\n >\n {/* Header */}\n <Box paddingX={1} justifyContent=\"space-between\">\n <Text bold color={theme.textPrimary}>\n Message Actions\n </Text>\n <Text dimColor>esc</Text>\n </Box>\n\n {/* Divider */}\n <Box paddingX={1}>\n <Text dimColor>{'─'.repeat(menuWidth - 4)}</Text>\n </Box>\n\n {/* Menu items */}\n <Box flexDirection=\"column\" paddingBottom={1}>\n {menuItems.map((item, index) => (\n <MenuItemRow\n key={item.action}\n item={item}\n index={index}\n isSelected={index === selectedIndex}\n rowWidth={menuWidth - 2}\n accent={theme.accent}\n onHover={handleHover}\n onClick={handleClick}\n />\n ))}\n </Box>\n </Box>\n );\n});\n","import { useOnClick, useOnMouseMove } from '@ink-tools/ink-mouse';\nimport { Box, type DOMElement, Text, useInput, useStdout } from 'ink';\nimport { memo, useRef, useState } from 'react';\nimport type { ConfigV2, ProviderName } from '../../core/types.js';\nimport {\n CHATGPT_SUBSCRIPTION_MODELS,\n CLAUDE_MODELS,\n CLAUDE_SUBSCRIPTION_MODELS,\n COPILOT_MODELS,\n OLLAMA_RECOMMENDED_MODELS,\n OPENAI_MODELS,\n OPENROUTER_MODELS,\n} from '../../providers/index.js';\nimport { useTheme } from '../utils/ThemeContext.js';\n\ninterface ModelSwitcherProps {\n config: ConfigV2;\n onSelect: (provider: ProviderName, model: string) => void;\n onClose: () => void;\n}\n\ninterface ModelOption {\n provider: ProviderName;\n providerLabel: string;\n model: string;\n label: string;\n}\n\ninterface ModelRowProps {\n option: ModelOption;\n isSelected: boolean;\n isCurrent: boolean;\n rowWidth: number;\n accent: string;\n onHover: () => void;\n onClick: () => void;\n}\n\nconst PROVIDER_LABELS: Record<ProviderName, string> = {\n 'claude-subscription': 'Claude Pro/Max',\n 'chatgpt-subscription': 'ChatGPT Plus/Pro',\n copilot: 'GitHub Copilot',\n claude: 'Claude API',\n openai: 'OpenAI API',\n ollama: 'Ollama',\n openrouter: 'OpenRouter',\n};\n\nconst ModelRow = memo(function ModelRow({\n option,\n isSelected,\n isCurrent,\n rowWidth,\n accent,\n onHover,\n onClick,\n}: ModelRowProps) {\n const rowRef = useRef<DOMElement>(null);\n\n useOnMouseMove(rowRef, onHover);\n useOnClick(rowRef, onClick);\n\n const prefix = isSelected ? '>' : isCurrent ? '✓' : ' ';\n const labelWithPrefix = ` ${prefix} ${option.label}`;\n const padding = Math.max(0, rowWidth - labelWithPrefix.length);\n const fullLine = labelWithPrefix + ' '.repeat(padding);\n\n return (\n <Box ref={rowRef}>\n <Text\n backgroundColor={isSelected ? accent : undefined}\n color={isSelected ? '#000000' : undefined}\n >\n {fullLine}\n </Text>\n </Box>\n );\n});\n\nfunction getModelsForProvider(\n provider: ProviderName,\n): Array<{ value: string; label: string }> {\n switch (provider) {\n case 'claude':\n return CLAUDE_MODELS;\n case 'claude-subscription':\n return CLAUDE_SUBSCRIPTION_MODELS;\n case 'openai':\n return OPENAI_MODELS;\n case 'chatgpt-subscription':\n return CHATGPT_SUBSCRIPTION_MODELS;\n case 'copilot':\n return COPILOT_MODELS;\n case 'ollama':\n return OLLAMA_RECOMMENDED_MODELS.map((m) => ({ value: m, label: m }));\n case 'openrouter':\n return OPENROUTER_MODELS;\n default:\n return [];\n }\n}\n\nexport function ModelSwitcher({\n config,\n onSelect,\n onClose,\n}: ModelSwitcherProps) {\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n const height = stdout?.rows ?? 24;\n const theme = useTheme();\n\n const currentProvider = config.activeProvider;\n const currentModel = config.providers[currentProvider]?.model;\n\n const options: ModelOption[] = [];\n const providers = Object.keys(config.providers) as ProviderName[];\n\n for (const provider of providers) {\n const models = getModelsForProvider(provider);\n const providerLabel = PROVIDER_LABELS[provider] || provider;\n\n for (const model of models) {\n options.push({\n provider,\n providerLabel,\n model: model.value,\n label: model.label,\n });\n }\n }\n\n const currentIndex = options.findIndex(\n (o) => o.provider === currentProvider && o.model === currentModel,\n );\n const [selectedIndex, setSelectedIndex] = useState(\n currentIndex >= 0 ? currentIndex : 0,\n );\n\n const handleHover = (index: number) => {\n setSelectedIndex(index);\n };\n\n const handleClick = (index: number) => {\n const selected = options[index];\n if (selected) {\n onSelect(selected.provider, selected.model);\n }\n };\n\n useInput((input, key) => {\n if (key.escape) {\n onClose();\n return;\n }\n\n if (key.return) {\n const selected = options[selectedIndex];\n if (selected) {\n onSelect(selected.provider, selected.model);\n }\n return;\n }\n\n if (key.upArrow || input === 'k') {\n setSelectedIndex((i) => Math.max(0, i - 1));\n }\n\n if (key.downArrow || input === 'j') {\n setSelectedIndex((i) => Math.min(options.length - 1, i + 1));\n }\n });\n\n const boxWidth = Math.min(60, width - 4);\n const maxListHeight = 12; // Maximum visible items\n const listHeight = Math.min(options.length, maxListHeight, height - 8);\n\n let startIndex = 0;\n if (selectedIndex >= listHeight) {\n startIndex = selectedIndex - listHeight + 1;\n }\n const visibleOptions = options.slice(startIndex, startIndex + listHeight);\n\n let lastProvider: ProviderName | null = null;\n\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n backgroundColor={theme.background}\n >\n <Box\n flexDirection=\"column\"\n width={boxWidth}\n borderStyle=\"round\"\n borderColor={theme.accent}\n paddingX={1}\n >\n {/* Header */}\n <Box marginBottom={1} justifyContent=\"space-between\">\n <Text bold color={theme.accent}>\n Model Selector\n </Text>\n <Text dimColor>esc to exit</Text>\n </Box>\n\n {/* Current model info */}\n <Box>\n <Text color={theme.accent}>Current: </Text>\n <Text>\n {PROVIDER_LABELS[currentProvider]} / {currentModel}\n </Text>\n </Box>\n\n {/* Top divider */}\n <Text dimColor>{'─'.repeat(boxWidth - 4)}</Text>\n\n {/* Model list */}\n <Box flexDirection=\"column\">\n {visibleOptions.map((option, i) => {\n const actualIndex = startIndex + i;\n const isSelected = actualIndex === selectedIndex;\n const isCurrent =\n option.provider === currentProvider &&\n option.model === currentModel;\n const showProviderHeader = option.provider !== lastProvider;\n lastProvider = option.provider;\n\n return (\n <Box\n key={`${option.provider}-${option.model}`}\n flexDirection=\"column\"\n >\n {showProviderHeader && (\n <Text bold color={theme.accent}>\n {i > 0 ? '\\n' : ''}\n {option.providerLabel}\n </Text>\n )}\n <ModelRow\n option={option}\n isSelected={isSelected}\n isCurrent={isCurrent}\n rowWidth={boxWidth - 4}\n accent={theme.accent}\n onHover={() => handleHover(actualIndex)}\n onClick={() => handleClick(actualIndex)}\n />\n </Box>\n );\n })}\n </Box>\n\n {/* Bottom divider */}\n <Text dimColor>{'─'.repeat(boxWidth - 4)}</Text>\n\n {/* Footer */}\n <Box justifyContent=\"space-between\">\n <Text dimColor>↑↓ navigate</Text>\n {options.length > listHeight && (\n <Text dimColor>\n {startIndex + 1}-\n {Math.min(startIndex + listHeight, options.length)}/\n {options.length}\n </Text>\n )}\n <Text dimColor>↵ select</Text>\n </Box>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport { memo } from 'react';\nimport { useTheme } from '../utils/ThemeContext.js';\n\ninterface SessionHeaderProps {\n sessionTitle: string;\n width: number;\n}\n\nexport const SessionHeader = memo(function SessionHeader({\n sessionTitle,\n width,\n}: SessionHeaderProps) {\n const theme = useTheme();\n\n return (\n <Box\n borderStyle=\"single\"\n borderLeft\n borderRight={false}\n borderTop={false}\n borderBottom={false}\n borderColor={theme.accent}\n backgroundColor={theme.secondaryBg}\n paddingX={1}\n paddingY={1}\n gap={1}\n width={width}\n >\n <Text color={theme.accent}>#</Text>\n <Text color={theme.textPrimary}>{sessionTitle}</Text>\n </Box>\n );\n});\n","import { useOnClick, useOnMouseMove } from '@ink-tools/ink-mouse';\nimport { Box, type DOMElement, Text, useInput, useStdout } from 'ink';\nimport { memo, useRef, useState } from 'react';\nimport {\n deleteSession,\n listSessions,\n type SessionMeta,\n} from '../utils/sessions.js';\nimport { useTheme } from '../utils/ThemeContext.js';\n\ninterface SessionPickerProps {\n onSelect: (sessionId: string | null) => void;\n onClose: () => void;\n}\n\nfunction formatDate(isoString: string): string {\n const date = new Date(isoString);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\ninterface SessionRowProps {\n isNew?: boolean;\n session?: SessionMeta;\n isSelected: boolean;\n rowWidth: number;\n titleWidth: number;\n index: number;\n accent: string;\n onHover: (index: number) => void;\n onClick: (index: number) => void;\n}\n\nconst SessionRow = memo(function SessionRow({\n isNew,\n session,\n isSelected,\n rowWidth,\n titleWidth,\n index,\n accent,\n onHover,\n onClick,\n}: SessionRowProps) {\n const rowRef = useRef<DOMElement>(null);\n\n useOnMouseMove(rowRef, () => {\n onHover(index);\n });\n\n useOnClick(rowRef, () => {\n onClick(index);\n });\n\n if (isNew) {\n return (\n <Box\n ref={rowRef}\n backgroundColor={isSelected ? accent : undefined}\n width={rowWidth}\n paddingX={1}\n >\n <Text color={isSelected ? 'white' : 'green'} bold={isSelected}>\n {isSelected ? ' > ' : ' '}+ New Chat\n </Text>\n </Box>\n );\n }\n\n if (!session) return null;\n\n const title =\n session.title.length > titleWidth\n ? `${session.title.slice(0, titleWidth - 3)}...`\n : session.title.padEnd(titleWidth);\n\n return (\n <Box\n ref={rowRef}\n backgroundColor={isSelected ? accent : undefined}\n width={rowWidth}\n paddingX={1}\n >\n <Text color={isSelected ? 'white' : undefined} bold={isSelected}>\n {isSelected ? ' > ' : ' '}\n {title}\n </Text>\n <Text color={isSelected ? 'white' : undefined} dimColor={!isSelected}>\n {' '}\n {session.messageCount} msgs | {formatDate(session.updatedAt)}\n </Text>\n </Box>\n );\n});\n\nexport function SessionPicker({ onSelect, onClose }: SessionPickerProps) {\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n const height = stdout?.rows ?? 24;\n\n const [sessions, setSessions] = useState<SessionMeta[]>(() => listSessions());\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const totalItems = sessions.length + 1;\n\n const handleSelect = (index: number) => {\n if (index === 0) {\n onSelect(null);\n } else {\n const session = sessions[index - 1];\n if (session) {\n onSelect(session.id);\n }\n }\n };\n\n const handleHover = (index: number) => {\n setSelectedIndex(index);\n };\n\n const handleClick = (index: number) => {\n handleSelect(index);\n };\n\n useInput((input, key) => {\n if (key.escape) {\n onClose();\n return;\n }\n\n if (key.return) {\n handleSelect(selectedIndex);\n return;\n }\n\n if (key.upArrow || input === 'k') {\n setSelectedIndex((i) => Math.max(0, i - 1));\n }\n\n if (key.downArrow || input === 'j') {\n setSelectedIndex((i) => Math.min(totalItems - 1, i + 1));\n }\n\n if (key.ctrl && input === 'd') {\n if (selectedIndex > 0) {\n const session = sessions[selectedIndex - 1];\n if (session) {\n deleteSession(session.id);\n setSessions(listSessions());\n if (selectedIndex >= sessions.length) {\n setSelectedIndex(Math.max(0, sessions.length - 1));\n }\n }\n }\n }\n });\n\n const listHeight = height - 8;\n const visibleCount = Math.max(1, listHeight);\n\n let startIndex = 0;\n if (selectedIndex >= visibleCount) {\n startIndex = selectedIndex - visibleCount + 1;\n }\n\n const allItems: Array<\n { type: 'new' } | { type: 'session'; session: SessionMeta }\n > = [\n { type: 'new' },\n ...sessions.map((session) => ({ type: 'session' as const, session })),\n ];\n\n const visibleItems = allItems.slice(startIndex, startIndex + visibleCount);\n\n const theme = useTheme();\n const rowWidth = Math.min(76, width - 6);\n const titleWidth = Math.min(40, width - 30);\n\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n backgroundColor={theme.background}\n >\n <Box\n flexDirection=\"column\"\n width={Math.min(80, width - 4)}\n borderStyle=\"double\"\n borderColor={theme.accent}\n >\n {/* Header */}\n <Box paddingX={2} paddingY={1} justifyContent=\"space-between\">\n <Text bold color={theme.accent}>\n Chat Sessions\n </Text>\n <Text dimColor>Esc: close | Enter: select | Ctrl+D: delete</Text>\n </Box>\n\n {/* Divider */}\n <Box paddingX={1}>\n <Text dimColor>{'─'.repeat(Math.min(76, width - 8))}</Text>\n </Box>\n\n {/* Session list */}\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n {visibleItems.map((item, i) => {\n const actualIndex = startIndex + i;\n const isSelected = actualIndex === selectedIndex;\n\n if (item.type === 'new') {\n return (\n <SessionRow\n key=\"new-chat\"\n isNew\n isSelected={isSelected}\n rowWidth={rowWidth}\n titleWidth={titleWidth}\n index={actualIndex}\n accent={theme.accent}\n onHover={handleHover}\n onClick={handleClick}\n />\n );\n }\n\n return (\n <SessionRow\n key={item.session.id}\n session={item.session}\n isSelected={isSelected}\n rowWidth={rowWidth}\n titleWidth={titleWidth}\n index={actualIndex}\n accent={theme.accent}\n onHover={handleHover}\n onClick={handleClick}\n />\n );\n })}\n\n {sessions.length === 0 && (\n <Box paddingY={1}>\n <Text dimColor>No previous sessions</Text>\n </Box>\n )}\n </Box>\n\n {/* Footer with scroll indicator */}\n {totalItems > visibleCount && (\n <Box paddingX={2} paddingBottom={1}>\n <Text dimColor>\n Showing {startIndex + 1}-\n {Math.min(startIndex + visibleCount, totalItems)} of {totalItems}\n </Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n}\n","import {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ProviderName } from '../../core/types.js';\nimport type { ChatMessage } from '../../providers/base.js';\n\nexport interface SessionMeta {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n messageCount: number;\n model: string;\n provider: ProviderName;\n}\n\nexport interface Session extends SessionMeta {\n messages: ChatMessage[];\n}\n\nconst MAX_SESSIONS = 50;\n\nfunction getSessionsDir(): string {\n const dir = join(homedir(), '.bashio', 'sessions');\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\nfunction getSessionPath(id: string): string {\n return join(getSessionsDir(), `${id}.json`);\n}\n\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction generateTitle(messages: ChatMessage[]): string {\n const firstUserMsg = messages.find((m) => m.role === 'user');\n if (!firstUserMsg) return 'New Chat';\n\n const content = firstUserMsg.content.trim();\n if (content.length <= 50) return content;\n return `${content.slice(0, 47)}...`;\n}\n\nexport function listSessions(): SessionMeta[] {\n const dir = getSessionsDir();\n const files = readdirSync(dir).filter((f) => f.endsWith('.json'));\n\n const sessions: SessionMeta[] = [];\n\n for (const file of files) {\n try {\n const content = readFileSync(join(dir, file), 'utf-8');\n const session = JSON.parse(content) as Session;\n sessions.push({\n id: session.id,\n title: session.title,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n messageCount: session.messages.length,\n model: session.model,\n provider: session.provider,\n });\n } catch {\n // Skip corrupted files\n }\n }\n\n // Sort by updatedAt descending (most recent first)\n return sessions.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n}\n\nexport function loadSession(id: string): Session | null {\n const path = getSessionPath(id);\n if (!existsSync(path)) return null;\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Session;\n } catch {\n return null;\n }\n}\n\nexport function saveSession(session: Session): void {\n const path = getSessionPath(session.id);\n\n // Update title if we have messages and title is default\n if (session.messages.length > 0 && session.title === 'New Chat') {\n session.title = generateTitle(session.messages);\n }\n\n session.updatedAt = new Date().toISOString();\n session.messageCount = session.messages.length;\n\n writeFileSync(path, JSON.stringify(session, null, 2));\n\n // Cleanup old sessions\n cleanupOldSessions();\n}\n\nexport function createSession(model: string, provider: ProviderName): Session {\n const now = new Date().toISOString();\n return {\n id: generateId(),\n title: 'New Chat',\n createdAt: now,\n updatedAt: now,\n messageCount: 0,\n model,\n provider,\n messages: [],\n };\n}\n\nexport function deleteSession(id: string): boolean {\n const path = getSessionPath(id);\n if (!existsSync(path)) return false;\n\n try {\n unlinkSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction cleanupOldSessions(): void {\n const sessions = listSessions();\n\n if (sessions.length <= MAX_SESSIONS) return;\n\n // Delete oldest sessions beyond limit\n const toDelete = sessions.slice(MAX_SESSIONS);\n for (const session of toDelete) {\n deleteSession(session.id);\n }\n}\n","import { useOnClick, useOnMouseMove, useOnWheel } from '@ink-tools/ink-mouse';\nimport { Box, type DOMElement, Text, useInput, useStdout } from 'ink';\nimport { memo, useRef, useState } from 'react';\nimport { THEMES, type Theme } from '../utils/themes.js';\n\nconst MAX_VISIBLE_THEMES = 12;\n\ninterface ThemePickerProps {\n currentTheme: string;\n onSelect: (themeName: string) => void;\n onClose: () => void;\n}\n\ninterface ThemeRowProps {\n theme: Theme;\n isSelected: boolean;\n isCurrent: boolean;\n rowWidth: number;\n selectedTheme: Theme;\n onHover: () => void;\n onClick: () => void;\n}\n\nconst ThemeRow = memo(function ThemeRow({\n theme,\n isSelected,\n isCurrent,\n rowWidth,\n selectedTheme,\n onHover,\n onClick,\n}: ThemeRowProps) {\n const rowRef = useRef<DOMElement>(null);\n\n useOnMouseMove(rowRef, onHover);\n useOnClick(rowRef, onClick);\n\n return (\n <Box\n ref={rowRef}\n backgroundColor={isSelected ? selectedTheme.accent : undefined}\n width={rowWidth}\n paddingX={1}\n >\n <Text color={isSelected ? 'white' : undefined} bold={isSelected}>\n {isCurrent && !isSelected && (\n <Text color={selectedTheme.accent}>● </Text>\n )}\n {isCurrent && isSelected && <Text color=\"white\">● </Text>}\n {!isCurrent && ' '}\n {theme.displayName}\n </Text>\n </Box>\n );\n});\n\nexport function ThemePicker({\n currentTheme,\n onSelect,\n onClose,\n}: ThemePickerProps) {\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n const height = stdout?.rows ?? 24;\n const listRef = useRef<DOMElement>(null);\n\n const currentIndex = THEMES.findIndex((t) => t.name === currentTheme);\n const [selectedIndex, setSelectedIndex] = useState(\n currentIndex >= 0 ? currentIndex : 0,\n );\n\n const visibleCount = Math.min(MAX_VISIBLE_THEMES, height - 10);\n\n const handleHover = (actualIndex: number) => {\n setSelectedIndex(actualIndex);\n };\n\n const handleClick = (actualIndex: number) => {\n const selected = THEMES[actualIndex];\n if (selected) {\n onSelect(selected.name);\n }\n };\n\n useInput((input, key) => {\n if (key.escape) {\n onClose();\n return;\n }\n\n if (key.return) {\n const selected = THEMES[selectedIndex];\n if (selected) {\n onSelect(selected.name);\n }\n return;\n }\n\n if (key.upArrow || input === 'k') {\n setSelectedIndex((i) => Math.max(0, i - 1));\n }\n\n if (key.downArrow || input === 'j') {\n setSelectedIndex((i) => Math.min(THEMES.length - 1, i + 1));\n }\n\n if (key.pageUp) {\n setSelectedIndex((i) => Math.max(0, i - visibleCount));\n }\n\n if (key.pageDown) {\n setSelectedIndex((i) => Math.min(THEMES.length - 1, i + visibleCount));\n }\n });\n\n useOnWheel(listRef, (event) => {\n if (event.button === 'wheel-up') {\n setSelectedIndex((i) => Math.max(0, i - 1));\n } else if (event.button === 'wheel-down') {\n setSelectedIndex((i) => Math.min(THEMES.length - 1, i + 1));\n }\n });\n\n let startIndex = 0;\n if (selectedIndex >= visibleCount) {\n startIndex = Math.min(\n selectedIndex - Math.floor(visibleCount / 2),\n THEMES.length - visibleCount,\n );\n }\n startIndex = Math.max(0, startIndex);\n\n const visibleThemes = THEMES.slice(startIndex, startIndex + visibleCount);\n const selectedTheme = THEMES[selectedIndex] ?? THEMES[0];\n const rowWidth = Math.min(60, width - 8);\n\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n backgroundColor={selectedTheme.background}\n >\n <Box\n flexDirection=\"column\"\n width={Math.min(64, width - 4)}\n borderStyle=\"round\"\n borderColor={selectedTheme.accent}\n >\n {/* Header */}\n <Box paddingX={2} paddingTop={1} justifyContent=\"space-between\">\n <Text bold color={selectedTheme.textPrimary}>\n Themes\n </Text>\n <Text dimColor>esc</Text>\n </Box>\n\n {/* Divider */}\n <Box paddingX={1}>\n <Text dimColor>{'─'.repeat(Math.min(60, width - 8))}</Text>\n </Box>\n\n {/* Theme list with scroll */}\n <Box ref={listRef} flexDirection=\"column\" paddingY={1}>\n {visibleThemes.map((theme, i) => {\n const actualIndex = startIndex + i;\n return (\n <ThemeRow\n key={theme.name}\n theme={theme}\n isSelected={actualIndex === selectedIndex}\n isCurrent={theme.name === currentTheme}\n rowWidth={rowWidth}\n selectedTheme={selectedTheme}\n onHover={() => handleHover(actualIndex)}\n onClick={() => handleClick(actualIndex)}\n />\n );\n })}\n </Box>\n\n {/* Footer with scroll indicator */}\n <Box paddingX={2} paddingBottom={1} justifyContent=\"space-between\">\n <Text dimColor>j/k or arrows to navigate</Text>\n {THEMES.length > visibleCount && (\n <Text dimColor>\n {startIndex + 1}-\n {Math.min(startIndex + visibleCount, THEMES.length)}/\n {THEMES.length}\n </Text>\n )}\n </Box>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { memo } from 'react';\nimport { useTheme } from '../utils/ThemeContext.js';\nimport { CatIcon } from './CatIcon.js';\n\nconst BASHIO_ASCII = `\n██████╗ █████╗ ███████╗██╗ ██╗██╗ ██████╗ \n██╔══██╗██╔══██╗██╔════╝██║ ██║██║██╔═══██╗\n██████╔╝███████║███████╗███████║██║██║ ██║\n██╔══██╗██╔══██║╚════██║██╔══██║██║██║ ██║\n██████╔╝██║ ██║███████║██║ ██║██║╚██████╔╝\n╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝ \n`.trim();\n\ninterface WelcomeScreenProps {\n width: number;\n height: number;\n children?: ReactNode;\n}\n\nexport const WelcomeScreen = memo(function WelcomeScreen({\n width,\n height,\n children,\n}: WelcomeScreenProps) {\n const lines = BASHIO_ASCII.split('\\n');\n const theme = useTheme();\n\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n backgroundColor={theme.background}\n >\n <Box\n flexDirection=\"column\"\n alignItems=\"center\"\n backgroundColor={theme.background}\n >\n {/* Cat Icon */}\n <CatIcon />\n {/* Gap between cat and text */}\n <Box paddingTop={1} backgroundColor={theme.background} />\n {/* BASHIO text */}\n {lines.map((line, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Static ASCII art lines\n <Text key={`ascii-${i}`} color={theme.textPrimary} bold>\n {line}\n </Text>\n ))}\n {/* Input box below ASCII art - use padding for proper background fill */}\n {children && (\n <Box paddingTop={2} backgroundColor={theme.background}>\n {children}\n </Box>\n )}\n </Box>\n </Box>\n );\n});\n","import { Box, Text } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { useTheme } from '../utils/ThemeContext.js';\n\n// Cat ASCII art with colors:\n// Theme accent - face/body\n// #241F33 - Dark purple (inner dark areas like eyes)\n// #FEFEFE - White (muzzle/mouth)\n// #000 or black - Border/outline\n\n// Character mapping:\n// █ = black border\n// ░ = face fill (theme accent)\n// ▓ = dark areas (dark purple #241F33)\n// ▒ = white muzzle (#FEFEFE)\n\n// Compact cat face - manually designed for clarity\nconst CAT_LINES = [\n ' ██ ██ ',\n ' ██░░████░░██ ',\n '██░░░░░░░░░░██',\n '██░▓░░░░░░▓░██',\n '██░░░▒▒▒▒░░░██',\n '██░░▒▒▓▓▒▒░░██',\n ' ██░▒▒▒▒▒▒░██ ',\n ' ██████████ ',\n];\n\nexport const CatIcon = memo(function CatIcon() {\n const theme = useTheme();\n\n const colors = useMemo(\n () => ({\n '█': 'black',\n '░': theme.accent,\n '▓': '#33221fff',\n '▒': '#fbfaf7ff',\n }),\n [theme.accent],\n );\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\">\n {CAT_LINES.map((line, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Static ASCII art\n <Text key={`line-${i}`}>\n {line.split('').map((char, j) => {\n const color = colors[char as keyof typeof colors];\n if (color) {\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: Static char\n <Text key={`char-${i}-${j}`} color={color}>\n █\n </Text>\n );\n }\n // Space - transparent\n // biome-ignore lint/suspicious/noArrayIndexKey: Static char\n return <Text key={`char-${i}-${j}`}> </Text>;\n })}\n </Text>\n ))}\n </Box>\n );\n});\n","import { Writable } from 'node:stream';\n\ninterface WriteStreamProxy extends NodeJS.WriteStream {\n _flushSyncOutput?: () => void;\n}\n\nexport interface SyncOutputStream extends NodeJS.WriteStream {\n _flushSyncOutput?: () => void;\n}\n\n// Synchronized output escape sequences (supported by iTerm2, kitty, and others)\n// This prevents screen tearing/flickering by batching terminal updates\nconst SYNC_START = '\\x1b[?2026h'; // Begin synchronized update\nconst SYNC_END = '\\x1b[?2026l'; // End synchronized update\n\n/**\n * Creates a writable stream that wraps stdout with synchronized output.\n * This batches terminal updates to prevent flickering in terminals like iTerm2.\n *\n * The wrapper:\n * 1. Buffers writes during a short window\n * 2. Wraps the buffered output with sync start/end sequences\n * 3. Flushes to the real stdout\n */\nexport function createSyncOutputStream(\n stdout: NodeJS.WriteStream,\n): SyncOutputStream {\n let buffer = '';\n let flushTimeout: ReturnType<typeof setTimeout> | null = null;\n const FLUSH_DELAY = 4; // 4ms batching window (slightly less than one frame at 60fps)\n\n const flush = () => {\n if (buffer.length > 0) {\n // Wrap the buffered output with synchronized update sequences\n stdout.write(SYNC_START + buffer + SYNC_END);\n buffer = '';\n }\n flushTimeout = null;\n };\n\n const stream = new Writable({\n write(\n chunk: Buffer | string,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ) {\n // Convert chunk to string - use utf8 for Buffer, direct for string\n const str = typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n buffer += str;\n\n // Schedule flush if not already scheduled\n if (!flushTimeout) {\n flushTimeout = setTimeout(flush, FLUSH_DELAY);\n }\n\n callback();\n },\n final(callback: (error?: Error | null) => void) {\n if (flushTimeout) {\n clearTimeout(flushTimeout);\n flushTimeout = null;\n }\n flush();\n callback();\n },\n });\n\n // Proxy important properties from stdout\n Object.defineProperty(stream, 'columns', {\n get: () => stdout.columns,\n });\n Object.defineProperty(stream, 'rows', {\n get: () => stdout.rows,\n });\n Object.defineProperty(stream, 'isTTY', {\n get: () => stdout.isTTY,\n });\n\n // Proxy resize events\n stdout.on('resize', () => {\n stream.emit('resize');\n });\n\n const proxy = Object.create(\n stdout,\n Object.getOwnPropertyDescriptors(stream),\n ) as WriteStreamProxy;\n\n proxy._flushSyncOutput = flush;\n\n return proxy;\n}\n"],"mappings":"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","names":["Box","Text","useInput","useStdout","useCallback","useEffect","useMemo","useRef","useState","Box","Text","memo","useMemo","useRef","MenuItem","SlashCommandMenu","jsx","jsxs","memo","InputBox","useMemo","useRef","Box","Text","useOnClick","Box","Text","useInput","memo","useMemo","useRef","useState","useOnClick","useOnMouseMove","Box","Text","useInput","memo","useRef","useState","jsx","jsxs","memo","MenuItemRow","useRef","useOnMouseMove","useOnClick","Box","Text","MessageContextMenu","useState","useInput","jsx","jsxs","Text","parsed","Box","memo","Message","useRef","useMemo","useOnClick","EmptyState","MessageList","useState","useInput","useOnClick","useOnMouseMove","Box","Text","useInput","memo","useRef","useState","jsx","jsxs","memo","ModelRow","useRef","useOnMouseMove","useOnClick","Box","Text","useState","useInput","Box","Text","memo","jsx","jsxs","memo","SessionHeader","Box","Text","useOnClick","useOnMouseMove","Box","Text","useInput","useStdout","memo","useRef","useState","jsx","jsxs","memo","SessionRow","useRef","useOnMouseMove","useOnClick","Box","Text","useStdout","useState","useInput","useOnClick","useOnMouseMove","useOnWheel","Box","Text","useInput","useStdout","memo","useRef","useState","jsx","jsxs","memo","ThemeRow","useRef","useOnMouseMove","useOnClick","Box","Text","useStdout","useState","useInput","useOnWheel","Box","Text","memo","Box","Text","memo","useMemo","jsx","memo","CatIcon","useMemo","Box","Text","jsx","jsxs","memo","WelcomeScreen","Box","Text","jsx","jsxs","useStdout","useState","useRef","useEffect","activeProvider","useCallback","useInput","useMemo","Box","Text"]}
|