diff --git a/ui/desktop/package-lock.json b/ui/desktop/package-lock.json index b702e46c..8d3e524d 100644 --- a/ui/desktop/package-lock.json +++ b/ui/desktop/package-lock.json @@ -86,6 +86,9 @@ "prettier": "^3.4.2", "tailwindcss": "^3.4.14", "vite": "^5.4.17" + }, + "engines": { + "node": "^23.0.0" } }, "node_modules/@ai-sdk/openai": { diff --git a/ui/desktop/src/components/settings_v2/SettingsView.tsx b/ui/desktop/src/components/settings_v2/SettingsView.tsx index 3d797ec1..37496658 100644 --- a/ui/desktop/src/components/settings_v2/SettingsView.tsx +++ b/ui/desktop/src/components/settings_v2/SettingsView.tsx @@ -6,18 +6,21 @@ import ExtensionsSection from './extensions/ExtensionsSection'; import ModelsSection from './models/ModelsSection'; import { ModeSection } from './mode/ModeSection'; import SessionSharingSection from './sessions/SessionSharingSection'; +import { ExtensionConfig } from '../../api'; export type SettingsViewOptions = { - extensionId?: string; + deepLinkConfig?: ExtensionConfig; showEnvVars?: boolean; }; export default function SettingsView({ onClose, setView, + viewOptions, }: { onClose: () => void; setView: (view: View) => void; + viewOptions: SettingsViewOptions; }) { return (
@@ -36,7 +39,10 @@ export default function SettingsView({ {/* Models Section */} {/* Extensions Section */} - + {/* Goose Modes */} {/*Session sharing*/} diff --git a/ui/desktop/src/components/settings_v2/extensions/ExtensionsSection.tsx b/ui/desktop/src/components/settings_v2/extensions/ExtensionsSection.tsx index b0e794c5..be651c97 100644 --- a/ui/desktop/src/components/settings_v2/extensions/ExtensionsSection.tsx +++ b/ui/desktop/src/components/settings_v2/extensions/ExtensionsSection.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useCallback } from 'react'; +import { useEffect, useState, useCallback } from 'react'; import { Button } from '../../ui/button'; import { Plus } from 'lucide-react'; import { GPSIcon } from '../../ui/icons'; @@ -14,14 +14,25 @@ import { } from './utils'; import { activateExtension, deleteExtension, toggleExtension, updateExtension } from './index'; +import { ExtensionConfig } from '../../../api/types.gen'; -export default function ExtensionsSection() { +interface ExtensionSectionProps { + deepLinkConfig?: ExtensionConfig; + showEnvVars?: boolean; +} + +export default function ExtensionsSection({ deepLinkConfig, showEnvVars }: ExtensionSectionProps) { const { getExtensions, addExtension, removeExtension } = useConfig(); const [extensions, setExtensions] = useState([]); const [selectedExtension, setSelectedExtension] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isAddModalOpen, setIsAddModalOpen] = useState(false); - // We don't need errorFormData anymore since we're not reopening modals on failure + const [deepLinkConfigStateVar, setDeepLinkConfigStateVar] = useState< + ExtensionConfig | undefined | null + >(deepLinkConfig); + const [showEnvVarsStateVar, setShowEnvVarsStateVar] = useState( + showEnvVars + ); const fetchExtensions = useCallback(async () => { const extensionsList = await getExtensions(true); // Force refresh @@ -115,6 +126,9 @@ export default function ExtensionsSection() { }; const handleModalClose = () => { + setDeepLinkConfigStateVar(null); + setShowEnvVarsStateVar(null); + setIsModalOpen(false); setIsAddModalOpen(false); setSelectedExtension(null); @@ -178,6 +192,18 @@ export default function ExtensionsSection() { modalType={'add'} /> )} + + {/* Modal for adding extension from deeplink*/} + {deepLinkConfigStateVar && showEnvVarsStateVar && ( + + )}
); diff --git a/ui/desktop/src/components/settings_v2/extensions/deeplink.ts b/ui/desktop/src/components/settings_v2/extensions/deeplink.ts index 13edd5ab..fd1bf78e 100644 --- a/ui/desktop/src/components/settings_v2/extensions/deeplink.ts +++ b/ui/desktop/src/components/settings_v2/extensions/deeplink.ts @@ -2,6 +2,7 @@ import type { ExtensionConfig } from '../../../api/types.gen'; import { toastService } from '../../../toasts'; import { activateExtension } from './extension-manager'; import { DEFAULT_EXTENSION_TIMEOUT, nameToKey } from './utils'; +import { settingsV2Enabled } from '../../../flags'; /** * Build an extension config for stdio from the deeplink URL @@ -82,7 +83,12 @@ export async function addExtensionFromDeepLink( extensionConfig: ExtensionConfig, enabled: boolean ) => Promise, - setView: (view: string, options: { extensionId: string; showEnvVars: boolean }) => void + setView: ( + view: string, + options: + | { extensionId: string; showEnvVars: boolean } + | { deepLinkConfig: ExtensionConfig; showEnvVars: boolean } + ) => void ) { const parsedUrl = new URL(url); @@ -123,7 +129,11 @@ export async function addExtensionFromDeepLink( // Check if extension requires env vars and go to settings if so if (config.envs && Object.keys(config.envs).length > 0) { console.log('Environment variables required, redirecting to settings'); - setView('settings', { extensionId: nameToKey(name), showEnvVars: true }); + if (settingsV2Enabled) { + setView('settings', { deepLinkConfig: config, showEnvVars: true }); + } else { + setView('settings', { extensionId: nameToKey(name), showEnvVars: true }); + } return; }