@mindstudio-ai/local-model-tunnel 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli.ts
4
4
  async function main() {
5
- const { startTUI } = await import("./tui-YFUZJIGF.js");
5
+ const { startTUI } = await import("./tui-KQ4LWB4E.js");
6
6
  await startTUI();
7
7
  process.exit(0);
8
8
  }
@@ -681,7 +681,7 @@ function DashboardPage({
681
681
  /* @__PURE__ */ jsx4(Text4, { color: "gray", children: displayProvider }),
682
682
  /* @__PURE__ */ jsx4(Text4, { color: "gray", children: " - " }),
683
683
  /* @__PURE__ */ jsx4(Text4, { color: cap.color, children: cap.label })
684
- ] }, model.name);
684
+ ] }, `${model.provider}:${model.name}`);
685
685
  }),
686
686
  modelWarnings.map((warning) => {
687
687
  const displayProvider = providers.find((p) => p.provider.name === warning.provider)?.provider.displayName ?? warning.provider;
@@ -692,7 +692,7 @@ function DashboardPage({
692
692
  /* @__PURE__ */ jsx4(Text4, { color: "gray", children: displayProvider }),
693
693
  /* @__PURE__ */ jsx4(Text4, { color: "gray", children: " - " }),
694
694
  /* @__PURE__ */ jsx4(Text4, { color: "yellow", children: warning.statusHint })
695
- ] }, warning.name);
695
+ ] }, `${warning.provider}:${warning.name}`);
696
696
  }),
