jh-web-gateway 2.1.0 → 2.2.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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tui/index.ts","../src/tui/App.tsx","../src/tui/AppContext.tsx","../src/tui/components/HeaderBar.tsx","../src/tui/components/FooterBar.tsx","../src/tui/components/QuitDialog.tsx","../src/tui/services/gateway-lifecycle.ts","../src/tui/utils/shortcuts.ts","../src/tui/panels/SplashScreen.tsx","../src/tui/panels/MainMenu.tsx","../src/tui/types.ts","../src/tui/utils/navigation.ts","../src/tui/panels/GatewayPanel.tsx","../src/tui/panels/ModelSelector.tsx","../src/tui/panels/ChatPanel.tsx","../src/tui/panels/InfoPanel.tsx","../src/tui/utils/clipboard.ts","../src/tui/panels/SettingsPanel.tsx"],"sourcesContent":["import React from \"react\";\nimport { render } from \"ink\";\nimport { App } from \"./App.js\";\n\nexport async function launchTui(): Promise<void> {\n // ── Terminal size check ────────────────────────────────────────────────────\n const checkSize = (): boolean => {\n const cols = process.stdout.columns ?? 0;\n const rows = process.stdout.rows ?? 0;\n return cols >= 80 && rows >= 24;\n };\n\n if (!checkSize()) {\n process.stderr.write(\n `Terminal too small (${process.stdout.columns ?? 0}×${process.stdout.rows ?? 0}). ` +\n `Please resize to at least 80×24.\\n`,\n );\n await new Promise<void>((resolve) => {\n const onResize = () => {\n if (checkSize()) {\n process.stdout.removeListener(\"resize\", onResize);\n resolve();\n }\n };\n process.stdout.on(\"resize\", onResize);\n });\n }\n\n // ── Shutdown callback registered by AppContent ─────────────────────────────\n let shutdown: (() => Promise<void>) | null = null;\n\n const { waitUntilExit, unmount } = render(\n React.createElement(App, {\n onRegisterShutdown: (fn) => {\n shutdown = fn;\n },\n }),\n { exitOnCtrlC: false },\n );\n\n // ── Signal handlers ────────────────────────────────────────────────────────\n const handleSignal = (): void => {\n void (async () => {\n try {\n if (shutdown) await shutdown();\n } catch {\n // ignore errors during graceful shutdown\n }\n unmount();\n process.exit(0);\n })();\n };\n\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n // ── Unhandled error safety net ─────────────────────────────────────────────\n process.on(\"uncaughtException\", (err) => {\n unmount();\n process.stderr.write(`Unhandled error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n });\n\n try {\n await waitUntilExit();\n } finally {\n process.removeListener(\"SIGINT\", handleSignal);\n process.removeListener(\"SIGTERM\", handleSignal);\n }\n}\n","import React, { useState, useRef, useEffect } from \"react\";\nimport { Box, useInput } from \"ink\";\nimport { AppProvider, useAppContext } from \"./AppContext.js\";\nimport { HeaderBar } from \"./components/HeaderBar.js\";\nimport { FooterBar } from \"./components/FooterBar.js\";\nimport { QuitDialog } from \"./components/QuitDialog.js\";\nimport { PANEL_SHORTCUTS } from \"./utils/shortcuts.js\";\nimport { SplashScreen } from \"./panels/SplashScreen.js\";\nimport { MainMenu } from \"./panels/MainMenu.js\";\nimport { GatewayPanel } from \"./panels/GatewayPanel.js\";\nimport { ModelSelector } from \"./panels/ModelSelector.js\";\nimport { ChatPanel } from \"./panels/ChatPanel.js\";\nimport { InfoPanel } from \"./panels/InfoPanel.js\";\nimport { SettingsPanel } from \"./panels/SettingsPanel.js\";\nimport { stopGateway } from \"./services/gateway-lifecycle.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\ninterface AppProps {\n onRegisterShutdown?: (fn: () => Promise<void>) => void;\n}\n\n// ── Inner component (inside AppProvider) ──────────────────────────────────────\n\nfunction AppContent({ onRegisterShutdown }: AppProps): React.ReactElement {\n const { state, navigate, setActiveModel } = useAppContext();\n const { currentPanel, gatewayStatus, activeModel } = state;\n\n const [showQuit, setShowQuit] = useState(false);\n\n // Keep a ref to the latest state so the shutdown closure always sees fresh values\n const latestStateRef = useRef(state);\n useEffect(() => {\n latestStateRef.current = state;\n });\n\n // Register the shutdown function once on mount\n useEffect(() => {\n if (onRegisterShutdown) {\n onRegisterShutdown(async () => {\n const { gatewayStatus: status, serverHandle, chromeState, tokenRefresher } =\n latestStateRef.current;\n if (status === \"running\" && serverHandle && chromeState && tokenRefresher) {\n await stopGateway(serverHandle, chromeState, tokenRefresher);\n }\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Global q handler — active only when the quit dialog is not already showing\n // and not on the splash screen\n useInput(\n (input) => {\n if (input === \"q\" && currentPanel !== \"splash\") {\n setShowQuit(true);\n }\n },\n { isActive: !showQuit },\n );\n\n // ── Panel router ─────────────────────────────────────────────────────────────\n\n const renderPanel = (): React.ReactElement => {\n switch (currentPanel) {\n case \"splash\":\n return <SplashScreen onComplete={() => navigate(\"menu\")} />;\n case \"menu\":\n return <MainMenu onQuit={() => setShowQuit(true)} />;\n case \"gateway\":\n return <GatewayPanel />;\n case \"model\":\n return (\n <ModelSelector\n activeModel={activeModel}\n onSelect={(model) => setActiveModel(model)}\n onBack={() => navigate(\"menu\")}\n />\n );\n case \"chat\":\n return <ChatPanel />;\n case \"info\":\n return <InfoPanel />;\n case \"settings\":\n return <SettingsPanel />;\n }\n };\n\n // ── Layout ───────────────────────────────────────────────────────────────────\n\n return (\n <Box flexDirection=\"column\" height=\"100%\">\n <HeaderBar gatewayStatus={gatewayStatus} />\n <Box flexGrow={1} flexDirection=\"column\">\n {showQuit ? (\n <QuitDialog onCancel={() => setShowQuit(false)} />\n ) : (\n renderPanel()\n )}\n </Box>\n <FooterBar shortcuts={PANEL_SHORTCUTS[currentPanel]} />\n </Box>\n );\n}\n\n// ── Root component ─────────────────────────────────────────────────────────────\n\nexport function App({ onRegisterShutdown }: AppProps): React.ReactElement {\n return (\n <AppProvider>\n <AppContent onRegisterShutdown={onRegisterShutdown} />\n </AppProvider>\n );\n}\n","import React, { createContext, useContext, useState, useEffect } from \"react\";\nimport { loadConfig } from \"../infra/config.js\";\nimport type { GatewayConfig } from \"../infra/types.js\";\nimport type { TuiAppState, PanelId } from \"./types.js\";\nimport type { ChromeManagerState } from \"../infra/chrome-manager.js\";\nimport type { TokenRefresher } from \"../core/token-refresher.js\";\nimport type { ServerHandle } from \"../server.js\";\n\n// ── Context value type ─────────────────────────────────────────────────────────\n\ninterface AppContextValue {\n state: TuiAppState;\n navigate: (panelId: PanelId) => void;\n setGatewayStatus: (status: TuiAppState[\"gatewayStatus\"]) => void;\n setGatewayError: (error: string | null) => void;\n setActiveModel: (model: string) => void;\n setServerHandle: (handle: ServerHandle | null) => void;\n setChromeState: (state: ChromeManagerState | null) => void;\n setTokenRefresher: (refresher: TokenRefresher | null) => void;\n setConfig: (config: GatewayConfig) => void;\n}\n\n// ── Default/initial state ──────────────────────────────────────────────────────\n\nconst defaultConfig: GatewayConfig = {\n cdpUrl: \"http://127.0.0.1:9222\",\n port: 8741,\n defaultModel: \"claude-opus-4.5\",\n defaultEndpoint: \"AnthropicClaude\",\n credentials: null,\n auth: { mode: \"none\", token: null },\n maxQueueWaitMs: 120000,\n};\n\nconst initialState: TuiAppState = {\n currentPanel: \"splash\",\n gatewayStatus: \"stopped\",\n gatewayError: null,\n activeModel: defaultConfig.defaultModel,\n config: defaultConfig,\n serverHandle: null,\n chromeState: null,\n tokenRefresher: null,\n};\n\n// ── Context ────────────────────────────────────────────────────────────────────\n\nconst AppContext = createContext<AppContextValue | null>(null);\n\n// ── Provider ──────────────────────────────────────────────────────────────────\n\ninterface AppProviderProps {\n children: React.ReactNode;\n}\n\nexport function AppProvider({ children }: AppProviderProps): React.ReactElement {\n const [state, setState] = useState<TuiAppState>(initialState);\n\n useEffect(() => {\n loadConfig()\n .then((config) => {\n setState((prev) => ({\n ...prev,\n config,\n activeModel: config.defaultModel,\n }));\n })\n .catch(() => {\n // Keep defaults on error\n });\n }, []);\n\n const navigate = (panelId: PanelId): void => {\n setState((prev) => ({ ...prev, currentPanel: panelId }));\n };\n\n const setGatewayStatus = (status: TuiAppState[\"gatewayStatus\"]): void => {\n setState((prev) => ({ ...prev, gatewayStatus: status }));\n };\n\n const setGatewayError = (error: string | null): void => {\n setState((prev) => ({ ...prev, gatewayError: error }));\n };\n\n const setActiveModel = (model: string): void => {\n setState((prev) => ({ ...prev, activeModel: model }));\n };\n\n const setServerHandle = (handle: ServerHandle | null): void => {\n setState((prev) => ({ ...prev, serverHandle: handle }));\n };\n\n const setChromeState = (chromeState: ChromeManagerState | null): void => {\n setState((prev) => ({ ...prev, chromeState }));\n };\n\n const setTokenRefresher = (refresher: TokenRefresher | null): void => {\n setState((prev) => ({ ...prev, tokenRefresher: refresher }));\n };\n\n const setConfig = (config: GatewayConfig): void => {\n setState((prev) => ({ ...prev, config }));\n };\n\n const value: AppContextValue = {\n state,\n navigate,\n setGatewayStatus,\n setGatewayError,\n setActiveModel,\n setServerHandle,\n setChromeState,\n setTokenRefresher,\n setConfig,\n };\n\n return <AppContext.Provider value={value}>{children}</AppContext.Provider>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────────────────\n\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContext);\n if (!ctx) {\n throw new Error(\"useAppContext must be used within AppProvider\");\n }\n return ctx;\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\ninterface HeaderBarProps {\n gatewayStatus: \"stopped\" | \"starting\" | \"running\" | \"error\";\n}\n\nexport function HeaderBar({ gatewayStatus }: HeaderBarProps): React.ReactElement {\n const dotColor =\n gatewayStatus === \"running\"\n ? \"green\"\n : gatewayStatus === \"starting\"\n ? \"yellow\"\n : \"red\";\n\n const statusLabel =\n gatewayStatus === \"running\"\n ? \"running\"\n : gatewayStatus === \"starting\"\n ? \"starting\"\n : gatewayStatus === \"error\"\n ? \"error\"\n : \"stopped\";\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Text bold>jh-gateway</Text>\n <Text>\n <Text color={dotColor}>●</Text>\n {\" \"}\n <Text>Gateway: {statusLabel}</Text>\n </Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport type { FooterShortcut } from \"../types.js\";\n\ninterface FooterBarProps {\n shortcuts: FooterShortcut[];\n}\n\nexport function FooterBar({ shortcuts }: FooterBarProps): React.ReactElement {\n return (\n <Box width=\"100%\" gap={2}>\n {shortcuts.map((s) => (\n <Text key={s.key}>\n <Text dimColor>{\"[\"}</Text>\n <Text bold>{s.key}</Text>\n <Text dimColor>{\"]\"}</Text>\n {\" \"}\n <Text>{s.label}</Text>\n </Text>\n ))}\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\nimport { stopGateway } from \"../services/gateway-lifecycle.js\";\n\ninterface QuitDialogProps {\n onCancel: () => void;\n}\n\nexport function QuitDialog({ onCancel }: QuitDialogProps): React.ReactElement {\n const { state } = useAppContext();\n const { gatewayStatus, serverHandle, chromeState, tokenRefresher } = state;\n\n useInput((input, key) => {\n if (input === \"y\" || input === \"Y\") {\n void (async () => {\n if (\n gatewayStatus === \"running\" &&\n serverHandle &&\n chromeState &&\n tokenRefresher\n ) {\n try {\n await stopGateway(serverHandle, chromeState, tokenRefresher);\n } catch {\n // proceed with exit even if stop fails\n }\n }\n process.exit(0);\n })();\n } else if (input === \"n\" || input === \"N\" || key.escape) {\n onCancel();\n }\n });\n\n return (\n <Box borderStyle=\"round\" borderColor=\"yellow\" padding={1} flexDirection=\"column\">\n <Text bold color=\"yellow\">\n Quit jh-gateway?\n </Text>\n <Box marginTop={1}>\n <Text>Running gateway will be stopped.</Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>[y] Yes [N/Esc] Cancel</Text>\n </Box>\n </Box>\n );\n}\n","import { ChromeManager } from \"../../infra/chrome-manager.js\";\nimport type { ChromeManagerState } from \"../../infra/chrome-manager.js\";\nimport { findOrOpenJhPage, checkBrowserLoginState } from \"../../infra/chrome-cdp.js\";\nimport { captureCredentials } from \"../../core/auth-capture.js\";\nimport { shouldRefresh, CredentialHolder, TokenRefresher } from \"../../core/token-refresher.js\";\nimport { PagePool } from \"../../core/page-pool.js\";\nimport { startServer } from \"../../server.js\";\nimport type { ServerHandle } from \"../../server.js\";\nimport type { GatewayConfig } from \"../../infra/types.js\";\n\nexport interface GatewayLifecycleCallbacks {\n onPhase: (phase: string) => void;\n onSuccess: (info: { baseUrl: string; apiKey: string | null }) => void;\n onError: (error: Error) => void;\n}\n\nexport interface StartGatewayResult {\n serverHandle: ServerHandle;\n chromeState: ChromeManagerState;\n tokenRefresher: TokenRefresher;\n}\n\nexport async function startGatewayForTui(\n config: GatewayConfig,\n options: { headless?: boolean; pages?: number },\n callbacks: GatewayLifecycleCallbacks,\n): Promise<StartGatewayResult> {\n const maxPages = options.pages ?? 3;\n const cdpPort = parseInt(new URL(config.cdpUrl).port, 10) || 9222;\n\n const chromeManager = new ChromeManager({\n cdpPort,\n headless: options.headless,\n });\n\n // ── Phase 1: Connect to Chrome ────────────────────────────────────────────\n callbacks.onPhase(\"Connecting to Chrome\");\n let state: ChromeManagerState;\n try {\n state = await chromeManager.connect();\n await chromeManager.showWindow(state);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError(error);\n throw error;\n }\n\n // ── Phase 2: Authenticate if needed ──────────────────────────────────────\n const needsAuth =\n !config.credentials ||\n !config.credentials.expiresAt ||\n shouldRefresh(Date.now(), config.credentials.expiresAt, 0);\n\n if (needsAuth) {\n callbacks.onPhase(\"Waiting for login\");\n try {\n const creds = await captureCredentials(config.cdpUrl, 300_000);\n config.credentials = {\n bearerToken: creds.bearerToken,\n cookie: creds.cookie,\n userAgent: creds.userAgent,\n expiresAt: creds.expiresAt,\n };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError(error);\n await chromeManager.shutdown(state);\n throw error;\n }\n } else {\n callbacks.onPhase(\"Verifying browser session\");\n const browserLoggedIn = await checkBrowserLoginState(state.browser);\n if (!browserLoggedIn) {\n callbacks.onPhase(\"Browser session expired — please log in\");\n try {\n const creds = await captureCredentials(config.cdpUrl, 300_000);\n config.credentials = {\n bearerToken: creds.bearerToken,\n cookie: creds.cookie,\n userAgent: creds.userAgent,\n expiresAt: creds.expiresAt,\n };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError(error);\n await chromeManager.shutdown(state);\n throw error;\n }\n }\n }\n\n // ── Phase 3: PagePool, CredentialHolder, Server ───────────────────────────\n callbacks.onPhase(\"Starting server\");\n try {\n const seedPage = await findOrOpenJhPage(state.browser);\n\n const pool = new PagePool({\n maxPages,\n maxWaitMs: config.maxQueueWaitMs,\n });\n await pool.init(state.browser, seedPage);\n\n const credentialHolder = new CredentialHolder();\n if (config.credentials) {\n credentialHolder.set(config.credentials);\n }\n\n const serverHandle = await startServer(config, {\n getPool: () => pool,\n getCredentials: () => credentialHolder.get(),\n });\n\n const tokenRefresher = new TokenRefresher(credentialHolder, config.cdpUrl);\n tokenRefresher.start();\n\n const baseUrl = `http://127.0.0.1:${config.port}`;\n const apiKey = config.auth.token ?? null;\n callbacks.onSuccess({ baseUrl, apiKey });\n\n return { serverHandle, chromeState: state, tokenRefresher };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError(error);\n await chromeManager.shutdown(state);\n throw error;\n }\n}\n\nexport async function stopGateway(\n serverHandle: ServerHandle,\n chromeState: ChromeManagerState,\n tokenRefresher: TokenRefresher,\n): Promise<void> {\n tokenRefresher.stop();\n await serverHandle.close();\n\n // disconnect (not shutdown): hides Chrome and detaches CDP, but keeps\n // the Chrome process alive so the next start reconnects instantly.\n const chromeManager = new ChromeManager();\n await chromeManager.disconnect(chromeState);\n}\n","import type { PanelId, FooterShortcut } from \"../types.js\";\n\nexport const PANEL_SHORTCUTS: Record<PanelId, FooterShortcut[]> = {\n splash: [\n { key: \"any\", label: \"Continue\" },\n ],\n menu: [\n { key: \"↑↓\", label: \"Navigate\" },\n { key: \"Enter\", label: \"Select\" },\n { key: \"q\", label: \"Quit\" },\n ],\n gateway: [\n { key: \"Enter\", label: \"Start/Stop\" },\n { key: \"b\", label: \"Back\" },\n { key: \"q\", label: \"Quit\" },\n ],\n model: [\n { key: \"↑↓\", label: \"Navigate\" },\n { key: \"Enter\", label: \"Select\" },\n { key: \"b\", label: \"Back\" },\n { key: \"q\", label: \"Quit\" },\n ],\n chat: [\n { key: \"Enter\", label: \"Send\" },\n { key: \"b\", label: \"Back\" },\n { key: \"q\", label: \"Quit\" },\n ],\n info: [\n { key: \"c\", label: \"Copy URL\" },\n { key: \"k\", label: \"Copy Key\" },\n { key: \"b\", label: \"Back\" },\n { key: \"q\", label: \"Quit\" },\n ],\n settings: [\n { key: \"Enter\", label: \"Edit\" },\n { key: \"b\", label: \"Back\" },\n { key: \"q\", label: \"Quit\" },\n ],\n};\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport { Box, Text, useInput, useStdout, useAnimation } from \"ink\";\n\nconst JHU_LOGO_LINES = [\n \" ██╗██╗ ██╗ ██╗ ██╗███████╗██████╗ \",\n \" ██║██║ ██║ ██║ ██║██╔════╝██╔══██╗\",\n \" ██║███████║ ██║ █╗ ██║█████╗ ██████╔╝\",\n \"██ ██║██╔══██║ ██║███╗██║██╔══╝ ██╔══██╗\",\n \"╚█████╔╝██║ ██║ ╚███╔███╔╝███████╗██████╔╝\",\n \" ╚════╝ ╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝╚═════╝ \",\n \"\",\n \" ██████╗ █████╗ ████████╗███████╗██╗ ██╗ █████╗ ██╗ ██╗\",\n \" ██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝██║ ██║██╔══██╗╚██╗ ██╔╝\",\n \" ██║ ███╗███████║ ██║ █████╗ ██║ █╗ ██║███████║ ╚████╔╝ \",\n \" ██║ ██║██╔══██║ ██║ ██╔══╝ ██║███╗██║██╔══██║ ╚██╔╝ \",\n \" ╚██████╔╝██║ ██║ ██║ ███████╗╚███╔███╔╝██║ ██║ ██║ \",\n \" ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═╝ \",\n];\n\nconst SUBTITLES = [\n \"// Infinite tokens, for school work of course :)))\",\n \"// powered by caffeine, desperation, and vibes\",\n \"// your professor will never know™\",\n \"// if it works, don't ask why\",\n \"// technically not cheating if the AI is also confused\",\n \"// [ERROR 418: I'm a teapot, but make it AI]\",\n \"// running on 3 hours of sleep and pure audacity\",\n \"// the tokens are infinite but my GPA is not\",\n \"// SYSTEM OVERRIDE: homework.exe has been defeated\",\n \"// now with 40% more hallucinations!\",\n \"// null pointer? more like null problems 😈\",\n \"// WARNING: may cause uncontrollable productivity\",\n \"// all citations are made up but they sound real\",\n \"// NOT affiliated with Skynet (probably)\",\n \"// lorem ipsum but it writes your thesis\",\n \"// sudo make my-homework --grade=A\",\n \"// ship it. always ship it.\",\n \"// this is fine 🔥 everything is fine 🔥\",\n \"// bridging the gap between laziness and genius\",\n \"// if AI wrote this disclaimer, does it count?\",\n];\n\nconst TAGLINE = SUBTITLES[Math.floor(Math.random() * SUBTITLES.length)]!;\nconst GLITCH_CHARS = \"█▓▒░╬╪╫▲▼◆◇○●□■#@$%&?!~^*\";\nconst STAR_CHARS = [\"·\", \".\", \"*\", \"✦\", \"✧\", \"⋆\", \"+\", \"×\"];\nconst LOGO_COLORS = [\"cyan\", \"cyan\", \"blueBright\", \"blueBright\", \"blue\", \"blue\", \"white\", \"greenBright\", \"green\", \"greenBright\", \"green\", \"greenBright\", \"green\"] as const;\n\nconst GLITCH_PHASE_MS = 600;\nconst REVEAL_PHASE_MS = 900;\nconst TYPEWRITER_INTERVAL_MS = 28;\n\nfunction seededRand(seed: number): () => number {\n let s = seed;\n return () => {\n s = (s * 1664525 + 1013904223) & 0xffffffff;\n return (s >>> 0) / 0xffffffff;\n };\n}\n\nfunction glitchLine(line: string, progress: number, rand: () => number): string {\n return line\n .split(\"\")\n .map((ch) => {\n if (ch === \" \" || ch === \"\\n\") return ch;\n if (rand() > progress) {\n return GLITCH_CHARS[Math.floor(rand() * GLITCH_CHARS.length)];\n }\n return ch;\n })\n .join(\"\");\n}\n\ninterface StarfieldProps {\n rows: number;\n cols: number;\n tick: number;\n}\n\nfunction Starfield({ rows, cols, tick }: StarfieldProps): React.ReactElement {\n const rand = seededRand(42);\n const lines: string[] = [];\n for (let r = 0; r < rows; r++) {\n let row = \"\";\n for (let c = 0; c < cols; c++) {\n const base = rand();\n const twinkleOffset = Math.sin((tick * 0.3 + r * 7.3 + c * 3.7)) * 0.5 + 0.5;\n row += base < 0.025 * twinkleOffset ? STAR_CHARS[Math.floor(rand() * STAR_CHARS.length)] : \" \";\n }\n lines.push(row);\n }\n return (\n <Box flexDirection=\"column\" position=\"absolute\" marginTop={0}>\n {lines.map((l, i) => (\n <Text key={i} dimColor color=\"cyan\">{l}</Text>\n ))}\n </Box>\n );\n}\n\ninterface SplashScreenProps {\n onComplete: () => void;\n}\n\nexport function SplashScreen({ onComplete }: SplashScreenProps): React.ReactElement {\n const { stdout } = useStdout();\n const termCols = stdout?.columns ?? 120;\n const termRows = stdout?.rows ?? 30;\n\n const [phase, setPhase] = useState<\"glitch\" | \"reveal\" | \"done\">(\"glitch\");\n const [glitchProgress, setGlitchProgress] = useState(0);\n const [revealedLines, setRevealedLines] = useState(0);\n const [typewriterCount, setTypewriterCount] = useState(0);\n const [showCursor, setShowCursor] = useState(true);\n const skippedRef = useRef(false);\n\n const { frame: tick } = useAnimation({ interval: 80 });\n\n const skip = useCallback(() => {\n if (skippedRef.current) return;\n skippedRef.current = true;\n setPhase(\"done\");\n setRevealedLines(JHU_LOGO_LINES.length);\n setTypewriterCount(TAGLINE.length);\n setShowCursor(false);\n }, []);\n\n useInput((_, key) => {\n if (phase !== \"done\") {\n skip();\n } else {\n onComplete();\n }\n });\n\n useEffect(() => {\n if (skippedRef.current) return;\n const start = Date.now();\n const id = setInterval(() => {\n const elapsed = Date.now() - start;\n const p = Math.min(elapsed / GLITCH_PHASE_MS, 1);\n setGlitchProgress(p);\n if (p >= 1) {\n clearInterval(id);\n setPhase(\"reveal\");\n }\n }, 40);\n return () => clearInterval(id);\n }, []);\n\n useEffect(() => {\n if (phase !== \"reveal\" || skippedRef.current) return;\n const total = JHU_LOGO_LINES.length;\n let count = 0;\n const id = setInterval(() => {\n count++;\n setRevealedLines(count);\n if (count >= total) {\n clearInterval(id);\n setPhase(\"done\");\n }\n }, Math.round(REVEAL_PHASE_MS / total));\n return () => clearInterval(id);\n }, [phase]);\n\n useEffect(() => {\n if (phase !== \"done\") return;\n if (typewriterCount >= TAGLINE.length) return;\n const id = setInterval(() => {\n setTypewriterCount((p) => {\n if (p >= TAGLINE.length) {\n clearInterval(id);\n return p;\n }\n return p + 1;\n });\n }, TYPEWRITER_INTERVAL_MS);\n return () => clearInterval(id);\n }, [phase, typewriterCount]);\n\n useEffect(() => {\n if (phase !== \"done\") return;\n const id = setInterval(() => setShowCursor((p) => !p), 530);\n return () => clearInterval(id);\n }, [phase]);\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" height=\"100%\">\n <Starfield rows={termRows} cols={termCols} tick={tick} />\n\n <Box width=\"100%\" justifyContent=\"flex-end\" paddingRight={2}>\n <Text dimColor color=\"cyan\">v{__APP_VERSION__}</Text>\n </Box>\n\n <Box flexDirection=\"column\" alignItems=\"flex-start\" paddingLeft={2}>\n {JHU_LOGO_LINES.map((line, i) => {\n let displayLine: string;\n const color = LOGO_COLORS[i] ?? \"cyan\";\n\n if (phase === \"glitch\") {\n const lineRand = seededRand(i * 137 + 11);\n displayLine = glitchLine(line, glitchProgress, lineRand);\n } else if (phase === \"reveal\") {\n if (i < revealedLines) {\n displayLine = line;\n } else {\n const lineRand = seededRand(i * 137 + 11);\n displayLine = glitchLine(line, 0.0, lineRand);\n }\n } else {\n displayLine = line;\n }\n\n return (\n <Text key={i} color={color} bold={i < 6}>\n {displayLine}\n </Text>\n );\n })}\n\n {phase === \"done\" && (\n <>\n <Box marginTop={1}>\n <Text color=\"greenBright\">\n {\" \"}\n {TAGLINE.slice(0, typewriterCount)}\n {showCursor ? \"█\" : \" \"}\n </Text>\n </Box>\n {typewriterCount >= TAGLINE.length && (\n <Box marginTop={1}>\n <Text dimColor> Press any key to continue_</Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n );\n}\n","import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { MENU_ITEMS } from \"../types.js\";\nimport { wrapIndex } from \"../utils/navigation.js\";\nimport { useAppContext } from \"../AppContext.js\";\nimport type { PanelId } from \"../types.js\";\n\ninterface MainMenuProps {\n onQuit: () => void;\n}\n\nexport function MainMenu({ onQuit }: MainMenuProps): React.ReactElement {\n const { navigate } = useAppContext();\n const [focusedIndex, setFocusedIndex] = useState(0);\n\n useInput((input, key) => {\n if (key.downArrow) {\n setFocusedIndex((i) => wrapIndex(i, 1, MENU_ITEMS.length));\n } else if (key.upArrow) {\n setFocusedIndex((i) => wrapIndex(i, -1, MENU_ITEMS.length));\n } else if (key.return) {\n const item = MENU_ITEMS[focusedIndex];\n if (item.id === \"quit\") {\n onQuit();\n } else {\n navigate(item.id as PanelId);\n }\n } else if (input === \"q\" || key.escape) {\n onQuit();\n }\n });\n\n const focusedItem = MENU_ITEMS[focusedIndex];\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Main Menu</Text>\n </Box>\n <Box flexDirection=\"column\">\n {MENU_ITEMS.map((item, index) => {\n const isFocused = index === focusedIndex;\n return (\n <Box key={item.id}>\n <Text color={isFocused ? \"cyan\" : undefined} bold={isFocused}>\n {isFocused ? \"> \" : \" \"}\n {item.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>{focusedItem.description}</Text>\n </Box>\n </Box>\n );\n}\n","import type { GatewayConfig } from \"../infra/types.js\";\nimport type { ChromeManagerState } from \"../infra/chrome-manager.js\";\nimport type { TokenRefresher } from \"../core/token-refresher.js\";\nimport type { ServerHandle } from \"../server.js\";\n\n// ── Panel IDs ─────────────────────────────────────────────────────────────────\n\nexport type PanelId = \"splash\" | \"menu\" | \"gateway\" | \"model\" | \"chat\" | \"info\" | \"settings\";\n\n// ── App State ─────────────────────────────────────────────────────────────────\n\nexport interface TuiAppState {\n currentPanel: PanelId;\n gatewayStatus: \"stopped\" | \"starting\" | \"running\" | \"error\";\n gatewayError: string | null;\n activeModel: string;\n config: GatewayConfig;\n serverHandle: ServerHandle | null;\n chromeState: ChromeManagerState | null;\n tokenRefresher: TokenRefresher | null;\n}\n\n// ── Menu ──────────────────────────────────────────────────────────────────────\n\nexport interface MenuItem {\n id: PanelId | \"quit\";\n label: string;\n description: string;\n}\n\nexport const MENU_ITEMS: MenuItem[] = [\n { id: \"gateway\", label: \"Start Gateway\", description: \"Launch Chrome, authenticate, and start the HTTP server\" },\n { id: \"model\", label: \"Model\", description: \"Select the active AI model\" },\n { id: \"chat\", label: \"Chat\", description: \"Send a test message to the running gateway\" },\n { id: \"info\", label: \"Server Info\", description: \"View and copy the server URL and API key\" },\n { id: \"settings\",label: \"Settings\", description: \"View and edit gateway configuration\" },\n { id: \"quit\", label: \"Quit\", description: \"Exit jh-gateway\" },\n];\n\n// ── Gateway Phase ─────────────────────────────────────────────────────────────\n\nexport interface GatewayPhase {\n label: string;\n status: \"pending\" | \"active\" | \"done\" | \"error\";\n}\n\n// ── Footer Shortcut ───────────────────────────────────────────────────────────\n\nexport type FooterShortcut = { key: string; label: string };\n","/**\n * Computes a wrapped index after moving `delta` steps through a list of `listSize` items.\n * Handles both positive (down) and negative (up) deltas, wrapping around boundaries.\n */\nexport function wrapIndex(current: number, delta: number, listSize: number): number {\n return ((current + delta) % listSize + listSize) % listSize;\n}\n","import React, { useState, useCallback } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\nimport { startGatewayForTui, stopGateway } from \"../services/gateway-lifecycle.js\";\nimport type { GatewayPhase } from \"../types.js\";\n\nconst PHASE_LABELS = [\"Connecting to Chrome\", \"Waiting for login\", \"Starting server\"];\n\nfunction phaseIcon(status: GatewayPhase[\"status\"]): string {\n switch (status) {\n case \"pending\": return \"○\";\n case \"active\": return \"◌\";\n case \"done\": return \"●\";\n case \"error\": return \"✗\";\n }\n}\n\nfunction phaseColor(status: GatewayPhase[\"status\"]): string | undefined {\n switch (status) {\n case \"done\": return \"green\";\n case \"active\": return \"cyan\";\n case \"error\": return \"red\";\n default: return \"gray\";\n }\n}\n\nexport function GatewayPanel(): React.ReactElement {\n const { state, navigate, setGatewayStatus, setGatewayError, setServerHandle, setChromeState, setTokenRefresher } = useAppContext();\n const { gatewayStatus, gatewayError, config, serverHandle, chromeState, tokenRefresher } = state;\n\n const [phases, setPhases] = useState<GatewayPhase[]>([]);\n const [starting, setStarting] = useState(false);\n const [stopping, setStopping] = useState(false);\n const [authPrompt, setAuthPrompt] = useState(false);\n\n const handleStart = useCallback(async () => {\n if (starting || stopping) return;\n setStarting(true);\n setGatewayError(null);\n setGatewayStatus(\"starting\");\n setAuthPrompt(false);\n\n const initial: GatewayPhase[] = PHASE_LABELS.map((label) => ({ label, status: \"pending\" }));\n setPhases(initial);\n\n let phaseIndex = 0;\n\n try {\n const result = await startGatewayForTui(\n config,\n { headless: false },\n {\n onPhase: (phase) => {\n const idx = PHASE_LABELS.indexOf(phase);\n if (idx >= 0) {\n if (phase === \"Waiting for login\") setAuthPrompt(true);\n else setAuthPrompt(false);\n phaseIndex = idx;\n setPhases((prev) =>\n prev.map((p, i) => {\n if (i < idx) return { ...p, status: \"done\" };\n if (i === idx) return { ...p, status: \"active\" };\n return p;\n }),\n );\n }\n },\n onSuccess: ({ baseUrl: _baseUrl, apiKey: _apiKey }) => {\n setAuthPrompt(false);\n setPhases((prev) => prev.map((p) => ({ ...p, status: \"done\" })));\n },\n onError: (_err) => {\n setPhases((prev) =>\n prev.map((p, i) => {\n if (i === phaseIndex) return { ...p, status: \"error\" };\n if (i < phaseIndex) return { ...p, status: \"done\" };\n return p;\n }),\n );\n },\n },\n );\n setServerHandle(result.serverHandle);\n setChromeState(result.chromeState);\n setTokenRefresher(result.tokenRefresher);\n setGatewayStatus(\"running\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n setGatewayError(message);\n setGatewayStatus(\"error\");\n } finally {\n setStarting(false);\n }\n }, [starting, stopping, config, setGatewayStatus, setGatewayError, setServerHandle, setChromeState, setTokenRefresher]);\n\n const handleStop = useCallback(async () => {\n if (stopping || starting || !serverHandle || !chromeState || !tokenRefresher) return;\n setStopping(true);\n try {\n await stopGateway(serverHandle, chromeState, tokenRefresher);\n setServerHandle(null);\n setChromeState(null);\n setTokenRefresher(null);\n setGatewayStatus(\"stopped\");\n setGatewayError(null);\n setPhases([]);\n } finally {\n setStopping(false);\n }\n }, [stopping, starting, serverHandle, chromeState, tokenRefresher, setGatewayStatus, setGatewayError, setServerHandle, setChromeState, setTokenRefresher]);\n\n useInput((_input, key) => {\n if (key.return) {\n if (gatewayStatus === \"running\") {\n void handleStop();\n } else if (gatewayStatus !== \"starting\") {\n void handleStart();\n }\n } else if (_input === \"b\" || key.escape) {\n navigate(\"menu\");\n }\n });\n\n const isRunning = gatewayStatus === \"running\";\n const isStopped = gatewayStatus === \"stopped\" || gatewayStatus === \"error\";\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Gateway Control</Text>\n </Box>\n\n {/* Action button */}\n <Box marginBottom={1}>\n {starting ? (\n <Text color=\"cyan\">Starting gateway…</Text>\n ) : stopping ? (\n <Text color=\"yellow\">Stopping gateway…</Text>\n ) : isRunning ? (\n <Text>\n <Text color=\"green\">● Running</Text>\n {\" \"}\n <Text dimColor>[Enter] Stop</Text>\n </Text>\n ) : (\n <Text>\n <Text color={gatewayStatus === \"error\" ? \"red\" : \"gray\"}>\n ● {gatewayStatus === \"error\" ? \"Error\" : \"Stopped\"}\n </Text>\n {\" \"}\n <Text dimColor>[Enter] {gatewayStatus === \"error\" ? \"Retry\" : \"Start\"}</Text>\n </Text>\n )}\n </Box>\n\n {/* Phase indicators */}\n {phases.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {phases.map((phase) => (\n <Box key={phase.label}>\n <Text color={phaseColor(phase.status)}>\n {phaseIcon(phase.status)} {phase.label}\n </Text>\n </Box>\n ))}\n </Box>\n )}\n\n {/* Auth prompt */}\n {authPrompt && (\n <Box marginBottom={1} borderStyle=\"round\" borderColor=\"yellow\" padding={1}>\n <Text color=\"yellow\">Please log in via the Chrome window</Text>\n </Box>\n )}\n\n {/* Error message */}\n {gatewayStatus === \"error\" && gatewayError && (\n <Box marginBottom={1}>\n <Text color=\"red\">Error: {gatewayError}</Text>\n </Box>\n )}\n\n {/* Connected info */}\n {isRunning && (\n <Box>\n <Text color=\"green\">Gateway running on http://127.0.0.1:{config.port}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n {isStopped && <Text dimColor>[b/Esc] Back to menu</Text>}\n {isRunning && <Text dimColor>[b/Esc] Back (gateway keeps running)</Text>}\n </Box>\n </Box>\n );\n}\n","import React, { useState, useEffect } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { MODEL_ENDPOINT_MAP } from \"../../infra/types.js\";\nimport { updateConfig } from \"../../infra/config.js\";\nimport { wrapIndex } from \"../utils/navigation.js\";\n\nconst MODELS = Object.keys(MODEL_ENDPOINT_MAP);\n\ninterface ModelSelectorProps {\n activeModel: string;\n onSelect: (model: string) => void;\n onBack: () => void;\n}\n\nexport function ModelSelector({ activeModel, onSelect, onBack }: ModelSelectorProps): React.ReactElement {\n const [focusedIndex, setFocusedIndex] = useState(() => {\n const idx = MODELS.indexOf(activeModel);\n return idx >= 0 ? idx : 0;\n });\n const [confirmationModel, setConfirmationModel] = useState<string | null>(null);\n\n useEffect(() => {\n if (confirmationModel !== null) {\n const timer = setTimeout(() => setConfirmationModel(null), 1500);\n return () => clearTimeout(timer);\n }\n }, [confirmationModel]);\n\n useInput((input, key) => {\n if (key.downArrow) {\n setFocusedIndex((i) => wrapIndex(i, 1, MODELS.length));\n } else if (key.upArrow) {\n setFocusedIndex((i) => wrapIndex(i, -1, MODELS.length));\n } else if (key.return) {\n const selected = MODELS[focusedIndex];\n updateConfig({ defaultModel: selected }).catch(() => {});\n onSelect(selected);\n setConfirmationModel(selected);\n } else if (input === \"b\" || key.escape) {\n onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Select Model</Text>\n </Box>\n <Box flexDirection=\"column\">\n {MODELS.map((model, index) => {\n const isFocused = index === focusedIndex;\n const isActive = model === activeModel;\n return (\n <Box key={model}>\n <Text color={isFocused ? \"cyan\" : undefined} bold={isFocused}>\n {isFocused ? \"> \" : \" \"}\n <Text color={isActive ? \"green\" : \"gray\"}>{isActive ? \"●\" : \"○\"}</Text>\n {\" \"}\n {model}\n </Text>\n </Box>\n );\n })}\n </Box>\n {confirmationModel !== null && (\n <Box marginTop={1}>\n <Text color=\"green\">✓ Selected: {confirmationModel}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\n\ninterface ChatMessage {\n role: \"user\" | \"assistant\" | \"error\";\n content: string;\n}\n\nexport function ChatPanel(): React.ReactElement {\n const { state, navigate } = useAppContext();\n const { gatewayStatus, config, activeModel } = state;\n const gatewayRunning = gatewayStatus === \"running\";\n\n const [input, setInput] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [lastMessage, setLastMessage] = useState<ChatMessage | null>(null);\n const [lastUserInput, setLastUserInput] = useState<string | null>(null);\n\n const handleSubmit = async (value: string) => {\n if (!gatewayRunning) {\n navigate(\"gateway\");\n return;\n }\n const trimmed = value.trim();\n if (!trimmed || loading) return;\n\n setLastUserInput(trimmed);\n setLastMessage(null);\n setLoading(true);\n setInput(\"\");\n\n const port = config.port;\n const apiKey = config.auth.token ?? null;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n let response: Response;\n try {\n response = await fetch(`http://127.0.0.1:${port}/v1/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),\n },\n body: JSON.stringify({\n model: activeModel,\n messages: [{ role: \"user\", content: trimmed }],\n }),\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n let errMsg = `Error ${response.status}`;\n try {\n const errBody = await response.json() as { error?: { message?: string } };\n if (errBody?.error?.message) errMsg += `: ${errBody.error.message}`;\n } catch { /* ignore */ }\n setLastMessage({ role: \"error\", content: errMsg });\n return;\n }\n\n const data = await response.json() as { choices?: Array<{ message?: { content?: string | null } }> };\n const content = data?.choices?.[0]?.message?.content ?? \"\";\n setLastMessage({ role: \"assistant\", content });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n setLastMessage({ role: \"error\", content: \"Request timed out\" });\n } else {\n const msg = err instanceof Error ? err.message : String(err);\n setLastMessage({ role: \"error\", content: `Connection failed: ${msg}` });\n }\n } finally {\n setLoading(false);\n }\n };\n\n useInput((_input, key) => {\n if (!gatewayRunning) {\n if (key.return) navigate(\"gateway\");\n else if (_input === \"b\" || key.escape) navigate(\"menu\");\n return;\n }\n\n if (key.escape) {\n if (!loading) navigate(\"menu\");\n return;\n }\n\n if (key.return) {\n void handleSubmit(input);\n return;\n }\n\n if (loading) return;\n\n if (key.backspace || key.delete) {\n setInput((prev) => prev.slice(0, -1));\n return;\n }\n\n if (_input && !key.ctrl && !key.meta) {\n setInput((prev) => prev + _input);\n }\n });\n\n if (!gatewayRunning) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Chat</Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"yellow\">Gateway is not running. Press Enter to start it.</Text>\n </Box>\n <Box>\n <Text dimColor>[b/Esc] Back</Text>\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Chat</Text>\n <Text dimColor> Model: {activeModel}</Text>\n </Box>\n\n {/* Response area */}\n <Box flexDirection=\"column\" marginBottom={1} minHeight={6}>\n {lastUserInput && (\n <Box marginBottom={1}>\n <Text color=\"cyan\">You: {lastUserInput}</Text>\n </Box>\n )}\n {loading && (\n <Box>\n <Text color=\"yellow\">Thinking…</Text>\n </Box>\n )}\n {!loading && lastMessage?.role === \"assistant\" && (\n <Box>\n <Text color=\"green\">Assistant: {lastMessage.content}</Text>\n </Box>\n )}\n {!loading && lastMessage?.role === \"error\" && (\n <Box>\n <Text color=\"red\">{lastMessage.content}</Text>\n </Box>\n )}\n </Box>\n\n {/* Input area */}\n <Box borderStyle=\"round\" borderColor=\"gray\" paddingX={1}>\n <Text>\n {input.length > 0 ? input : <Text dimColor>Type a message and press Enter…</Text>}\n <Text color=\"cyan\">█</Text>\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>[Enter] Send [b/Esc] Back</Text>\n </Box>\n </Box>\n );\n}\n","import React, { useState, useEffect } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\nimport { copyToClipboard } from \"../utils/clipboard.js\";\n\nexport function InfoPanel(): React.ReactElement {\n const { state, navigate } = useAppContext();\n const { gatewayStatus, config } = state;\n const gatewayRunning = gatewayStatus === \"running\";\n\n const port = config.port;\n const apiKey = config.auth.token ?? null;\n const baseUrl = `http://127.0.0.1:${port}`;\n\n const [flash, setFlash] = useState<string | null>(null);\n const [clipboardFailed, setClipboardFailed] = useState<{ url?: boolean; key?: boolean }>({});\n\n useEffect(() => {\n if (flash !== null) {\n const timer = setTimeout(() => setFlash(null), 1500);\n return () => clearTimeout(timer);\n }\n }, [flash]);\n\n useInput((_input, key) => {\n if (_input === \"c\") {\n copyToClipboard(baseUrl).then((ok) => {\n if (ok) {\n setFlash(\"Copied URL!\");\n setClipboardFailed((prev) => ({ ...prev, url: false }));\n } else {\n setFlash(\"Clipboard unavailable\");\n setClipboardFailed((prev) => ({ ...prev, url: true }));\n }\n }).catch(() => {\n setFlash(\"Clipboard unavailable\");\n setClipboardFailed((prev) => ({ ...prev, url: true }));\n });\n return;\n }\n\n if (_input === \"k\") {\n if (!apiKey) return;\n copyToClipboard(apiKey).then((ok) => {\n if (ok) {\n setFlash(\"Copied API key!\");\n setClipboardFailed((prev) => ({ ...prev, key: false }));\n } else {\n setFlash(\"Clipboard unavailable\");\n setClipboardFailed((prev) => ({ ...prev, key: true }));\n }\n }).catch(() => {\n setFlash(\"Clipboard unavailable\");\n setClipboardFailed((prev) => ({ ...prev, key: true }));\n });\n return;\n }\n\n if (_input === \"b\" || key.escape) {\n navigate(\"menu\");\n }\n });\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Server Info</Text>\n </Box>\n\n {!gatewayRunning && (\n <Box marginBottom={1}>\n <Text color=\"red\">● Gateway not running</Text>\n </Box>\n )}\n\n <Box borderStyle=\"round\" borderColor={gatewayRunning ? \"green\" : \"gray\"} padding={1} flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text bold>Base URL: </Text>\n <Text color={gatewayRunning ? \"green\" : \"gray\"}>{baseUrl}</Text>\n </Box>\n {clipboardFailed.url && (\n <Box marginBottom={1}>\n <Box borderStyle=\"single\" borderColor=\"yellow\" paddingX={1}>\n <Text color=\"yellow\">{baseUrl}</Text>\n </Box>\n </Box>\n )}\n <Box>\n <Text bold>API Key: </Text>\n {apiKey ? (\n <Text color={gatewayRunning ? \"cyan\" : \"gray\"}>{apiKey}</Text>\n ) : (\n <Text dimColor>no auth</Text>\n )}\n </Box>\n {clipboardFailed.key && apiKey && (\n <Box marginTop={1}>\n <Box borderStyle=\"single\" borderColor=\"yellow\" paddingX={1}>\n <Text color=\"yellow\">{apiKey}</Text>\n </Box>\n </Box>\n )}\n </Box>\n\n {flash && (\n <Box marginBottom={1}>\n <Text color={flash.startsWith(\"Copied\") ? \"green\" : \"yellow\"}>{flash}</Text>\n </Box>\n )}\n\n <Box>\n <Text dimColor>[c] Copy URL {apiKey ? \"[k] Copy Key \" : \"\"}[b/Esc] Back</Text>\n </Box>\n </Box>\n );\n}\n","import { spawn } from \"node:child_process\";\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n let command: string;\n let args: string[];\n\n switch (process.platform) {\n case \"darwin\":\n command = \"pbcopy\";\n args = [];\n break;\n case \"linux\":\n command = \"xclip\";\n args = [\"-selection\", \"clipboard\"];\n break;\n case \"win32\":\n command = \"clip\";\n args = [];\n break;\n default:\n return false;\n }\n\n return new Promise((resolve) => {\n let proc: ReturnType<typeof spawn>;\n try {\n proc = spawn(command, args, { stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n } catch {\n resolve(false);\n return;\n }\n\n proc.on(\"error\", () => resolve(false));\n proc.on(\"close\", (code) => resolve(code === 0));\n\n try {\n proc.stdin?.write(text);\n proc.stdin?.end();\n } catch {\n resolve(false);\n }\n });\n}\n","import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\nimport { updateConfig, validateConfig } from \"../../infra/config.js\";\n\ninterface SettingField {\n key: string;\n label: string;\n getValue: (config: ReturnType<typeof getConfigSnapshot>) => string;\n applyValue: (config: ReturnType<typeof getConfigSnapshot>, raw: string) => Record<string, unknown>;\n validate: (raw: string) => string | null;\n}\n\ninterface ConfigSnapshot {\n port: number;\n cdpUrl: string;\n defaultModel: string;\n authMode: string;\n}\n\nfunction getConfigSnapshot(config: { port: number; cdpUrl: string; defaultModel: string; auth: { mode: string } }): ConfigSnapshot {\n return {\n port: config.port,\n cdpUrl: config.cdpUrl,\n defaultModel: config.defaultModel,\n authMode: config.auth.mode,\n };\n}\n\nconst FIELDS: SettingField[] = [\n {\n key: \"port\",\n label: \"Port\",\n getValue: (s) => String(s.port),\n applyValue: (_s, raw) => ({ port: parseInt(raw, 10) }),\n validate: (raw) => {\n const n = parseInt(raw, 10);\n if (isNaN(n) || n < 1 || n > 65535) return \"Port must be between 1 and 65535\";\n return null;\n },\n },\n {\n key: \"cdpUrl\",\n label: \"CDP URL\",\n getValue: (s) => s.cdpUrl,\n applyValue: (_s, raw) => ({ cdpUrl: raw }),\n validate: (raw) => {\n if (!/^https?:\\/\\//.test(raw)) return \"CDP URL must start with http:// or https://\";\n return null;\n },\n },\n {\n key: \"defaultModel\",\n label: \"Default Model\",\n getValue: (s) => s.defaultModel,\n applyValue: (_s, raw) => ({ defaultModel: raw }),\n validate: (raw) => {\n if (!raw.trim()) return \"Model must be a non-empty string\";\n return null;\n },\n },\n {\n key: \"authMode\",\n label: \"Auth Mode\",\n getValue: (s) => s.authMode,\n applyValue: (_s, raw) => ({ auth: { mode: raw } }),\n validate: (raw) => {\n if (raw !== \"none\" && raw !== \"bearer\" && raw !== \"basic\")\n return 'Auth mode must be \"none\", \"bearer\", or \"basic\"';\n return null;\n },\n },\n];\n\nexport function SettingsPanel(): React.ReactElement {\n const { state, navigate, setConfig } = useAppContext();\n const { config } = state;\n\n const snapshot = getConfigSnapshot(config);\n\n const [focusedField, setFocusedField] = useState(0);\n const [editingField, setEditingField] = useState<number | null>(null);\n const [editValue, setEditValue] = useState(\"\");\n const [fieldError, setFieldError] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [savedField, setSavedField] = useState<string | null>(null);\n\n const confirmEdit = async () => {\n if (editingField === null) return;\n const field = FIELDS[editingField];\n\n const validErr = field.validate(editValue);\n if (validErr) {\n setFieldError(validErr);\n return;\n }\n\n const partial = field.applyValue(snapshot, editValue);\n\n try {\n const merged = { ...config, ...partial } as Record<string, unknown>;\n if (\"auth\" in partial && typeof partial.auth === \"object\") {\n merged.auth = { ...config.auth, ...(partial.auth as Record<string, unknown>) };\n }\n validateConfig(merged);\n await updateConfig(partial as Parameters<typeof updateConfig>[0]);\n\n const updatedConfig = { ...config, ...partial } as typeof config;\n if (\"auth\" in partial && typeof partial.auth === \"object\") {\n updatedConfig.auth = { ...config.auth, ...(partial.auth as { mode?: \"none\" | \"bearer\" | \"basic\"; token?: string | null }) };\n }\n setConfig(updatedConfig);\n setSavedField(field.key);\n setTimeout(() => setSavedField(null), 1500);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setSaveError(msg);\n setTimeout(() => setSaveError(null), 3000);\n return;\n }\n\n setEditingField(null);\n setEditValue(\"\");\n setFieldError(null);\n };\n\n useInput((_input, key) => {\n if (editingField !== null) {\n if (key.escape) {\n setEditingField(null);\n setEditValue(\"\");\n setFieldError(null);\n return;\n }\n if (key.return) {\n void confirmEdit();\n return;\n }\n if (key.backspace || key.delete) {\n setEditValue((prev) => prev.slice(0, -1));\n setFieldError(null);\n return;\n }\n if (_input && !key.ctrl && !key.meta) {\n setEditValue((prev) => prev + _input);\n setFieldError(null);\n return;\n }\n return;\n }\n\n if (key.downArrow) {\n setFocusedField((i) => (i + 1) % FIELDS.length);\n return;\n }\n if (key.upArrow) {\n setFocusedField((i) => (i - 1 + FIELDS.length) % FIELDS.length);\n return;\n }\n if (key.return) {\n const field = FIELDS[focusedField];\n setEditValue(field.getValue(snapshot));\n setEditingField(focusedField);\n setFieldError(null);\n return;\n }\n if (_input === \"b\" || key.escape) {\n navigate(\"menu\");\n }\n });\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold>Settings</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n {FIELDS.map((field, index) => {\n const isFocused = index === focusedField;\n const isEditing = editingField === index;\n const currentValue = field.getValue(snapshot);\n const isSaved = savedField === field.key;\n\n return (\n <Box key={field.key} flexDirection=\"column\" marginBottom={1}>\n <Box>\n <Text color={isFocused ? \"cyan\" : undefined} bold={isFocused}>\n {isFocused ? \"> \" : \" \"}\n <Text bold>{field.label}: </Text>\n {isEditing ? (\n <Text color=\"cyan\">\n {editValue}\n <Text color=\"cyan\">█</Text>\n </Text>\n ) : (\n <Text color={isSaved ? \"green\" : undefined}>\n {currentValue}\n {isSaved ? \" ✓\" : \"\"}\n </Text>\n )}\n </Text>\n </Box>\n {isEditing && fieldError && (\n <Box marginLeft={4}>\n <Text color=\"red\">{fieldError}</Text>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n\n {saveError && (\n <Box marginBottom={1}>\n <Text color=\"red\">{saveError}</Text>\n </Box>\n )}\n\n <Box>\n {editingField !== null ? (\n <Text dimColor>[Enter] Confirm [Esc] Cancel</Text>\n ) : (\n <Text dimColor>[↑↓] Navigate [Enter] Edit [b/Esc] Back</Text>\n )}\n </Box>\n </Box>\n );\n}\n"],"mappings":"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","names":["React","useState","useRef","useEffect","Box","useInput","jsx","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","useState","useEffect","Box","Text","useInput","jsx","jsxs","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","useCallback","Box","Text","useInput","jsx","jsxs","useState","useCallback","useInput","Box","Text","useState","useEffect","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","useEffect","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","jsx","jsxs","useState","useRef","useEffect","useInput","Box","React"]}