()
| 30 | import { emptySnapshot } from './app/types'; |
| 31 | |
| 32 | export default function App() { |
| 33 | const onboardingKey = 'claw-code:onboarding-complete-v1'; |
| 34 | const [snapshot, setSnapshot] = useState<Snapshot>(emptySnapshot); |
| 35 | const [config, setConfig] = useState<ConfigState>(emptySnapshot.config); |
| 36 | const [prompt, setPrompt] = useState(''); |
| 37 | const [showSettings, setShowSettings] = useState(false); |
| 38 | const [showMemory, setShowMemory] = useState(false); |
| 39 | const [activeTab, setActiveTab] = useState<TabKey>('Chat'); |
| 40 | const [showLogs, setShowLogs] = useState(false); |
| 41 | const [showDiagnostics, setShowDiagnostics] = useState(false); |
| 42 | const [isSubmitting, setIsSubmitting] = useState(false); |
| 43 | const [isTestingConnection, setIsTestingConnection] = useState(false); |
| 44 | const [isLoadingDiagnostics, setIsLoadingDiagnostics] = useState(false); |
| 45 | const [connectionReport, setConnectionReport] = useState<ConnectionReport | null>(null); |
| 46 | const [diagnosticsReport, setDiagnosticsReport] = useState<DiagnosticsReport | null>(null); |
| 47 | const [errorMessage, setErrorMessage] = useState<string | null>(null); |
| 48 | const [hostMessage, setHostMessage] = useState<string | null>(null); |
| 49 | const [encryptionAvailable, setEncryptionAvailable] = useState<boolean | null>(null); |
| 50 | const [appInfo, setAppInfo] = useState<AppInfo | null>(null); |
| 51 | const [showWizard, setShowWizard] = useState(false); |
| 52 | const [showAbout, setShowAbout] = useState(false); |
| 53 | const [initialHydrated, setInitialHydrated] = useState(false); |
| 54 | const [pendingUserMessages, setPendingUserMessages] = useState<FeedEntry[]>([]); |
| 55 | const [deleteConfirm, setDeleteConfirm] = useState<{ sessionId: string; name: string } | null>(null); |
| 56 | const [skills, setSkills] = useState<Array<{ name: string; description: string }>>([]); |
| 57 | |
| 58 | useEffect(() => { |
| 59 | let cancelled = false; |
| 60 | |
| 61 | async function loadInitialState() { |
| 62 | try { |
| 63 | const next = await api<Snapshot>('/api/state'); |
| 64 | let nextConfig = mergeConfig(next.config); |
| 65 | |
| 66 | if (window.clawDesktop?.getBootstrap) { |
| 67 | try { |
| 68 | const desktop = await window.clawDesktop.getBootstrap() as DesktopBootstrap; |
| 69 | setEncryptionAvailable(Boolean(desktop.encryptionAvailable)); |
| 70 | setAppInfo(desktop.appInfo || null); |
| 71 | if (desktop.upstreamApiKey) { |
| 72 | nextConfig = { |
| 73 | ...nextConfig, |
| 74 | upstreamApiKey: desktop.upstreamApiKey, |
| 75 | }; |
| 76 | await api('/api/config', { |
| 77 | method: 'POST', |
| 78 | body: nextConfig, |
| 79 | }); |
| 80 | } |
| 81 | } catch (error) { |
| 82 | console.warn('Failed to hydrate desktop bootstrap', error); |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | if (!cancelled) { |
| 87 | setSnapshot(next); |
| 88 | setConfig(nextConfig); |
| 89 | setInitialHydrated(true); |
nothing calls this directly
no test coverage detected