diff --git a/package.json b/package.json index 1ef85ac84..934ba1058 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alphahuman", "private": true, - "version": "0.44.0", + "version": "0.47.0", "type": "module", "scripts": { "dev": "vite", @@ -39,6 +39,7 @@ "prepare": "husky" }, "dependencies": { + "@heroicons/react": "^2.2.0", "@reduxjs/toolkit": "^2.11.2", "@sentry/react": "^10.38.0", "@tauri-apps/api": "^2", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 40868c3c1..2423e82bb 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "AlphaHuman", - "version": "0.44.0", + "version": "0.46.0", "identifier": "com.alphahuman.app", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/components/settings/panels/TauriCommandsPanel.tsx b/src/components/settings/panels/TauriCommandsPanel.tsx index 8c7752f25..e57b11691 100644 --- a/src/components/settings/panels/TauriCommandsPanel.tsx +++ b/src/components/settings/panels/TauriCommandsPanel.tsx @@ -1,7 +1,19 @@ import { useMemo, useState } from 'react'; +import { + CogIcon, + CpuChipIcon, + ShieldCheckIcon, + ServerIcon, + WrenchScrewdriverIcon, + ChatBubbleLeftRightIcon, + DocumentTextIcon, +} from '@heroicons/react/24/outline'; import SettingsHeader from '../components/SettingsHeader'; import { useSettingsNavigation } from '../hooks/useSettingsNavigation'; +import SectionCard from './components/SectionCard'; +import InputGroup, { Field, CheckboxField } from './components/InputGroup'; +import ActionPanel, { PrimaryButton } from './components/ActionPanel'; import { alphahumanAgentChat, alphahumanDecryptSecret, @@ -38,8 +50,17 @@ const formatJson = (value: unknown) => JSON.stringify(value, null, 2); const TauriCommandsPanel = () => { const { navigateBack } = useSettingsNavigation(); + + // View mode removed - always show all sections + const [expandedSections] = useState>( + new Set(['system-configuration', 'runtime-execution', 'security-data', 'network-infrastructure', 'development-operations', 'interactive-tools']) + ); + + // Output and error states const [output, setOutput] = useState(''); const [error, setError] = useState(''); + + // Form states (preserved from original) const [providerOverride, setProviderOverride] = useState(''); const [integrationName, setIntegrationName] = useState(''); const [hardwarePath, setHardwarePath] = useState(''); @@ -76,6 +97,10 @@ const TauriCommandsPanel = () => { const [chatModel, setChatModel] = useState(''); const [chatTemperature, setChatTemperature] = useState('0.7'); const [chatLog, setChatLog] = useState>([]); + + // Loading states + const [operationLoading, setOperationLoading] = useState(''); + const tauriAvailable = useMemo(() => isTauri(), []); const parseOptionalNumber = (value: string): number | null => { if (!value.trim()) { @@ -85,19 +110,23 @@ const TauriCommandsPanel = () => { return Number.isFinite(parsed) ? parsed : null; }; - const run = async (fn: () => Promise) => { + const run = async (fn: () => Promise, operationName?: string) => { setError(''); + if (operationName) setOperationLoading(operationName); try { const result = await fn(); setOutput(formatJson(result)); } catch (err) { const message = err instanceof Error ? err.message : String(err); setError(message); + } finally { + setOperationLoading(''); } }; - const runWithResult = async (fn: () => Promise): Promise => { + const runWithResult = async (fn: () => Promise, operationName?: string): Promise => { setError(''); + if (operationName) setOperationLoading(operationName); try { const result = await fn(); setOutput(formatJson(result)); @@ -106,11 +135,13 @@ const TauriCommandsPanel = () => { const message = err instanceof Error ? err.message : String(err); setError(message); return null; + } finally { + setOperationLoading(''); } }; const loadConfig = async () => { - const response = await runWithResult(() => alphahumanGetConfig()); + const response = await runWithResult(() => alphahumanGetConfig(), 'loadConfig'); if (!response) { return; } @@ -188,10 +219,11 @@ const TauriCommandsPanel = () => { default_provider: defaultProvider.trim() ? defaultProvider : null, default_model: defaultModel.trim() ? defaultModel : null, default_temperature: parseOptionalNumber(defaultTemp), - }) + }), + 'saveModelSettings' ); - const saveTunnelSettings = () => run(() => alphahumanUpdateTunnelSettings(buildTunnelConfig())); + const saveTunnelSettings = () => run(() => alphahumanUpdateTunnelSettings(buildTunnelConfig()), 'saveTunnelSettings'); const saveGatewaySettings = () => run(() => @@ -200,7 +232,8 @@ const TauriCommandsPanel = () => { port: parseOptionalNumber(gatewayPort), require_pairing: gatewayPairing, allow_public_bind: gatewayPublic, - }) + }), + 'saveGatewaySettings' ); const saveMemorySettings = () => @@ -211,7 +244,8 @@ const TauriCommandsPanel = () => { embedding_provider: embeddingProvider.trim() ? embeddingProvider : null, embedding_model: embeddingModel.trim() ? embeddingModel : null, embedding_dimensions: parseOptionalNumber(embeddingDims), - }) + }), + 'saveMemorySettings' ); const saveRuntimeSettings = () => @@ -219,7 +253,8 @@ const TauriCommandsPanel = () => { alphahumanUpdateRuntimeSettings({ kind: runtimeKind.trim() ? runtimeKind : null, reasoning_enabled: reasoningEnabled, - }) + }), + 'saveRuntimeSettings' ); const loadSkills = async () => { @@ -244,9 +279,9 @@ const TauriCommandsPanel = () => { const toggleSkill = async (skillId: string, nextEnabled: boolean) => { if (nextEnabled) { - await run(() => runtimeEnableSkill(skillId)); + await run(() => runtimeEnableSkill(skillId), 'enableSkill'); } else { - await run(() => runtimeDisableSkill(skillId)); + await run(() => runtimeDisableSkill(skillId), 'disableSkill'); } setSkills((prev) => prev.map((item) => @@ -270,13 +305,34 @@ const TauriCommandsPanel = () => { chatProvider.trim() ? chatProvider : undefined, chatModel.trim() ? chatModel : undefined, parseOptionalNumber(chatTemperature) ?? undefined - ) + ), + 'sendChat' ); if (response) { setChatLog((prev) => [...prev, { role: 'agent', text: response.result }]); } }; + // Always show all sections + const isSectionVisible = () => { + return true; // Always show all sections + }; + + const isCollapsed = (sectionId: string) => { + return !expandedSections.has(sectionId); + }; + + // Helper to check if a section is collapsed (currently unused but kept for future expansion) + // const toggleSection = (sectionId: string) => { + // const newExpanded = new Set(expandedSections); + // if (newExpanded.has(sectionId)) { + // newExpanded.delete(sectionId); + // } else { + // newExpanded.add(sectionId); + // } + // setExpandedSections(newExpanded); + // }; + return (
{ onBack={navigateBack} /> -
+
{!tauriAvailable && (
Tauri runtime not detected. Commands will fail in browser mode.
)} -
-

Config

-
- + {operationLoading && ( +
+
+
+ {operationLoading} +
-
+ )} -
-

Model API Keys

-
- - - - - -
- -
- -
-

Diagnostics

-
- - - setProviderOverride(event.target.value)} - /> -
-
+ + setApiKey(event.target.value)} + /> + + + setApiUrl(event.target.value)} + /> + + + setDefaultProvider(event.target.value)} + /> + + + setDefaultModel(event.target.value)} + /> + + + setDefaultTemp(event.target.value)} + /> + + -
-

Integrations

-
- - - setIntegrationName(event.target.value)} - /> -
-
+ + setRuntimeKind(event.target.value)} + /> + + + -
-

Models

-
-
+ + {/* Category 3: Security & Data - Full width in basic mode, grid in advanced+ */} + {isSectionVisible() && ( + } + collapsible={true} + defaultExpanded={!isCollapsed('security-data')} + hasChanges={false} + loading={operationLoading?.includes('Secret') || operationLoading?.includes('Models') || operationLoading?.includes('Integration')} + > +
+ + +