697
697
  unavailableSynced.length > 0 && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: models.length > 0 ? 1 : 0, children: [
698
698
  /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Synced but not currently available:" }),
@@ -1714,4 +1714,4 @@ async function startTUI() {
1714
1714
  export {
1715
1715
  startTUI
1716
1716
  };
1717
- //# sourceMappingURL=tui-YFUZJIGF.js.map
1717
+ //# sourceMappingURL=tui-KQ4LWB4E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tui/index.tsx","../src/tui/App.tsx","../src/tui/components/Header.tsx","../src/tui/components/NavigationMenu.tsx","../src/tui/hooks/useConnection.ts","../src/tui/hooks/useProviders.ts","../src/tui/hooks/useModels.ts","../src/tui/hooks/useRequests.ts","../src/tui/hooks/useRegisteredModels.ts","../src/tui/pages/DashboardPage.tsx","../src/tui/components/RequestLog.tsx","../src/tui/hooks/useSetupProviders.ts","../src/tui/pages/RegisterPage.tsx","../src/tui/hooks/useRegister.ts","../src/tui/pages/SetupPage.tsx","../src/tui/components/MarkdownText.tsx","../src/tui/pages/OnboardingPage.tsx","../src/tui/hooks/useAuth.ts","../src/update.ts","../src/tui/components/UpdatePrompt.tsx"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { execFileSync, execSync } from 'node:child_process';\nimport { App } from './App';\nimport { TunnelRunner } from '../runner';\nimport { checkForUpdate } from '../update';\nimport { UpdatePrompt } from './components/UpdatePrompt';\n\nasync function promptForUpdate(\n currentVersion: string,\n latestVersion: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n const { unmount } = render(\n <UpdatePrompt\n currentVersion={currentVersion}\n latestVersion={latestVersion}\n onChoice={(shouldUpdate) => {\n unmount();\n resolve(shouldUpdate);\n }}\n />,\n { exitOnCtrlC: true },\n );\n });\n}\n\nexport async function startTUI(): Promise<void> {\n // Clear the screen\n console.clear();\n\n // Check for updates before launching the main app\n const update = await checkForUpdate();\n if (update) {\n const shouldUpdate = await promptForUpdate(\n update.currentVersion,\n update.latestVersion,\n );\n if (shouldUpdate) {\n console.log('\\nUpdating to v' + update.latestVersion + '...\\n');\n try {\n execSync('npm install -g @mindstudio-ai/local-model-tunnel@latest', {\n stdio: 'inherit',\n });\n console.log('\\nRestarting...\\n');\n execFileSync(process.execPath, process.argv.slice(1), {\n stdio: 'inherit',\n });\n } catch {\n console.error('\\nUpdate failed. Continuing with current version.\\n');\n }\n return;\n }\n console.clear();\n }\n\n // Create the runner instance\n const runner = new TunnelRunner();\n\n // Render the TUI with stdin configured for keyboard input\n const { waitUntilExit } = render(\n <App runner={runner} />,\n {\n exitOnCtrlC: true,\n },\n );\n\n // Wait for the app to exit\n await waitUntilExit();\n\n // Ensure clean shutdown\n runner.stop();\n}\n","import React, { useEffect, useCallback, useState } from 'react';\nimport { Box, useApp, useStdout } from 'ink';\nimport { Header } from './components/Header';\nimport { NavigationMenu } from './components/NavigationMenu';\nimport type { MenuItem } from './components/NavigationMenu';\nimport { useConnection } from './hooks/useConnection';\nimport { useProviders } from './hooks/useProviders';\nimport { useModels } from './hooks/useModels';\nimport { useRequests } from './hooks/useRequests';\nimport { useSyncedModels } from './hooks/useRegisteredModels';\nimport { DashboardPage } from './pages/DashboardPage';\nimport { SyncPage } from './pages/RegisterPage';\nimport { SetupPage } from './pages/SetupPage';\nimport { OnboardingPage } from './pages/OnboardingPage';\nimport { TunnelRunner } from '../runner';\nimport { getApiKey, getConfigPath } from '../config';\nimport type { Page } from './types';\n\ninterface AppProps {\n runner: TunnelRunner;\n}\n\nexport function App({ runner }: AppProps) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const {\n status: connectionStatus,\n environment,\n error: connectionError,\n retry: retryConnection,\n } = useConnection();\n const { refresh: refreshProviders } = useProviders();\n const {\n models,\n warnings: modelWarnings,\n loading: modelsLoading,\n refresh: refreshModels,\n } = useModels();\n const { requests } = useRequests();\n const { syncedNames, refresh: refreshSynced } =\n useSyncedModels(connectionStatus);\n const shouldOnboard = getApiKey() === undefined;\n const [page, setPage] = useState<Page>(\n shouldOnboard ? 'onboarding' : 'dashboard',\n );\n\n // Refresh everything when returning to dashboard\n useEffect(() => {\n if (page === 'dashboard') {\n refreshAll();\n }\n }, [page]);\n\n // Start runner when connected with models\n useEffect(() => {\n if (connectionStatus === 'connected' && models.length > 0) {\n runner.start(models.map((m) => m.name));\n }\n }, [connectionStatus, models, runner]);\n\n // Stop only on unmount\n useEffect(() => () => runner.stop(), [runner]);\n\n // Refresh everything\n const refreshAll = useCallback(async () => {\n await Promise.all([\n refreshProviders(),\n refreshModels(),\n refreshSynced(),\n ]);\n }, [refreshProviders, refreshModels, refreshSynced]);\n\n const handleQuit = useCallback(() => {\n runner.stop();\n exit();\n }, [runner, exit]);\n\n const handleOnboardingComplete = useCallback(() => {\n retryConnection();\n refreshAll();\n setPage('dashboard');\n }, [retryConnection, refreshAll]);\n\n const handleNavigate = useCallback(\n (id: string) => {\n switch (id) {\n case 'auth':\n setPage('onboarding');\n break;\n case 'register':\n setPage('sync');\n break;\n case 'setup':\n setPage('setup');\n break;\n case 'refresh':\n refreshAll();\n break;\n case 'quit':\n handleQuit();\n break;\n }\n },\n [refreshModels, refreshSynced, refreshAll, handleQuit],\n );\n\n const subpageMenuItems: MenuItem[] = [\n { id: 'back', label: 'Back', description: 'Return to dashboard' },\n ];\n\n const handleSubpageNavigate = useCallback(\n (id: string) => {\n if (id === 'back') {\n setPage('dashboard');\n } else {\n handleNavigate(id);\n }\n },\n [handleNavigate],\n );\n\n const termHeight = (stdout?.rows ?? 24) - 4;\n\n return (\n <Box flexDirection=\"column\" height={termHeight} overflow=\"hidden\">\n {page === 'onboarding' ? (\n <OnboardingPage onComplete={handleOnboardingComplete} />\n ) : (\n <>\n <Header\n connection={connectionStatus}\n environment={environment}\n configPath={getConfigPath()}\n connectionError={connectionError}\n />\n\n {page === 'dashboard' && (\n <DashboardPage\n requests={requests}\n models={models}\n modelWarnings={modelWarnings}\n syncedNames={syncedNames}\n modelsLoading={modelsLoading}\n onNavigate={handleNavigate}\n />\n )}\n {page === 'setup' && (\n <SetupPage onBack={() => setPage('dashboard')} />\n )}\n {page === 'sync' && <SyncPage />}\n\n {page !== 'dashboard' && page !== 'setup' && <Box flexGrow={1} />}\n\n {page !== 'dashboard' && page !== 'setup' && (\n <NavigationMenu\n items={subpageMenuItems}\n onSelect={handleSubpageNavigate}\n />\n )}\n </>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport os from 'node:os';\nimport { Box, Text } from 'ink';\nimport type { ConnectionStatus } from '../types';\nimport { createRequire } from 'node:module';\n\ninterface HeaderProps {\n connection: ConnectionStatus;\n environment: 'prod' | 'local';\n configPath: string;\n connectionError?: string | null;\n}\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nexport const LogoString = ` .=+-. :++.\n *@@@@@+ :%@@@@%:\n .%@@@@@@#..@@@@@@@=\n .*@@@@@@@--@@@@@@@#.**.\n *@@@@@@@.-@@@@@@@@.#@@*\n.#@@@@@@@-.@@@@@@@* #@@@@%.\n=@@@@@@@-.@@@@@@@#.-@@@@@@+\n:@@@@@@: +@@@@@#. .@@@@@@:\n .++: .-*-. .++:`;\n\nconst getConnectionDisplay = (status: ConnectionStatus) => {\n switch (status) {\n case 'connected':\n return { color: 'green', text: 'Connected to Cloud' };\n case 'connecting':\n return { color: 'yellow', text: 'Connecting...' };\n case 'not_authenticated':\n return { color: 'yellow', text: 'Not Authenticated' };\n case 'disconnected':\n return { color: 'red', text: 'Disconnected' };\n default:\n return { color: 'red', text: 'Error' };\n }\n};\n\nexport function Header({\n connection,\n environment,\n configPath,\n connectionError,\n}: HeaderProps) {\n const { color: connectionColor, text: connectionText } =\n getConnectionDisplay(connection);\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n borderStyle=\"round\"\n borderColor=\"cyan\"\n paddingX={1}\n paddingY={1}\n width=\"100%\"\n >\n <Box paddingLeft={3}>\n <Text color=\"cyan\">{LogoString}</Text>\n </Box>\n <Box flexDirection=\"column\" marginLeft={4}>\n <Box>\n <Text bold color=\"white\">\n MindStudio Local Tunnel\n </Text>\n {environment !== 'prod' && (\n <>\n <Text> </Text>\n <Text color=\"yellow\" bold>\n [LOCAL]\n </Text>\n </>\n )}\n </Box>\n <Text color=\"gray\">v{pkg.version}</Text>\n <Text color={connectionColor}>● {connectionText}</Text>\n {connectionError && <Text color=\"red\">{connectionError}</Text>}\n <Text color=\"gray\">\n Config: {configPath.replace(os.homedir(), '~')}\n </Text>\n </Box>\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useInput } from 'ink';\n\nexport interface MenuItem {\n id: string;\n label: string;\n description: string;\n disabled?: boolean;\n disabledReason?: string;\n isSeparator?: boolean;\n color?: string;\n}\n\ninterface NavigationMenuProps {\n items: MenuItem[];\n onSelect: (id: string) => void;\n title?: string;\n}\n\nexport function NavigationMenu({ items, onSelect, title }: NavigationMenuProps) {\n const getDefaultIndex = () => {\n const backIdx = items.findIndex((i) => i.id === 'back');\n if (backIdx >= 0) return backIdx;\n const firstIdx = items.findIndex((i) => !i.disabled && !i.isSeparator);\n return firstIdx >= 0 ? firstIdx : 0;\n };\n const [selectedIndex, setSelectedIndex] = useState(getDefaultIndex);\n\n useEffect(() => {\n setSelectedIndex(getDefaultIndex());\n }, [items]);\n\n const findNextEnabled = (from: number, direction: 1 | -1): number => {\n let idx = from;\n for (let i = 0; i < items.length; i++) {\n idx = (idx + direction + items.length) % items.length;\n if (!items[idx]!.disabled && !items[idx]!.isSeparator) return idx;\n }\n return from;\n };\n\n useInput((input, key) => {\n if (input === 'q' || key.escape) {\n const backItem = items.find((i) => i.id === 'back');\n if (backItem) {\n onSelect('back');\n } else if (input === 'q') {\n onSelect('quit');\n }\n return;\n }\n if (key.upArrow) {\n setSelectedIndex((prev) => findNextEnabled(prev, -1));\n } else if (key.downArrow) {\n setSelectedIndex((prev) => findNextEnabled(prev, 1));\n } else if (key.return) {\n const item = items[selectedIndex];\n if (item && !item.disabled) {\n onSelect(item.id);\n }\n }\n });\n\n // Fixed height: header + items + hint + margins\n const separatorExtraLines = items.filter((item, idx) => item.isSeparator && idx > 0).length;\n const menuHeight = items.length + 4 + separatorExtraLines;\n\n return (\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1} borderStyle=\"single\" borderTop borderBottom={false} borderLeft={false} borderRight={false} borderColor=\"gray\">\n <Box marginTop={1}>\n <Text color=\"gray\">{title ?? 'Actions'}</Text>\n </Box>\n <Box flexDirection=\"column\">\n {items.map((item, index) => {\n if (item.isSeparator) {\n return (\n <Box key={item.id} marginTop={index > 0 ? 1 : 0}>\n {item.label ? (\n <Text bold color={item.color ?? 'gray'} wrap=\"truncate-end\">\n {item.label}\n </Text>\n ) : null}\n </Box>\n );\n }\n\n const isSelected = index === selectedIndex;\n const prefix = isSelected ? '❯' : ' ';\n\n if (item.disabled) {\n return (\n <Box key={item.id}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n {prefix} {item.label}\n {item.disabledReason ? ` (${item.disabledReason})` : ''}\n </Text>\n </Box>\n );\n }\n\n return (\n <Box key={item.id}>\n <Text color={isSelected ? 'cyan' : 'white'} bold={isSelected} wrap=\"truncate-end\">\n {prefix} {item.label}\n </Text>\n {isSelected && (\n <Text color=\"gray\" wrap=\"truncate-end\"> - {item.description}</Text>\n )}\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={1} height={1}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n {items.some((i) => i.id === 'back')\n ? 'Up/Down Navigate \\u2022 Enter Select \\u2022 q/Esc Back'\n : 'Up/Down Navigate \\u2022 Enter Select \\u2022 q Quit'}\n </Text>\n </Box>\n </Box>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { verifyApiKey } from '../../api';\nimport { getApiKey, getEnvironment } from '../../config';\nimport type { ConnectionStatus } from '../types';\n\ninterface UseConnectionResult {\n status: ConnectionStatus;\n environment: 'prod' | 'local';\n error: string | null;\n retry: () => void;\n}\n\nexport function useConnection(): UseConnectionResult {\n const [status, setStatus] = useState<ConnectionStatus>('connecting');\n const [error, setError] = useState<string | null>(null);\n const environment = getEnvironment();\n\n const connect = useCallback(async () => {\n setStatus('connecting');\n setError(null);\n\n const apiKey = getApiKey();\n if (!apiKey) {\n setStatus('not_authenticated');\n return;\n }\n\n try {\n const isValid = await verifyApiKey();\n if (isValid) {\n setStatus('connected');\n } else {\n setStatus('not_authenticated');\n }\n } catch (err) {\n setStatus('error');\n setError(err instanceof Error ? err.message : 'Connection failed');\n }\n }, []);\n\n useEffect(() => {\n connect();\n }, [connect]);\n\n return {\n status,\n environment,\n error,\n retry: connect,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { getProviderStatuses } from '../../providers';\nimport type { ProviderStatus } from '../types';\n\ninterface UseProvidersResult {\n providers: ProviderStatus[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useProviders(pollInterval: number = 10000): UseProvidersResult {\n const [providers, setProviders] = useState<ProviderStatus[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n try {\n const statuses = await getProviderStatuses();\n setProviders(statuses);\n } catch {\n // Keep existing state on error\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n refresh();\n\n // Poll for provider status changes\n const interval = setInterval(refresh, pollInterval);\n return () => clearInterval(interval);\n }, [refresh, pollInterval]);\n\n return {\n providers,\n loading,\n refresh,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { discoverAllModels } from '../../providers';\nimport type { LocalModel } from '../../providers/types';\n\ninterface UseModelsResult {\n models: LocalModel[];\n warnings: LocalModel[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useModels(): UseModelsResult {\n const [models, setModels] = useState<LocalModel[]>([]);\n const [warnings, setWarnings] = useState<LocalModel[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const discoveredModels = await discoverAllModels();\n setModels(discoveredModels.filter((m) => !m.statusHint));\n setWarnings(discoveredModels.filter((m) => !!m.statusHint));\n } catch {\n // Keep existing state on error\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return {\n models,\n warnings,\n loading,\n refresh,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { requestEvents } from '../../events';\nimport type { RequestLogEntry } from '../types';\n\ninterface UseRequestsResult {\n requests: RequestLogEntry[];\n activeCount: number;\n clear: () => void;\n}\n\nexport function useRequests(maxHistory: number = 50): UseRequestsResult {\n const [requests, setRequests] = useState<RequestLogEntry[]>([]);\n const requestsRef = useRef<Map<string, RequestLogEntry>>(new Map());\n\n // Update timer for active request durations\n useEffect(() => {\n const interval = setInterval(() => {\n // Force re-render for active requests to update elapsed time\n setRequests((prev) => {\n const hasActive = prev.some((r) => r.status === 'processing');\n return hasActive ? [...prev] : prev;\n });\n }, 1000);\n\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n const unsubStart = requestEvents.onStart((event) => {\n const entry: RequestLogEntry = {\n id: event.id,\n modelId: event.modelId,\n requestType: event.requestType,\n status: 'processing',\n startTime: event.timestamp,\n };\n\n requestsRef.current.set(event.id, entry);\n setRequests((prev) => [...prev, entry].slice(-maxHistory));\n });\n\n const unsubProgress = requestEvents.onProgress((event) => {\n const existing = requestsRef.current.get(event.id);\n if (existing && existing.status === 'processing') {\n const updated: RequestLogEntry = {\n ...existing,\n ...(event.content !== undefined && { content: event.content }),\n ...(event.step !== undefined && { step: event.step }),\n ...(event.totalSteps !== undefined && { totalSteps: event.totalSteps }),\n };\n requestsRef.current.set(event.id, updated);\n setRequests((prev) =>\n prev.map((r) => (r.id === event.id ? updated : r)),\n );\n }\n });\n\n const unsubComplete = requestEvents.onComplete((event) => {\n const existing = requestsRef.current.get(event.id);\n if (existing) {\n const updated: RequestLogEntry = {\n ...existing,\n status: event.success ? 'completed' : 'failed',\n endTime: Date.now(),\n duration: event.duration,\n result: event.result,\n error: event.error,\n };\n\n requestsRef.current.set(event.id, updated);\n setRequests((prev) =>\n prev.map((r) => (r.id === event.id ? updated : r)),\n );\n }\n });\n\n return () => {\n unsubStart();\n unsubProgress();\n unsubComplete();\n };\n }, [maxHistory]);\n\n const activeCount = requests.filter((r) => r.status === 'processing').length;\n\n const clear = useCallback(() => {\n requestsRef.current.clear();\n setRequests([]);\n }, []);\n\n return {\n requests,\n activeCount,\n clear,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { getSyncedModels } from '../../api';\nimport type { ConnectionStatus } from '../types';\n\ninterface UseSyncedModelsResult {\n syncedNames: Set<string>;\n refresh: () => Promise<void>;\n}\n\nexport function useSyncedModels(\n connectionStatus: ConnectionStatus,\n): UseSyncedModelsResult {\n const [syncedNames, setSyncedNames] = useState<Set<string>>(\n new Set(),\n );\n\n const refresh = useCallback(async () => {\n if (connectionStatus !== 'connected') {\n setSyncedNames(new Set());\n return;\n }\n\n try {\n const models = await getSyncedModels();\n setSyncedNames(new Set(models.map((m) => m.name)));\n } catch {\n // Keep existing state on error\n }\n }, [connectionStatus]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return {\n syncedNames,\n refresh,\n };\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { RequestLog } from '../components/RequestLog';\nimport { NavigationMenu } from '../components/NavigationMenu';\nimport type { MenuItem } from '../components/NavigationMenu';\nimport type { LocalModel, ComfyWorkflowParameterSchema } from '../../providers/types';\nimport type { ProviderStatus, RequestLogEntry } from '../types';\nimport { useSetupProviders } from '../hooks/useSetupProviders';\n\nfunction getWorkflowCount(model: LocalModel): number | null {\n const param = model.parameters?.find((p) => p.type === 'comfyWorkflow');\n if (!param) return null;\n return (param as ComfyWorkflowParameterSchema).comfyWorkflowOptions.availableWorkflows.length;\n}\n\nfunction getCapabilityLabel(capability: string): {\n label: string;\n color: string;\n} {\n switch (capability) {\n case 'text':\n return { label: 'Text Generation', color: 'gray' };\n case 'image':\n return { label: 'Image Generation', color: 'gray' };\n case 'video':\n return { label: 'Video Generation', color: 'gray' };\n default:\n return { label: capability, color: 'gray' };\n }\n}\n\ninterface DashboardPageProps {\n requests: RequestLogEntry[];\n models: LocalModel[];\n modelWarnings?: LocalModel[];\n syncedNames: Set<string>;\n modelsLoading?: boolean;\n onNavigate: (id: string) => void;\n}\n\nexport function DashboardPage({\n requests,\n models,\n modelWarnings = [],\n syncedNames,\n modelsLoading,\n onNavigate,\n}: DashboardPageProps) {\n const { stdout } = useStdout();\n const { providers, loading: setupLoading } = useSetupProviders();\n\n const installedProviders = providers.filter(({ status }) => status.installed);\n\n const provNameWidth = Math.max(\n ...installedProviders.map((p) => p.provider.displayName.length),\n 8,\n );\n const provStatusWidth = 'Local Server Running'.length;\n\n const allModelNames = new Set(models.map((m) => m.name));\n const unavailableSynced = [...syncedNames].filter(\n (name) => !allModelNames.has(name),\n );\n\n const menuItems = useMemo((): MenuItem[] => {\n return [\n {\n id: 'register',\n label: 'Sync Models',\n description: 'Sync models with MindStudio Cloud',\n },\n {\n id: 'refresh',\n label: 'Refresh Providers',\n description: 'Re-detect local AI providers and models',\n },\n {\n id: 'setup',\n label: 'Manage Providers',\n description: 'Manage local AI providers',\n },\n {\n id: 'auth',\n label: 'Re-authenticate',\n description: 'Re-authenticate with MindStudio',\n },\n {\n id: 'quit',\n label: 'Exit',\n description: 'Quit the application',\n },\n ];\n }, []);\n\n // Compute maxVisible for request log based on terminal height\n const termHeight = (stdout?.rows ?? 24) - 4; // matches App's height calculation\n\n // Header: border(2) + padding(2) + logo(~10 lines) = 14\n const headerLines = 14;\n\n // Providers section: marginTop(1) + title(1) + content gap(1) + content\n const providerContentLines = setupLoading\n ? 1\n : installedProviders.length === 0\n ? 2\n : installedProviders.length;\n const providersLines = 3 + providerContentLines;\n\n // Models section: marginTop(1) + title(1) + content gap(1) + content\n const modelContentLines = modelsLoading\n ? 1\n : models.length === 0 && unavailableSynced.length === 0 && modelWarnings.length === 0\n ? 2\n : models.length +\n modelWarnings.length +\n (unavailableSynced.length > 0\n ? 1 + unavailableSynced.length\n : 0);\n const modelsLines = 3 + modelContentLines;\n\n // Request log overhead: marginTop(1) + title(1) + content gap(1)\n const requestLogOverhead = 3;\n\n // Menu: border-top(1) + marginTop(1) + title(1) + items + hint(1) + marginTop(1) + marginBottom(1)\n const menuLines = menuItems.length + 6;\n\n const usedLines =\n headerLines + providersLines + modelsLines + requestLogOverhead + menuLines;\n const maxVisible = Math.max(3, termHeight - usedLines);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {/* Providers */}\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Providers\n </Text>\n\n {setupLoading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Detecting providers...</Text>\n </Box>\n ) : installedProviders.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\">No providers installed.</Text>\n <Text color=\"gray\">\n Use \"Manage Providers\" below to install one.\n </Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {installedProviders.map(({ provider, status }) => {\n const url = provider.baseUrl;\n const statusColor = status.running ? 'green' : 'yellow';\n const statusText = status.running\n ? 'Local Server Running'\n : 'Installed (not running)';\n\n return (\n <Box key={provider.name}>\n <Text color=\"white\">\n {provider.displayName.padEnd(provNameWidth + 2)}\n </Text>\n <Text color={statusColor}>\n {statusText.padEnd(provStatusWidth + 2)}\n </Text>\n {status.running && <Text color=\"gray\">{url}</Text>}\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n\n {/* Models */}\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Models\n </Text>\n\n {modelsLoading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Discovering models...</Text>\n </Box>\n ) : models.length === 0 && unavailableSynced.length === 0 && modelWarnings.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\">No models found.</Text>\n <Text color=\"gray\">\n Download models using your provider (e.g., ollama pull llama3.2)\n </Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {models.map((model) => {\n const cap = getCapabilityLabel(model.capability);\n const isSynced = syncedNames.has(model.name);\n const displayProvider =\n providers.find((p) => p.provider.name === model.provider)\n ?.provider.displayName ?? model.provider;\n const workflowCount = getWorkflowCount(model);\n const workflowSuffix = workflowCount !== null\n ? ` (${workflowCount} workflow${workflowCount !== 1 ? 's' : ''}, ${isSynced ? workflowCount : 0} synced)`\n : '';\n return (\n <Box key={`${model.provider}:${model.name}`}>\n <Text color={isSynced ? 'green' : 'gray'}>\n {isSynced ? '\\u25CF' : '\\u25CB'}\n </Text>\n <Text color=\"white\">{` ${model.name}`}</Text>\n {workflowSuffix && <Text color=\"gray\">{workflowSuffix}</Text>}\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"gray\">{displayProvider}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color={cap.color}>{cap.label}</Text>\n </Box>\n );\n })}\n {modelWarnings.map((warning) => {\n const displayProvider =\n providers.find((p) => p.provider.name === warning.provider)\n ?.provider.displayName ?? warning.provider;\n return (\n <Box key={`${warning.provider}:${warning.name}`}>\n <Text color=\"gray\">{'\\u25CB'}</Text>\n <Text color=\"white\">{` ${warning.name}`}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"gray\">{displayProvider}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"yellow\">{warning.statusHint}</Text>\n </Box>\n );\n })}\n\n {unavailableSynced.length > 0 && (\n <Box flexDirection=\"column\" marginTop={models.length > 0 ? 1 : 0}>\n <Text color=\"gray\">\n Synced but not currently available:\n </Text>\n {unavailableSynced.map((name) => (\n <Box key={name}>\n <Text color=\"gray\">{'\\u25CB'}</Text>\n <Text color=\"gray\">{` ${name}`}</Text>\n </Box>\n ))}\n </Box>\n )}\n </Box>\n )}\n </Box>\n\n {/* Request log */}\n <RequestLog\n requests={requests}\n maxVisible={maxVisible}\n hasModels={models.length > 0}\n />\n\n {/* Bottom: Navigation menu pane */}\n <NavigationMenu items={menuItems} onSelect={onNavigate} />\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport type { RequestLogEntry } from '../types';\n\ninterface RequestLogProps {\n requests: RequestLogEntry[];\n maxVisible?: number;\n hasModels?: boolean;\n}\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction getRequestTypeLabel(type: string): { label: string; color: string } {\n switch (type) {\n case 'llm_chat':\n return { label: 'text', color: 'gray' };\n case 'image_generation':\n return { label: 'image', color: 'gray' };\n case 'video_generation':\n return { label: 'video', color: 'gray' };\n default:\n return { label: type, color: 'gray' };\n }\n}\n\nfunction snippetLine(content: string, maxWidth: number): string {\n // Collapse whitespace/newlines into single spaces\n const flat = content.replace(/\\s+/g, ' ').trim();\n if (flat.length <= maxWidth) return flat;\n return '\\u2026' + flat.slice(-(maxWidth - 1));\n}\n\nfunction RequestItem({ request, width }: { request: RequestLogEntry; width: number }) {\n const time = formatTime(request.startTime);\n const typeLabel = getRequestTypeLabel(request.requestType);\n // indent for snippet: status(1) + space(1) + padding for alignment\n const snippetIndent = ' ';\n const snippetWidth = width - snippetIndent.length - 2; // 2 for paddingX\n\n if (request.status === 'processing') {\n const elapsed = Date.now() - request.startTime;\n const snippet = request.content && request.requestType === 'llm_chat'\n ? snippetLine(request.content, snippetWidth)\n : null;\n const stepProgress = request.step !== undefined && request.totalSteps\n ? `Step ${request.step}/${request.totalSteps}`\n : null;\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"gray\"> {formatDuration(elapsed)}...</Text>\n </Box>\n {snippet && (\n <Text color=\"gray\" wrap=\"truncate-end\">\n {snippetIndent}{snippet}\n </Text>\n )}\n {stepProgress && (\n <Text color=\"gray\">\n {snippetIndent}{stepProgress}\n </Text>\n )}\n </Box>\n );\n }\n\n if (request.status === 'completed') {\n const duration = request.duration ? formatDuration(request.duration) : '';\n let resultInfo = '';\n if (request.result?.chars) {\n resultInfo = ` \\u00B7 ${request.result.chars} chars`;\n } else if (request.result?.imageSize) {\n resultInfo = ` \\u00B7 ${Math.round(request.result.imageSize / 1024)}KB`;\n } else if (request.result?.videoSize) {\n resultInfo = ` \\u00B7 ${Math.round(request.result.videoSize / 1024 / 1024)}MB`;\n }\n\n const snippet = request.content && request.requestType === 'llm_chat'\n ? snippetLine(request.content, snippetWidth)\n : null;\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"green\">{'\\u2713'}</Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"gray\"> {duration}{resultInfo}</Text>\n </Box>\n {snippet && (\n <Text color=\"gray\" wrap=\"truncate-end\">\n {snippetIndent}{snippet}\n </Text>\n )}\n </Box>\n );\n }\n\n // Failed\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"red\">{'\\u25CF'}</Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"red\"> {request.error || 'Failed'}</Text>\n </Box>\n </Box>\n );\n}\n\nexport function RequestLog({ requests, maxVisible = 8, hasModels = true }: RequestLogProps) {\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n\n // Get the most recent requests, with active ones always shown\n const activeRequests = requests.filter((r) => r.status === 'processing');\n const completedRequests = requests.filter((r) => r.status !== 'processing');\n\n // Requests with a snippet or step progress take 2 lines, others take 1\n const itemLines = (r: RequestLogEntry) => {\n if (r.requestType === 'llm_chat' && r.content) return 2;\n if (r.status === 'processing' && r.step !== undefined) return 2;\n return 1;\n };\n\n let completedToShow: RequestLogEntry[] = [];\n let linesUsed = activeRequests.reduce((sum, r) => sum + itemLines(r), 0);\n for (let i = completedRequests.length - 1; i >= 0 && linesUsed < maxVisible; i--) {\n const r = completedRequests[i]!;\n const lines = itemLines(r);\n if (linesUsed + lines <= maxVisible) {\n completedToShow.unshift(r);\n linesUsed += lines;\n } else {\n break;\n }\n }\n\n const visibleRequests = [...completedToShow, ...activeRequests];\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n width=\"100%\"\n paddingX={1}\n marginTop={1}\n >\n <Box>\n <Text bold underline color=\"white\">\n Generation Requests\n </Text>\n {activeRequests.length > 0 && (\n <Text color=\"cyan\"> ({activeRequests.length} active)</Text>\n )}\n </Box>\n\n {requests.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\">{hasModels\n ? 'Tunnel is live — requests will appear here when models are used in MindStudio'\n : 'Start a model to begin receiving generation requests.'\n }</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {visibleRequests.map((request) => (\n <RequestItem key={request.id} request={request} width={width} />\n ))}\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport {\n detectAllProviderStatuses,\n type Provider,\n type ProviderSetupStatus,\n} from '../../providers';\n\ninterface ProviderWithStatus {\n provider: Provider;\n status: ProviderSetupStatus;\n}\n\ninterface UseSetupProvidersResult {\n providers: ProviderWithStatus[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useSetupProviders(): UseSetupProvidersResult {\n const [providers, setProviders] = useState<ProviderWithStatus[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n const statuses = await detectAllProviderStatuses();\n setProviders(statuses);\n setLoading(false);\n }, []);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return { providers, loading, refresh };\n}\n","import React, { useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { useSync } from '../hooks/useRegister';\n\nexport function SyncPage() {\n const { status, progress, syncedModels, error, startSync, cancel } =\n useSync();\n\n // Start sync on mount\n useEffect(() => {\n startSync();\n return () => cancel();\n }, []);\n\n if (status === 'idle') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"gray\">Starting model sync...</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'error') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"red\">Sync failed: {error}</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'discovering') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Discovering local models...</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'syncing') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text>\n {' '}\n Syncing {progress.current}/{progress.total} models...\n </Text>\n </Box>\n </Box>\n );\n }\n\n // Done\n const newModels = syncedModels.filter((m) => m.isNew);\n const resyncedModels = syncedModels.filter((m) => !m.isNew);\n\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n {newModels.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"green\">\n Synced {newModels.length} new model\n {newModels.length !== 1 ? 's' : ''}:\n </Text>\n {newModels.map((m) => (\n <Box key={m.name}>\n <Text color=\"green\">{' ✓ '}</Text>\n <Text>{m.name} </Text>\n <Text color=\"gray\">[{m.provider}]</Text>\n </Box>\n ))}\n </Box>\n )}\n\n {resyncedModels.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"green\">\n Resynced {resyncedModels.length} existing model\n {resyncedModels.length !== 1 ? 's' : ''}:\n </Text>\n {resyncedModels.map((m) => (\n <Box key={m.name}>\n <Text color=\"green\">{' ✓ '}</Text>\n <Text>{m.name} </Text>\n <Text color=\"gray\">[{m.provider}]</Text>\n </Box>\n ))}\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { getSyncedModels, syncLocalModel, updateLocalModel } from '../../api';\nimport { discoverAllModelsWithParameters } from '../../providers';\n\ntype SyncStatus = 'idle' | 'discovering' | 'syncing' | 'done' | 'error';\n\ninterface SyncProgress {\n current: number;\n total: number;\n}\n\ninterface SyncedModel {\n name: string;\n provider: string;\n capability: string;\n isNew: boolean;\n}\n\ninterface UseSyncResult {\n status: SyncStatus;\n progress: SyncProgress;\n syncedModels: SyncedModel[];\n error: string | null;\n startSync: () => void;\n cancel: () => void;\n}\n\nconst MODEL_TYPE_MAP = {\n text: 'llm_chat',\n image: 'image_generation',\n video: 'video_generation',\n} as const;\n\nexport function useSync(): UseSyncResult {\n const [status, setStatus] = useState<SyncStatus>('idle');\n const [progress, setProgress] = useState<SyncProgress>({\n current: 0,\n total: 0,\n });\n const [syncedModels, setSyncedModels] = useState<SyncedModel[]>(\n [],\n );\n const [error, setError] = useState<string | null>(null);\n const cancelledRef = useRef(false);\n\n useEffect(() => {\n return () => {\n cancelledRef.current = true;\n };\n }, []);\n\n const cancel = useCallback(() => {\n cancelledRef.current = true;\n setStatus('idle');\n }, []);\n\n const startSync = useCallback(() => {\n cancelledRef.current = false;\n setError(null);\n setSyncedModels([]);\n\n const run = async () => {\n try {\n setStatus('discovering');\n\n const localModels = await discoverAllModelsWithParameters();\n if (cancelledRef.current) return;\n\n if (localModels.length === 0) {\n setError('No local models found.');\n setStatus('error');\n return;\n }\n\n const existingSynced = await getSyncedModels();\n if (cancelledRef.current) return;\n\n // Map remote model names to their IDs for updates\n const remoteByName = new Map(\n existingSynced.map((m) => [m.name, m.id]),\n );\n\n setStatus('syncing');\n setProgress({ current: 0, total: localModels.length });\n\n for (let i = 0; i < localModels.length; i++) {\n if (cancelledRef.current) return;\n\n const model = localModels[i]!;\n const modelType =\n MODEL_TYPE_MAP[model.capability as keyof typeof MODEL_TYPE_MAP];\n const existingId = remoteByName.get(model.name);\n\n if (existingId) {\n await updateLocalModel({\n modelId: existingId,\n modelName: model.name,\n provider: model.provider,\n modelType,\n parameters: model.parameters,\n });\n } else {\n await syncLocalModel({\n modelName: model.name,\n provider: model.provider,\n modelType,\n parameters: model.parameters,\n });\n }\n\n setProgress({ current: i + 1, total: localModels.length });\n }\n\n if (cancelledRef.current) return;\n\n const finalModels: SyncedModel[] = localModels.map((m) => ({\n name: m.name,\n provider: m.provider,\n capability: m.capability,\n isNew: !remoteByName.has(m.name),\n }));\n\n setSyncedModels(finalModels);\n setStatus('done');\n } catch (err) {\n if (!cancelledRef.current) {\n setError(err instanceof Error ? err.message : 'Sync failed');\n setStatus('error');\n }\n }\n };\n\n run();\n }, []);\n\n return {\n status,\n progress,\n syncedModels,\n error,\n startSync,\n cancel,\n };\n}\n","import React, { useState, useMemo, useEffect } from 'react';\nimport { Box, Text, useInput, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { renderMarkdown } from '../components/MarkdownText';\nimport { useSetupProviders } from '../hooks/useSetupProviders';\nimport type { Provider } from '../../providers/types';\n\ninterface SetupPageProps {\n onBack: () => void;\n}\n\nfunction ProviderDetailView({\n provider,\n onBack,\n}: {\n provider: Provider;\n onBack: () => void;\n}) {\n const [scrollOffset, setScrollOffset] = useState(0);\n const { stdout } = useStdout();\n const termHeight = (stdout?.rows ?? 24) - 4; // matches App's height calc\n const headerHeight = 14; // border(2) + padding(2) + logo(9) + 1\n const footerLines = 6; // border-top(1) + margin(1) + \"Actions\"(1) + \"Back\"(1) + margin(1) + hint(1)\n const contentPadding = 2; // paddingY={1}\n const viewHeight = termHeight - headerHeight - footerLines - contentPadding;\n const contentWidth = (stdout?.columns ?? 80) - 4; // 2 padding + 1 scrollbar + 1 margin\n\n const renderedLines = useMemo(() => {\n const rendered = renderMarkdown(provider.readme, contentWidth);\n return rendered.split('\\n');\n }, [provider.readme, contentWidth]);\n\n const maxScroll = Math.max(0, renderedLines.length - viewHeight);\n\n useInput((input, key) => {\n if (input === 'q' || key.escape || key.return) {\n onBack();\n return;\n }\n if (key.upArrow) {\n setScrollOffset((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setScrollOffset((prev) => Math.min(maxScroll, prev + 1));\n }\n });\n\n const visibleContent = renderedLines\n .slice(scrollOffset, scrollOffset + viewHeight)\n .join('\\n');\n\n const scrollbar = useMemo(() => {\n if (maxScroll === 0) return null;\n const thumbSize = Math.max(\n 1,\n Math.round((viewHeight / renderedLines.length) * viewHeight),\n );\n const thumbPos = Math.round(\n (scrollOffset / maxScroll) * (viewHeight - thumbSize),\n );\n\n return Array.from(\n { length: viewHeight },\n (_, i) => i >= thumbPos && i < thumbPos + thumbSize,\n );\n }, [scrollOffset, maxScroll, viewHeight, renderedLines.length]);\n\n return (\n <Box flexDirection=\"column\">\n <Box height={viewHeight}>\n <Box\n flexDirection=\"column\"\n paddingX={1}\n paddingY={1}\n flexGrow={1}\n overflow=\"hidden\"\n >\n <Text>{visibleContent}</Text>\n </Box>\n {scrollbar && (\n <Box flexDirection=\"column\">\n {scrollbar.map((isThumb, i) => (\n <Text\n key={i}\n color={isThumb ? 'cyan' : 'gray'}\n dimColor={!isThumb}\n >\n {isThumb ? '\\u2503' : '\\u2502'}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box\n flexDirection=\"column\"\n paddingX={1}\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n borderColor=\"gray\"\n >\n <Box marginTop={1}>\n <Text color=\"gray\">\n Actions\n </Text>\n </Box>\n <Box>\n <Text color=\"cyan\" bold>\n {'\\u276F'} Back\n </Text>\n <Text color=\"gray\"> - Return to providers</Text>\n </Box>\n <Box marginTop={1} height={1}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n Up/Down Scroll {'\\u2022'} Enter/q/Esc Back\n {maxScroll > 0 &&\n ` \\u2022 ${Math.round((scrollOffset / maxScroll) * 100)}%`}\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nexport function SetupPage({ onBack }: SetupPageProps) {\n const { providers, loading } = useSetupProviders();\n const [selectedProvider, setSelectedProvider] = useState<string | null>(null);\n const running = useMemo(\n () => providers.filter((p) => p.status.running),\n [providers],\n );\n const installed = useMemo(\n () => providers.filter((p) => p.status.installed && !p.status.running),\n [providers],\n );\n const notInstalled = useMemo(\n () => providers.filter((p) => !p.status.installed),\n [providers],\n );\n const allProviders = useMemo(\n () => [...running, ...installed, ...notInstalled],\n [running, installed, notInstalled],\n );\n\n const totalItems = allProviders.length + 1; // +1 for Back\n const backIndex = allProviders.length;\n const [cursorIndex, setCursorIndex] = useState(backIndex);\n\n useEffect(() => {\n setCursorIndex(backIndex);\n }, [backIndex]);\n\n useInput((input, key) => {\n if (selectedProvider) return;\n if (input === 'q' || key.escape) {\n onBack();\n return;\n }\n if (key.upArrow) {\n setCursorIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setCursorIndex((prev) => Math.min(totalItems - 1, prev + 1));\n } else if (key.return) {\n if (cursorIndex === backIndex) {\n onBack();\n } else if (allProviders[cursorIndex]) {\n setSelectedProvider(allProviders[cursorIndex]!.provider.name);\n }\n }\n });\n\n if (selectedProvider) {\n const found = providers.find((p) => p.provider.name === selectedProvider);\n if (found) {\n return (\n <ProviderDetailView\n provider={found.provider}\n onBack={() => setSelectedProvider(null)}\n />\n );\n }\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Manage Providers\n </Text>\n <Text color=\"gray\">Select a provider to view its setup guide.</Text>\n\n {loading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Detecting providers...</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {running.length > 0 && (\n <>\n <Text bold color=\"green\">\n Running\n </Text>\n {running.map(({ provider }, i) => {\n const index = i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {'\\u25CF'}{' '}\n {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </>\n )}\n {installed.length > 0 && (\n <Box\n flexDirection=\"column\"\n marginTop={running.length > 0 ? 1 : 0}\n >\n <Text bold color=\"yellow\">\n Installed\n </Text>\n {installed.map(({ provider, status }, i) => {\n const index = running.length + i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {'\\u25CB'}{' '}\n {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </Box>\n )}\n {notInstalled.length > 0 && (\n <Box\n flexDirection=\"column\"\n marginTop={running.length > 0 || installed.length > 0 ? 1 : 0}\n >\n <Text bold color=\"gray\">\n Not Installed\n </Text>\n {notInstalled.map(({ provider }, i) => {\n const index = running.length + installed.length + i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </Box>\n )}\n\n {/* Back option */}\n <Box marginTop={1}>\n <Text\n color={cursorIndex === backIndex ? 'cyan' : 'white'}\n bold={cursorIndex === backIndex}\n >\n {cursorIndex === backIndex ? '\\u276F' : ' '} Back\n </Text>\n </Box>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color=\"gray\">\n Up/Down Navigate {'\\u2022'} Enter Select {'\\u2022'} q/Esc Back\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n","import React, { useMemo } from 'react';\nimport { Text, useStdout } from 'ink';\nimport chalk from 'chalk';\nimport { marked } from 'marked';\nimport { markedTerminal } from 'marked-terminal';\n\nconst codeStyle = chalk.cyan;\nconst identity = (s: string) => s;\n\ninterface MarkdownTextProps {\n content: string;\n width?: number;\n}\n\n/**\n * Render markdown to an ANSI string.\n * Each line is self-contained (no cross-line ANSI escapes).\n */\nexport function renderMarkdown(content: string, width: number): string {\n marked.use(\n markedTerminal({\n width,\n codespan: codeStyle,\n link: identity,\n href: identity,\n }) as any,\n );\n marked.use({\n renderer: {\n code({ text }: { text: string }) {\n const lines = text\n .trim()\n .split('\\n')\n .map((l) => ' ' + codeStyle(l))\n .join('\\n');\n return lines + '\\n\\n';\n },\n link({ href, text }: { href: string; text: string }) {\n if (text && text !== href) {\n return `${text} (${href})`;\n }\n return href;\n },\n },\n });\n return (marked.parse(content) as string).trimEnd();\n}\n\nexport function MarkdownText({ content, width: widthProp }: MarkdownTextProps) {\n const { stdout } = useStdout();\n const width = widthProp ?? (stdout?.columns ?? 80) - 4;\n\n const rendered = useMemo(\n () => renderMarkdown(content, width),\n [content, width],\n );\n\n return <Text wrap=\"wrap\">{rendered}</Text>;\n}\n","import React, { useEffect, useCallback, useState, useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport Spinner from 'ink-spinner';\nimport chalk from 'chalk';\nimport { useAuth } from '../hooks/useAuth';\nimport { LogoString } from '../components/Header';\n\ninterface OnboardingPageProps {\n onComplete: () => void;\n}\n\nconst SHIMMER_SPEED = 35;\n\nfunction useShimmerLogo(): string {\n const [frame, setFrame] = useState(0);\n\n const lines = useMemo(() => LogoString.split('\\n'), []);\n const totalChars = useMemo(() => {\n let count = 0;\n for (const line of lines) {\n for (const ch of line) {\n if (ch !== ' ' && ch !== '\\t') count++;\n }\n }\n return count;\n }, [lines]);\n\n // Full cycle: fade in + hold + fade out + pause\n const cycleLength = totalChars + 40;\n\n useEffect(() => {\n const interval = setInterval(() => {\n setFrame((f) => (f + 1) % cycleLength);\n }, SHIMMER_SPEED);\n return () => clearInterval(interval);\n }, [cycleLength]);\n\n return useMemo(() => {\n // Map frame to a wave that fades the whole logo in and out\n // Phase 0..totalChars: characters light up one by one (sweep in)\n // Phase totalChars..totalChars+20: hold bright\n // Phase totalChars+20..cycleLength: all fade out together\n const sweepPos = frame;\n const holdEnd = totalChars + 20;\n\n let charIdx = 0;\n return lines\n .map((line) => {\n let result = '';\n for (let i = 0; i < line.length; i++) {\n const ch = line[i]!;\n if (ch === ' ' || ch === '\\t') {\n result += ch;\n continue;\n }\n\n let brightness: number;\n if (sweepPos <= totalChars) {\n // Sweep phase: characters light up as the wave passes\n const lag = charIdx;\n const t = sweepPos - lag;\n brightness = t <= 0 ? 0.1 : Math.min(1, t / 8);\n } else if (sweepPos <= holdEnd) {\n // Hold phase: everything bright\n brightness = 1;\n } else {\n // Fade out phase\n const fadeProgress = (sweepPos - holdEnd) / (cycleLength - holdEnd);\n brightness = Math.max(0.1, 1 - fadeProgress);\n }\n\n if (brightness >= 0.9) {\n result += chalk.cyanBright.bold(ch);\n } else if (brightness >= 0.6) {\n result += chalk.cyan(ch);\n } else if (brightness >= 0.3) {\n result += chalk.rgb(0, 100, 120)(ch);\n } else {\n result += chalk.rgb(0, 50, 60)(ch);\n }\n\n charIdx++;\n }\n return result;\n })\n .join('\\n');\n }, [frame, lines, totalChars, cycleLength]);\n}\n\nexport function OnboardingPage({ onComplete }: OnboardingPageProps) {\n const {\n status: authStatus,\n authUrl,\n timeRemaining,\n startAuth,\n cancel: cancelAuth,\n } = useAuth();\n const shimmerLogo = useShimmerLogo();\n\n // Auto-navigate to dashboard on success\n useEffect(() => {\n if (authStatus === 'success') {\n const timer = setTimeout(() => onComplete(), 1500);\n return () => clearTimeout(timer);\n }\n }, [authStatus, onComplete]);\n\n // Clean up auth on unmount\n useEffect(() => {\n return () => cancelAuth();\n }, []);\n\n const handleAction = useCallback(() => {\n cancelAuth();\n startAuth();\n }, [cancelAuth, startAuth]);\n\n const canAct =\n authStatus === 'idle' ||\n authStatus === 'expired' ||\n authStatus === 'timeout';\n\n useInput((_input, key) => {\n if (canAct && !key.ctrl) {\n handleAction();\n }\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexGrow={1} />\n\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>{shimmerLogo}</Text>\n\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={2}>\n <Text bold color=\"white\">\n MindStudio Local Tunnel\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" alignItems=\"center\">\n {authStatus === 'idle' && (\n <>\n <Text color=\"gray\">\n Connect your MindStudio account to get started.\n </Text>\n <Box marginTop={1}>\n <Text color=\"cyan\" bold>\n Press any key to Connect Account\n </Text>\n </Box>\n </>\n )}\n\n {(authStatus === 'expired' || authStatus === 'timeout') && (\n <>\n <Text color=\"red\">\n {authStatus === 'expired'\n ? 'Authorization expired.'\n : 'Authorization timed out.'}\n </Text>\n <Box marginTop={1}>\n <Text color=\"cyan\" bold>\n Press any key to Try Again\n </Text>\n </Box>\n </>\n )}\n\n {authStatus === 'waiting' && (\n <>\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text>\n {' '}\n Waiting for browser authorization... ({timeRemaining}s\n remaining)\n </Text>\n </Box>\n {authUrl && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n <Text color=\"gray\">If browser didn't open, visit:</Text>\n <Text color=\"cyan\">{authUrl}</Text>\n </Box>\n )}\n </>\n )}\n\n {authStatus === 'success' && (\n <Text color=\"green\">{'\\u2713'} Authenticated!</Text>\n )}\n </Box>\n </Box>\n\n <Box flexGrow={1} />\n </Box>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport open from 'open';\nimport { requestDeviceAuth, pollDeviceAuth } from '../../api';\nimport { setApiKey } from '../../config';\n\ntype AuthStatus = 'idle' | 'waiting' | 'success' | 'expired' | 'timeout';\n\ninterface UseAuthResult {\n status: AuthStatus;\n authUrl: string | null;\n timeRemaining: number;\n startAuth: () => void;\n cancel: () => void;\n}\n\nconst POLL_INTERVAL = 2000;\nconst MAX_ATTEMPTS = 30;\n\nexport function useAuth(): UseAuthResult {\n const [status, setStatus] = useState<AuthStatus>('idle');\n const [authUrl, setAuthUrl] = useState<string | null>(null);\n const [timeRemaining, setTimeRemaining] = useState(0);\n const cancelledRef = useRef(false);\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Clean up timer on unmount\n useEffect(() => {\n return () => {\n cancelledRef.current = true;\n if (timerRef.current) clearInterval(timerRef.current);\n };\n }, []);\n\n const cancel = useCallback(() => {\n cancelledRef.current = true;\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n setStatus('idle');\n setAuthUrl(null);\n setTimeRemaining(0);\n }, []);\n\n const startAuth = useCallback(() => {\n cancelledRef.current = false;\n\n const run = async () => {\n try {\n const { url, token } = await requestDeviceAuth();\n if (cancelledRef.current) return;\n\n setAuthUrl(url);\n setStatus('waiting');\n\n const totalTime = (MAX_ATTEMPTS * POLL_INTERVAL) / 1000;\n setTimeRemaining(totalTime);\n\n // Countdown timer\n timerRef.current = setInterval(() => {\n setTimeRemaining((prev) => {\n const next = prev - 1;\n if (next <= 0 && timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n return Math.max(0, next);\n });\n }, 1000);\n\n await open(url);\n\n // Poll loop\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\n if (cancelledRef.current) return;\n\n const result = await pollDeviceAuth(token);\n\n if (result.status === 'completed' && result.apiKey) {\n if (timerRef.current) clearInterval(timerRef.current);\n setApiKey(result.apiKey);\n setStatus('success');\n return;\n }\n\n if (result.status === 'expired') {\n if (timerRef.current) clearInterval(timerRef.current);\n setStatus('expired');\n return;\n }\n }\n\n if (!cancelledRef.current) {\n setStatus('timeout');\n }\n } catch {\n if (!cancelledRef.current) {\n setStatus('expired');\n }\n }\n };\n\n run();\n }, []);\n\n return {\n status,\n authUrl,\n timeRemaining,\n startAuth,\n cancel,\n };\n}\n","import { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nexport function getCurrentVersion(): string {\n return pkg.version;\n}\n\nexport async function fetchLatestVersion(): Promise<string | null> {\n try {\n const res = await fetch(\n 'https://registry.npmjs.org/@mindstudio-ai/local-model-tunnel/latest',\n { signal: AbortSignal.timeout(5000) },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\nexport function isNewerVersion(current: string, latest: string): boolean {\n const currentParts = current.split('.').map(Number);\n const latestParts = latest.split('.').map(Number);\n for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {\n const c = currentParts[i] ?? 0;\n const l = latestParts[i] ?? 0;\n if (l > c) return true;\n if (l < c) return false;\n }\n return false;\n}\n\nexport async function checkForUpdate(): Promise<{\n currentVersion: string;\n latestVersion: string;\n} | null> {\n const currentVersion = getCurrentVersion();\n const latestVersion = await fetchLatestVersion();\n if (!latestVersion) return null;\n if (!isNewerVersion(currentVersion, latestVersion)) return null;\n return { currentVersion, latestVersion };\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface UpdatePromptProps {\n currentVersion: string;\n latestVersion: string;\n onChoice: (shouldUpdate: boolean) => void;\n}\n\nexport function UpdatePrompt({\n currentVersion,\n latestVersion,\n onChoice,\n}: UpdatePromptProps) {\n useInput((input) => {\n if (input.toLowerCase() === 'y') {\n onChoice(true);\n } else {\n onChoice(false);\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2}>\n <Text>\n <Text color=\"yellow\" bold>\n Update available:\n </Text>\n <Text>\n {' '}\n v{currentVersion} {'\\u2192'} v{latestVersion}\n </Text>\n </Text>\n <Box marginTop={1}>\n <Text>\n Press <Text bold color=\"cyan\">y</Text> to update, any other key to\n skip\n </Text>\n </Box>\n </Box>\n );\n}\n"],"mappings":"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","names":["useEffect","useCallback","useState","Box","useStdout","require","Box","Text","jsx","jsxs","useState","useEffect","useState","useEffect","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useCallback","useState","useEffect","useCallback","useState","useEffect","useCallback","useState","useCallback","useEffect","Box","Text","useStdout","Spinner","Box","Text","jsx","jsxs","useState","useEffect","useCallback","useState","useCallback","useEffect","jsx","jsxs","useStdout","Box","Text","Spinner","useEffect","Box","Text","Spinner","useState","useCallback","useRef","useEffect","useState","useRef","useEffect","useCallback","jsx","jsxs","useEffect","Box","Text","Spinner","useState","useMemo","useEffect","Box","Text","useInput","useStdout","Spinner","useMemo","Text","useStdout","jsx","Fragment","jsx","jsxs","useState","useStdout","useMemo","useInput","Box","Text","useEffect","Spinner","useEffect","useCallback","useState","useMemo","Box","Text","useInput","Spinner","chalk","useState","useCallback","useRef","useEffect","useState","useRef","useEffect","useCallback","Fragment","jsx","jsxs","useState","useMemo","useEffect","chalk","useCallback","useInput","Box","Text","Spinner","Fragment","jsx","jsxs","useStdout","useState","useEffect","useCallback","Box","createRequire","require","pkg","Box","Text","useInput","jsx","jsxs","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/local-model-tunnel",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Run local AI models with MindStudio",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tui/index.tsx","../src/tui/App.tsx","../src/tui/components/Header.tsx","../src/tui/components/NavigationMenu.tsx","../src/tui/hooks/useConnection.ts","../src/tui/hooks/useProviders.ts","../src/tui/hooks/useModels.ts","../src/tui/hooks/useRequests.ts","../src/tui/hooks/useRegisteredModels.ts","../src/tui/pages/DashboardPage.tsx","../src/tui/components/RequestLog.tsx","../src/tui/hooks/useSetupProviders.ts","../src/tui/pages/RegisterPage.tsx","../src/tui/hooks/useRegister.ts","../src/tui/pages/SetupPage.tsx","../src/tui/components/MarkdownText.tsx","../src/tui/pages/OnboardingPage.tsx","../src/tui/hooks/useAuth.ts","../src/update.ts","../src/tui/components/UpdatePrompt.tsx"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { execFileSync, execSync } from 'node:child_process';\nimport { App } from './App';\nimport { TunnelRunner } from '../runner';\nimport { checkForUpdate } from '../update';\nimport { UpdatePrompt } from './components/UpdatePrompt';\n\nasync function promptForUpdate(\n currentVersion: string,\n latestVersion: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n const { unmount } = render(\n <UpdatePrompt\n currentVersion={currentVersion}\n latestVersion={latestVersion}\n onChoice={(shouldUpdate) => {\n unmount();\n resolve(shouldUpdate);\n }}\n />,\n { exitOnCtrlC: true },\n );\n });\n}\n\nexport async function startTUI(): Promise<void> {\n // Clear the screen\n console.clear();\n\n // Check for updates before launching the main app\n const update = await checkForUpdate();\n if (update) {\n const shouldUpdate = await promptForUpdate(\n update.currentVersion,\n update.latestVersion,\n );\n if (shouldUpdate) {\n console.log('\\nUpdating to v' + update.latestVersion + '...\\n');\n try {\n execSync('npm install -g @mindstudio-ai/local-model-tunnel@latest', {\n stdio: 'inherit',\n });\n console.log('\\nRestarting...\\n');\n execFileSync(process.execPath, process.argv.slice(1), {\n stdio: 'inherit',\n });\n } catch {\n console.error('\\nUpdate failed. Continuing with current version.\\n');\n }\n return;\n }\n console.clear();\n }\n\n // Create the runner instance\n const runner = new TunnelRunner();\n\n // Render the TUI with stdin configured for keyboard input\n const { waitUntilExit } = render(\n <App runner={runner} />,\n {\n exitOnCtrlC: true,\n },\n );\n\n // Wait for the app to exit\n await waitUntilExit();\n\n // Ensure clean shutdown\n runner.stop();\n}\n","import React, { useEffect, useCallback, useState } from 'react';\nimport { Box, useApp, useStdout } from 'ink';\nimport { Header } from './components/Header';\nimport { NavigationMenu } from './components/NavigationMenu';\nimport type { MenuItem } from './components/NavigationMenu';\nimport { useConnection } from './hooks/useConnection';\nimport { useProviders } from './hooks/useProviders';\nimport { useModels } from './hooks/useModels';\nimport { useRequests } from './hooks/useRequests';\nimport { useSyncedModels } from './hooks/useRegisteredModels';\nimport { DashboardPage } from './pages/DashboardPage';\nimport { SyncPage } from './pages/RegisterPage';\nimport { SetupPage } from './pages/SetupPage';\nimport { OnboardingPage } from './pages/OnboardingPage';\nimport { TunnelRunner } from '../runner';\nimport { getApiKey, getConfigPath } from '../config';\nimport type { Page } from './types';\n\ninterface AppProps {\n runner: TunnelRunner;\n}\n\nexport function App({ runner }: AppProps) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const {\n status: connectionStatus,\n environment,\n error: connectionError,\n retry: retryConnection,\n } = useConnection();\n const { refresh: refreshProviders } = useProviders();\n const {\n models,\n warnings: modelWarnings,\n loading: modelsLoading,\n refresh: refreshModels,\n } = useModels();\n const { requests } = useRequests();\n const { syncedNames, refresh: refreshSynced } =\n useSyncedModels(connectionStatus);\n const shouldOnboard = getApiKey() === undefined;\n const [page, setPage] = useState<Page>(\n shouldOnboard ? 'onboarding' : 'dashboard',\n );\n\n // Refresh everything when returning to dashboard\n useEffect(() => {\n if (page === 'dashboard') {\n refreshAll();\n }\n }, [page]);\n\n // Start runner when connected with models\n useEffect(() => {\n if (connectionStatus === 'connected' && models.length > 0) {\n runner.start(models.map((m) => m.name));\n }\n }, [connectionStatus, models, runner]);\n\n // Stop only on unmount\n useEffect(() => () => runner.stop(), [runner]);\n\n // Refresh everything\n const refreshAll = useCallback(async () => {\n await Promise.all([\n refreshProviders(),\n refreshModels(),\n refreshSynced(),\n ]);\n }, [refreshProviders, refreshModels, refreshSynced]);\n\n const handleQuit = useCallback(() => {\n runner.stop();\n exit();\n }, [runner, exit]);\n\n const handleOnboardingComplete = useCallback(() => {\n retryConnection();\n refreshAll();\n setPage('dashboard');\n }, [retryConnection, refreshAll]);\n\n const handleNavigate = useCallback(\n (id: string) => {\n switch (id) {\n case 'auth':\n setPage('onboarding');\n break;\n case 'register':\n setPage('sync');\n break;\n case 'setup':\n setPage('setup');\n break;\n case 'refresh':\n refreshAll();\n break;\n case 'quit':\n handleQuit();\n break;\n }\n },\n [refreshModels, refreshSynced, refreshAll, handleQuit],\n );\n\n const subpageMenuItems: MenuItem[] = [\n { id: 'back', label: 'Back', description: 'Return to dashboard' },\n ];\n\n const handleSubpageNavigate = useCallback(\n (id: string) => {\n if (id === 'back') {\n setPage('dashboard');\n } else {\n handleNavigate(id);\n }\n },\n [handleNavigate],\n );\n\n const termHeight = (stdout?.rows ?? 24) - 4;\n\n return (\n <Box flexDirection=\"column\" height={termHeight} overflow=\"hidden\">\n {page === 'onboarding' ? (\n <OnboardingPage onComplete={handleOnboardingComplete} />\n ) : (\n <>\n <Header\n connection={connectionStatus}\n environment={environment}\n configPath={getConfigPath()}\n connectionError={connectionError}\n />\n\n {page === 'dashboard' && (\n <DashboardPage\n requests={requests}\n models={models}\n modelWarnings={modelWarnings}\n syncedNames={syncedNames}\n modelsLoading={modelsLoading}\n onNavigate={handleNavigate}\n />\n )}\n {page === 'setup' && (\n <SetupPage onBack={() => setPage('dashboard')} />\n )}\n {page === 'sync' && <SyncPage />}\n\n {page !== 'dashboard' && page !== 'setup' && <Box flexGrow={1} />}\n\n {page !== 'dashboard' && page !== 'setup' && (\n <NavigationMenu\n items={subpageMenuItems}\n onSelect={handleSubpageNavigate}\n />\n )}\n </>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport os from 'node:os';\nimport { Box, Text } from 'ink';\nimport type { ConnectionStatus } from '../types';\nimport { createRequire } from 'node:module';\n\ninterface HeaderProps {\n connection: ConnectionStatus;\n environment: 'prod' | 'local';\n configPath: string;\n connectionError?: string | null;\n}\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nexport const LogoString = ` .=+-. :++.\n *@@@@@+ :%@@@@%:\n .%@@@@@@#..@@@@@@@=\n .*@@@@@@@--@@@@@@@#.**.\n *@@@@@@@.-@@@@@@@@.#@@*\n.#@@@@@@@-.@@@@@@@* #@@@@%.\n=@@@@@@@-.@@@@@@@#.-@@@@@@+\n:@@@@@@: +@@@@@#. .@@@@@@:\n .++: .-*-. .++:`;\n\nconst getConnectionDisplay = (status: ConnectionStatus) => {\n switch (status) {\n case 'connected':\n return { color: 'green', text: 'Connected to Cloud' };\n case 'connecting':\n return { color: 'yellow', text: 'Connecting...' };\n case 'not_authenticated':\n return { color: 'yellow', text: 'Not Authenticated' };\n case 'disconnected':\n return { color: 'red', text: 'Disconnected' };\n default:\n return { color: 'red', text: 'Error' };\n }\n};\n\nexport function Header({\n connection,\n environment,\n configPath,\n connectionError,\n}: HeaderProps) {\n const { color: connectionColor, text: connectionText } =\n getConnectionDisplay(connection);\n\n return (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n borderStyle=\"round\"\n borderColor=\"cyan\"\n paddingX={1}\n paddingY={1}\n width=\"100%\"\n >\n <Box paddingLeft={3}>\n <Text color=\"cyan\">{LogoString}</Text>\n </Box>\n <Box flexDirection=\"column\" marginLeft={4}>\n <Box>\n <Text bold color=\"white\">\n MindStudio Local Tunnel\n </Text>\n {environment !== 'prod' && (\n <>\n <Text> </Text>\n <Text color=\"yellow\" bold>\n [LOCAL]\n </Text>\n </>\n )}\n </Box>\n <Text color=\"gray\">v{pkg.version}</Text>\n <Text color={connectionColor}>● {connectionText}</Text>\n {connectionError && <Text color=\"red\">{connectionError}</Text>}\n <Text color=\"gray\">\n Config: {configPath.replace(os.homedir(), '~')}\n </Text>\n </Box>\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useInput } from 'ink';\n\nexport interface MenuItem {\n id: string;\n label: string;\n description: string;\n disabled?: boolean;\n disabledReason?: string;\n isSeparator?: boolean;\n color?: string;\n}\n\ninterface NavigationMenuProps {\n items: MenuItem[];\n onSelect: (id: string) => void;\n title?: string;\n}\n\nexport function NavigationMenu({ items, onSelect, title }: NavigationMenuProps) {\n const getDefaultIndex = () => {\n const backIdx = items.findIndex((i) => i.id === 'back');\n if (backIdx >= 0) return backIdx;\n const firstIdx = items.findIndex((i) => !i.disabled && !i.isSeparator);\n return firstIdx >= 0 ? firstIdx : 0;\n };\n const [selectedIndex, setSelectedIndex] = useState(getDefaultIndex);\n\n useEffect(() => {\n setSelectedIndex(getDefaultIndex());\n }, [items]);\n\n const findNextEnabled = (from: number, direction: 1 | -1): number => {\n let idx = from;\n for (let i = 0; i < items.length; i++) {\n idx = (idx + direction + items.length) % items.length;\n if (!items[idx]!.disabled && !items[idx]!.isSeparator) return idx;\n }\n return from;\n };\n\n useInput((input, key) => {\n if (input === 'q' || key.escape) {\n const backItem = items.find((i) => i.id === 'back');\n if (backItem) {\n onSelect('back');\n } else if (input === 'q') {\n onSelect('quit');\n }\n return;\n }\n if (key.upArrow) {\n setSelectedIndex((prev) => findNextEnabled(prev, -1));\n } else if (key.downArrow) {\n setSelectedIndex((prev) => findNextEnabled(prev, 1));\n } else if (key.return) {\n const item = items[selectedIndex];\n if (item && !item.disabled) {\n onSelect(item.id);\n }\n }\n });\n\n // Fixed height: header + items + hint + margins\n const separatorExtraLines = items.filter((item, idx) => item.isSeparator && idx > 0).length;\n const menuHeight = items.length + 4 + separatorExtraLines;\n\n return (\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1} borderStyle=\"single\" borderTop borderBottom={false} borderLeft={false} borderRight={false} borderColor=\"gray\">\n <Box marginTop={1}>\n <Text color=\"gray\">{title ?? 'Actions'}</Text>\n </Box>\n <Box flexDirection=\"column\">\n {items.map((item, index) => {\n if (item.isSeparator) {\n return (\n <Box key={item.id} marginTop={index > 0 ? 1 : 0}>\n {item.label ? (\n <Text bold color={item.color ?? 'gray'} wrap=\"truncate-end\">\n {item.label}\n </Text>\n ) : null}\n </Box>\n );\n }\n\n const isSelected = index === selectedIndex;\n const prefix = isSelected ? '❯' : ' ';\n\n if (item.disabled) {\n return (\n <Box key={item.id}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n {prefix} {item.label}\n {item.disabledReason ? ` (${item.disabledReason})` : ''}\n </Text>\n </Box>\n );\n }\n\n return (\n <Box key={item.id}>\n <Text color={isSelected ? 'cyan' : 'white'} bold={isSelected} wrap=\"truncate-end\">\n {prefix} {item.label}\n </Text>\n {isSelected && (\n <Text color=\"gray\" wrap=\"truncate-end\"> - {item.description}</Text>\n )}\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={1} height={1}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n {items.some((i) => i.id === 'back')\n ? 'Up/Down Navigate \\u2022 Enter Select \\u2022 q/Esc Back'\n : 'Up/Down Navigate \\u2022 Enter Select \\u2022 q Quit'}\n </Text>\n </Box>\n </Box>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { verifyApiKey } from '../../api';\nimport { getApiKey, getEnvironment } from '../../config';\nimport type { ConnectionStatus } from '../types';\n\ninterface UseConnectionResult {\n status: ConnectionStatus;\n environment: 'prod' | 'local';\n error: string | null;\n retry: () => void;\n}\n\nexport function useConnection(): UseConnectionResult {\n const [status, setStatus] = useState<ConnectionStatus>('connecting');\n const [error, setError] = useState<string | null>(null);\n const environment = getEnvironment();\n\n const connect = useCallback(async () => {\n setStatus('connecting');\n setError(null);\n\n const apiKey = getApiKey();\n if (!apiKey) {\n setStatus('not_authenticated');\n return;\n }\n\n try {\n const isValid = await verifyApiKey();\n if (isValid) {\n setStatus('connected');\n } else {\n setStatus('not_authenticated');\n }\n } catch (err) {\n setStatus('error');\n setError(err instanceof Error ? err.message : 'Connection failed');\n }\n }, []);\n\n useEffect(() => {\n connect();\n }, [connect]);\n\n return {\n status,\n environment,\n error,\n retry: connect,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { getProviderStatuses } from '../../providers';\nimport type { ProviderStatus } from '../types';\n\ninterface UseProvidersResult {\n providers: ProviderStatus[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useProviders(pollInterval: number = 10000): UseProvidersResult {\n const [providers, setProviders] = useState<ProviderStatus[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n try {\n const statuses = await getProviderStatuses();\n setProviders(statuses);\n } catch {\n // Keep existing state on error\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n refresh();\n\n // Poll for provider status changes\n const interval = setInterval(refresh, pollInterval);\n return () => clearInterval(interval);\n }, [refresh, pollInterval]);\n\n return {\n providers,\n loading,\n refresh,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { discoverAllModels } from '../../providers';\nimport type { LocalModel } from '../../providers/types';\n\ninterface UseModelsResult {\n models: LocalModel[];\n warnings: LocalModel[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useModels(): UseModelsResult {\n const [models, setModels] = useState<LocalModel[]>([]);\n const [warnings, setWarnings] = useState<LocalModel[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const discoveredModels = await discoverAllModels();\n setModels(discoveredModels.filter((m) => !m.statusHint));\n setWarnings(discoveredModels.filter((m) => !!m.statusHint));\n } catch {\n // Keep existing state on error\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return {\n models,\n warnings,\n loading,\n refresh,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { requestEvents } from '../../events';\nimport type { RequestLogEntry } from '../types';\n\ninterface UseRequestsResult {\n requests: RequestLogEntry[];\n activeCount: number;\n clear: () => void;\n}\n\nexport function useRequests(maxHistory: number = 50): UseRequestsResult {\n const [requests, setRequests] = useState<RequestLogEntry[]>([]);\n const requestsRef = useRef<Map<string, RequestLogEntry>>(new Map());\n\n // Update timer for active request durations\n useEffect(() => {\n const interval = setInterval(() => {\n // Force re-render for active requests to update elapsed time\n setRequests((prev) => {\n const hasActive = prev.some((r) => r.status === 'processing');\n return hasActive ? [...prev] : prev;\n });\n }, 1000);\n\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n const unsubStart = requestEvents.onStart((event) => {\n const entry: RequestLogEntry = {\n id: event.id,\n modelId: event.modelId,\n requestType: event.requestType,\n status: 'processing',\n startTime: event.timestamp,\n };\n\n requestsRef.current.set(event.id, entry);\n setRequests((prev) => [...prev, entry].slice(-maxHistory));\n });\n\n const unsubProgress = requestEvents.onProgress((event) => {\n const existing = requestsRef.current.get(event.id);\n if (existing && existing.status === 'processing') {\n const updated: RequestLogEntry = {\n ...existing,\n ...(event.content !== undefined && { content: event.content }),\n ...(event.step !== undefined && { step: event.step }),\n ...(event.totalSteps !== undefined && { totalSteps: event.totalSteps }),\n };\n requestsRef.current.set(event.id, updated);\n setRequests((prev) =>\n prev.map((r) => (r.id === event.id ? updated : r)),\n );\n }\n });\n\n const unsubComplete = requestEvents.onComplete((event) => {\n const existing = requestsRef.current.get(event.id);\n if (existing) {\n const updated: RequestLogEntry = {\n ...existing,\n status: event.success ? 'completed' : 'failed',\n endTime: Date.now(),\n duration: event.duration,\n result: event.result,\n error: event.error,\n };\n\n requestsRef.current.set(event.id, updated);\n setRequests((prev) =>\n prev.map((r) => (r.id === event.id ? updated : r)),\n );\n }\n });\n\n return () => {\n unsubStart();\n unsubProgress();\n unsubComplete();\n };\n }, [maxHistory]);\n\n const activeCount = requests.filter((r) => r.status === 'processing').length;\n\n const clear = useCallback(() => {\n requestsRef.current.clear();\n setRequests([]);\n }, []);\n\n return {\n requests,\n activeCount,\n clear,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { getSyncedModels } from '../../api';\nimport type { ConnectionStatus } from '../types';\n\ninterface UseSyncedModelsResult {\n syncedNames: Set<string>;\n refresh: () => Promise<void>;\n}\n\nexport function useSyncedModels(\n connectionStatus: ConnectionStatus,\n): UseSyncedModelsResult {\n const [syncedNames, setSyncedNames] = useState<Set<string>>(\n new Set(),\n );\n\n const refresh = useCallback(async () => {\n if (connectionStatus !== 'connected') {\n setSyncedNames(new Set());\n return;\n }\n\n try {\n const models = await getSyncedModels();\n setSyncedNames(new Set(models.map((m) => m.name)));\n } catch {\n // Keep existing state on error\n }\n }, [connectionStatus]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return {\n syncedNames,\n refresh,\n };\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { RequestLog } from '../components/RequestLog';\nimport { NavigationMenu } from '../components/NavigationMenu';\nimport type { MenuItem } from '../components/NavigationMenu';\nimport type { LocalModel, ComfyWorkflowParameterSchema } from '../../providers/types';\nimport type { ProviderStatus, RequestLogEntry } from '../types';\nimport { useSetupProviders } from '../hooks/useSetupProviders';\n\nfunction getWorkflowCount(model: LocalModel): number | null {\n const param = model.parameters?.find((p) => p.type === 'comfyWorkflow');\n if (!param) return null;\n return (param as ComfyWorkflowParameterSchema).comfyWorkflowOptions.availableWorkflows.length;\n}\n\nfunction getCapabilityLabel(capability: string): {\n label: string;\n color: string;\n} {\n switch (capability) {\n case 'text':\n return { label: 'Text Generation', color: 'gray' };\n case 'image':\n return { label: 'Image Generation', color: 'gray' };\n case 'video':\n return { label: 'Video Generation', color: 'gray' };\n default:\n return { label: capability, color: 'gray' };\n }\n}\n\ninterface DashboardPageProps {\n requests: RequestLogEntry[];\n models: LocalModel[];\n modelWarnings?: LocalModel[];\n syncedNames: Set<string>;\n modelsLoading?: boolean;\n onNavigate: (id: string) => void;\n}\n\nexport function DashboardPage({\n requests,\n models,\n modelWarnings = [],\n syncedNames,\n modelsLoading,\n onNavigate,\n}: DashboardPageProps) {\n const { stdout } = useStdout();\n const { providers, loading: setupLoading } = useSetupProviders();\n\n const installedProviders = providers.filter(({ status }) => status.installed);\n\n const provNameWidth = Math.max(\n ...installedProviders.map((p) => p.provider.displayName.length),\n 8,\n );\n const provStatusWidth = 'Local Server Running'.length;\n\n const allModelNames = new Set(models.map((m) => m.name));\n const unavailableSynced = [...syncedNames].filter(\n (name) => !allModelNames.has(name),\n );\n\n const menuItems = useMemo((): MenuItem[] => {\n return [\n {\n id: 'register',\n label: 'Sync Models',\n description: 'Sync models with MindStudio Cloud',\n },\n {\n id: 'refresh',\n label: 'Refresh Providers',\n description: 'Re-detect local AI providers and models',\n },\n {\n id: 'setup',\n label: 'Manage Providers',\n description: 'Manage local AI providers',\n },\n {\n id: 'auth',\n label: 'Re-authenticate',\n description: 'Re-authenticate with MindStudio',\n },\n {\n id: 'quit',\n label: 'Exit',\n description: 'Quit the application',\n },\n ];\n }, []);\n\n // Compute maxVisible for request log based on terminal height\n const termHeight = (stdout?.rows ?? 24) - 4; // matches App's height calculation\n\n // Header: border(2) + padding(2) + logo(~10 lines) = 14\n const headerLines = 14;\n\n // Providers section: marginTop(1) + title(1) + content gap(1) + content\n const providerContentLines = setupLoading\n ? 1\n : installedProviders.length === 0\n ? 2\n : installedProviders.length;\n const providersLines = 3 + providerContentLines;\n\n // Models section: marginTop(1) + title(1) + content gap(1) + content\n const modelContentLines = modelsLoading\n ? 1\n : models.length === 0 && unavailableSynced.length === 0 && modelWarnings.length === 0\n ? 2\n : models.length +\n modelWarnings.length +\n (unavailableSynced.length > 0\n ? 1 + unavailableSynced.length\n : 0);\n const modelsLines = 3 + modelContentLines;\n\n // Request log overhead: marginTop(1) + title(1) + content gap(1)\n const requestLogOverhead = 3;\n\n // Menu: border-top(1) + marginTop(1) + title(1) + items + hint(1) + marginTop(1) + marginBottom(1)\n const menuLines = menuItems.length + 6;\n\n const usedLines =\n headerLines + providersLines + modelsLines + requestLogOverhead + menuLines;\n const maxVisible = Math.max(3, termHeight - usedLines);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {/* Providers */}\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Providers\n </Text>\n\n {setupLoading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Detecting providers...</Text>\n </Box>\n ) : installedProviders.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\">No providers installed.</Text>\n <Text color=\"gray\">\n Use \"Manage Providers\" below to install one.\n </Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {installedProviders.map(({ provider, status }) => {\n const url = provider.baseUrl;\n const statusColor = status.running ? 'green' : 'yellow';\n const statusText = status.running\n ? 'Local Server Running'\n : 'Installed (not running)';\n\n return (\n <Box key={provider.name}>\n <Text color=\"white\">\n {provider.displayName.padEnd(provNameWidth + 2)}\n </Text>\n <Text color={statusColor}>\n {statusText.padEnd(provStatusWidth + 2)}\n </Text>\n {status.running && <Text color=\"gray\">{url}</Text>}\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n\n {/* Models */}\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Models\n </Text>\n\n {modelsLoading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Discovering models...</Text>\n </Box>\n ) : models.length === 0 && unavailableSynced.length === 0 && modelWarnings.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"yellow\">No models found.</Text>\n <Text color=\"gray\">\n Download models using your provider (e.g., ollama pull llama3.2)\n </Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {models.map((model) => {\n const cap = getCapabilityLabel(model.capability);\n const isSynced = syncedNames.has(model.name);\n const displayProvider =\n providers.find((p) => p.provider.name === model.provider)\n ?.provider.displayName ?? model.provider;\n const workflowCount = getWorkflowCount(model);\n const workflowSuffix = workflowCount !== null\n ? ` (${workflowCount} workflow${workflowCount !== 1 ? 's' : ''}, ${isSynced ? workflowCount : 0} synced)`\n : '';\n return (\n <Box key={model.name}>\n <Text color={isSynced ? 'green' : 'gray'}>\n {isSynced ? '\\u25CF' : '\\u25CB'}\n </Text>\n <Text color=\"white\">{` ${model.name}`}</Text>\n {workflowSuffix && <Text color=\"gray\">{workflowSuffix}</Text>}\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"gray\">{displayProvider}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color={cap.color}>{cap.label}</Text>\n </Box>\n );\n })}\n {modelWarnings.map((warning) => {\n const displayProvider =\n providers.find((p) => p.provider.name === warning.provider)\n ?.provider.displayName ?? warning.provider;\n return (\n <Box key={warning.name}>\n <Text color=\"gray\">{'\\u25CB'}</Text>\n <Text color=\"white\">{` ${warning.name}`}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"gray\">{displayProvider}</Text>\n <Text color=\"gray\">{' - '}</Text>\n <Text color=\"yellow\">{warning.statusHint}</Text>\n </Box>\n );\n })}\n\n {unavailableSynced.length > 0 && (\n <Box flexDirection=\"column\" marginTop={models.length > 0 ? 1 : 0}>\n <Text color=\"gray\">\n Synced but not currently available:\n </Text>\n {unavailableSynced.map((name) => (\n <Box key={name}>\n <Text color=\"gray\">{'\\u25CB'}</Text>\n <Text color=\"gray\">{` ${name}`}</Text>\n </Box>\n ))}\n </Box>\n )}\n </Box>\n )}\n </Box>\n\n {/* Request log */}\n <RequestLog\n requests={requests}\n maxVisible={maxVisible}\n hasModels={models.length > 0}\n />\n\n {/* Bottom: Navigation menu pane */}\n <NavigationMenu items={menuItems} onSelect={onNavigate} />\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport type { RequestLogEntry } from '../types';\n\ninterface RequestLogProps {\n requests: RequestLogEntry[];\n maxVisible?: number;\n hasModels?: boolean;\n}\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction getRequestTypeLabel(type: string): { label: string; color: string } {\n switch (type) {\n case 'llm_chat':\n return { label: 'text', color: 'gray' };\n case 'image_generation':\n return { label: 'image', color: 'gray' };\n case 'video_generation':\n return { label: 'video', color: 'gray' };\n default:\n return { label: type, color: 'gray' };\n }\n}\n\nfunction snippetLine(content: string, maxWidth: number): string {\n // Collapse whitespace/newlines into single spaces\n const flat = content.replace(/\\s+/g, ' ').trim();\n if (flat.length <= maxWidth) return flat;\n return '\\u2026' + flat.slice(-(maxWidth - 1));\n}\n\nfunction RequestItem({ request, width }: { request: RequestLogEntry; width: number }) {\n const time = formatTime(request.startTime);\n const typeLabel = getRequestTypeLabel(request.requestType);\n // indent for snippet: status(1) + space(1) + padding for alignment\n const snippetIndent = ' ';\n const snippetWidth = width - snippetIndent.length - 2; // 2 for paddingX\n\n if (request.status === 'processing') {\n const elapsed = Date.now() - request.startTime;\n const snippet = request.content && request.requestType === 'llm_chat'\n ? snippetLine(request.content, snippetWidth)\n : null;\n const stepProgress = request.step !== undefined && request.totalSteps\n ? `Step ${request.step}/${request.totalSteps}`\n : null;\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"gray\"> {formatDuration(elapsed)}...</Text>\n </Box>\n {snippet && (\n <Text color=\"gray\" wrap=\"truncate-end\">\n {snippetIndent}{snippet}\n </Text>\n )}\n {stepProgress && (\n <Text color=\"gray\">\n {snippetIndent}{stepProgress}\n </Text>\n )}\n </Box>\n );\n }\n\n if (request.status === 'completed') {\n const duration = request.duration ? formatDuration(request.duration) : '';\n let resultInfo = '';\n if (request.result?.chars) {\n resultInfo = ` \\u00B7 ${request.result.chars} chars`;\n } else if (request.result?.imageSize) {\n resultInfo = ` \\u00B7 ${Math.round(request.result.imageSize / 1024)}KB`;\n } else if (request.result?.videoSize) {\n resultInfo = ` \\u00B7 ${Math.round(request.result.videoSize / 1024 / 1024)}MB`;\n }\n\n const snippet = request.content && request.requestType === 'llm_chat'\n ? snippetLine(request.content, snippetWidth)\n : null;\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"green\">{'\\u2713'}</Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"gray\"> {duration}{resultInfo}</Text>\n </Box>\n {snippet && (\n <Text color=\"gray\" wrap=\"truncate-end\">\n {snippetIndent}{snippet}\n </Text>\n )}\n </Box>\n );\n }\n\n // Failed\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"red\">{'\\u25CF'}</Text>\n <Text color=\"gray\">{' '}{time} </Text>\n <Text color=\"white\">{request.modelId}</Text>\n <Text color=\"gray\"> </Text>\n <Text color={typeLabel.color}>{typeLabel.label}</Text>\n <Text color=\"red\"> {request.error || 'Failed'}</Text>\n </Box>\n </Box>\n );\n}\n\nexport function RequestLog({ requests, maxVisible = 8, hasModels = true }: RequestLogProps) {\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n\n // Get the most recent requests, with active ones always shown\n const activeRequests = requests.filter((r) => r.status === 'processing');\n const completedRequests = requests.filter((r) => r.status !== 'processing');\n\n // Requests with a snippet or step progress take 2 lines, others take 1\n const itemLines = (r: RequestLogEntry) => {\n if (r.requestType === 'llm_chat' && r.content) return 2;\n if (r.status === 'processing' && r.step !== undefined) return 2;\n return 1;\n };\n\n let completedToShow: RequestLogEntry[] = [];\n let linesUsed = activeRequests.reduce((sum, r) => sum + itemLines(r), 0);\n for (let i = completedRequests.length - 1; i >= 0 && linesUsed < maxVisible; i--) {\n const r = completedRequests[i]!;\n const lines = itemLines(r);\n if (linesUsed + lines <= maxVisible) {\n completedToShow.unshift(r);\n linesUsed += lines;\n } else {\n break;\n }\n }\n\n const visibleRequests = [...completedToShow, ...activeRequests];\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n width=\"100%\"\n paddingX={1}\n marginTop={1}\n >\n <Box>\n <Text bold underline color=\"white\">\n Generation Requests\n </Text>\n {activeRequests.length > 0 && (\n <Text color=\"cyan\"> ({activeRequests.length} active)</Text>\n )}\n </Box>\n\n {requests.length === 0 ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\">{hasModels\n ? 'Tunnel is live — requests will appear here when models are used in MindStudio'\n : 'Start a model to begin receiving generation requests.'\n }</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {visibleRequests.map((request) => (\n <RequestItem key={request.id} request={request} width={width} />\n ))}\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport {\n detectAllProviderStatuses,\n type Provider,\n type ProviderSetupStatus,\n} from '../../providers';\n\ninterface ProviderWithStatus {\n provider: Provider;\n status: ProviderSetupStatus;\n}\n\ninterface UseSetupProvidersResult {\n providers: ProviderWithStatus[];\n loading: boolean;\n refresh: () => Promise<void>;\n}\n\nexport function useSetupProviders(): UseSetupProvidersResult {\n const [providers, setProviders] = useState<ProviderWithStatus[]>([]);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n const statuses = await detectAllProviderStatuses();\n setProviders(statuses);\n setLoading(false);\n }, []);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return { providers, loading, refresh };\n}\n","import React, { useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { useSync } from '../hooks/useRegister';\n\nexport function SyncPage() {\n const { status, progress, syncedModels, error, startSync, cancel } =\n useSync();\n\n // Start sync on mount\n useEffect(() => {\n startSync();\n return () => cancel();\n }, []);\n\n if (status === 'idle') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"gray\">Starting model sync...</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'error') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"red\">Sync failed: {error}</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'discovering') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Discovering local models...</Text>\n </Box>\n </Box>\n );\n }\n\n if (status === 'syncing') {\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text>\n {' '}\n Syncing {progress.current}/{progress.total} models...\n </Text>\n </Box>\n </Box>\n );\n }\n\n // Done\n const newModels = syncedModels.filter((m) => m.isNew);\n const resyncedModels = syncedModels.filter((m) => !m.isNew);\n\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingX={1}>\n {newModels.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"green\">\n Synced {newModels.length} new model\n {newModels.length !== 1 ? 's' : ''}:\n </Text>\n {newModels.map((m) => (\n <Box key={m.name}>\n <Text color=\"green\">{' ✓ '}</Text>\n <Text>{m.name} </Text>\n <Text color=\"gray\">[{m.provider}]</Text>\n </Box>\n ))}\n </Box>\n )}\n\n {resyncedModels.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"green\">\n Resynced {resyncedModels.length} existing model\n {resyncedModels.length !== 1 ? 's' : ''}:\n </Text>\n {resyncedModels.map((m) => (\n <Box key={m.name}>\n <Text color=\"green\">{' ✓ '}</Text>\n <Text>{m.name} </Text>\n <Text color=\"gray\">[{m.provider}]</Text>\n </Box>\n ))}\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { getSyncedModels, syncLocalModel, updateLocalModel } from '../../api';\nimport { discoverAllModelsWithParameters } from '../../providers';\n\ntype SyncStatus = 'idle' | 'discovering' | 'syncing' | 'done' | 'error';\n\ninterface SyncProgress {\n current: number;\n total: number;\n}\n\ninterface SyncedModel {\n name: string;\n provider: string;\n capability: string;\n isNew: boolean;\n}\n\ninterface UseSyncResult {\n status: SyncStatus;\n progress: SyncProgress;\n syncedModels: SyncedModel[];\n error: string | null;\n startSync: () => void;\n cancel: () => void;\n}\n\nconst MODEL_TYPE_MAP = {\n text: 'llm_chat',\n image: 'image_generation',\n video: 'video_generation',\n} as const;\n\nexport function useSync(): UseSyncResult {\n const [status, setStatus] = useState<SyncStatus>('idle');\n const [progress, setProgress] = useState<SyncProgress>({\n current: 0,\n total: 0,\n });\n const [syncedModels, setSyncedModels] = useState<SyncedModel[]>(\n [],\n );\n const [error, setError] = useState<string | null>(null);\n const cancelledRef = useRef(false);\n\n useEffect(() => {\n return () => {\n cancelledRef.current = true;\n };\n }, []);\n\n const cancel = useCallback(() => {\n cancelledRef.current = true;\n setStatus('idle');\n }, []);\n\n const startSync = useCallback(() => {\n cancelledRef.current = false;\n setError(null);\n setSyncedModels([]);\n\n const run = async () => {\n try {\n setStatus('discovering');\n\n const localModels = await discoverAllModelsWithParameters();\n if (cancelledRef.current) return;\n\n if (localModels.length === 0) {\n setError('No local models found.');\n setStatus('error');\n return;\n }\n\n const existingSynced = await getSyncedModels();\n if (cancelledRef.current) return;\n\n // Map remote model names to their IDs for updates\n const remoteByName = new Map(\n existingSynced.map((m) => [m.name, m.id]),\n );\n\n setStatus('syncing');\n setProgress({ current: 0, total: localModels.length });\n\n for (let i = 0; i < localModels.length; i++) {\n if (cancelledRef.current) return;\n\n const model = localModels[i]!;\n const modelType =\n MODEL_TYPE_MAP[model.capability as keyof typeof MODEL_TYPE_MAP];\n const existingId = remoteByName.get(model.name);\n\n if (existingId) {\n await updateLocalModel({\n modelId: existingId,\n modelName: model.name,\n provider: model.provider,\n modelType,\n parameters: model.parameters,\n });\n } else {\n await syncLocalModel({\n modelName: model.name,\n provider: model.provider,\n modelType,\n parameters: model.parameters,\n });\n }\n\n setProgress({ current: i + 1, total: localModels.length });\n }\n\n if (cancelledRef.current) return;\n\n const finalModels: SyncedModel[] = localModels.map((m) => ({\n name: m.name,\n provider: m.provider,\n capability: m.capability,\n isNew: !remoteByName.has(m.name),\n }));\n\n setSyncedModels(finalModels);\n setStatus('done');\n } catch (err) {\n if (!cancelledRef.current) {\n setError(err instanceof Error ? err.message : 'Sync failed');\n setStatus('error');\n }\n }\n };\n\n run();\n }, []);\n\n return {\n status,\n progress,\n syncedModels,\n error,\n startSync,\n cancel,\n };\n}\n","import React, { useState, useMemo, useEffect } from 'react';\nimport { Box, Text, useInput, useStdout } from 'ink';\nimport Spinner from 'ink-spinner';\nimport { renderMarkdown } from '../components/MarkdownText';\nimport { useSetupProviders } from '../hooks/useSetupProviders';\nimport type { Provider } from '../../providers/types';\n\ninterface SetupPageProps {\n onBack: () => void;\n}\n\nfunction ProviderDetailView({\n provider,\n onBack,\n}: {\n provider: Provider;\n onBack: () => void;\n}) {\n const [scrollOffset, setScrollOffset] = useState(0);\n const { stdout } = useStdout();\n const termHeight = (stdout?.rows ?? 24) - 4; // matches App's height calc\n const headerHeight = 14; // border(2) + padding(2) + logo(9) + 1\n const footerLines = 6; // border-top(1) + margin(1) + \"Actions\"(1) + \"Back\"(1) + margin(1) + hint(1)\n const contentPadding = 2; // paddingY={1}\n const viewHeight = termHeight - headerHeight - footerLines - contentPadding;\n const contentWidth = (stdout?.columns ?? 80) - 4; // 2 padding + 1 scrollbar + 1 margin\n\n const renderedLines = useMemo(() => {\n const rendered = renderMarkdown(provider.readme, contentWidth);\n return rendered.split('\\n');\n }, [provider.readme, contentWidth]);\n\n const maxScroll = Math.max(0, renderedLines.length - viewHeight);\n\n useInput((input, key) => {\n if (input === 'q' || key.escape || key.return) {\n onBack();\n return;\n }\n if (key.upArrow) {\n setScrollOffset((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setScrollOffset((prev) => Math.min(maxScroll, prev + 1));\n }\n });\n\n const visibleContent = renderedLines\n .slice(scrollOffset, scrollOffset + viewHeight)\n .join('\\n');\n\n const scrollbar = useMemo(() => {\n if (maxScroll === 0) return null;\n const thumbSize = Math.max(\n 1,\n Math.round((viewHeight / renderedLines.length) * viewHeight),\n );\n const thumbPos = Math.round(\n (scrollOffset / maxScroll) * (viewHeight - thumbSize),\n );\n\n return Array.from(\n { length: viewHeight },\n (_, i) => i >= thumbPos && i < thumbPos + thumbSize,\n );\n }, [scrollOffset, maxScroll, viewHeight, renderedLines.length]);\n\n return (\n <Box flexDirection=\"column\">\n <Box height={viewHeight}>\n <Box\n flexDirection=\"column\"\n paddingX={1}\n paddingY={1}\n flexGrow={1}\n overflow=\"hidden\"\n >\n <Text>{visibleContent}</Text>\n </Box>\n {scrollbar && (\n <Box flexDirection=\"column\">\n {scrollbar.map((isThumb, i) => (\n <Text\n key={i}\n color={isThumb ? 'cyan' : 'gray'}\n dimColor={!isThumb}\n >\n {isThumb ? '\\u2503' : '\\u2502'}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box\n flexDirection=\"column\"\n paddingX={1}\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n borderColor=\"gray\"\n >\n <Box marginTop={1}>\n <Text color=\"gray\">\n Actions\n </Text>\n </Box>\n <Box>\n <Text color=\"cyan\" bold>\n {'\\u276F'} Back\n </Text>\n <Text color=\"gray\"> - Return to providers</Text>\n </Box>\n <Box marginTop={1} height={1}>\n <Text color=\"gray\" wrap=\"truncate-end\">\n Up/Down Scroll {'\\u2022'} Enter/q/Esc Back\n {maxScroll > 0 &&\n ` \\u2022 ${Math.round((scrollOffset / maxScroll) * 100)}%`}\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nexport function SetupPage({ onBack }: SetupPageProps) {\n const { providers, loading } = useSetupProviders();\n const [selectedProvider, setSelectedProvider] = useState<string | null>(null);\n const running = useMemo(\n () => providers.filter((p) => p.status.running),\n [providers],\n );\n const installed = useMemo(\n () => providers.filter((p) => p.status.installed && !p.status.running),\n [providers],\n );\n const notInstalled = useMemo(\n () => providers.filter((p) => !p.status.installed),\n [providers],\n );\n const allProviders = useMemo(\n () => [...running, ...installed, ...notInstalled],\n [running, installed, notInstalled],\n );\n\n const totalItems = allProviders.length + 1; // +1 for Back\n const backIndex = allProviders.length;\n const [cursorIndex, setCursorIndex] = useState(backIndex);\n\n useEffect(() => {\n setCursorIndex(backIndex);\n }, [backIndex]);\n\n useInput((input, key) => {\n if (selectedProvider) return;\n if (input === 'q' || key.escape) {\n onBack();\n return;\n }\n if (key.upArrow) {\n setCursorIndex((prev) => Math.max(0, prev - 1));\n } else if (key.downArrow) {\n setCursorIndex((prev) => Math.min(totalItems - 1, prev + 1));\n } else if (key.return) {\n if (cursorIndex === backIndex) {\n onBack();\n } else if (allProviders[cursorIndex]) {\n setSelectedProvider(allProviders[cursorIndex]!.provider.name);\n }\n }\n });\n\n if (selectedProvider) {\n const found = providers.find((p) => p.provider.name === selectedProvider);\n if (found) {\n return (\n <ProviderDetailView\n provider={found.provider}\n onBack={() => setSelectedProvider(null)}\n />\n );\n }\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" paddingX={1} marginTop={1}>\n <Text bold color=\"white\" underline>\n Manage Providers\n </Text>\n <Text color=\"gray\">Select a provider to view its setup guide.</Text>\n\n {loading ? (\n <Box marginTop={1}>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text> Detecting providers...</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\" marginTop={1}>\n {running.length > 0 && (\n <>\n <Text bold color=\"green\">\n Running\n </Text>\n {running.map(({ provider }, i) => {\n const index = i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {'\\u25CF'}{' '}\n {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </>\n )}\n {installed.length > 0 && (\n <Box\n flexDirection=\"column\"\n marginTop={running.length > 0 ? 1 : 0}\n >\n <Text bold color=\"yellow\">\n Installed\n </Text>\n {installed.map(({ provider, status }, i) => {\n const index = running.length + i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {'\\u25CB'}{' '}\n {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </Box>\n )}\n {notInstalled.length > 0 && (\n <Box\n flexDirection=\"column\"\n marginTop={running.length > 0 || installed.length > 0 ? 1 : 0}\n >\n <Text bold color=\"gray\">\n Not Installed\n </Text>\n {notInstalled.map(({ provider }, i) => {\n const index = running.length + installed.length + i;\n const isSelected = index === cursorIndex;\n return (\n <Box\n key={provider.name}\n flexDirection=\"column\"\n marginTop={i > 0 ? 1 : 0}\n >\n <Box>\n <Text\n color={isSelected ? 'cyan' : 'white'}\n bold={isSelected}\n >\n {isSelected ? '\\u276F' : ' '} {provider.displayName}\n </Text>\n </Box>\n <Text color=\"gray\" wrap=\"wrap\">\n {' '}\n {provider.description}\n </Text>\n </Box>\n );\n })}\n </Box>\n )}\n\n {/* Back option */}\n <Box marginTop={1}>\n <Text\n color={cursorIndex === backIndex ? 'cyan' : 'white'}\n bold={cursorIndex === backIndex}\n >\n {cursorIndex === backIndex ? '\\u276F' : ' '} Back\n </Text>\n </Box>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color=\"gray\">\n Up/Down Navigate {'\\u2022'} Enter Select {'\\u2022'} q/Esc Back\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n","import React, { useMemo } from 'react';\nimport { Text, useStdout } from 'ink';\nimport chalk from 'chalk';\nimport { marked } from 'marked';\nimport { markedTerminal } from 'marked-terminal';\n\nconst codeStyle = chalk.cyan;\nconst identity = (s: string) => s;\n\ninterface MarkdownTextProps {\n content: string;\n width?: number;\n}\n\n/**\n * Render markdown to an ANSI string.\n * Each line is self-contained (no cross-line ANSI escapes).\n */\nexport function renderMarkdown(content: string, width: number): string {\n marked.use(\n markedTerminal({\n width,\n codespan: codeStyle,\n link: identity,\n href: identity,\n }) as any,\n );\n marked.use({\n renderer: {\n code({ text }: { text: string }) {\n const lines = text\n .trim()\n .split('\\n')\n .map((l) => ' ' + codeStyle(l))\n .join('\\n');\n return lines + '\\n\\n';\n },\n link({ href, text }: { href: string; text: string }) {\n if (text && text !== href) {\n return `${text} (${href})`;\n }\n return href;\n },\n },\n });\n return (marked.parse(content) as string).trimEnd();\n}\n\nexport function MarkdownText({ content, width: widthProp }: MarkdownTextProps) {\n const { stdout } = useStdout();\n const width = widthProp ?? (stdout?.columns ?? 80) - 4;\n\n const rendered = useMemo(\n () => renderMarkdown(content, width),\n [content, width],\n );\n\n return <Text wrap=\"wrap\">{rendered}</Text>;\n}\n","import React, { useEffect, useCallback, useState, useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport Spinner from 'ink-spinner';\nimport chalk from 'chalk';\nimport { useAuth } from '../hooks/useAuth';\nimport { LogoString } from '../components/Header';\n\ninterface OnboardingPageProps {\n onComplete: () => void;\n}\n\nconst SHIMMER_SPEED = 35;\n\nfunction useShimmerLogo(): string {\n const [frame, setFrame] = useState(0);\n\n const lines = useMemo(() => LogoString.split('\\n'), []);\n const totalChars = useMemo(() => {\n let count = 0;\n for (const line of lines) {\n for (const ch of line) {\n if (ch !== ' ' && ch !== '\\t') count++;\n }\n }\n return count;\n }, [lines]);\n\n // Full cycle: fade in + hold + fade out + pause\n const cycleLength = totalChars + 40;\n\n useEffect(() => {\n const interval = setInterval(() => {\n setFrame((f) => (f + 1) % cycleLength);\n }, SHIMMER_SPEED);\n return () => clearInterval(interval);\n }, [cycleLength]);\n\n return useMemo(() => {\n // Map frame to a wave that fades the whole logo in and out\n // Phase 0..totalChars: characters light up one by one (sweep in)\n // Phase totalChars..totalChars+20: hold bright\n // Phase totalChars+20..cycleLength: all fade out together\n const sweepPos = frame;\n const holdEnd = totalChars + 20;\n\n let charIdx = 0;\n return lines\n .map((line) => {\n let result = '';\n for (let i = 0; i < line.length; i++) {\n const ch = line[i]!;\n if (ch === ' ' || ch === '\\t') {\n result += ch;\n continue;\n }\n\n let brightness: number;\n if (sweepPos <= totalChars) {\n // Sweep phase: characters light up as the wave passes\n const lag = charIdx;\n const t = sweepPos - lag;\n brightness = t <= 0 ? 0.1 : Math.min(1, t / 8);\n } else if (sweepPos <= holdEnd) {\n // Hold phase: everything bright\n brightness = 1;\n } else {\n // Fade out phase\n const fadeProgress = (sweepPos - holdEnd) / (cycleLength - holdEnd);\n brightness = Math.max(0.1, 1 - fadeProgress);\n }\n\n if (brightness >= 0.9) {\n result += chalk.cyanBright.bold(ch);\n } else if (brightness >= 0.6) {\n result += chalk.cyan(ch);\n } else if (brightness >= 0.3) {\n result += chalk.rgb(0, 100, 120)(ch);\n } else {\n result += chalk.rgb(0, 50, 60)(ch);\n }\n\n charIdx++;\n }\n return result;\n })\n .join('\\n');\n }, [frame, lines, totalChars, cycleLength]);\n}\n\nexport function OnboardingPage({ onComplete }: OnboardingPageProps) {\n const {\n status: authStatus,\n authUrl,\n timeRemaining,\n startAuth,\n cancel: cancelAuth,\n } = useAuth();\n const shimmerLogo = useShimmerLogo();\n\n // Auto-navigate to dashboard on success\n useEffect(() => {\n if (authStatus === 'success') {\n const timer = setTimeout(() => onComplete(), 1500);\n return () => clearTimeout(timer);\n }\n }, [authStatus, onComplete]);\n\n // Clean up auth on unmount\n useEffect(() => {\n return () => cancelAuth();\n }, []);\n\n const handleAction = useCallback(() => {\n cancelAuth();\n startAuth();\n }, [cancelAuth, startAuth]);\n\n const canAct =\n authStatus === 'idle' ||\n authStatus === 'expired' ||\n authStatus === 'timeout';\n\n useInput((_input, key) => {\n if (canAct && !key.ctrl) {\n handleAction();\n }\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexGrow={1} />\n\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>{shimmerLogo}</Text>\n\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={2}>\n <Text bold color=\"white\">\n MindStudio Local Tunnel\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" alignItems=\"center\">\n {authStatus === 'idle' && (\n <>\n <Text color=\"gray\">\n Connect your MindStudio account to get started.\n </Text>\n <Box marginTop={1}>\n <Text color=\"cyan\" bold>\n Press any key to Connect Account\n </Text>\n </Box>\n </>\n )}\n\n {(authStatus === 'expired' || authStatus === 'timeout') && (\n <>\n <Text color=\"red\">\n {authStatus === 'expired'\n ? 'Authorization expired.'\n : 'Authorization timed out.'}\n </Text>\n <Box marginTop={1}>\n <Text color=\"cyan\" bold>\n Press any key to Try Again\n </Text>\n </Box>\n </>\n )}\n\n {authStatus === 'waiting' && (\n <>\n <Box>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n <Text>\n {' '}\n Waiting for browser authorization... ({timeRemaining}s\n remaining)\n </Text>\n </Box>\n {authUrl && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n <Text color=\"gray\">If browser didn't open, visit:</Text>\n <Text color=\"cyan\">{authUrl}</Text>\n </Box>\n )}\n </>\n )}\n\n {authStatus === 'success' && (\n <Text color=\"green\">{'\\u2713'} Authenticated!</Text>\n )}\n </Box>\n </Box>\n\n <Box flexGrow={1} />\n </Box>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport open from 'open';\nimport { requestDeviceAuth, pollDeviceAuth } from '../../api';\nimport { setApiKey } from '../../config';\n\ntype AuthStatus = 'idle' | 'waiting' | 'success' | 'expired' | 'timeout';\n\ninterface UseAuthResult {\n status: AuthStatus;\n authUrl: string | null;\n timeRemaining: number;\n startAuth: () => void;\n cancel: () => void;\n}\n\nconst POLL_INTERVAL = 2000;\nconst MAX_ATTEMPTS = 30;\n\nexport function useAuth(): UseAuthResult {\n const [status, setStatus] = useState<AuthStatus>('idle');\n const [authUrl, setAuthUrl] = useState<string | null>(null);\n const [timeRemaining, setTimeRemaining] = useState(0);\n const cancelledRef = useRef(false);\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Clean up timer on unmount\n useEffect(() => {\n return () => {\n cancelledRef.current = true;\n if (timerRef.current) clearInterval(timerRef.current);\n };\n }, []);\n\n const cancel = useCallback(() => {\n cancelledRef.current = true;\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n setStatus('idle');\n setAuthUrl(null);\n setTimeRemaining(0);\n }, []);\n\n const startAuth = useCallback(() => {\n cancelledRef.current = false;\n\n const run = async () => {\n try {\n const { url, token } = await requestDeviceAuth();\n if (cancelledRef.current) return;\n\n setAuthUrl(url);\n setStatus('waiting');\n\n const totalTime = (MAX_ATTEMPTS * POLL_INTERVAL) / 1000;\n setTimeRemaining(totalTime);\n\n // Countdown timer\n timerRef.current = setInterval(() => {\n setTimeRemaining((prev) => {\n const next = prev - 1;\n if (next <= 0 && timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n return Math.max(0, next);\n });\n }, 1000);\n\n await open(url);\n\n // Poll loop\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\n if (cancelledRef.current) return;\n\n const result = await pollDeviceAuth(token);\n\n if (result.status === 'completed' && result.apiKey) {\n if (timerRef.current) clearInterval(timerRef.current);\n setApiKey(result.apiKey);\n setStatus('success');\n return;\n }\n\n if (result.status === 'expired') {\n if (timerRef.current) clearInterval(timerRef.current);\n setStatus('expired');\n return;\n }\n }\n\n if (!cancelledRef.current) {\n setStatus('timeout');\n }\n } catch {\n if (!cancelledRef.current) {\n setStatus('expired');\n }\n }\n };\n\n run();\n }, []);\n\n return {\n status,\n authUrl,\n timeRemaining,\n startAuth,\n cancel,\n };\n}\n","import { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nexport function getCurrentVersion(): string {\n return pkg.version;\n}\n\nexport async function fetchLatestVersion(): Promise<string | null> {\n try {\n const res = await fetch(\n 'https://registry.npmjs.org/@mindstudio-ai/local-model-tunnel/latest',\n { signal: AbortSignal.timeout(5000) },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\nexport function isNewerVersion(current: string, latest: string): boolean {\n const currentParts = current.split('.').map(Number);\n const latestParts = latest.split('.').map(Number);\n for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {\n const c = currentParts[i] ?? 0;\n const l = latestParts[i] ?? 0;\n if (l > c) return true;\n if (l < c) return false;\n }\n return false;\n}\n\nexport async function checkForUpdate(): Promise<{\n currentVersion: string;\n latestVersion: string;\n} | null> {\n const currentVersion = getCurrentVersion();\n const latestVersion = await fetchLatestVersion();\n if (!latestVersion) return null;\n if (!isNewerVersion(currentVersion, latestVersion)) return null;\n return { currentVersion, latestVersion };\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface UpdatePromptProps {\n currentVersion: string;\n latestVersion: string;\n onChoice: (shouldUpdate: boolean) => void;\n}\n\nexport function UpdatePrompt({\n currentVersion,\n latestVersion,\n onChoice,\n}: UpdatePromptProps) {\n useInput((input) => {\n if (input.toLowerCase() === 'y') {\n onChoice(true);\n } else {\n onChoice(false);\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2}>\n <Text>\n <Text color=\"yellow\" bold>\n Update available:\n </Text>\n <Text>\n {' '}\n v{currentVersion} {'\\u2192'} v{latestVersion}\n </Text>\n </Text>\n <Box marginTop={1}>\n <Text>\n Press <Text bold color=\"cyan\">y</Text> to update, any other key to\n skip\n </Text>\n </Box>\n </Box>\n );\n}\n"],"mappings":"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","names":["useEffect","useCallback","useState","Box","useStdout","require","Box","Text","jsx","jsxs","useState","useEffect","useState","useEffect","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useCallback","useState","useEffect","useCallback","useState","useEffect","useCallback","useState","useCallback","useEffect","Box","Text","useStdout","Spinner","Box","Text","jsx","jsxs","useState","useEffect","useCallback","useState","useCallback","useEffect","jsx","jsxs","useStdout","Box","Text","Spinner","useEffect","Box","Text","Spinner","useState","useCallback","useRef","useEffect","useState","useRef","useEffect","useCallback","jsx","jsxs","useEffect","Box","Text","Spinner","useState","useMemo","useEffect","Box","Text","useInput","useStdout","Spinner","useMemo","Text","useStdout","jsx","Fragment","jsx","jsxs","useState","useStdout","useMemo","useInput","Box","Text","useEffect","Spinner","useEffect","useCallback","useState","useMemo","Box","Text","useInput","Spinner","chalk","useState","useCallback","useRef","useEffect","useState","useRef","useEffect","useCallback","Fragment","jsx","jsxs","useState","useMemo","useEffect","chalk","useCallback","useInput","Box","Text","Spinner","Fragment","jsx","jsxs","useStdout","useState","useEffect","useCallback","Box","createRequire","require","pkg","Box","Text","useInput","jsx","jsxs","jsx"]}