diff --git a/ui/desktop/announcements/content.ts b/ui/desktop/announcements/content.ts index 4b20e4865d..d7323d147f 100644 --- a/ui/desktop/announcements/content.ts +++ b/ui/desktop/announcements/content.ts @@ -1,5 +1,5 @@ // Map of announcement file names to their content -export const announcementContents: Record = {}; +const announcementContents: Record = {}; // Helper function to get announcement content by filename export function getAnnouncementContent(filename: string): string | null { diff --git a/ui/desktop/package.json b/ui/desktop/package.json index a0bb7693ee..880a13b427 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -53,31 +53,24 @@ "@agentclientprotocol/sdk": "^0.19.0", "@mcp-ui/client": "6.1.0", "@modelcontextprotocol/ext-apps": "^1.1.1", - "@radix-ui/react-accordion": "^1.2.12", - "@radix-ui/react-avatar": "^1.1.11", + "@radix-ui/react-collapsible": "^1.1.14", "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-icons": "^1.3.2", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-radio-group": "^1.3.8", + "@radix-ui/react-dropdown-menu": "^2.1.18", "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-switch": "^1.3.1", "@radix-ui/react-tabs": "^1.1.13", - "@radix-ui/themes": "^3.3.0", + "@radix-ui/react-tooltip": "^1.2.10", "@tanstack/react-form": "1.28.3", - "@types/react-router-dom": "^5.3.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "compare-versions": "^6.1.1", - "cors": "^2.8.6", "cronstrue": "^3.12.0", - "date-fns": "^4.1.0", "dotenv": "^17.3.1", "electron-log": "^5.4.3", "electron-squirrel-startup": "^1.0.1", "electron-updater": "^6.8.3", "electron-window-state": "^5.0.3", - "express": "^5.2.1", "framer-motion": "^12.34.3", "katex": "^0.16.33", "lodash": "^4.17.23", @@ -96,13 +89,9 @@ "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", "shell-quote": "^1.8.3", - "split-type": "^0.3.4", - "swr": "^2.4.0", "tailwind-merge": "^3.5.0", - "tailwindcss-animate": "^1.0.7", "turndown": "^7.2.4", "tw-animate-css": "^1.4.0", - "unist-util-visit": "^5.1.0", "uuid": "^13.0.0", "zod": "^3.25.76", "zod-to-json-schema": "3.25.1" @@ -123,15 +112,12 @@ "@formatjs/icu-messageformat-parser": "3.5.3", "@modelcontextprotocol/sdk": "^1.27.0", "@playwright/test": "^1.58.2", - "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.2.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", - "@types/cors": "^2.8.19", "@types/electron-squirrel-startup": "^1.0.2", - "@types/express": "^5.0.6", "@types/lodash": "^4.17.24", "@types/node": "^25.5.0", "@types/react": "^19.2.14", @@ -139,13 +125,11 @@ "@types/react-syntax-highlighter": "^15.5.13", "@types/shell-quote": "^1.7.5", "@types/turndown": "^5.0.6", - "@types/yauzl": "^2.10.3", "@typescript-eslint/eslint-plugin": "^8.56.1", "@typescript-eslint/parser": "^8.56.1", "@vitejs/plugin-react": "^5.1.4", "@vitest/coverage-v8": "^4.0.18", "@vitest/ui": "^4.0.18", - "autoprefixer": "^10.4.24", "electron": "41.0.0", "electron-devtools-installer": "^4.0.0", "eslint": "^9.39.2", @@ -153,7 +137,6 @@ "eslint-plugin-react-hooks": "^5.2.0", "jsdom": "^28.1.0", "knip": "^5.85.0", - "postcss": "^8.5.6", "prettier": "^3.8.1", "tailwindcss": "^4.2.1", "typescript": "~5.9.3", diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx index 509f43c1e2..37854fd2bd 100644 --- a/ui/desktop/src/App.tsx +++ b/ui/desktop/src/App.tsx @@ -88,9 +88,6 @@ const PairRouteWrapper = ({ initialMessage?: UserInput; noAutoSubmit?: boolean; }>; - setActiveSessions: ( - sessions: Array<{ sessionId: string; initialMessage?: UserInput; noAutoSubmit?: boolean }> - ) => void; }) => { const { extensionsList } = useConfig(); const location = useLocation(); @@ -637,15 +634,7 @@ export function AppInner() { } > } /> - - } - /> + } /> } /> { resolvePromptCancellation!(); await updatePromise; - expect(acpTruncateSessionConversation).toHaveBeenCalledWith(SESSION_ID, existingMessage.created); + expect(acpTruncateSessionConversation).toHaveBeenCalledWith( + SESSION_ID, + existingMessage.created + ); expect(acpPromptSession).toHaveBeenCalled(); expect(acpChatSessionActions.clearPromptCancellation).not.toHaveBeenCalledWith( SESSION_ID, diff --git a/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts b/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts index c9037f678c..cb0a5415b5 100644 --- a/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts +++ b/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts @@ -583,9 +583,7 @@ describe('createAcpSessionNotificationAdapter', () => { status: { type: 'progress', message: 'Still working' }, }) ); - expect(progressStateChanges).toEqual([ - { type: 'progressMessage', message: 'Still working' }, - ]); + expect(progressStateChanges).toEqual([{ type: 'progressMessage', message: 'Still working' }]); }); }); diff --git a/ui/desktop/src/acp/acpConnection.ts b/ui/desktop/src/acp/acpConnection.ts index fd40944ea4..cb2ea4ae68 100644 --- a/ui/desktop/src/acp/acpConnection.ts +++ b/ui/desktop/src/acp/acpConnection.ts @@ -105,18 +105,10 @@ export async function getAcpClient(): Promise { return (await getInitializedAcpClient()).client; } -export function getAcpClientSync(): GooseClient | null { - return resolvedClient?.client ?? null; -} - export async function getAcpInitializeResponse(): Promise { return (await getInitializedAcpClient()).initializeResponse; } -export function isAcpClientReady(): boolean { - return resolvedClient !== null; -} - async function getInitializedAcpClient(): Promise { if (resolvedClient) { return resolvedClient; diff --git a/ui/desktop/src/acp/autocomplete.ts b/ui/desktop/src/acp/autocomplete.ts index d60817fcde..7b2a0ede29 100644 --- a/ui/desktop/src/acp/autocomplete.ts +++ b/ui/desktop/src/acp/autocomplete.ts @@ -11,10 +11,7 @@ function isSlashCommandItemType(value: unknown): value is SlashCommandItemType { return typeof value === 'string' && SLASH_COMMAND_ITEM_TYPES.has(value); } -function stringMetaValue( - meta: AvailableCommand['_meta'], - key: string -): string | undefined { +function stringMetaValue(meta: AvailableCommand['_meta'], key: string): string | undefined { const value = meta?.[key]; return typeof value === 'string' && value.trim() ? value : undefined; } @@ -33,7 +30,8 @@ export function availableCommandToDisplayItem( } const sourcePath = stringMetaValue(command._meta, 'sourcePath'); - const extra = commandType === 'Recipe' ? sourcePath ?? command.description : command.description; + const extra = + commandType === 'Recipe' ? (sourcePath ?? command.description) : command.description; return { name: command.name, diff --git a/ui/desktop/src/acp/capabilities.ts b/ui/desktop/src/acp/capabilities.ts index bc5c6b9ed8..096da132ac 100644 --- a/ui/desktop/src/acp/capabilities.ts +++ b/ui/desktop/src/acp/capabilities.ts @@ -1,7 +1,7 @@ import type { InitializeResponse } from '@agentclientprotocol/sdk'; import { getAcpInitializeResponse } from './acpConnection'; -export interface AcpFeatureCapabilities { +interface AcpFeatureCapabilities { localInference: boolean; } diff --git a/ui/desktop/src/acp/chatNotifications.ts b/ui/desktop/src/acp/chatNotifications.ts index 6e870eed2b..336b5989eb 100644 --- a/ui/desktop/src/acp/chatNotifications.ts +++ b/ui/desktop/src/acp/chatNotifications.ts @@ -6,9 +6,8 @@ import { toolNotificationEvent } from './adapter/toolNotifications'; import { acpChatSessionActions, acpChatSessionStore } from './chatSessionStore'; export function handleAcpSessionNotification(notification: SessionNotification): Promise { - const sessionNameBeforeNotification = acpChatSessionStore.getSnapshot( - notification.sessionId - )?.session?.name; + const sessionNameBeforeNotification = acpChatSessionStore.getSnapshot(notification.sessionId) + ?.session?.name; const updatedName = notification.update.sessionUpdate === 'session_info_update' ? notification.update.title diff --git a/ui/desktop/src/acp/chatSessionController.ts b/ui/desktop/src/acp/chatSessionController.ts index 849d6a9bbf..b5cc26c6a3 100644 --- a/ui/desktop/src/acp/chatSessionController.ts +++ b/ui/desktop/src/acp/chatSessionController.ts @@ -5,11 +5,7 @@ import { ChatState } from '../types/chatState'; import type { Session } from '../types/session'; import { errorMessage } from '../utils/conversionUtils'; import { showExtensionLoadResults } from '../utils/extensionErrorUtils'; -import { - createUserMessage, - getPendingToolConfirmationIds, - type Message, -} from '../types/message'; +import { createUserMessage, getPendingToolConfirmationIds, type Message } from '../types/message'; import { acpChatSessionActions, acpChatSessionStore, @@ -29,19 +25,19 @@ import { type AcpRecipeOptions, } from './sessions'; -export interface AcpLoadSessionOptions { +interface AcpLoadSessionOptions { onSessionLoaded?: () => void; } -export interface AcpSnapshotOptions { +interface AcpSnapshotOptions { getCurrentSnapshot(): AcpChatSessionSnapshot | undefined; } -export interface AcpSubmitMessageOptions extends AcpSnapshotOptions { +interface AcpSubmitMessageOptions extends AcpSnapshotOptions { onFinish(error?: string): void | Promise; } -export interface AcpChatSessionController { +interface AcpChatSessionController { createSession( cwd: string, gooseExtensions: GooseExtension[], diff --git a/ui/desktop/src/acp/chatSessionStore.ts b/ui/desktop/src/acp/chatSessionStore.ts index b773f260b7..c4b608b8f1 100644 --- a/ui/desktop/src/acp/chatSessionStore.ts +++ b/ui/desktop/src/acp/chatSessionStore.ts @@ -49,11 +49,11 @@ const initialTokenState: TokenState = { accumulatedTotalTokens: 0, }; -export interface AcpChatSessionStore { +interface AcpChatSessionStore { getSnapshot(sessionId: string): AcpChatSessionSnapshot | undefined; } -export interface AcpChatSessionActions { +interface AcpChatSessionActions { deleteSnapshot(sessionId: string): void; applyAcpSessionNotification(notification: SessionNotification): AcpChatSessionSnapshot; diff --git a/ui/desktop/src/acp/config.ts b/ui/desktop/src/acp/config.ts index 7ca81030bb..8772810a5a 100644 --- a/ui/desktop/src/acp/config.ts +++ b/ui/desktop/src/acp/config.ts @@ -1,6 +1,6 @@ import { getAcpClient } from './acpConnection'; -export type ConfigReadValue = unknown; +type ConfigReadValue = unknown; export async function acpReadConfig( key: string, diff --git a/ui/desktop/src/acp/createWebSocketStream.ts b/ui/desktop/src/acp/createWebSocketStream.ts index 73d7448161..d07ad75260 100644 --- a/ui/desktop/src/acp/createWebSocketStream.ts +++ b/ui/desktop/src/acp/createWebSocketStream.ts @@ -1,6 +1,6 @@ import type { Stream } from '@aaif/goose-sdk'; -export type ClosableAcpStream = Stream & { +type ClosableAcpStream = Stream & { close: () => void; }; diff --git a/ui/desktop/src/acp/dictation.ts b/ui/desktop/src/acp/dictation.ts index aebe23d754..70418ec2dd 100644 --- a/ui/desktop/src/acp/dictation.ts +++ b/ui/desktop/src/acp/dictation.ts @@ -7,7 +7,7 @@ import { getAcpClient } from './acpConnection'; export type { DictationProviderStatusEntry }; -export type DictationProviders = Record; +type DictationProviders = Record; export type LocalDictationModel = DictationLocalModelStatus; export type LocalDictationDownloadProgress = DictationDownloadProgress; diff --git a/ui/desktop/src/acp/extensions.ts b/ui/desktop/src/acp/extensions.ts index 72e1efd2b8..b169010a09 100644 --- a/ui/desktop/src/acp/extensions.ts +++ b/ui/desktop/src/acp/extensions.ts @@ -2,9 +2,9 @@ import type { ExtensionConfig, ExtensionEntry } from '../types/extensions'; import type { GooseExtension, GooseExtensionEntry } from '@aaif/goose-sdk'; import { getAcpClient } from './acpConnection'; -export type ConfiguredExtensionEntry = ExtensionEntry & { configKey?: string }; +type ConfiguredExtensionEntry = ExtensionEntry & { configKey?: string }; -export interface ConfiguredExtensionsResponse { +interface ConfiguredExtensionsResponse { extensions: ConfiguredExtensionEntry[]; warnings: string[]; } diff --git a/ui/desktop/src/acp/mcp-apps.ts b/ui/desktop/src/acp/mcp-apps.ts index 66021215b1..a399513912 100644 --- a/ui/desktop/src/acp/mcp-apps.ts +++ b/ui/desktop/src/acp/mcp-apps.ts @@ -5,7 +5,7 @@ import { getAcpClient } from './acpConnection'; type JsonRecord = Record; export type McpAppTool = ToolListItem; -export type McpAppResourceResponse = { +type McpAppResourceResponse = { uri: string; mimeType: string | null; text: string; diff --git a/ui/desktop/src/acp/permissions.ts b/ui/desktop/src/acp/permissions.ts index c88dc9119d..fffe4c447d 100644 --- a/ui/desktop/src/acp/permissions.ts +++ b/ui/desktop/src/acp/permissions.ts @@ -1,9 +1,12 @@ import type { ToolListItem, ToolPermissionEntry, ToolPermissionLevel } from '@aaif/goose-sdk'; import { getAcpClient } from './acpConnection'; -export type { ToolListItem, ToolPermissionEntry, ToolPermissionLevel }; +export type { ToolListItem, ToolPermissionLevel }; -export async function listTools(sessionId: string, extensionName?: string): Promise { +export async function listTools( + sessionId: string, + extensionName?: string +): Promise { const client = await getAcpClient(); const response = await client.goose.toolsList_unstable({ sessionId, diff --git a/ui/desktop/src/acp/prompts.ts b/ui/desktop/src/acp/prompts.ts index 8a3a7329f0..1c8324cec1 100644 --- a/ui/desktop/src/acp/prompts.ts +++ b/ui/desktop/src/acp/prompts.ts @@ -1,7 +1,4 @@ -import type { - GetPromptResponse_unstable, - PromptTemplateEntry, -} from '@aaif/goose-sdk'; +import type { GetPromptResponse_unstable, PromptTemplateEntry } from '@aaif/goose-sdk'; import { getAcpClient } from './acpConnection'; export type PromptTemplate = PromptTemplateEntry; diff --git a/ui/desktop/src/acp/providers.ts b/ui/desktop/src/acp/providers.ts index e9e967f405..a17e6bd0a5 100644 --- a/ui/desktop/src/acp/providers.ts +++ b/ui/desktop/src/acp/providers.ts @@ -6,7 +6,11 @@ import type { ProviderTemplateCatalogEntryDto, ProviderTemplateDto, } from '@aaif/goose-sdk'; -import type { ProviderDetails, ThinkingEffort, UpdateCustomProviderRequest } from '../types/providers'; +import type { + ProviderDetails, + ThinkingEffort, + UpdateCustomProviderRequest, +} from '../types/providers'; import { getAcpClient } from './acpConnection'; export type { CanonicalModelInfoDto, ProviderSecretDto }; diff --git a/ui/desktop/src/acp/recipeParamRequests.ts b/ui/desktop/src/acp/recipeParamRequests.ts index 1fcbcbafa9..5c317bd977 100644 --- a/ui/desktop/src/acp/recipeParamRequests.ts +++ b/ui/desktop/src/acp/recipeParamRequests.ts @@ -5,7 +5,7 @@ import type { } from '@aaif/goose-sdk'; import { v7 as uuidv7 } from 'uuid'; -export interface AcpRecipeParamRequest { +interface AcpRecipeParamRequest { id: string; sessionId: string; parameters: RecipeParameterDto[]; diff --git a/ui/desktop/src/acp/sessions.ts b/ui/desktop/src/acp/sessions.ts index dc1c18321e..0a968e680f 100644 --- a/ui/desktop/src/acp/sessions.ts +++ b/ui/desktop/src/acp/sessions.ts @@ -42,19 +42,19 @@ export interface SessionListItem { hasRecipe?: boolean; } -export interface SessionListPage { +interface SessionListPage { sessions: SessionListItem[]; nextCursor: string | null; } -export interface LoadSessionMeta { +interface LoadSessionMeta { recipe?: Recipe | null; userRecipeValues?: Record | null; extensionResults?: ExtensionLoadResult[] | null; workingDir?: string; } -export interface AcpLoadSessionResult { +interface AcpLoadSessionResult { sessionInfo: SessionInfo; response: LoadSessionResponse; meta: LoadSessionMeta; @@ -72,7 +72,7 @@ function parseSessionResponseMeta(rawMeta: unknown): LoadSessionMeta { }; } -export function parseLoadMeta(response: LoadSessionResponse): LoadSessionMeta { +function parseLoadMeta(response: LoadSessionResponse): LoadSessionMeta { return parseSessionResponseMeta(response._meta); } @@ -131,7 +131,7 @@ function sessionInfoToListItem(s: SessionInfo): SessionListItem { }; } -export interface SessionListFilter { +interface SessionListFilter { keyword?: string; } @@ -215,7 +215,7 @@ async function loadAcpSession(sessionId: string): Promise }; } -export interface AcpNewSessionResult { +interface AcpNewSessionResult { sessionId: string; sessionInfo: SessionInfo; meta: LoadSessionMeta; @@ -302,10 +302,7 @@ export async function acpExportSession(sessionId: string): Promise { return response.data; } -export async function acpImportSession( - input: string, - source: SessionImportSource -): Promise { +export async function acpImportSession(input: string, source: SessionImportSource): Promise { const client = await getAcpClient(); await client.goose.sessionImport_unstable({ input, source }); } diff --git a/ui/desktop/src/backendStatus.ts b/ui/desktop/src/backendStatus.ts index 3b6dd16c2d..3b4bc1a484 100644 --- a/ui/desktop/src/backendStatus.ts +++ b/ui/desktop/src/backendStatus.ts @@ -7,11 +7,11 @@ const PROBE_TIMEOUT_MS = 1000; type FetchInput = Parameters[0]; type FetchInit = Parameters[1]; -export interface CheckServerStatusOptions { +interface CheckServerStatusOptions { onEvent?: (name: string, details?: Record) => void; } -export interface CheckBackendStatusParams { +interface CheckBackendStatusParams { baseUrl: string; serverSecret: string; fetch: typeof globalThis.fetch; @@ -19,7 +19,7 @@ export interface CheckBackendStatusParams { options?: CheckServerStatusOptions; } -export const isFatalError = (line: string): boolean => { +const isFatalError = (line: string): boolean => { const fatalPatterns = [/panicked at/, /RUST_BACKTRACE/, /fatal error/i]; return fatalPatterns.some((pattern) => pattern.test(line)); }; diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx index d501f820c4..2ca31f6102 100644 --- a/ui/desktop/src/components/BaseChat.tsx +++ b/ui/desktop/src/components/BaseChat.tsx @@ -43,13 +43,6 @@ const i18n = defineMessages({ interface BaseChatProps { setChat: (chat: ChatType) => void; - onMessageSubmit?: (message: string) => void; - renderHeader?: () => React.ReactNode; - customChatInputProps?: Record; - customMainLayoutProps?: Record; - contentClassName?: string; - disableSearch?: boolean; - suppressEmptyState: boolean; sessionId: string; isActiveSession: boolean; initialMessage?: UserInput; @@ -58,9 +51,6 @@ interface BaseChatProps { export default function BaseChat({ setChat, - renderHeader, - customChatInputProps = {}, - customMainLayoutProps = {}, sessionId, initialMessage, noAutoSubmit, @@ -96,7 +86,6 @@ export default function BaseChat({ sessionLoadError, tokenState, notifications: toolCallNotifications, - pauseQueueOnStop, queueProcessingBlocked, onMessageUpdate, } = useChatSession({ @@ -354,12 +343,7 @@ export default function BaseChat({ if (sessionLoadError) { return (
- - {renderHeader && renderHeader()} +
@@ -387,14 +371,7 @@ export default function BaseChat({ return (
- - {/* Custom header */} - {renderHeader && renderHeader()} - + {/* Chat container with sticky recipe header */}
{/* Goose watermark - top right */} @@ -483,7 +460,6 @@ export default function BaseChat({ chatState={chatState} onStop={stopStreaming} onSteerQueuedMessage={onSteerQueuedMessage} - pauseQueueOnStop={pauseQueueOnStop} queueProcessingBlocked={queueProcessingBlocked} commandHistory={commandHistory} initialValue={initialPrompt} @@ -504,7 +480,6 @@ export default function BaseChat({ onFilesProcessed={() => setDroppedFiles([])} // Clear dropped files after processing messages={messages} disableAnimation={disableAnimation} - recipe={recipe} recipeAccepted={!hasNotAcceptedRecipe} initialPrompt={initialPrompt} sessionModel={sessionModel} @@ -513,7 +488,6 @@ export default function BaseChat({ workingDir={session?.working_dir} onWorkingDirChange={handleWorkingDirChange} latestInference={latestInference} - {...customChatInputProps} /> diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx index 73e0881d10..2e279394f1 100644 --- a/ui/desktop/src/components/ChatInput.tsx +++ b/ui/desktop/src/components/ChatInput.tsx @@ -23,7 +23,6 @@ import { COST_TRACKING_ENABLED } from '../updates'; import { CostTracker } from './bottom_menu/CostTracker'; import { ContextWindowIndicator } from './bottom_menu/ContextWindowIndicator'; import { DroppedFile, useFileDrop } from '../hooks/useFileDrop'; -import { Recipe } from '../recipe'; import { MessageQueue, QueuedMessage } from './MessageQueue'; import { detectInterruption } from '../utils/interruptionDetector'; import { DiagnosticsModal } from './ui/Diagnostics'; @@ -162,7 +161,6 @@ interface ChatInputProps { chatState: ChatState; onStop?: () => void; onSteerQueuedMessage?: (input: UserInput) => Promise; - pauseQueueOnStop?: boolean; queueProcessingBlocked?: boolean; commandHistory?: string[]; initialValue?: string; @@ -175,11 +173,8 @@ interface ChatInputProps { accumulatedCost?: number | null; messages?: Message[]; disableAnimation?: boolean; - recipe?: Recipe | null; - recipeId?: string | null; recipeAccepted?: boolean; initialPrompt?: string; - append?: (message: Message) => void; onWorkingDirChange?: (newDir: string) => Promise | void; inputRef?: React.RefObject; sessionModel?: string | null; @@ -197,7 +192,6 @@ export default function ChatInput({ chatState = ChatState.Idle, onStop, onSteerQueuedMessage, - pauseQueueOnStop = false, queueProcessingBlocked = false, commandHistory = [], initialValue = '', @@ -210,11 +204,8 @@ export default function ChatInput({ accumulatedCost, messages = [], disableAnimation = false, - recipe: _recipe, - recipeId: _recipeId, recipeAccepted, initialPrompt, - append: _append, onWorkingDirChange, inputRef, sessionModel, @@ -336,36 +327,6 @@ export default function ChatInput({ setWorkingDirOverride(null); }, [sessionId, workingDir]); - // Save queue state (paused/interrupted) to storage - useEffect(() => { - try { - window.sessionStorage.setItem('goose-queue-paused', JSON.stringify(queuePausedRef.current)); - } catch (error) { - console.error('Error saving queue pause state:', error); - } - }, [queuedMessages]); // Save when queue changes - - useEffect(() => { - try { - window.sessionStorage.setItem('goose-queue-interruption', JSON.stringify(lastInterruption)); - } catch (error) { - console.error('Error saving queue interruption state:', error); - } - }, [lastInterruption]); - - // Cleanup effect - save final state on component unmount - useEffect(() => { - return () => { - // Save final queue state when component unmounts - try { - window.sessionStorage.setItem('goose-queue-paused', JSON.stringify(queuePausedRef.current)); - window.sessionStorage.setItem('goose-queue-interruption', JSON.stringify(lastInterruption)); - } catch (error) { - console.error('Error saving queue state on unmount:', error); - } - }; - }, [lastInterruption]); // Include lastInterruption in dependency array - // Queue processing useEffect(() => { const becameIdle = wasLoadingRef.current && !isLoading; @@ -1434,13 +1395,6 @@ export default function ChatInput({ if (onStop) onStop(); }; - const handleStop = () => { - if (pauseQueueOnStop && queuedMessages.length > 0) { - pauseRemainingQueue(); - } - if (onStop) onStop(); - }; - const handleResumeQueue = () => { queuePausedRef.current = false; setLastInterruption(null); @@ -1807,7 +1761,7 @@ export default function ChatInput({ {isLoading && !hasSubmittableContent ? (
diff --git a/ui/desktop/src/components/ErrorBoundary.tsx b/ui/desktop/src/components/ErrorBoundary.tsx index 8a9dd001e3..662de39882 100644 --- a/ui/desktop/src/components/ErrorBoundary.tsx +++ b/ui/desktop/src/components/ErrorBoundary.tsx @@ -72,7 +72,9 @@ export function ErrorUI({ error }: { error: string }) {
-

{intl.formatMessage(i18n.heading)}

+

+ {intl.formatMessage(i18n.heading)} +

{version !== undefined diff --git a/ui/desktop/src/components/ExtensionInstallModal.test.tsx b/ui/desktop/src/components/ExtensionInstallModal.test.tsx index 594f3d4739..4e773cce68 100644 --- a/ui/desktop/src/components/ExtensionInstallModal.test.tsx +++ b/ui/desktop/src/components/ExtensionInstallModal.test.tsx @@ -55,7 +55,9 @@ describe('ExtensionInstallModal', () => { it('should handle trusted extension (default behaviour, no allowlist)', async () => { mockElectron.getAllowedExtensions.mockResolvedValue([]); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -72,7 +74,9 @@ describe('ExtensionInstallModal', () => { it('should handle trusted extension (from allowlist)', async () => { mockElectron.getAllowedExtensions.mockResolvedValue(['npx test-extension']); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -90,7 +94,9 @@ describe('ExtensionInstallModal', () => { }); mockElectron.getAllowedExtensions.mockResolvedValue(['uvx allowed-package']); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -109,7 +115,9 @@ describe('ExtensionInstallModal', () => { it('should handle i-ching-mcp-server as allowed command', async () => { mockElectron.getAllowedExtensions.mockResolvedValue([]); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -128,7 +136,9 @@ describe('ExtensionInstallModal', () => { it('should handle blocked extension', async () => { mockElectron.getAllowedExtensions.mockResolvedValue(['uvx allowed-package']); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -147,7 +157,9 @@ describe('ExtensionInstallModal', () => { it('should dismiss modal correctly', async () => { mockElectron.getAllowedExtensions.mockResolvedValue([]); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); @@ -168,7 +180,9 @@ describe('ExtensionInstallModal', () => { vi.mocked(addExtensionFromDeepLink).mockResolvedValue(undefined); mockElectron.getAllowedExtensions.mockResolvedValue([]); - renderWithIntl(); + renderWithIntl( + + ); const eventHandler = getAddExtensionEventHandler(); diff --git a/ui/desktop/src/components/ExtensionInstallModal.tsx b/ui/desktop/src/components/ExtensionInstallModal.tsx index 8628aa317b..6dad5765f8 100644 --- a/ui/desktop/src/components/ExtensionInstallModal.tsx +++ b/ui/desktop/src/components/ExtensionInstallModal.tsx @@ -29,7 +29,8 @@ const i18n = defineMessages({ }, blockedMessage: { id: 'extensionInstallModal.blockedMessage', - defaultMessage: 'This extension command is not in the allowed list and its installation is blocked.\n\nExtension: {name}\nCommand: {command}\n\nContact your administrator to request approval for this extension.', + defaultMessage: + 'This extension command is not in the allowed list and its installation is blocked.\n\nExtension: {name}\nCommand: {command}\n\nContact your administrator to request approval for this extension.', }, ok: { id: 'extensionInstallModal.ok', @@ -41,15 +42,18 @@ const i18n = defineMessages({ }, untrustedSecurityMessage: { id: 'extensionInstallModal.untrustedSecurityMessage', - defaultMessage: 'This extension command is not in the allowed list and will be able to access your conversations and provide additional functionality.\n\nInstalling extensions from untrusted sources may pose security risks.', + defaultMessage: + 'This extension command is not in the allowed list and will be able to access your conversations and provide additional functionality.\n\nInstalling extensions from untrusted sources may pose security risks.', }, untrustedMessageWithUrl: { id: 'extensionInstallModal.untrustedMessageWithUrl', - defaultMessage: '{securityMessage}\n\nExtension: {name}\nURL: {url}\n\nContact your administrator if you are unsure about this.', + defaultMessage: + '{securityMessage}\n\nExtension: {name}\nURL: {url}\n\nContact your administrator if you are unsure about this.', }, untrustedMessageWithCommand: { id: 'extensionInstallModal.untrustedMessageWithCommand', - defaultMessage: '{securityMessage}\n\nExtension: {name}\nCommand: {command}\n\nContact your administrator if you are unsure about this.', + defaultMessage: + '{securityMessage}\n\nExtension: {name}\nCommand: {command}\n\nContact your administrator if you are unsure about this.', }, installAnyway: { id: 'extensionInstallModal.installAnyway', @@ -81,7 +85,8 @@ const i18n = defineMessages({ }, alreadyInstalledMessage: { id: 'extensionInstallModal.alreadyInstalledMessage', - defaultMessage: "''{name}'' extension has already been installed successfully. Start a new chat session to use it.", + defaultMessage: + "''{name}'' extension has already been installed successfully. Start a new chat session to use it.", }, installing: { id: 'extensionInstallModal.installing', @@ -200,7 +205,8 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal case 'blocked': return { title: intl.formatMessage(i18n.blockedTitle), - message: '\n\n' + intl.formatMessage(i18n.blockedMessage, { name, command: displayCommand }), + message: + '\n\n' + intl.formatMessage(i18n.blockedMessage, { name, command: displayCommand }), confirmLabel: intl.formatMessage(i18n.ok), cancelLabel: '', showSingleButton: true, @@ -210,8 +216,16 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal case 'untrusted': { const securityMessage = '\n\n' + intl.formatMessage(i18n.untrustedSecurityMessage); const message = remoteUrl - ? intl.formatMessage(i18n.untrustedMessageWithUrl, { securityMessage, name, url: remoteUrl }) - : intl.formatMessage(i18n.untrustedMessageWithCommand, { securityMessage, name, command: displayCommand }); + ? intl.formatMessage(i18n.untrustedMessageWithUrl, { + securityMessage, + name, + url: remoteUrl, + }) + : intl.formatMessage(i18n.untrustedMessageWithCommand, { + securityMessage, + name, + command: displayCommand, + }); return { title: intl.formatMessage(i18n.untrustedTitle), @@ -236,58 +250,59 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal } }; - const handleExtensionRequest = useCallback(async (link: string): Promise => { - if (processingLinkRef.current === link) { - return; - } - processingLinkRef.current = link; - - try { - - const command = extractCommand(link); - const remoteUrl = extractRemoteUrl(link); - const extName = extractExtensionName(link); - const extensionsList = await getExtensionsRef.current(true); - - if (extensionsList?.find((ext) => ext.name === extName)) { - - toastService.success({ - title: intl.formatMessage(i18n.alreadyInstalledTitle, { name: extName }), - msg: intl.formatMessage(i18n.alreadyInstalledMessage, { name: extName }), - }); + const handleExtensionRequest = useCallback( + async (link: string): Promise => { + if (processingLinkRef.current === link) { return; } + processingLinkRef.current = link; - const extensionInfo: ExtensionInfo = { - name: extName, - command: command, - remoteUrl: remoteUrl || undefined, - link: link, - }; + try { + const command = extractCommand(link); + const remoteUrl = extractRemoteUrl(link); + const extName = extractExtensionName(link); + const extensionsList = await getExtensionsRef.current(true); - const modalType = await determineModalType(command, remoteUrl); + if (extensionsList?.find((ext) => ext.name === extName)) { + toastService.success({ + title: intl.formatMessage(i18n.alreadyInstalledTitle, { name: extName }), + msg: intl.formatMessage(i18n.alreadyInstalledMessage, { name: extName }), + }); + return; + } - setModalState({ - isOpen: true, - modalType, - extensionInfo, - isPending: false, - error: null, - }); + const extensionInfo: ExtensionInfo = { + name: extName, + command: command, + remoteUrl: remoteUrl || undefined, + link: link, + }; - setPendingLink(modalType === 'blocked' ? null : link); + const modalType = await determineModalType(command, remoteUrl); - window.electron.logInfo(`Extension modal opened: ${modalType} for ${extName}`); - } catch (error) { - console.error('Error processing extension request:', error); - setModalState((prev) => ({ - ...prev, - error: errorMessage(error, 'Unknown error'), - })); - } finally { - processingLinkRef.current = null; - } - }, [intl]); + setModalState({ + isOpen: true, + modalType, + extensionInfo, + isPending: false, + error: null, + }); + + setPendingLink(modalType === 'blocked' ? null : link); + + window.electron.logInfo(`Extension modal opened: ${modalType} for ${extName}`); + } catch (error) { + console.error('Error processing extension request:', error); + setModalState((prev) => ({ + ...prev, + error: errorMessage(error, 'Unknown error'), + })); + } finally { + processingLinkRef.current = null; + } + }, + [intl] + ); const dismissModal = useCallback(() => { setModalState({ @@ -308,7 +323,6 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal setModalState((prev) => ({ ...prev, isPending: true })); try { - if (addExtension) { await addExtensionFromDeepLink( pendingLink, @@ -331,7 +345,6 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal }, [pendingLink, dismissModal, addExtension, setView]); useEffect(() => { - const handleAddExtension = async (_event: IpcRendererEvent, ...args: unknown[]) => { const link = args[0] as string; await handleExtensionRequest(link); diff --git a/ui/desktop/src/components/GooseSidebar/ThemeSelector.tsx b/ui/desktop/src/components/GooseSidebar/ThemeSelector.tsx index ae6f5e342f..2dae8d8fa6 100644 --- a/ui/desktop/src/components/GooseSidebar/ThemeSelector.tsx +++ b/ui/desktop/src/components/GooseSidebar/ThemeSelector.tsx @@ -39,7 +39,9 @@ const ThemeSelector: React.FC = ({ return (

- {!hideTitle &&
{intl.formatMessage(i18n.theme)}
} + {!hideTitle && ( +
{intl.formatMessage(i18n.theme)}
+ )}
diff --git a/ui/desktop/src/components/GroupedExtensionLoadingToast.tsx b/ui/desktop/src/components/GroupedExtensionLoadingToast.tsx index 87e96dde15..87adad1bb8 100644 --- a/ui/desktop/src/components/GroupedExtensionLoadingToast.tsx +++ b/ui/desktop/src/components/GroupedExtensionLoadingToast.tsx @@ -20,7 +20,8 @@ const i18n = defineMessages({ }, partiallyLoaded: { id: 'groupedExtensionLoadingToast.partiallyLoaded', - defaultMessage: 'Loaded {successCount}/{totalCount, plural, one {# extension} other {# extensions}}', + defaultMessage: + 'Loaded {successCount}/{totalCount, plural, one {# extension} other {# extensions}}', }, failedToLoad: { id: 'groupedExtensionLoadingToast.failedToLoad', @@ -158,7 +159,10 @@ export function GroupedExtensionLoadingToast({ {ext.status === 'error' && ext.error && (
- {formatExtensionErrorMessage(ext.error, intl.formatMessage(i18n.failedToAddExtension))} + {formatExtensionErrorMessage( + ext.error, + intl.formatMessage(i18n.failedToAddExtension) + )}
{ext.recoverHints && setView && ( @@ -185,7 +189,9 @@ export function GroupedExtensionLoadingToast({ setTimeout(() => setCopiedExtension(null), 2000); }} > - {copiedExtension === ext.name ? intl.formatMessage(i18n.copied) : intl.formatMessage(i18n.copyError)} + {copiedExtension === ext.name + ? intl.formatMessage(i18n.copied) + : intl.formatMessage(i18n.copyError)}
@@ -202,7 +208,11 @@ export function GroupedExtensionLoadingToast({
); }; - -export default MessageQueue; diff --git a/ui/desktop/src/components/ProgressiveMessageList.tsx b/ui/desktop/src/components/ProgressiveMessageList.tsx index 0a5b094ade..2aee2588fd 100644 --- a/ui/desktop/src/components/ProgressiveMessageList.tsx +++ b/ui/desktop/src/components/ProgressiveMessageList.tsx @@ -270,15 +270,17 @@ export default function ProgressiveMessageList({ const previousResolvedModel = currentResolvedModel ? getPreviousResolvedModel(index) : null; const showModelChangeDisclosure = Boolean( currentResolvedModel && - previousResolvedModel && - currentResolvedModel !== previousResolvedModel + previousResolvedModel && + currentResolvedModel !== previousResolvedModel ); const messageKey = message.id ?? `msg-${index}-${message.created}`; return ( - {showModelChangeDisclosure && currentResolvedModel && previousResolvedModel && + {showModelChangeDisclosure && + currentResolvedModel && + previousResolvedModel && renderModelChangeDisclosure(previousResolvedModel, currentResolvedModel)}
setIsRenameOpen(false)} disabled={isRenaming}> {intl.formatMessage(i18n.cancel)} - diff --git a/ui/desktop/src/components/SessionIndicators.tsx b/ui/desktop/src/components/SessionIndicators.tsx index 49842ba16c..9e691f3a7e 100644 --- a/ui/desktop/src/components/SessionIndicators.tsx +++ b/ui/desktop/src/components/SessionIndicators.tsx @@ -44,7 +44,10 @@ export const SessionIndicators = React.memo( if (isStreaming) { return (
- +
); } @@ -52,7 +55,10 @@ export const SessionIndicators = React.memo( if (hasUnread) { return (
-
+
); } diff --git a/ui/desktop/src/components/ToolApprovalButtons.tsx b/ui/desktop/src/components/ToolApprovalButtons.tsx index 5dcfbce047..445cef3b22 100644 --- a/ui/desktop/src/components/ToolApprovalButtons.tsx +++ b/ui/desktop/src/components/ToolApprovalButtons.tsx @@ -51,7 +51,7 @@ const globalApprovalState = new Map< } >(); -export interface ToolApprovalData { +interface ToolApprovalData { id: string; toolName: string; prompt?: string; @@ -133,7 +133,11 @@ export default function ToolApprovalButtons({ data }: { data: ToolApprovalData } {intl.formatMessage(i18n.alwaysAllow)} )} -
diff --git a/ui/desktop/src/components/ToolCallArguments.tsx b/ui/desktop/src/components/ToolCallArguments.tsx index ee1ad911e5..2fba567349 100644 --- a/ui/desktop/src/components/ToolCallArguments.tsx +++ b/ui/desktop/src/components/ToolCallArguments.tsx @@ -33,14 +33,18 @@ export function ToolCallArguments({ args }: ToolCallArgumentsProps) { return (
-
+
-
+
{isExpanded ? (
                 {text}
diff --git a/ui/desktop/src/components/ToolCallStatusIndicator.tsx b/ui/desktop/src/components/ToolCallStatusIndicator.tsx
index a95a755085..8a8ab0f6cf 100644
--- a/ui/desktop/src/components/ToolCallStatusIndicator.tsx
+++ b/ui/desktop/src/components/ToolCallStatusIndicator.tsx
@@ -16,10 +16,7 @@ interface ToolCallStatusIndicatorProps {
   className?: string;
 }
 
-export const ToolCallStatusIndicator: React.FC = ({
-  status,
-  className,
-}) => {
+const ToolCallStatusIndicator: React.FC = ({ status, className }) => {
   const intl = useIntl();
   const getStatusStyles = () => {
     switch (status) {
diff --git a/ui/desktop/src/components/ToolCallWithResponse.tsx b/ui/desktop/src/components/ToolCallWithResponse.tsx
index 1f02354833..a3fab0fc1c 100644
--- a/ui/desktop/src/components/ToolCallWithResponse.tsx
+++ b/ui/desktop/src/components/ToolCallWithResponse.tsx
@@ -12,7 +12,6 @@ import {
   ToolConfirmationData,
 } from '../types/message';
 import { cn, snakeToTitleCase } from '../utils';
-import { LoadingStatus } from './ui/Dot';
 import { ChevronRight, ExternalLink } from 'lucide-react';
 import { TooltipWrapper } from './settings/providers/subcomponents/buttons/TooltipWrapper';
 import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
@@ -22,6 +21,8 @@ import McpAppRenderer from './McpApps/McpAppRenderer';
 import ToolApprovalButtons from './ToolApprovalButtons';
 import { defineMessages, useIntl } from '../i18n';
 
+type LoadingStatus = 'loading' | 'success' | 'error';
+
 const i18n = defineMessages({
   viewSubagentSession: {
     id: 'toolCallWithResponse.viewSubagentSession',
diff --git a/ui/desktop/src/components/UserMessage.tsx b/ui/desktop/src/components/UserMessage.tsx
index eafefb438d..7292b655e6 100644
--- a/ui/desktop/src/components/UserMessage.tsx
+++ b/ui/desktop/src/components/UserMessage.tsx
@@ -23,7 +23,8 @@ const i18n = defineMessages({
   },
   editInPlaceDescription: {
     id: 'userMessage.editInPlaceDescription',
-    defaultMessage: 'Edit in Place updates this session • Fork Session creates a new session',
+    defaultMessage:
+      'Edit in Place updates this session • Fork Session creates a new session',
   },
   cancel: {
     id: 'userMessage.cancel',
@@ -233,7 +234,11 @@ export default function UserMessage({ message, onMessageUpdate }: UserMessagePro
                 })}
               
-
)} @@ -427,7 +432,9 @@ export default function LocalModelPicker({ onConfigured }: LocalModelPickerProps ) : (
- {intl.formatMessage(i18n.startingDownload)} + + {intl.formatMessage(i18n.startingDownload)} +
)}
diff --git a/ui/desktop/src/components/onboarding/OnboardingGuard.tsx b/ui/desktop/src/components/onboarding/OnboardingGuard.tsx index 97325ad6dd..3f7b890495 100644 --- a/ui/desktop/src/components/onboarding/OnboardingGuard.tsx +++ b/ui/desktop/src/components/onboarding/OnboardingGuard.tsx @@ -106,7 +106,12 @@ export default function OnboardingGuard({ children }: OnboardingGuardProps) { }, []); useEffect(() => { - if (!isCheckingProvider && !hasProvider && !checkProviderError && !hasTrackedOnboardingStart.current) { + if ( + !isCheckingProvider && + !hasProvider && + !checkProviderError && + !hasTrackedOnboardingStart.current + ) { trackOnboardingStarted(); hasTrackedOnboardingStart.current = true; } @@ -152,11 +157,13 @@ export default function OnboardingGuard({ children }: OnboardingGuardProps) {
-

{intl.formatMessage(i18n.checkProviderErrorTitle)}

-

{intl.formatMessage(i18n.checkProviderErrorDescription)}

- +

+ {intl.formatMessage(i18n.checkProviderErrorTitle)} +

+

+ {intl.formatMessage(i18n.checkProviderErrorDescription)} +

+
); @@ -185,7 +192,9 @@ export default function OnboardingGuard({ children }: OnboardingGuardProps) {
-

{intl.formatMessage(i18n.welcomeTitle)}

+

+ {intl.formatMessage(i18n.welcomeTitle)} +

{intl.formatMessage(i18n.welcomeDescription)}

diff --git a/ui/desktop/src/components/onboarding/OnboardingSuccess.tsx b/ui/desktop/src/components/onboarding/OnboardingSuccess.tsx index 5f0b121c5e..dc0ce27d7e 100644 --- a/ui/desktop/src/components/onboarding/OnboardingSuccess.tsx +++ b/ui/desktop/src/components/onboarding/OnboardingSuccess.tsx @@ -24,7 +24,8 @@ const i18n = defineMessages({ }, privacyDescription: { id: 'onboardingSuccess.privacyDescription', - defaultMessage: 'Anonymous usage data helps improve goose. We never collect your conversations, code, or personal data.', + defaultMessage: + 'Anonymous usage data helps improve goose. We never collect your conversations, code, or personal data.', }, learnMore: { id: 'onboardingSuccess.learnMore', @@ -80,7 +81,9 @@ export default function OnboardingSuccess({ providerName, onFinish }: Onboarding
-

{intl.formatMessage(i18n.privacyTitle)}

+

+ {intl.formatMessage(i18n.privacyTitle)} +

{intl.formatMessage(i18n.privacyDescription)}{' '}

diff --git a/ui/desktop/src/components/onboarding/PrivacyInfoModal.tsx b/ui/desktop/src/components/onboarding/PrivacyInfoModal.tsx index 739fd69e10..ec70667955 100644 --- a/ui/desktop/src/components/onboarding/PrivacyInfoModal.tsx +++ b/ui/desktop/src/components/onboarding/PrivacyInfoModal.tsx @@ -8,7 +8,8 @@ const i18n = defineMessages({ }, description: { id: 'privacyInfoModal.description', - defaultMessage: 'Anonymous usage data helps us understand how goose is used and identify areas for improvement.', + defaultMessage: + 'Anonymous usage data helps us understand how goose is used and identify areas for improvement.', }, whatWeCollect: { id: 'privacyInfoModal.whatWeCollect', @@ -40,7 +41,8 @@ const i18n = defineMessages({ }, neverCollect: { id: 'privacyInfoModal.neverCollect', - defaultMessage: 'We never collect your conversations, code, tool arguments, error messages, or any personal data. You can change this setting anytime in Settings.', + defaultMessage: + 'We never collect your conversations, code, tool arguments, error messages, or any personal data. You can change this setting anytime in Settings.', }, }); @@ -60,10 +62,10 @@ export default function PrivacyInfoModal({ isOpen, onClose }: PrivacyInfoModalPr
-

- {intl.formatMessage(i18n.description)} +

{intl.formatMessage(i18n.description)}

+

+ {intl.formatMessage(i18n.whatWeCollect)}

-

{intl.formatMessage(i18n.whatWeCollect)}

  • {intl.formatMessage(i18n.collectOs)}
  • {intl.formatMessage(i18n.collectVersion)}
  • @@ -72,9 +74,7 @@ export default function PrivacyInfoModal({ isOpen, onClose }: PrivacyInfoModalPr
  • {intl.formatMessage(i18n.collectSession)}
  • {intl.formatMessage(i18n.collectErrors)}
-

- {intl.formatMessage(i18n.neverCollect)} -

+

{intl.formatMessage(i18n.neverCollect)}

diff --git a/ui/desktop/src/components/parameter/ParameterInput.tsx b/ui/desktop/src/components/parameter/ParameterInput.tsx index a5cf00bce9..e1d84c117c 100644 --- a/ui/desktop/src/components/parameter/ParameterInput.tsx +++ b/ui/desktop/src/components/parameter/ParameterInput.tsx @@ -146,7 +146,9 @@ const ParameterInput: React.FC = ({ title={intl.formatMessage(i18n.unusedWarningTitle)} > - {intl.formatMessage(i18n.unused)} + + {intl.formatMessage(i18n.unused)} +
)}
diff --git a/ui/desktop/src/components/recipes/ImportRecipeForm.tsx b/ui/desktop/src/components/recipes/ImportRecipeForm.tsx index 174a0f0cdd..f9d67e76d7 100644 --- a/ui/desktop/src/components/recipes/ImportRecipeForm.tsx +++ b/ui/desktop/src/components/recipes/ImportRecipeForm.tsx @@ -47,7 +47,8 @@ const i18n = defineMessages({ }, reviewWarning: { id: 'importRecipeForm.reviewWarning', - defaultMessage: 'Ensure you review contents of recipe files before adding them to your goose interface.', + defaultMessage: + 'Ensure you review contents of recipe files before adding them to your goose interface.', }, cancel: { id: 'importRecipeForm.cancel', @@ -67,7 +68,8 @@ const i18n = defineMessages({ }, schemaDescription: { id: 'importRecipeForm.schemaDescription', - defaultMessage: 'Your YAML or JSON file should follow this structure. Required fields are: title, description, and either instructions or prompt.', + defaultMessage: + 'Your YAML or JSON file should follow this structure. Required fields are: title, description, and either instructions or prompt.', }, }); @@ -208,7 +210,9 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR <>
-

{intl.formatMessage(i18n.importRecipeTitle)}

+

+ {intl.formatMessage(i18n.importRecipeTitle)} +

{ @@ -354,7 +358,9 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR disabled={!canSubmit || importing || isSubmitting} variant="default" > - {importing || isSubmitting ? intl.formatMessage(i18n.importing) : intl.formatMessage(i18n.importRecipeButton)} + {importing || isSubmitting + ? intl.formatMessage(i18n.importing) + : intl.formatMessage(i18n.importRecipeButton)} )} @@ -368,7 +374,9 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR
-

{intl.formatMessage(i18n.expectedRecipeStructure)}

+

+ {intl.formatMessage(i18n.expectedRecipeStructure)} +

{/* Title Field */} @@ -283,7 +293,8 @@ export default function CreateSubRecipeInline({ htmlFor="subrecipe-title" className="block text-sm font-medium text-text-standard mb-2" > - {intl.formatMessage(i18n.recipeTitleLabel)} * + {intl.formatMessage(i18n.recipeTitleLabel)}{' '} + * - {intl.formatMessage(i18n.recipeDescriptionLabel)} * + {intl.formatMessage(i18n.recipeDescriptionLabel)}{' '} + * - {intl.formatMessage(i18n.instructionsLabel)} * + {intl.formatMessage(i18n.instructionsLabel)}{' '} + *