jh-web-gateway 2.1.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
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/core/request-activity-tracker.ts","../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/ChatPanel.tsx","../src/tui/panels/InfoPanel.tsx","../src/tui/utils/clipboard.ts","../src/tui/components/RequestTracker.tsx","../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 { 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 } = useAppContext();\n const { currentPanel, gatewayStatus } = 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 \"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\";\nimport type { RequestActivityTracker } from \"../core/request-activity-tracker.js\";\nimport type { RequestQueue } from \"../core/request-queue.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 setRequestTracker: (tracker: RequestActivityTracker | null) => void;\n setRequestQueue: (queue: RequestQueue | null) => 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 requestTracker: null,\n requestQueue: 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 setRequestTracker = (requestTracker: RequestActivityTracker | null): void => {\n setState((prev) => ({ ...prev, requestTracker }));\n };\n\n const setRequestQueue = (requestQueue: RequestQueue | null): void => {\n setState((prev) => ({ ...prev, requestQueue }));\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 setRequestTracker,\n setRequestQueue,\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","/**\n * Pure TypeScript request activity tracker — no React dependency.\n * Maintains the canonical list of HTTP request entries, enforces a bounded\n * retention limit, and exposes state via a subscription model.\n */\n\nexport type RequestStatus = \"active\" | \"completed\" | \"error\";\n\nexport interface RequestEntry {\n id: string;\n method: string;\n path: string;\n status: RequestStatus;\n statusCode: number | null;\n startTime: number;\n endTime: number | null;\n elapsedMs: number | null;\n}\n\nexport type TrackerListener = (entries: ReadonlyArray<RequestEntry>) => void;\n\nexport class RequestActivityTracker {\n private entries: Map<string, RequestEntry> = new Map();\n private orderedIds: string[] = [];\n private listeners: Set<TrackerListener> = new Set();\n private maxCompleted: number;\n\n constructor(maxCompleted: number = 50) {\n this.maxCompleted = maxCompleted;\n }\n\n /** Called by middleware when a request arrives. */\n start(id: string, method: string, path: string): void {\n if (this.entries.has(id)) return;\n\n const entry: RequestEntry = {\n id,\n method,\n path,\n status: \"active\",\n statusCode: null,\n startTime: Date.now(),\n endTime: null,\n elapsedMs: null,\n };\n\n this.entries.set(id, entry);\n this.orderedIds.unshift(id);\n this.notify();\n }\n\n /** Called by middleware when a response is sent. */\n end(id: string, statusCode: number): void {\n const entry = this.entries.get(id);\n if (!entry) return;\n\n const endTime = Date.now();\n entry.status = statusCode >= 200 && statusCode < 300 ? \"completed\" : \"error\";\n entry.statusCode = statusCode;\n entry.endTime = endTime;\n entry.elapsedMs = endTime - entry.startTime;\n\n this.prune();\n this.notify();\n }\n\n /** Subscribe to state changes. Returns unsubscribe function. */\n subscribe(listener: TrackerListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /** Get current snapshot of entries (most-recent-first). */\n getEntries(): ReadonlyArray<RequestEntry> {\n return this.orderedIds\n .map((id) => this.entries.get(id)!)\n .filter(Boolean);\n }\n\n /** Get a single entry by ID. */\n getEntry(id: string): RequestEntry | undefined {\n return this.entries.get(id);\n }\n\n /** Clear all entries. */\n clear(): void {\n this.entries.clear();\n this.orderedIds = [];\n this.notify();\n }\n\n /** Notify all listeners with current entries snapshot. */\n private notify(): void {\n const snapshot = this.getEntries();\n for (const listener of this.listeners) {\n try {\n listener(snapshot);\n } catch (err) {\n console.error(\"[RequestActivityTracker] subscriber error:\", err);\n }\n }\n }\n\n /** Remove oldest completed entries beyond maxCompleted. */\n private prune(): void {\n const completed = this.orderedIds.filter((id) => {\n const e = this.entries.get(id);\n return e && e.status !== \"active\";\n });\n\n while (completed.length > this.maxCompleted) {\n const oldestId = completed.pop()!;\n this.entries.delete(oldestId);\n const idx = this.orderedIds.indexOf(oldestId);\n if (idx !== -1) this.orderedIds.splice(idx, 1);\n }\n }\n}\n\n// ── Formatting utilities ──────────────────────────────────────────────\n\n/** Convert milliseconds to \"X.Xs\" format (e.g., 3200 → \"3.2s\"). */\nexport function formatElapsed(ms: number): string {\n const seconds = Math.round(ms / 100) / 10;\n return `${seconds.toFixed(1)}s`;\n}\n\n/** Format queue depth for display. */\nexport function formatQueueDepth(n: number, online: boolean): string {\n if (!online) return \"Queue: offline\";\n if (n === 0) return \"Queue: idle\";\n return `Queue: ${n} pending`;\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 { RequestActivityTracker } from \"../../core/request-activity-tracker.js\";\nimport { startServer } from \"../../server.js\";\nimport type { ServerHandle } from \"../../server.js\";\nimport type { GatewayConfig } from \"../../infra/types.js\";\nimport type { RequestQueue } from \"../../core/request-queue.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 tracker: RequestActivityTracker;\n requestQueue: RequestQueue;\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 ?? 1;\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 // Grab the RequestQueue reference from the pool (single-page default)\n const { queue: requestQueue, release } = await pool.acquire();\n release();\n\n const tracker = new RequestActivityTracker();\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 requestTracker: tracker,\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, tracker, requestQueue };\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 tracker?: RequestActivityTracker,\n): Promise<void> {\n tokenRefresher.stop();\n if (tracker) tracker.clear();\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 chat: [\n { key: \"Enter\", label: \"Send\" },\n { key: \"↑↓\", label: \"Model\" },\n { key: \"Esc\", 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 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\" | \"done\">(\"glitch\");\n const [glitchProgress, setGlitchProgress] = 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 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(\"done\");\n }\n }, 40);\n return () => clearInterval(id);\n }, []);\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 {\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\";\nimport type { RequestActivityTracker } from \"../core/request-activity-tracker.js\";\nimport type { RequestQueue } from \"../core/request-queue.js\";\n\n// ── Panel IDs ─────────────────────────────────────────────────────────────────\n\nexport type PanelId = \"splash\" | \"menu\" | \"gateway\" | \"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 requestTracker: RequestActivityTracker | null;\n requestQueue: RequestQueue | 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: \"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, setRequestTracker, setRequestQueue } = 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 setRequestTracker(result.tracker);\n setRequestQueue(result.requestQueue);\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, setRequestTracker, setRequestQueue]);\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, state.requestTracker ?? undefined);\n setServerHandle(null);\n setChromeState(null);\n setTokenRefresher(null);\n setRequestTracker(null);\n setRequestQueue(null);\n setGatewayStatus(\"stopped\");\n setGatewayError(null);\n setPhases([]);\n } finally {\n setStopping(false);\n }\n }, [stopping, starting, serverHandle, chromeState, tokenRefresher, state.requestTracker, setGatewayStatus, setGatewayError, setServerHandle, setChromeState, setTokenRefresher, setRequestTracker, setRequestQueue]);\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 { useAppContext } from \"../AppContext.js\";\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 ChatMessage {\n role: \"user\" | \"assistant\" | \"error\";\n content: string;\n}\n\nexport function ChatPanel(): React.ReactElement {\n const { state, navigate, setActiveModel } = 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 // Inline model picker state\n const [showModelPicker, setShowModelPicker] = useState(false);\n const [modelFocusIndex, setModelFocusIndex] = useState(() => {\n const idx = MODELS.indexOf(activeModel);\n return idx >= 0 ? idx : 0;\n });\n const [confirmationModel, setConfirmationModel] = useState<string | null>(null);\n\n // Blinking cursor\n const [cursorVisible, setCursorVisible] = useState(true);\n useEffect(() => {\n const id = setInterval(() => setCursorVisible((v) => !v), 530);\n return () => clearInterval(id);\n }, []);\n\n useEffect(() => {\n if (confirmationModel !== null) {\n const timer = setTimeout(() => setConfirmationModel(null), 1500);\n return () => clearTimeout(timer);\n }\n }, [confirmationModel]);\n\n // Sync focus index when picker opens\n useEffect(() => {\n if (showModelPicker) {\n const idx = MODELS.indexOf(activeModel);\n setModelFocusIndex(idx >= 0 ? idx : 0);\n }\n }, [showModelPicker, activeModel]);\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 // ── Model picker mode ──────────────────────────────────────────────────\n if (showModelPicker) {\n if (key.downArrow) {\n setModelFocusIndex((i) => wrapIndex(i, 1, MODELS.length));\n } else if (key.upArrow) {\n setModelFocusIndex((i) => wrapIndex(i, -1, MODELS.length));\n } else if (key.return) {\n const selected = MODELS[modelFocusIndex];\n updateConfig({ defaultModel: selected }).catch(() => { });\n setActiveModel(selected);\n setConfirmationModel(selected);\n setShowModelPicker(false);\n } else if (key.escape) {\n setShowModelPicker(false);\n }\n return;\n }\n\n // ── Normal chat mode ───────────────────────────────────────────────────\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 // Arrow keys open the model picker\n if ((key.upArrow || key.downArrow) && !loading) {\n setShowModelPicker(true);\n // Also move in the direction pressed\n if (key.upArrow) {\n setModelFocusIndex((i) => wrapIndex(i, -1, MODELS.length));\n } else {\n setModelFocusIndex((i) => wrapIndex(i, 1, MODELS.length));\n }\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 {/* Header with model indicator */}\n <Box marginBottom={1}>\n <Text bold>Chat</Text>\n <Text dimColor> Model: </Text>\n <Text color=\"green\">{activeModel}</Text>\n {confirmationModel !== null && (\n <Text color=\"green\"> ✓ Switched!</Text>\n )}\n {!showModelPicker && (\n <Text dimColor> [↑↓] change</Text>\n )}\n </Box>\n\n {/* Inline model picker overlay */}\n {showModelPicker && (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} marginBottom={1}>\n <Box marginBottom={1}>\n <Text bold color=\"cyan\">Select Model</Text>\n <Text dimColor> [↑↓] Navigate [Enter] Select [Esc] Cancel</Text>\n </Box>\n {MODELS.map((model, index) => {\n const isFocused = index === modelFocusIndex;\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 )}\n\n {/* Response area */}\n {!showModelPicker && (\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\n {/* Input area */}\n {!showModelPicker && (\n <>\n <Box borderStyle=\"round\" borderColor=\"gray\" paddingX={1}>\n <Text>\n {input.length > 0\n ? <>{input}<Text color=\"cyan\">{cursorVisible ? \"█\" : \" \"}</Text></>\n : <><Text color=\"cyan\">{cursorVisible ? \"█\" : \" \"}</Text><Text dimColor>Type a message and press Enter…</Text></>\n }\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>[Enter] Send [↑↓] Model [Esc] Back</Text>\n </Box>\n </>\n )}\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\";\nimport { RequestTracker } from \"../components/RequestTracker.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 marginBottom={1}>\n <RequestTracker />\n </Box>\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, useEffect } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useAppContext } from \"../AppContext.js\";\nimport {\n formatElapsed,\n formatQueueDepth,\n type RequestEntry,\n} from \"../../core/request-activity-tracker.js\";\n\n// ── Spinner ────────────────────────────────────────────────────────────────────\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\nfunction getSpinnerFrame(): string {\n return SPINNER_FRAMES[Math.floor(Date.now() / 100) % SPINNER_FRAMES.length];\n}\n\n// ── RequestEntryRow ────────────────────────────────────────────────────────────\n\ninterface RequestEntryRowProps {\n entry: RequestEntry;\n tick: number;\n}\n\nfunction RequestEntryRow({ entry, tick: _tick }: RequestEntryRowProps): React.ReactElement {\n const elapsed =\n entry.status === \"active\"\n ? formatElapsed(Date.now() - entry.startTime)\n : entry.elapsedMs !== null\n ? formatElapsed(entry.elapsedMs)\n : \"\";\n\n if (entry.status === \"active\") {\n return (\n <Text>\n <Text color=\"yellow\">{getSpinnerFrame()}</Text>\n {\" \"}\n <Text>{entry.method}</Text>\n {\" \"}\n <Text dimColor>{entry.path}</Text>\n {\" \"}\n <Text color=\"yellow\">{elapsed}</Text>\n </Text>\n );\n }\n\n const codeColor =\n entry.statusCode !== null && entry.statusCode >= 200 && entry.statusCode < 300\n ? \"green\"\n : \"red\";\n\n return (\n <Text>\n <Text color={codeColor}>{entry.statusCode ?? \"???\"}</Text>\n {\" \"}\n <Text>{entry.method}</Text>\n {\" \"}\n <Text dimColor>{entry.path}</Text>\n {\" \"}\n <Text dimColor>{elapsed}</Text>\n </Text>\n );\n}\n\n// ── RequestTracker ─────────────────────────────────────────────────────────────\n\nconst VISIBLE_ROWS = 8;\n\nexport function RequestTracker(): React.ReactElement {\n const { state } = useAppContext();\n const { requestTracker: tracker, requestQueue: queue, gatewayStatus } = state;\n const online = gatewayStatus === \"running\";\n\n const [entries, setEntries] = useState<ReadonlyArray<RequestEntry>>([]);\n\n useEffect(() => {\n if (!tracker) {\n setEntries([]);\n return;\n }\n setEntries(tracker.getEntries());\n const unsub = tracker.subscribe((snapshot) => setEntries(snapshot));\n return unsub;\n }, [tracker]);\n\n // Live elapsed tick — 200ms interval while any entry is active\n const [tick, setTick] = useState(0);\n const hasActive = entries.some((e) => e.status === \"active\");\n\n useEffect(() => {\n if (!hasActive) return;\n const id = setInterval(() => setTick((t) => t + 1), 200);\n return () => clearInterval(id);\n }, [hasActive]);\n\n // Scroll offset\n const [scrollOffset, setScrollOffset] = useState(0);\n const maxOffset = Math.max(0, entries.length - VISIBLE_ROWS);\n\n useEffect(() => {\n setScrollOffset((prev) => Math.min(prev, maxOffset));\n }, [maxOffset]);\n\n useInput((_input, key) => {\n if (_input === \"j\" || key.downArrow) {\n setScrollOffset((prev) => Math.min(prev + 1, maxOffset));\n }\n if (_input === \"k\" || key.upArrow) {\n setScrollOffset((prev) => Math.max(prev - 1, 0));\n }\n });\n\n const visibleEntries = entries.slice(scrollOffset, scrollOffset + VISIBLE_ROWS);\n const queueDepth = formatQueueDepth(queue?.pending ?? 0, online);\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>Server Activity</Text>\n <Text dimColor>{queueDepth}</Text>\n\n {!online && (\n <Box marginTop={1}>\n <Text color=\"red\">Gateway offline</Text>\n </Box>\n )}\n\n {online && entries.length === 0 && (\n <Box marginTop={1}>\n <Text dimColor>No recent activity</Text>\n </Box>\n )}\n\n {entries.length > 0 && (\n <Box height={VISIBLE_ROWS} overflowY=\"hidden\" flexDirection=\"column\" marginTop={1}>\n {visibleEntries.map((entry) => (\n <RequestEntryRow key={entry.id} entry={entry} tick={tick} />\n ))}\n </Box>\n )}\n\n {entries.length > VISIBLE_ROWS && (\n <Text dimColor>\n ↑↓/jk to scroll ({scrollOffset + 1}–{Math.min(scrollOffset + VISIBLE_ROWS, entries.length)} of {entries.length})\n </Text>\n )}\n </Box>\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","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","useEffect","Box","Text","useInput","useState","useEffect","Box","Text","useInput","jsx","jsxs","Text","useState","useEffect","useInput","Box","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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jh-web-gateway",
3
- "version": "2.1.1",
3
+ "version": "2.3.0",
4
4
  "description": "Standalone local HTTP server exposing an OpenAI-compatible API backed by the JH web platform",
5
5
  "type": "module",
6
6
  "bin": {