@shuffleio/shuffle-mcps 0.0.10 → 0.0.12

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../ShuffleMCP.tsx","../AppDetailDrawer.tsx","../toast.ts","../api.ts","../datastore.ts","../useAppAuth.ts","../IntegrationStatus.tsx","../authenticatedApps.ts","../appsCache.ts","../auth-utils.ts","../AppDetailContext.tsx","../ingestionDetection.ts","../AppTitleHeader.tsx","../AppAuthSection.tsx","../AppAuthConfig.tsx","../TryMcpSection.tsx","../AppMcpChat.tsx","../AgentIcon.tsx","../SingulActionsPreview.tsx","../AppSearchDrawer.tsx","../ShufflePipelinesBanner.tsx","../AgentUI.tsx","../resolveApp.ts","../agentRun.ts","../scheduleHint.ts","../AgentRunDiagnosisBanner.tsx","../agentDiagnosis.ts","../AgentRunDrawer.tsx","../AgentActivityList.tsx","../agentActivity.ts","../AgentExecutionDrawer.tsx","../useAppLookup.ts"],"sourcesContent":["/**\n * Local Singul Library — fully self-contained.\n * No host-app `@/` imports remain inside this folder (assets aside).\n */\n\n// Side-effect import: ensures shadcn-style token fallbacks (--card, --background,\n// --border, --foreground, --muted, --primary, etc.) are always defined when any\n// lib component is used standalone in a host app that does NOT define those\n// CSS custom properties. Host overrides still win (defaults use :where(:root),\n// specificity 0).\nimport './shuffle-mcp.css';\n\nexport { ShuffleMCP, default } from './ShuffleMCP';\nexport type { ShuffleMCPHandle } from './ShuffleMCP';\nexport { default as AppDetailDrawer } from './AppDetailDrawer';\nexport { default as AppSearchDrawer } from './AppSearchDrawer';\nexport { default as ShufflePipelinesBanner } from './ShufflePipelinesBanner';\nexport { default as AppTitleHeader } from './AppTitleHeader';\nexport type { AppTitleHeaderProps } from './AppTitleHeader';\nexport { default as AppAuthSection } from './AppAuthSection';\nexport type { AppAuthSectionProps } from './AppAuthSection';\nexport { default as TryMcpSection } from './TryMcpSection';\nexport type { TryMcpSectionProps } from './TryMcpSection';\nexport { default as SingulActionsPreview } from './SingulActionsPreview';\nexport { default as AgentUI } from './AgentUI';\nexport type { AgentUIProps, AgentUIApp } from './AgentUI';\nexport { default as AgentRunDrawer } from './AgentRunDrawer';\nexport type { AgentRunDrawerProps, AgentRunDrawerTab } from './AgentRunDrawer';\nexport { default as AgentActivityList } from './AgentActivityList';\nexport type { AgentActivityListProps } from './AgentActivityList';\nexport { default as AgentExecutionDrawer } from './AgentExecutionDrawer';\nexport type { AgentExecutionDrawerProps } from './AgentExecutionDrawer';\nexport { default as AgentRunDiagnosisBanner } from './AgentRunDiagnosisBanner';\nexport {\n parseRunResult,\n getFailureInfo,\n hasOutputWarning,\n diagnoseOutputWarning,\n} from './agentDiagnosis';\nexport type {\n DiagnosableRun,\n DiagnosisEvidence,\n OutputDiagnosis,\n} from './agentDiagnosis';\nexport { searchAgentActivity } from './agentActivity';\nexport type {\n AgentRun,\n AgentRunResult,\n AgentDecision,\n AgentActivityResponse,\n AgentActivityParams,\n} from './agentActivity';\nexport { useAppLookup } from './useAppLookup';\nexport type { AppLookupResult } from './useAppLookup';\nexport {\n resolveApp,\n resolveApps,\n seedResolvedApp,\n invalidateResolvedApps,\n} from './resolveApp';\nexport type { ResolvedApp } from './resolveApp';\nexport { IntegrationStatus, refreshAllIntegrationStatus } from './IntegrationStatus';\nexport { useAppAuth } from './useAppAuth';\nexport { AppDetailProvider, useAppDetail } from './AppDetailContext';\nexport { API_CONFIG, getApiUrl, getAuthHeader } from './api';\nexport { setToastImpl, toast } from './toast';\nexport type {\n AlgoliaSearchApp,\n AppSelectedEvent,\n AppAuthentication,\n CustomStyles,\n ShuffleMCPProps,\n} from './shuffle-mcp.helpers';\n","/**\n * Local Singul Library - React Component\n * This is a local copy for development. Changes here should be merged back to:\n * https://github.com/Shuffle/singul.js\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo, useImperativeHandle } from 'react';\nimport { algoliasearch, SearchClient } from 'algoliasearch';\nimport { Tooltip } from '@mui/material';\nimport type { AlgoliaSearchApp, AppSelectedEvent, ShuffleMCPProps, AppAuthentication } from './shuffle-mcp.helpers';\nimport AppDetailDrawer from './AppDetailDrawer';\nimport './shuffle-mcp.css';\nimport { fetchApps } from './appsCache';\n\nconst DEFAULT_ALGOLIA_APP_ID = 'JNSS5CFDZZ';\nconst DEFAULT_ALGOLIA_API_KEY = '33e4e3564f4f060e96e0531957bed552';\nconst DEFAULT_ALGOLIA_INDEX = 'appsearch';\nconst EMPTY_SELECTED_APPS: AlgoliaSearchApp[] = [];\n\nexport interface ShuffleMCPHandle {\n search: (query: string) => void;\n clear: () => void;\n}\n\nexport const ShuffleMCP = React.forwardRef<ShuffleMCPHandle, ShuffleMCPProps>(({\n authToken,\n orgId,\n placeholder = 'Search apps...',\n layout = 'list',\n gridColumns = 3,\n showDescription = false,\n showCategories = false,\n showCheckbox = false,\n multiSelect = false,\n selectedApps = EMPTY_SELECTED_APPS,\n preventDefault = false,\n inline = false,\n initialQuery = '',\n initialFilterQuery,\n hitsPerPage = 15,\n apiKey,\n apiBaseUrl = 'https://shuffler.io',\n authPath = '/api/v1/apps/authentication',\n appAuthPath = '/appauth',\n privateAppsPath = '/api/v1/apps',\n disablePrivateApps = false,\n showSourceFilter = true,\n singulBaseUrl = 'https://singul.io',\n hideAuthStatus = false,\n authenticatedApps: externalAuthenticatedApps,\n pinnedApps,\n algoliaAppId = DEFAULT_ALGOLIA_APP_ID,\n algoliaApiKey = DEFAULT_ALGOLIA_API_KEY,\n algoliaIndexName = DEFAULT_ALGOLIA_INDEX,\n customStyles = {},\n className = '',\n renderItem,\n renderEmptyState,\n renderLoadingState,\n onAppSelected,\n onSelectionChange,\n onSearchChange,\n}, ref) => {\n const [query, setQuery] = useState(initialQuery);\n const [results, setResults] = useState<AlgoliaSearchApp[]>([]);\n const [privateApps, setPrivateApps] = useState<AlgoliaSearchApp[]>([]);\n const [sourceFilter, setSourceFilter] = useState<'all' | 'public' | 'private' | 'authenticated'>('all');\n const [isLoading, setIsLoading] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [internalSelectedApps, setInternalSelectedApps] = useState<AlgoliaSearchApp[]>(selectedApps);\n const [authenticatedApps, setAuthenticatedApps] = useState<AppAuthentication[]>(externalAuthenticatedApps || []);\n const [drawerApp, setDrawerApp] = useState<AlgoliaSearchApp | null>(null);\n const hasInitialized = useRef(false);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const searchClient = useRef<SearchClient | null>(null);\n\n // Fetch authenticated apps when apiKey is provided\n const fetchAuthenticatedApps = useCallback(async () => {\n if (!apiKey) return;\n try {\n const response = await fetch(`${apiBaseUrl}${authPath}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n ...(orgId ? { 'Org-Id': orgId } : {}),\n },\n });\n if (response.ok) {\n const result = await response.json();\n const authData = result.data || result;\n if (Array.isArray(authData)) {\n setAuthenticatedApps(authData);\n }\n }\n } catch (error) {\n console.error('Failed to fetch authenticated apps:', error);\n }\n }, [apiKey, apiBaseUrl, authPath, orgId]);\n\n useEffect(() => {\n fetchAuthenticatedApps();\n }, [fetchAuthenticatedApps]);\n\n // Fetch the user's private apps from /api/v1/apps when apiKey is provided.\n // These get merged into search results so users can find their own apps too.\n useEffect(() => {\n if (disablePrivateApps) {\n setPrivateApps([]);\n return;\n }\n const fetchPrivateApps = async () => {\n try {\n const apps = await fetchApps({\n baseUrl: apiBaseUrl,\n path: privateAppsPath,\n apiKey: apiKey || null,\n orgId: orgId || null,\n });\n // Normalize to AlgoliaSearchApp shape, tagged as 'private' source.\n const normalized: AlgoliaSearchApp[] = apps.map((a: any) => ({\n name: a.name || '',\n description: a.description || '',\n objectID: a.id || a.objectID || `private-${a.name}`,\n creator: a.owner || a.creator || '',\n app_version: a.app_version || '1.0.0',\n image_url: a.large_image || a.image_url || '',\n time_edited: a.edited || 0,\n generated: !!a.generated,\n invalid: !!a.invalid,\n priority: a.priority || 0,\n actions: Array.isArray(a.actions) ? a.actions.length : (a.actions || 0),\n tags: a.tags || [],\n accessible_by: a.accessible_by || [],\n categories: a.categories || [],\n action_labels: a.action_labels || [],\n triggers: a.triggers || [],\n verified: !!a.verified,\n source: 'private',\n }));\n setPrivateApps(normalized);\n } catch (error) {\n console.error('Failed to fetch private apps:', error);\n }\n };\n fetchPrivateApps();\n }, [apiKey, apiBaseUrl, privateAppsPath, disablePrivateApps, orgId]);\n\n // Auto-select validated apps when they're loaded (validated = tests ran successfully)\n useEffect(() => {\n if (authenticatedApps.length > 0 && results.length > 0) {\n const validatedApps = authenticatedApps.filter(auth => auth.validation?.valid);\n const appsToAutoSelect = results.filter(app => \n validatedApps.some(auth => auth.app.name.toLowerCase() === app.name.toLowerCase())\n );\n \n if (appsToAutoSelect.length > 0) {\n const newSelection = [...internalSelectedApps];\n appsToAutoSelect.forEach(app => {\n if (!newSelection.some(a => a.objectID === app.objectID)) {\n newSelection.push(app);\n }\n });\n if (newSelection.length !== internalSelectedApps.length) {\n setInternalSelectedApps(newSelection);\n onSelectionChange?.(newSelection);\n }\n }\n }\n }, [authenticatedApps, results]);\n\n // Sync external authenticatedApps\n useEffect(() => {\n if (externalAuthenticatedApps) {\n setAuthenticatedApps(externalAuthenticatedApps);\n }\n }, [externalAuthenticatedApps]);\n\n // Initialize Algolia client and run initial search\n useEffect(() => {\n searchClient.current = algoliasearch(algoliaAppId, algoliaApiKey);\n \n // Run initial search after client is ready\n if (!hasInitialized.current) {\n hasInitialized.current = true;\n const searchTerm = initialQuery || initialFilterQuery || '';\n setTimeout(() => {\n if (searchClient.current) {\n performSearch(searchTerm);\n onSearchChange?.(initialQuery); // Only report the visible query\n }\n }, 100);\n }\n }, []);\n\n // Sync external selectedApps\n useEffect(() => {\n setInternalSelectedApps(selectedApps);\n }, [selectedApps]);\n\n // Handle click outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setSelectedIndex(-1);\n }\n };\n\n document.addEventListener('click', handleClickOutside);\n return () => document.removeEventListener('click', handleClickOutside);\n }, []);\n\n // Check if an app is configured (found in authentication API with active: true)\n const isAppConfigured = useCallback((app: AlgoliaSearchApp) => {\n return authenticatedApps.some(\n auth => auth.app.name.toLowerCase() === app.name.toLowerCase() && auth.active === true\n );\n }, [authenticatedApps]);\n\n // Check if an app is validated/tested (validation.valid is true)\n const isAppValidated = useCallback((app: AlgoliaSearchApp) => {\n return authenticatedApps.some(\n auth => auth.app.name.toLowerCase() === app.name.toLowerCase() && auth.validation?.valid === true\n );\n }, [authenticatedApps]);\n\n // Get auth state for an app\n const getAppAuthState = useCallback((app: AlgoliaSearchApp) => {\n return {\n configured: isAppConfigured(app),\n validated: isAppValidated(app),\n };\n }, [isAppConfigured, isAppValidated]);\n\n // Perform search\n const performSearch = useCallback(async (searchQuery: string) => {\n if (!searchClient.current) {\n return;\n }\n\n setIsLoading(true);\n try {\n const searchResult = await searchClient.current.searchSingleIndex({\n indexName: algoliaIndexName,\n searchParams: {\n query: searchQuery || '', // Empty string gets top results\n hitsPerPage,\n },\n });\n\n const hits = (searchResult.hits as AlgoliaSearchApp[]).map(h => ({ ...h, source: 'public' as const }));\n setResults(hits);\n // Open dropdown if we got Algolia hits OR we have private apps to show\n setIsOpen(hits.length > 0 || privateApps.length > 0);\n setSelectedIndex(-1);\n } catch (error) {\n // Algolia rate-limit (429) or network error: don't blank out the dropdown\n // if we still have private apps to show from /api/v1/apps.\n console.error('Search failed:', error);\n setResults([]);\n setIsOpen(privateApps.length > 0);\n } finally {\n setIsLoading(false);\n }\n }, [hitsPerPage, algoliaIndexName, privateApps.length]);\n\n // Expose imperative methods via ref\n useImperativeHandle(ref, () => ({\n search: (searchQuery: string) => {\n setQuery(searchQuery);\n onSearchChange?.(searchQuery);\n performSearch(searchQuery);\n },\n clear: () => {\n setQuery('');\n performSearch(''); // Show top results when cleared\n },\n getQuery: () => query,\n }), [performSearch, onSearchChange, query]);\n\n // Handle input change\n const handleInputChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.target.value;\n setQuery(value);\n setSelectedIndex(-1);\n onSearchChange?.(value);\n\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n\n debounceTimer.current = setTimeout(() => {\n performSearch(value);\n }, 300);\n }, [performSearch, onSearchChange]);\n\n // Handle app selection\n const selectApp = useCallback((app: AlgoliaSearchApp) => {\n const handoffToken = apiKey || authToken || '';\n const authUrl = `${apiBaseUrl}${appAuthPath}?app_id=${app.objectID}&auth=${handoffToken}&source=shuffle${orgId ? `&org_id=${encodeURIComponent(orgId)}` : ''}`;\n\n if (multiSelect) {\n const isAlreadySelected = internalSelectedApps.some((a) => a.objectID === app.objectID);\n const newSelection = isAlreadySelected\n ? internalSelectedApps.filter((a) => a.objectID !== app.objectID)\n : [...internalSelectedApps, app];\n\n setInternalSelectedApps(newSelection);\n onSelectionChange?.(newSelection);\n } else {\n // If consumer wired up onAppSelected, defer entirely to them.\n if (onAppSelected) {\n onAppSelected({ app, authUrl });\n if (!preventDefault) {\n window.open(authUrl, '_blank');\n }\n } else if (!preventDefault) {\n // New default: open built-in side drawer with the app + its existing\n // authentications, instead of popping a new tab to shuffler.io.\n setDrawerApp(app);\n }\n\n setIsOpen(false);\n }\n }, [authToken, apiKey, apiBaseUrl, appAuthPath, orgId, multiSelect, internalSelectedApps, onAppSelected, onSelectionChange, preventDefault]);\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (!isOpen) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setSelectedIndex((prev) => Math.min(prev + 1, displayResults.length - 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n setSelectedIndex((prev) => Math.max(prev - 1, -1));\n break;\n case 'Enter':\n event.preventDefault();\n if (selectedIndex >= 0 && displayResults[selectedIndex]) {\n selectApp(displayResults[selectedIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n setIsOpen(false);\n setSelectedIndex(-1);\n inputRef.current?.blur();\n break;\n }\n }, [isOpen, results, selectedIndex, selectApp]);\n\n // Check if app is selected. Matches by objectID first, then falls back to\n // normalized name so callers can pre-select apps without knowing the\n // canonical Algolia objectID (e.g. AgentUI's chosenApps).\n const isAppSelected = useCallback((app: AlgoliaSearchApp) => {\n const norm = (s?: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const target = norm(app.name);\n return internalSelectedApps.some(\n (a) => a.objectID === app.objectID || (target && norm(a.name) === target),\n );\n }, [internalSelectedApps]);\n\n\n // Filter the user's private apps client-side by the current query.\n const filteredPrivateApps = useMemo(() => {\n if (privateApps.length === 0) return [];\n const q = query.trim().toLowerCase();\n if (!q) return privateApps;\n return privateApps.filter(a =>\n a.name.toLowerCase().includes(q) ||\n (a.description || '').toLowerCase().includes(q) ||\n (a.categories || []).some(c => c.toLowerCase().includes(q))\n );\n }, [privateApps, query]);\n\n // Merge private + public apps, apply source filter, prepend pinned, dedupe by name.\n const displayResults = useMemo(() => {\n const norm = (n: string) => (n || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n\n let merged: AlgoliaSearchApp[];\n if (sourceFilter === 'public') {\n merged = results;\n } else if (sourceFilter === 'private') {\n merged = filteredPrivateApps;\n } else if (sourceFilter === 'authenticated') {\n const privateNames = new Set(filteredPrivateApps.map(a => norm(a.name)));\n const publicOnly = results.filter(a => !privateNames.has(norm(a.name)));\n merged = [...filteredPrivateApps, ...publicOnly].filter(isAppConfigured);\n } else {\n // 'all' — private apps first (your own tools win), then public, deduped by name\n const privateNames = new Set(filteredPrivateApps.map(a => norm(a.name)));\n const publicOnly = results.filter(a => !privateNames.has(norm(a.name)));\n merged = [...filteredPrivateApps, ...publicOnly];\n }\n\n if (!pinnedApps || pinnedApps.length === 0) return merged;\n const pinnedNames = new Set(pinnedApps.map(a => norm(a.name)));\n return [...pinnedApps, ...merged.filter(a => !pinnedNames.has(norm(a.name)))];\n }, [pinnedApps, results, filteredPrivateApps, sourceFilter, isAppConfigured]);\n\n // Get grid columns style\n const getGridColumnsStyle = useMemo(() => {\n if (layout !== 'grid') return {};\n \n const cols = typeof gridColumns === 'number' ? gridColumns : gridColumns.md || 3;\n return { '--singul-grid-columns': cols } as React.CSSProperties;\n }, [layout, gridColumns]);\n\n // Render individual app item\n const renderAppItem = (app: AlgoliaSearchApp, index: number) => {\n const selected = isAppSelected(app);\n const isHighlighted = index === selectedIndex;\n const authState = getAppAuthState(app);\n\n // Use custom render if provided\n if (renderItem) {\n return (\n <div\n key={app.objectID}\n onClick={() => selectApp(app)}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {renderItem(app, selected, () => selectApp(app), authState)}\n </div>\n );\n }\n\n // Show both chips (configured/not configured AND tested/not tested)\n return (\n <div\n key={app.objectID}\n className={`singul-dropdown-item ${selected ? 'singul-selected' : ''} ${authState.validated ? 'singul-validated' : ''} ${authState.configured ? 'singul-configured' : ''}`}\n data-app-name={app.name}\n data-object-id={app.objectID}\n style={{\n ...customStyles.dropdownItem,\n ...(selected ? customStyles.selectedItem : {}),\n }}\n onClick={() => selectApp(app)}\n >\n <div className=\"singul-app-info\" style={customStyles.appInfo}>\n {app.image_url && (\n <div style={{ position: 'relative', flexShrink: 0 }}>\n <img\n src={app.image_url}\n alt={app.name}\n className=\"singul-app-icon\"\n style={customStyles.appIcon}\n />\n {/* Color-coded status dot: green=tested, yellow=configured, blue=activated/selected, gray=inactive */}\n {!hideAuthStatus && (\n <span\n className={`singul-status-dot ${\n authState.validated ? 'singul-dot-validated' :\n authState.configured ? 'singul-dot-configured' :\n selected ? 'singul-dot-activated' :\n 'singul-dot-inactive'\n }`}\n />\n )}\n </div>\n )}\n <div className=\"singul-app-details\" style={customStyles.appDetails}>\n <span className=\"singul-app-name\" style={customStyles.appName}>\n {app.name.replace(/_/g, ' ')}\n {app.source === 'private' && (\n <Tooltip\n title=\"Private apps are apps you have activated in your organization, or your own custom apps — not just from the public Algolia catalog.\"\n arrow\n enterDelay={100}\n enterNextDelay={100}\n placement=\"top\"\n slotProps={{ popper: { style: { zIndex: 10000 } } }}\n >\n <span className=\"singul-private-badge\">Private</span>\n </Tooltip>\n )}\n </span>\n {showDescription && app.description && (\n <span className=\"singul-app-description\" style={customStyles.appDescription}>\n {app.description}\n </span>\n )}\n {showCategories && app.categories?.[0] && (\n <span className=\"singul-app-category\" style={customStyles.appCategory}>\n {app.categories[0]}\n </span>\n )}\n </div>\n {showCheckbox && (\n <div\n className={`singul-checkbox ${selected ? 'singul-checked' : ''}`}\n style={selected ? customStyles.checkboxChecked : customStyles.checkbox}\n >\n {selected && (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )}\n </div>\n )}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={containerRef}\n className={`singul-container ${inline ? 'singul-inline' : ''} ${className}`}\n style={customStyles.container}\n >\n <div className=\"singul-search-bar-container\">\n <div className=\"singul-search-input-wrapper\" style={customStyles.inputWrapper}>\n <input\n ref={inputRef}\n type=\"text\"\n className=\"singul-search-input\"\n style={customStyles.input}\n placeholder={placeholder}\n value={query}\n onChange={handleInputChange}\n onFocus={() => {\n if (!inline && query.trim() && results.length > 0) {\n setIsOpen(true);\n }\n }}\n onKeyDown={handleKeyDown}\n autoComplete=\"off\"\n />\n <div className=\"singul-search-icon\" style={customStyles.searchIcon}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </svg>\n </div>\n {isLoading && (\n <div className=\"singul-loading-spinner\" style={customStyles.loadingSpinner}>\n {renderLoadingState ? (\n renderLoadingState()\n ) : (\n <div className=\"singul-spinner\" style={customStyles.spinner} />\n )}\n </div>\n )}\n </div>\n\n {/* Source filter — only shown when private apps are loaded */}\n {showSourceFilter && privateApps.length > 0 && (\n <div className=\"singul-source-filter\" role=\"tablist\" aria-label=\"Filter by app source\">\n {([\n { key: 'all', label: 'All', count: results.length + filteredPrivateApps.length, title: 'All available apps — both the public catalog and your private apps.' },\n { key: 'public', label: 'Public', count: results.length, title: 'Public apps from the Shuffle catalog (powered by Algolia).' },\n { key: 'private', label: 'Private', count: filteredPrivateApps.length, title: 'Private apps are apps you have activated in your organization, or your own custom apps — not just from the public Algolia catalog.' },\n { key: 'authenticated', label: 'Authenticated', count: [...filteredPrivateApps, ...results].filter((a, i, arr) => arr.findIndex(x => x.name?.toLowerCase() === a.name?.toLowerCase()) === i).filter(isAppConfigured).length, title: 'Apps you have authenticated and that are ready to use.' },\n ] as const).map(opt => (\n <Tooltip\n key={opt.key}\n title={opt.title}\n arrow\n enterDelay={100}\n enterNextDelay={100}\n placement=\"top\"\n slotProps={{ popper: { style: { zIndex: 10000 } } }}\n >\n <span style={{ display: 'inline-flex' }}>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={sourceFilter === opt.key}\n className={`singul-source-pill ${sourceFilter === opt.key ? 'singul-source-pill-active' : ''}`}\n onClick={() => setSourceFilter(opt.key)}\n >\n {opt.label}\n <span className=\"singul-source-count\">{opt.count}</span>\n </button>\n </span>\n </Tooltip>\n ))}\n </div>\n )}\n\n {/* Inline Results Container */}\n {inline && (\n <div\n className={`singul-results-container ${layout === 'grid' ? 'singul-results-grid' : ''}`}\n style={{\n ...customStyles.resultsContainer,\n ...getGridColumnsStyle,\n ...(layout === 'grid' ? { display: 'grid' } : {}),\n }}\n >\n {displayResults.length > 0 ? (\n <>\n {displayResults.map((app, index) => renderAppItem(app, index))}\n <div className=\"singul-end-of-results\" style={{\n padding: '10px 16px',\n color: 'hsl(var(--foreground) / 0.3)',\n textAlign: 'center' as const,\n fontSize: '11px',\n gridColumn: '1 / -1',\n }}>\n Can't find what you're looking for? Try a different search term.\n </div>\n </>\n ) : query.trim() ? (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n {renderEmptyState ? (\n renderEmptyState()\n ) : (\n <>No integrations match \"{query}\". Try searching for a different app or category.</>\n )}\n </div>\n ) : (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n Start typing to search integrations...\n </div>\n )}\n </div>\n )}\n\n {/* Dropdown Results (non-inline mode) */}\n {!inline && isOpen && (\n <div\n className={`singul-dropdown ${layout === 'grid' ? 'singul-dropdown-grid' : ''}`}\n style={{\n ...customStyles.dropdown,\n ...getGridColumnsStyle,\n ...(layout === 'grid' ? { display: 'grid' } : {}),\n }}\n >\n {displayResults.length > 0 ? (\n displayResults.map((app, index) => renderAppItem(app, index))\n ) : (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n {renderEmptyState ? (\n renderEmptyState()\n ) : (\n <>No apps found for \"{query}\"</>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Built-in app config drawer — same drawer used by /incidents Add ingestion source */}\n {drawerApp && (\n <AppDetailDrawer\n open={true}\n appName={drawerApp.name}\n anchor=\"right\"\n width={560}\n onClose={() => setDrawerApp(null)}\n onRefresh={fetchAuthenticatedApps}\n />\n )}\n </div>\n );\n});\n\nShuffleMCP.displayName = 'ShuffleMCP';\n\nexport default ShuffleMCP;\n","/**\n * AppDetailDrawer — Shows app detail content (header, auth, MCP chat, API viewer)\n * inside a drawer. Used from alluvial diagrams and the app search drawer.\n *\n * Accepts either an app name (fetches data) or pre-loaded app info.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport { Download, Forward } from 'lucide-react';\nimport { getDatastoreByCategory, DATASTORE_CATEGORIES } from '@/Shuffle-MCPs/datastore';\nimport {\n Box,\n Typography,\n Avatar,\n Chip,\n IconButton,\n Skeleton,\n Button,\n Divider,\n Drawer,\n Autocomplete,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n} from '@mui/material';\nimport CloseIcon from '@mui/icons-material/Close';\nimport PlayArrowIcon from '@mui/icons-material/PlayArrow';\nimport CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { motion } from 'framer-motion';\nimport { AppAuthCard } from '@/Shuffle-MCPs/AppAuthConfig';\nimport AppMcpChat from '@/Shuffle-MCPs/AppMcpChat';\nimport ApiCallViewer from '@/Shuffle-MCPs/ApiCallViewer';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\nimport { useAppAuth } from '@/Shuffle-MCPs/useAppAuth';\nimport { API_CONFIG, getApiUrl, getAuthHeader, getTrackedOrgId } from '@/Shuffle-MCPs/api';\nimport { fetchAppsViaApiConfig } from '@/Shuffle-MCPs/appsCache';\nimport AppTitleHeader from './AppTitleHeader';\nimport AppAuthSection from './AppAuthSection';\nimport TryMcpSection from './TryMcpSection';\nimport SingulActionsPreview from './SingulActionsPreview';\n// AuthContext detached — consumers can pass `isAuthenticated` as a prop. Defaults to true.\n\ninterface AppInfo {\n name: string;\n description: string;\n large_image?: string;\n categories?: string[];\n authentication?: {\n type?: string;\n parameters?: { id: string; name: string; description: string; example: string; required: boolean }[];\n };\n}\n\n/** Collapsible markdown description */\nconst CollapsibleDescription = ({ description }: { description: string }) => {\n const [expanded, setExpanded] = useState(false);\n return (\n <Box\n onClick={() => setExpanded(prev => !prev)}\n sx={{\n cursor: 'pointer',\n position: 'relative',\n ...(!expanded && {\n maxHeight: '5em',\n overflow: 'hidden',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: 32,\n background: 'linear-gradient(transparent, hsl(var(--card)))',\n pointerEvents: 'none',\n },\n }),\n '& p': { fontSize: '0.78rem', lineHeight: 1.5, color: 'hsl(var(--muted-foreground))', m: 0, '&:not(:last-child)': { mb: 1 } },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': { fontSize: '0.7rem', fontFamily: \"'JetBrains Mono', monospace\", bgcolor: 'hsl(var(--muted))', px: 0.5, borderRadius: 0.5 },\n '& ul, & ol': { pl: 2, fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{description}</ReactMarkdown>\n {!expanded && (\n <Typography sx={{ fontSize: '0.68rem', color: 'hsl(var(--primary))', mt: 0.5, fontWeight: 500 }}>Show more…</Typography>\n )}\n </Box>\n );\n};\n\n/**\n * Singul standard actions catalog, keyed by lowercase category fragment.\n * Mirrors the canonical action names exposed by https://singul.io —\n * each name becomes the `{action}` segment in `POST /api/{action}`.\n * Fields shown here are starter parameters; the full schema lives on\n * the Singul side and is editable in the curl preview below.\n */\n\ninterface AppDetailDrawerProps {\n open: boolean;\n onClose: () => void;\n /** App name to load */\n appName: string | null;\n /** Pre-resolved Algolia objectID — bypasses Algolia lookup when provided (e.g. when the\n * caller already had the hit, like AppSearchDrawer / \"Add Ingestion Source\"). */\n appId?: string | null;\n /** Anchor side */\n anchor?: 'left' | 'right';\n /** Width in px */\n width?: number;\n /** Called when drawer closes so parent can refresh data */\n onRefresh?: () => void;\n /** When set, replaces the Activate button with \"+ Add\" and calls this on click */\n onAddToCanvas?: (appInfo: { name: string; icon: string; algoliaId: string | null }) => void;\n /** Whether the current user is authenticated. Defaults to true. */\n isAuthenticated?: boolean;\n /** Host app's currently active org id. If different from the library's tracked org,\n * an `Org-Id` header is injected into the Singul curl preview. */\n activeOrgId?: string | null;\n}\n\nexport default function AppDetailDrawer({\n open,\n onClose,\n appName,\n appId,\n anchor = 'right',\n width = 520,\n onRefresh,\n onAddToCanvas,\n isAuthenticated = true,\n activeOrgId,\n}: AppDetailDrawerProps) {\n const [appInfo, setAppInfo] = useState<AppInfo | null>(null);\n const [appLoading, setAppLoading] = useState(false);\n const [isActivated, setIsActivated] = useState<boolean | null>(null);\n const [activatedAppId, setActivatedAppId] = useState<string | null>(null);\n const [activateLoading, setActivateLoading] = useState(false);\n const [resolvedAlgoliaId, setResolvedAlgoliaId] = useState<string | null>(null);\n const [authExpanded, setAuthExpanded] = useState(true);\n // Auto-collapse Authentication section when a valid auth exists; expand otherwise.\n // Only fires when validity flips, so user manual toggles are preserved.\n const lastValidAuthRef = useRef<boolean | null>(null);\n const [incidentStats, setIncidentStats] = useState<{ ingested: number; forwarded: number } | null>(null);\n\n const {\n authStates,\n authenticatedApps,\n loading: appAuthLoading,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n } = useAppAuth();\n\n // Fetch app info and refresh auth when opened with a new app\n useEffect(() => {\n if (!open || !appName) return;\n setAppLoading(true);\n setAppInfo(null);\n setIsActivated(null);\n // Seed from caller-provided id (e.g. AppSearchDrawer already has the Algolia hit)\n setResolvedAlgoliaId(appId || null);\n // Always refresh auth when opening a different app\n refreshAuth();\n\n const normalizedName = appName.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n const searchName = appName.replace(/_/g, ' ');\n\n (async () => {\n // Algolia lookup — also runs when caller passed an appId, so we still get\n // the image/description/categories that the caller didn't have.\n let algoliaId: string | null = appId || null;\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const res = await client.search({\n requests: [{ indexName: 'appsearch', query: searchName, hitsPerPage: 10 }],\n });\n const hits = (res as any)?.results?.[0]?.hits || [];\n const match =\n (algoliaId && hits.find((h: any) => h.objectID === algoliaId)) ||\n hits.find((h: any) =>\n h.name?.toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName\n ) ||\n (hits.length > 0 ? hits[0] : null);\n\n if (match) {\n if (!algoliaId) {\n algoliaId = match.objectID;\n setResolvedAlgoliaId(algoliaId);\n }\n setAppInfo({\n name: match.name || searchName,\n description: match.description || '',\n large_image: match.image_url || '',\n categories: match.categories || [],\n });\n }\n } catch {}\n\n // Fallback: if Algolia didn't resolve an id, look it up via /api/v1/apps\n // This also doubles as our activation check below.\n let appsList: any[] | null = null;\n if (API_CONFIG.apiKey) {\n try {\n const apps = await fetchAppsViaApiConfig();\n if (Array.isArray(apps)) appsList = apps;\n } catch {}\n }\n\n if (!algoliaId && appsList) {\n const localMatch = appsList.find((a: any) =>\n (a.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName\n );\n if (localMatch?.id) {\n algoliaId = localMatch.id;\n setResolvedAlgoliaId(localMatch.id);\n setAppInfo(prev => prev ?? {\n name: localMatch.name || searchName,\n description: localMatch.description || '',\n large_image: localMatch.large_image || '',\n categories: localMatch.categories || [],\n authentication: localMatch.authentication,\n });\n }\n }\n\n // Config API — only available when we have an id\n if (API_CONFIG.apiKey && algoliaId) {\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(algoliaId)}/config`),\n { credentials: 'include', headers: { ...getAuthHeader() } }\n );\n if (response.ok) {\n const data = await response.json();\n if (data?.name) {\n setAppInfo(prev => ({ ...prev, ...data, large_image: data.large_image || prev?.large_image || '' }));\n }\n }\n } catch {}\n }\n\n // Activation status from the same /api/v1/apps response\n if (appsList) {\n const activeMatch = appsList.find((a: any) =>\n (a.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName && a.activated\n );\n setIsActivated(!!activeMatch);\n setActivatedAppId(activeMatch?.id || null);\n } else {\n setIsActivated(false);\n }\n\n // Last-resort: if we still have no appInfo, seed from the name so the drawer renders\n setAppInfo(prev => prev ?? {\n name: searchName,\n description: '',\n large_image: '',\n categories: [],\n });\n\n setAppLoading(false);\n })();\n }, [open, appName, appId]);\n\n // Fetch incident stats for this app\n useEffect(() => {\n if (!open || !appName || !isAuthenticated) {\n setIncidentStats(null);\n return;\n }\n\n (async () => {\n try {\n const result = await getDatastoreByCategory(DATASTORE_CATEGORIES.INCIDENTS);\n if (!result.success || !result.data) {\n setIncidentStats({ ingested: 0, forwarded: 0 });\n return;\n }\n\n const normalizedAppName = appName.toLowerCase().replace(/[\\s_\\-]+/g, '');\n let ingested = 0;\n let forwarded = 0;\n\n for (const item of result.data) {\n try {\n const parsed = JSON.parse(item.value);\n const productName = (parsed.metadata?.product?.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n if (productName && productName === normalizedAppName) {\n ingested++;\n }\n // Check if forwarded to this app (via finding_info dest or similar)\n const forwardDest = (parsed.metadata?.product?.forward_name || parsed.forward_target || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n if (forwardDest && forwardDest === normalizedAppName) {\n forwarded++;\n }\n } catch {}\n }\n\n setIncidentStats({ ingested, forwarded });\n } catch {\n setIncidentStats({ ingested: 0, forwarded: 0 });\n }\n })();\n }, [open, appName, isAuthenticated]);\n\n const handleClose = () => {\n onRefresh?.();\n onClose();\n };\n\n // Matching auth entries\n const matchingEntries = useMemo(() => {\n if (!appName || !isAuthenticated) return [];\n return authenticatedApps.filter(\n auth => auth.app?.name?.toLowerCase().replace(/[\\s_\\-]+/g, '_') === appName.toLowerCase().replace(/[\\s_\\-]+/g, '_')\n );\n }, [appName, authenticatedApps, isAuthenticated]);\n\n const resolvedImage = useMemo(() => {\n if (appInfo?.large_image) return appInfo.large_image;\n for (const entry of matchingEntries) {\n const img = (entry as any).app?.large_image || (entry as any).large_image;\n if (img) return img;\n }\n return '';\n }, [appInfo, matchingEntries]);\n\n const algoliaApp: AlgoliaSearchApp | null = useMemo(() => {\n if (!appName) return null;\n return {\n objectID: resolvedAlgoliaId || appName,\n name: appName,\n image_url: resolvedImage,\n description: appInfo?.description || '',\n categories: appInfo?.categories || [],\n } as AlgoliaSearchApp;\n }, [appName, appInfo, resolvedImage, resolvedAlgoliaId]);\n\n const authState = authStates[appName || ''] || { systemId: appName || '', status: 'pending' as const, credentials: {} };\n const hasValidAuth = matchingEntries.some(e => e.validation?.valid === true);\n const hasAnyAuth = matchingEntries.length > 0;\n // If the app has any authentication entry, it must already exist in the\n // tenant — Shuffle does not allow auth on an un-activated app. Treat as\n // activated even if `/api/v1/apps` didn't surface an `activated:true` row\n // (name-mismatch / cache lag is common for renamed apps like \"Gmail\" vs\n // \"google_mail\"). This keeps the header from showing a stale \"Activate\"\n // button when the sidebar already shows the app as Verified.\n const effectiveActivated = isActivated === null\n ? (hasAnyAuth ? true : null)\n : (isActivated || hasAnyAuth);\n const authCount = matchingEntries.length;\n const displayName = (appInfo?.name || appName || '').replace(/_/g, ' ');\n\n // Auto-collapse when valid auth appears, auto-expand when it disappears.\n useEffect(() => {\n if (lastValidAuthRef.current === hasValidAuth) return;\n lastValidAuthRef.current = hasValidAuth;\n setAuthExpanded(!hasValidAuth);\n }, [hasValidAuth]);\n\n // Reset tracker when switching apps so the new app starts from current state.\n useEffect(() => {\n lastValidAuthRef.current = null;\n }, [appName]);\n\n const handleActivateToggle = async () => {\n if (!appName || activateLoading) return;\n const wasActivated = isActivated;\n const prevAppId = activatedAppId;\n setIsActivated(!wasActivated);\n setActivateLoading(true);\n try {\n if (wasActivated && prevAppId) {\n const res = await fetch(getApiUrl(`/api/v1/apps/${prevAppId}/deactivate`), {\n method: 'POST', credentials: 'include', headers: { ...getAuthHeader() },\n });\n if (!res.ok) throw new Error('Deactivate failed');\n setActivatedAppId(null);\n toast.success(`${displayName} deactivated`);\n } else {\n const appId = resolvedAlgoliaId;\n if (!appId) throw new Error('App ID not resolved yet');\n const activateRes = await fetch(getApiUrl(`/api/v1/apps/${appId}/activate`), {\n method: 'GET', credentials: 'include', headers: { ...getAuthHeader() },\n });\n if (!activateRes.ok) throw new Error(`Activate failed (${activateRes.status})`);\n setActivatedAppId(appId);\n toast.success(`${displayName} activated`);\n }\n } catch (err: any) {\n console.error('[Activate] Error:', err);\n toast.error(err?.message || 'Activation failed');\n setIsActivated(wasActivated);\n setActivatedAppId(prevAppId);\n } finally {\n setActivateLoading(false);\n }\n };\n\n const isLoadingAll = appLoading || (isAuthenticated && appAuthLoading);\n\n return (\n <Drawer\n anchor={anchor}\n open={open}\n onClose={handleClose}\n sx={{\n '& .MuiDrawer-paper': {\n width,\n maxWidth: '100vw',\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: anchor === 'right' ? '1px solid hsl(var(--border))' : 'none',\n borderRight: anchor === 'left' ? '1px solid hsl(var(--border))' : 'none',\n },\n }}\n >\n {/* Header bar */}\n <Box\n sx={{\n px: 3,\n py: 2,\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n }}\n >\n <Box sx={{ flex: 1 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', lineHeight: 1.2, textTransform: 'capitalize' }}>\n {isLoadingAll ? <Skeleton width={140} /> : displayName}\n </Typography>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.75rem' }}>\n App configuration\n </Typography>\n </Box>\n <IconButton\n size=\"small\"\n onClick={handleClose}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--foreground))' } }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n\n {/* Content */}\n <Box sx={{ flex: 1, overflowY: 'auto', p: 3 }}>\n {isLoadingAll ? (\n <Box>\n <Box sx={{ display: 'flex', gap: 2, mb: 3 }}>\n <Skeleton variant=\"circular\" width={56} height={56} />\n <Box sx={{ flex: 1 }}>\n <Skeleton width={180} height={28} />\n <Skeleton width={260} height={18} sx={{ mt: 0.5 }} />\n </Box>\n </Box>\n <Skeleton variant=\"rectangular\" height={160} sx={{ borderRadius: 2 }} />\n </Box>\n ) : (\n <>\n {/* App header */}\n <AppTitleHeader\n name={displayName}\n image={resolvedImage}\n hasValidAuth={hasValidAuth}\n hasAnyAuth={hasAnyAuth}\n isAuthenticated={isAuthenticated}\n categories={appInfo?.categories}\n isActivated={onAddToCanvas ? null : effectiveActivated}\n activateLoading={activateLoading}\n onActivateToggle={handleActivateToggle}\n onAdd={onAddToCanvas && appName ? () => {\n onAddToCanvas({ name: appName, icon: resolvedImage || '', algoliaId: resolvedAlgoliaId });\n onClose();\n } : undefined}\n />\n\n {/* Incident stats */}\n {isAuthenticated && incidentStats && incidentStats.ingested > 0 && (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.08 }}>\n <Box sx={{\n display: 'flex',\n gap: 2,\n mb: 3,\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--muted) / 0.3)',\n }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Download size={14} style={{ color: 'hsl(var(--primary))' }} />\n <Box>\n <Typography sx={{ fontSize: '1.1rem', fontWeight: 700, color: 'hsl(var(--foreground))', lineHeight: 1 }}>\n {incidentStats.ingested}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', fontWeight: 500 }}>\n Incidents ingested\n </Typography>\n </Box>\n </Box>\n {incidentStats.forwarded > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, ml: 2, pl: 2, borderLeft: '1px solid hsl(var(--border))' }}>\n <Forward size={14} style={{ color: 'hsl(var(--severity-low))' }} />\n <Box>\n <Typography sx={{ fontSize: '1.1rem', fontWeight: 700, color: 'hsl(var(--foreground))', lineHeight: 1 }}>\n {incidentStats.forwarded}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', fontWeight: 500 }}>\n Forwarded\n </Typography>\n </Box>\n </Box>\n )}\n </Box>\n </motion.div>\n )}\n\n {/* Authentication section */}\n <Box id=\"app-auth-section\">\n <AppAuthSection\n displayName={displayName}\n algoliaApp={algoliaApp}\n resolvedAlgoliaId={resolvedAlgoliaId}\n authState={authState}\n expanded={authExpanded}\n onToggle={() => setAuthExpanded(prev => !prev)}\n authCount={authCount}\n isAuthenticated={isAuthenticated}\n matchingEntries={matchingEntries}\n onAuthChange={handleAuthChange}\n onTestConnection={(appId, authId) => handleTestConnection(appName || appId, authId)}\n onSaveAuth={(appId, creds) => handleSaveAuth(appId, creds, appName || undefined)}\n onRefreshAuth={refreshAuth}\n />\n </Box>\n\n {/* MCP Chat + individual actions */}\n {isAuthenticated && (\n <>\n <TryMcpSection\n appName={appName || ''}\n appIcon={resolvedImage}\n appId={matchingEntries[0]?.app?.id || matchingEntries[0]?.id || appName || ''}\n categories={appInfo?.categories}\n />\n <SingulActionsPreview appName={appName || ''} appIcon={resolvedImage} categories={appInfo?.categories} activeOrgId={activeOrgId} />\n </>\n )}\n </>\n )}\n </Box>\n </Drawer>\n );\n}\n","/**\n * Tiny toast facade — library version. Mirrors the sonner-style surface\n * (`toast(...)`, `toast.success`, `toast.error`, `toast.info`, `toast.warning`)\n * plus the legacy `{ title, description, variant }` shape used elsewhere in\n * the host app. The host app can replace the impl via `setToastImpl()`.\n */\n\ntype Variant = 'default' | 'destructive' | 'success' | 'error' | 'info' | 'warning';\ntype ToastArg = string | { title?: string; description?: string; variant?: Variant };\ntype ToastOptions = { description?: string; [key: string]: unknown };\n\ntype ToastImpl = (arg: ToastArg, opts?: ToastOptions) => void;\n\nconst defaultImpl: ToastImpl = (arg, opts) => {\n const isObj = typeof arg === 'object' && arg !== null;\n const title = isObj ? arg.title : arg;\n const description = isObj ? arg.description : opts?.description;\n const variant: Variant = (isObj ? arg.variant : undefined) || 'default';\n const msg = [title, description].filter(Boolean).join(' — ');\n if (variant === 'destructive' || variant === 'error') console.error('[toast]', msg);\n else if (variant === 'warning') console.warn('[toast]', msg);\n else console.log('[toast]', msg);\n};\n\nlet _impl: ToastImpl = defaultImpl;\n\nexport function setToastImpl(fn: ToastImpl) {\n _impl = fn;\n}\n\ntype ToastApi = ((arg: ToastArg, opts?: ToastOptions) => void) & {\n success: (msg: string, opts?: ToastOptions) => void;\n error: (msg: string, opts?: ToastOptions) => void;\n info: (msg: string, opts?: ToastOptions) => void;\n warning: (msg: string, opts?: ToastOptions) => void;\n};\n\nconst base = ((arg: ToastArg, opts?: ToastOptions) => _impl(arg, opts)) as ToastApi;\nbase.success = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'success' }, opts);\nbase.error = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'destructive' }, opts);\nbase.info = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'info' }, opts);\nbase.warning = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'warning' }, opts);\n\nexport const toast: ToastApi = base;\n","/**\n * API Configuration\n * \n * Configure the base URL based on your deployment:\n * - Shuffle Cloud (EU): https://shuffler.io\n * - Shuffle Cloud (US): https://us.shuffler.io \n * - Self-hosted: Your own backend URL (e.g., https://shuffle.yourdomain.com)\n *\n * The region URL is dynamically resolved from /api/v1/getinfo's `region_url` field.\n * If the user switches orgs, it resets to the default until getinfo is called again.\n */\n\nconst DEV_BACKEND = 'https://tunnel.schemaless.org';\nconst PROD_BACKEND = 'https://shuffler.io';\n\n// Base URL for Shuffle Automation dashboard (used in tool switcher)\nexport const SHUFFLE_AUTOMATION_URL = 'https://shuffler.io/new-dashboard';\n\n// Known cloud domains that should always use shuffler.io as the default backend\nconst CLOUD_DOMAINS = ['security.shuffler.io', 'shutdown.no'];\n\n// Safely read Vite-style env vars without depending on `vite/client` types\n// (the published library should not require Vite to be installed).\nconst getEnvVar = (key: string): string | undefined => {\n try {\n const meta = import.meta as unknown as { env?: Record<string, string | undefined> };\n return meta?.env?.[key];\n } catch {\n return undefined;\n }\n};\n\n// Determine if we're in Lovable preview (dev) or published (prod)\nexport const isDevEnvironment = (): boolean => {\n if (getEnvVar('VITE_SHUFFLE_API_URL')) return false;\n const hostname = typeof window !== 'undefined' ? window.location.hostname : '';\n return hostname.includes('lovableproject.com') || hostname.includes('id-preview--');\n};\n\n/** Check if running on a known Shuffle Cloud domain */\nexport const isCloudDomain = (): boolean => {\n const hostname = typeof window !== 'undefined' ? window.location.hostname : '';\n return CLOUD_DOMAINS.includes(hostname);\n};\n\n/**\n * True when running on Shuffle Cloud (a known *.shuffler.io / shutdown.no domain).\n * Use this to gate cloud-only features like Google Analytics (ReactGA).\n *\n * isCloud() → cloud deployment, GA allowed, telemetry OK\n * !isCloud() → either Lovable preview (dev) OR self-hosted onprem; do NOT call GA\n */\nexport const isCloud = (): boolean => isCloudDomain();\n\n/**\n * True when running self-hosted (onprem) — i.e. NOT in Lovable preview AND NOT on a known cloud domain.\n */\nexport const isOnprem = (): boolean => !isDevEnvironment() && !isCloudDomain();\n\nconst getDefaultBaseUrl = (): string => {\n const envUrl = getEnvVar('VITE_SHUFFLE_API_URL');\n if (envUrl) {\n return envUrl;\n }\n if (isDevEnvironment()) return DEV_BACKEND;\n // Cloud domains always default to shuffler.io; region_url from getinfo may override later\n if (isCloudDomain()) return PROD_BACKEND;\n // Self-hosted / on-prem: use current domain (nginx proxies /api/* to backend)\n if (typeof window !== 'undefined') {\n return window.location.origin;\n }\n return PROD_BACKEND;\n};\n\n// Dynamic region URL state (only applies in production, not dev)\nlet _regionUrl: string | null = null;\nlet _trackedOrgId: string | null = null;\n\n/** Check if a URL is a valid shuffler.io subdomain */\nconst isShufflerSubdomain = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return parsed.hostname.endsWith('.shuffler.io') || parsed.hostname === 'shuffler.io';\n } catch {\n return false;\n }\n};\n\n/**\n * Set the dynamic region URL from getinfo response.\n * Only applies if the URL is a shuffler.io subdomain and different from default.\n */\nexport const setRegionUrl = (regionUrl: string | undefined | null, orgId: string | undefined | null) => {\n // In dev environments, don't override — always use dev backend\n if (isDevEnvironment()) {\n _trackedOrgId = orgId || null;\n return;\n }\n\n _trackedOrgId = orgId || null;\n\n if (regionUrl && isShufflerSubdomain(regionUrl)) {\n // Normalize: strip trailing slash\n const normalized = regionUrl.replace(/\\/+$/, '');\n if (normalized !== PROD_BACKEND) {\n _regionUrl = normalized;\n console.log(`[API] Region URL set to: ${_regionUrl}`);\n return;\n }\n }\n\n // No valid region override — use default\n _regionUrl = null;\n};\n\n/**\n * Called when org changes. Resets region URL to default until next getinfo.\n */\nexport const resetRegionUrl = () => {\n if (_regionUrl) {\n console.log(`[API] Region URL reset to default (org changed)`);\n }\n _regionUrl = null;\n};\n\n/** Get the currently tracked org ID */\nexport const getTrackedOrgId = (): string | null => _trackedOrgId;\n\nexport const API_CONFIG = {\n // Shuffle backend URL - uses region URL if set, otherwise default\n get baseUrl(): string {\n return _regionUrl || getDefaultBaseUrl();\n },\n \n // API version\n version: 'v1',\n \n // Get API key from localStorage (for local development)\n get apiKey(): string | null {\n return localStorage.getItem('shuffle_api_key');\n },\n \n // Set API key in localStorage\n setApiKey(key: string | null) {\n if (key) {\n localStorage.setItem('shuffle_api_key', key);\n } else {\n localStorage.removeItem('shuffle_api_key');\n }\n },\n};\n\n// Computed API endpoint - pass full path including /api/v1 or /api/v2\nexport const getApiUrl = (endpoint: string): string => {\n return `${API_CONFIG.baseUrl}${endpoint}`;\n};\n\n/**\n * Resolve an agent approval / form URL (typically `/forms/{id}`) to the\n * original Shuffle Core where the form actually lives. On Cloud this is\n * always https://shuffler.io (regardless of the active region URL — forms\n * are served from core), and onprem / dev fall back to the configured\n * backend baseUrl. Absolute URLs are returned unchanged.\n */\nexport const getShuffleCoreFormUrl = (refUrl: string): string => {\n if (!refUrl) return refUrl;\n // Already absolute — trust it.\n if (/^https?:\\/\\//i.test(refUrl)) return refUrl;\n const path = refUrl.startsWith('/') ? refUrl : `/${refUrl}`;\n // Cloud always points at shuffler.io for forms.\n if (isCloud()) return `https://shuffler.io${path}`;\n // Self-hosted / dev — use the active backend.\n return `${API_CONFIG.baseUrl}${path}`;\n};\n\n/** True when a notification.reference_url points at an agent approval form. */\nexport const isAgentApprovalFormUrl = (refUrl: string | undefined | null): boolean => {\n if (!refUrl) return false;\n try {\n // Strip an optional origin so we can match the path consistently.\n const path = /^https?:\\/\\//i.test(refUrl) ? new URL(refUrl).pathname : refUrl;\n return /^\\/forms\\/[^/?#]+/.test(path);\n } catch {\n return false;\n }\n};\n\n/**\n * Central fetch wrapper that ALWAYS includes credentials and auth headers.\n * Use this instead of raw fetch() for all Shuffle API calls.\n */\nexport const shuffleFetch = (url: string, init?: RequestInit): Promise<Response> => {\n const { headers: extraHeaders, ...rest } = init || {};\n return fetch(url, {\n credentials: 'include',\n ...rest,\n headers: {\n ...getAuthHeader(),\n ...extraHeaders,\n },\n });\n};\n\n// Common endpoints\nexport const API_ENDPOINTS = {\n login: '/login',\n logout: '/logout',\n me: '/me',\n getinfo: '/getinfo',\n alerts: '/alerts',\n cases: '/cases',\n workflows: '/workflows',\n apps: '/apps',\n};\n\n// Get authorization header - uses API key if available, otherwise session token.\n// Always scopes the request to the currently-active org via Org-Id when known,\n// so a user in a sub-org reads/writes against that sub-org rather than their\n// default home org. Pass `overrideOrgId` to force a different org (e.g. when\n// reading data from another tenant in a multi-tenant view).\nexport const getAuthHeader = (overrideOrgId?: string | null): Record<string, string> => {\n const headers: Record<string, string> = {};\n\n // Only send Authorization header for API key auth.\n // Session-based (cookie) auth is handled by credentials: 'include' — never both.\n const apiKey = API_CONFIG.apiKey;\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // Scope to the active org. Explicit override beats the tracked org.\n const orgId = overrideOrgId ?? _trackedOrgId;\n if (orgId) {\n headers['Org-Id'] = orgId;\n }\n\n return headers;\n};\n\n","/**\n * Shuffle Datastore Service\n * \n * Provides reusable functions for interacting with the Shuffle datastore API.\n * Uses the correct Shuffle cache API endpoints.\n */\n\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\nexport interface DatastoreItem {\n key: string;\n value: string;\n category: string;\n created?: number;\n edited?: number;\n public_authorization?: string;\n enrichments?: Array<{ type: string; value?: string; data?: string }>;\n}\n\nexport interface CategoryAutomation {\n id?: string;\n name: string;\n type?: 'workflow' | 'webhook' | 'ai_agent' | 'enrich' | 'send_message' | 'security_rules';\n trigger?: 'on_create' | 'on_edit' | 'on_delete';\n workflow_id?: string;\n webhook_url?: string;\n enabled: boolean;\n description?: string;\n options?: { key: string; value: string }[];\n}\n\nexport interface CategoryConfig {\n id: string;\n org_id: string;\n category: string;\n automations: CategoryAutomation[] | null;\n settings: {\n timeout: number;\n public: boolean;\n };\n}\n\nexport interface DatastoreResponse {\n success: boolean;\n data?: DatastoreItem[];\n categoryConfig?: CategoryConfig;\n cursor?: string;\n totalAmount?: number;\n error?: string;\n diagnostics?: DatastoreDiagnostics;\n}\n\nexport interface DatastoreDiagnostics {\n operation: string;\n category?: string;\n orgId?: string | null;\n url?: string;\n cursor?: string;\n status?: number;\n statusText?: string;\n contentType?: string | null;\n responseShape?: 'array' | 'keys' | 'data' | 'unknown';\n itemCount?: number;\n totalAmount?: number | null;\n bodyPreview?: string;\n errorStage?: 'request' | 'response' | 'parse' | 'unknown';\n timestamp: string;\n}\n\n/**\n * Runtime-injected active org ID. AuthContext sets this synchronously when\n * /api/v1/getinfo resolves, so callers don't need to wait for the\n * `shuffle_user_info` localStorage write to land. Falls back to localStorage\n * for cases where the service is imported before AuthContext mounts.\n */\nlet _runtimeOrgId: string | null = null;\n\nexport const setRuntimeOrgId = (orgId: string | null) => {\n _runtimeOrgId = orgId || null;\n};\n\n/**\n * Get current org ID. Prefers the runtime value set by AuthContext, then\n * falls back to localStorage so legacy callers keep working.\n */\nconst getOrgId = (): string | null => {\n if (_runtimeOrgId) return _runtimeOrgId;\n try {\n const userInfo = localStorage.getItem('shuffle_user_info');\n if (userInfo) {\n const parsed = JSON.parse(userInfo);\n return parsed.active_org?.id || null;\n }\n } catch {\n // Ignore parsing errors\n }\n return null;\n};\n\nconst normalizeDatastoreKey = (key: string): string => {\n if (!key?.includes('::')) return key;\n const parts = key.split('::').filter(Boolean);\n return parts.length > 0 ? parts[parts.length - 1] : key;\n};\n\nconst truncateResponsePreview = (value: string | null | undefined, maxLength = 280): string | undefined => {\n if (!value) return undefined;\n const normalized = value.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > maxLength ? `${normalized.slice(0, maxLength)}…` : normalized;\n};\n\n/**\n * Serialize a datastore value to a string for the API.\n * Validates JSON-shaped strings (parse+restringify) so we always send valid JSON.\n */\nconst serializeDatastoreValue = (value: unknown): string => {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.stringify(JSON.parse(trimmed));\n } catch {\n return value;\n }\n }\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\n\n/**\n * Set a single item in the datastore\n */\nexport const setDatastoreItem = async (\n key: string,\n value: string | object,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n // Use the v2 datastore endpoint as a single-item array. This is the same\n // endpoint the bulk writer uses; set_cache has been retired for incident\n // updates because it stringifies the payload differently and caused\n // double-encoded JSON to land in the datastore.\n const payload = [{\n key: rawKey,\n value: serializeDatastoreValue(value),\n category,\n // Incident category is governed by automation/security rules that would\n // otherwise reject programmatic edits — bypass them for our own writes.\n ...(category === 'shuffle-security_incidents' ? { ignore_security_rules: true } : {}),\n }];\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Org-Id': orgId,\n ...getAuthHeader(),\n };\n\n const response = await fetch(getApiUrl('/api/v2/datastore'), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n return { success: false, error: `Failed to set datastore item: ${response.statusText}` };\n }\n\n return { success: true };\n};\n\n/**\n * Set multiple items in the datastore (bulk create) using v2 API\n */\nexport const setDatastoreItems = async (\n items: { key: string; value: string | object }[],\n category: string\n): Promise<DatastoreResponse> => {\n const orgId = getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n // Use v2 API for bulk operations - send as array\n const payload = items.map(item => ({\n key: item.key,\n value: serializeDatastoreValue(item.value),\n category,\n ...(category === 'shuffle-security_incidents' ? { ignore_security_rules: true } : {}),\n }));\n\n const response = await fetch(getApiUrl('/api/v2/datastore'), {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'Org-Id': orgId,\n ...getAuthHeader(),\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const fallbackResults = await Promise.all(items.map(item =>\n setDatastoreItem(item.key, item.value, category)\n ));\n const failedWrites = fallbackResults.filter(result => !result.success);\n if (failedWrites.length > 0) {\n return {\n success: false,\n error: failedWrites[0]?.error || `Failed to set datastore items: ${response.statusText}`,\n };\n }\n return { success: true };\n }\n\n return { success: true };\n};\n\n/**\n * Get a single item from the datastore\n */\nexport const getDatastoreItem = async (\n key: string,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse & { item?: DatastoreItem }> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n const payload: Record<string, string> = {\n key: rawKey,\n org_id: orgId,\n };\n \n if (category) {\n payload.category = category;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n };\n if (overrideOrgId) {\n headers['Org-Id'] = overrideOrgId;\n }\n\n const response = await fetch(getApiUrl(`/api/v1/orgs/${orgId}/get_cache`), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n // 404 means key doesn't exist - not an error, just empty\n if (response.status === 404) {\n return { success: true, item: undefined };\n }\n return { success: false, error: `Failed to get datastore item: ${response.statusText}` };\n }\n\n const data = await response.json();\n \n // API returns success: false if key not found\n if (data.success === false && !data.value) {\n return { success: true, item: undefined };\n }\n \n return { success: true, item: data };\n};\n\n/**\n * Get a single item from the datastore using public authorization (no login required)\n */\nexport const getDatastoreItemPublic = async (\n key: string,\n orgId: string,\n authorization: string,\n): Promise<DatastoreResponse & { item?: DatastoreItem }> => {\n const response = await fetch(\n getApiUrl(`/api/v1/orgs/${orgId}/cache/${key}?authorization=${authorization}`),\n { method: 'GET' },\n );\n\n if (!response.ok) {\n if (response.status === 404) {\n return { success: true, item: undefined };\n }\n return { success: false, error: `Failed to get public datastore item: ${response.statusText}` };\n }\n\n const data = await response.json();\n if (data.success === false && !data.value) {\n return { success: true, item: undefined };\n }\n return { success: true, item: data };\n};\n\n/**\n * Try to extract valid datastore items from a response body string,\n * even if the HTTP status was non-2xx (some backend servers return 400 with valid data).\n */\nconst tryExtractItemsFromBody = (rawBody: string): { items: DatastoreItem[]; categoryConfig?: CategoryConfig; cursor?: string; totalAmount?: number; shape: DatastoreDiagnostics['responseShape'] } | null => {\n try {\n const data = rawBody ? JSON.parse(rawBody) : null;\n if (!data || typeof data !== 'object') return null;\n\n const items = Array.isArray(data) ? data : data.keys || data.data || [];\n if (!Array.isArray(items) || items.length === 0) return null;\n\n // Basic validation: at least one item should have a key\n if (!items.some((i: any) => i && typeof i === 'object' && typeof i.key === 'string')) return null;\n\n const shape: DatastoreDiagnostics['responseShape'] = Array.isArray(data)\n ? 'array'\n : Array.isArray(data?.keys) ? 'keys'\n : Array.isArray(data?.data) ? 'data'\n : 'unknown';\n\n return {\n items,\n categoryConfig: data.category_config,\n cursor: data.cursor,\n totalAmount: data.total_amount,\n shape,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Get all items in a category with optional cursor-based pagination\n */\nexport const getDatastoreByCategory = async (\n category: string,\n cursor?: string\n): Promise<DatastoreResponse> => {\n const orgId = getOrgId();\n if (!orgId) {\n return {\n success: false,\n error: 'No organization ID found',\n diagnostics: {\n operation: 'list',\n category,\n orgId: null,\n cursor,\n errorStage: 'request',\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n // Cap page size at 50 — large `top` values can blow up payloads (especially\n // for incidents). Pagination via cursor handles the rest.\n const limit = 50;\n let url = `/api/v1/orgs/${orgId}/list_cache?category=${encodeURIComponent(category)}&top=${limit}`;\n if (cursor) {\n url += `&cursor=${encodeURIComponent(cursor)}`;\n }\n\n const requestUrl = getApiUrl(url);\n const baseDiagnostics: DatastoreDiagnostics = {\n operation: 'list',\n category,\n orgId,\n url: requestUrl,\n cursor,\n timestamp: new Date().toISOString(),\n };\n\n let response: Response;\n\n try {\n response = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n } catch (error) {\n // Network error — retry once\n try {\n response = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n } catch (retryError) {\n return {\n success: false,\n error: retryError instanceof Error ? retryError.message : 'Failed to request datastore items',\n diagnostics: {\n ...baseDiagnostics,\n errorStage: 'request',\n },\n };\n }\n }\n\n const contentType = response.headers.get('content-type');\n const rawBody = await response.text();\n\n if (!response.ok) {\n // Some backend servers return 400 but still include valid data in the body.\n // Try to extract items before treating as a hard failure.\n const extracted = tryExtractItemsFromBody(rawBody);\n if (extracted && extracted.items.length > 0) {\n console.warn(`[Datastore] ${response.status} response for category=${category} but body contained ${extracted.items.length} valid items — treating as success`);\n return {\n success: true,\n data: extracted.items,\n categoryConfig: extracted.categoryConfig,\n cursor: extracted.cursor,\n totalAmount: extracted.totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n responseShape: extracted.shape,\n itemCount: extracted.items.length,\n totalAmount: extracted.totalAmount ?? null,\n },\n };\n }\n\n // No valid data in body — retry once for transient server errors\n if (response.status >= 400 && response.status < 500) {\n try {\n const retryResponse = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n const retryBody = await retryResponse.text();\n const retryExtracted = tryExtractItemsFromBody(retryBody);\n if (retryResponse.ok || (retryExtracted && retryExtracted.items.length > 0)) {\n const items = retryExtracted?.items || [];\n console.warn(`[Datastore] Retry succeeded for category=${category} (status=${retryResponse.status}, items=${items.length})`);\n return {\n success: true,\n data: items,\n categoryConfig: retryExtracted?.categoryConfig,\n cursor: retryExtracted?.cursor,\n totalAmount: retryExtracted?.totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: retryResponse.status,\n statusText: retryResponse.statusText,\n contentType: retryResponse.headers.get('content-type'),\n responseShape: retryExtracted?.shape || 'unknown',\n itemCount: items.length,\n totalAmount: retryExtracted?.totalAmount ?? null,\n },\n };\n }\n } catch { /* retry failed, fall through to error */ }\n }\n\n return {\n success: false,\n error: `Failed to get datastore items: ${response.status} ${response.statusText}`.trim(),\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n bodyPreview: truncateResponsePreview(rawBody),\n errorStage: 'response',\n },\n };\n }\n\n try {\n const data = rawBody ? JSON.parse(rawBody) : {};\n const responseShape: DatastoreDiagnostics['responseShape'] = Array.isArray(data)\n ? 'array'\n : Array.isArray(data?.keys)\n ? 'keys'\n : Array.isArray(data?.data)\n ? 'data'\n : 'unknown';\n const items = Array.isArray(data) ? data : data.keys || data.data || [];\n const totalAmount = data.total_amount ?? data.total ?? data.amount;\n\n return {\n success: true,\n data: items,\n categoryConfig: data.category_config,\n cursor: data.cursor,\n totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n responseShape,\n itemCount: Array.isArray(items) ? items.length : 0,\n totalAmount: totalAmount ?? null,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? `Failed to parse datastore response: ${error.message}` : 'Failed to parse datastore response',\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n bodyPreview: truncateResponsePreview(rawBody),\n errorStage: 'parse',\n },\n };\n }\n};\n\n/**\n * Delete a single item from the datastore\n */\nexport const deleteDatastoreItem = async (\n key: string,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n const payload: Record<string, string> = {\n key: rawKey,\n org_id: orgId,\n };\n \n if (category) {\n payload.category = category;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n };\n if (overrideOrgId) {\n headers['Org-Id'] = overrideOrgId;\n }\n\n const response = await fetch(getApiUrl(`/api/v1/orgs/${orgId}/delete_cache`), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n return { success: false, error: `Failed to delete datastore item: ${response.statusText}` };\n }\n\n return { success: true };\n};\n\n/**\n * Delete multiple items from the datastore (bulk delete)\n */\nexport const deleteDatastoreItems = async (\n keys: string[],\n category: string\n): Promise<{ success: boolean; deleted: number; failed: string[]; error?: string }> => {\n const orgId = getOrgId();\n if (!orgId) {\n return { success: false, deleted: 0, failed: keys, error: 'No organization ID found' };\n }\n\n const results = await Promise.allSettled(\n keys.map(key => deleteDatastoreItem(key, category))\n );\n\n const failed: string[] = [];\n let deleted = 0;\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled' && result.value.success) {\n deleted++;\n } else {\n failed.push(keys[index]);\n }\n });\n\n return {\n success: failed.length === 0,\n deleted,\n failed,\n };\n};\n\n// Category constants for consistency\nexport const DATASTORE_CATEGORIES = {\n INCIDENTS: 'shuffle-security_incidents',\n ASSETS: 'shuffle-security_assets',\n TEMPLATES: 'shuffle-security_templates',\n CONFIGURATION: 'shuffle-security_configuration',\n IOCS: 'shuffle-security_ioc-config',\n CUSTOM_FIELDS: 'shuffle-security_custom-fields',\n THREAT_FEEDS: 'shuffle-security_threat-feeds',\n INFRASTRUCTURE: 'shuffle-security_infrastructure',\n USERS: 'shuffle-security_users',\n REPORTS: 'shuffle-security_reports',\n // Legacy - for migration purposes\n LEGACY_ALERTS: 'shuffle-security_alerts',\n LEGACY_CASES: 'shuffle-security_cases',\n} as const;\n","import { useState, useCallback, useEffect } from 'react';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport type { AppAuthState, AuthStatus, ApiAuthEntry } from '@/Shuffle-MCPs/AppAuthConfig';\nimport { refreshAllIntegrationStatus } from '@/Shuffle-MCPs/IntegrationStatus';\n\n// Helper to process auth data and invalidate entries older than 30 days\nconst processAuthData = (authData: ApiAuthEntry[]): ApiAuthEntry[] => {\n const thirtyDaysAgoMs = Date.now() - (30 * 24 * 60 * 60 * 1000);\n \n return authData.map(entry => {\n if (entry.validation?.valid === true && entry.validation?.last_valid) {\n const lastValidMs = entry.validation.last_valid > 1e12 \n ? entry.validation.last_valid \n : entry.validation.last_valid * 1000;\n \n if (lastValidMs < thirtyDaysAgoMs) {\n return {\n ...entry,\n validation: {\n ...entry.validation,\n valid: false,\n error: 'Validation expired (older than 30 days)',\n },\n };\n }\n }\n return entry;\n });\n};\n\n// Human-readable error descriptions for HTTP status codes\nconst getStatusDescription = (status: number | string): string => {\n const statusDescriptions: Record<number, string> = {\n 400: 'Bad Request – The request was malformed or missing required parameters',\n 401: 'Unauthorized – Invalid or expired API key/credentials',\n 403: 'Forbidden – Access denied. Check your permissions',\n 404: 'Not Found – The API endpoint or resource doesn\\'t exist',\n 429: 'Too Many Requests – Rate limit exceeded. Try again later',\n 500: 'Internal Server Error – Something went wrong on the server',\n 502: 'Bad Gateway – The server received an invalid response',\n 503: 'Service Unavailable – The service is temporarily down',\n };\n const num = Number(status);\n if (statusDescriptions[num]) return statusDescriptions[num];\n if (num >= 400 && num < 500) return 'Client Error – Check your request parameters';\n if (num >= 500 && num < 600) return 'Server Error – The remote service may be unavailable';\n return '';\n};\n\nconst parseResultData = (data: any) => {\n const rawData = data.result || data.raw_response;\n if (!rawData) return null;\n try {\n return typeof rawData === 'string' ? JSON.parse(rawData) : rawData;\n } catch {\n return null;\n }\n};\n\nexport function useAppAuth() {\n const [authStates, setAuthStates] = useState<Record<string, AppAuthState>>({});\n const [authenticatedApps, setAuthenticatedApps] = useState<ApiAuthEntry[]>([]);\n const [loading, setLoading] = useState(true);\n\n // Load authenticated apps on mount\n const fetchAuthenticatedApps = useCallback(async () => {\n \n try {\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers: { ...getAuthHeader() },\n });\n if (response.ok) {\n const result = await response.json();\n const authData = result.data || result;\n if (Array.isArray(authData)) {\n setAuthenticatedApps(processAuthData(authData));\n }\n }\n } catch (error) {\n console.error('Failed to fetch auth data:', error);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchAuthenticatedApps();\n }, [fetchAuthenticatedApps]);\n\n const handleAuthChange = useCallback((systemId: string, credentials: Record<string, string>) => {\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n systemId,\n status: 'pending' as AuthStatus,\n credentials,\n },\n }));\n }, []);\n\n const handleTestConnection = useCallback(async (systemId: string, authenticationId?: string) => {\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n status: 'testing' as AuthStatus,\n credentials: prev[systemId]?.credentials || {},\n },\n }));\n\n try {\n const requestBody: Record<string, string | boolean> = {\n action: 'test_api',\n app: systemId,\n skip_workflow: true,\n };\n \n if (authenticationId) {\n requestBody.authentication_id = authenticationId;\n }\n\n const response = await fetch(getApiUrl('/api/v1/apps/categories/run'), {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n 'Accept-Encoding': 'identity',\n },\n body: JSON.stringify(requestBody),\n });\n\n const result = await response.json();\n \n let isValid = false;\n let errorMessage = 'Failed to connect. Please check your credentials.';\n let successMessage = '';\n let warningMessage = '';\n let errorCode: number | undefined;\n let workflowId = result.workflow_id || '';\n let executionId = result.execution_id || '';\n\n const validActions = ['done', 'app_validation'];\n if (response.ok && validActions.includes(result.action) && result.success === true) {\n try {\n const resultData = parseResultData(result);\n \n const hasErrorInBody = resultData && (\n resultData.error !== undefined || \n resultData.ok === false\n );\n \n if (hasErrorInBody) {\n const errorDetail = resultData.error || resultData.reason || 'unknown error';\n isValid = true;\n successMessage = `Connection likely working, but API returned: ${typeof errorDetail === 'string' ? errorDetail : JSON.stringify(errorDetail)}`;\n warningMessage = 'The API responded but included an error field.';\n } else if (resultData && resultData.status) {\n const parsedStatus = resultData.status;\n const statusLower = String(parsedStatus).toLowerCase();\n const statusNum = Number(parsedStatus);\n\n const isErrorStatus = (statusNum >= 400 && statusNum < 600) ||\n statusLower === 'error' || statusLower === 'failed' ||\n statusLower === 'unauthorized' || statusLower === 'forbidden';\n \n if (statusNum === 401 || statusNum === 403 || statusLower === 'unauthorized' || statusLower === 'forbidden') {\n errorCode = statusNum || 401;\n }\n \n const isGoodStatus = !isErrorStatus && (\n statusLower === 'ok' || statusLower === 'success' || statusLower === 'healthy' ||\n statusLower === 'connected' || statusLower === '200' || statusNum === 200\n );\n \n if (isErrorStatus) {\n const statusDesc = getStatusDescription(parsedStatus);\n const reason = resultData.reason ? ` • ${resultData.reason}` : '';\n errorMessage = statusDesc ? `${statusDesc}${reason}` : `Connection failed • Status: ${parsedStatus}${reason}`;\n } else if (isGoodStatus) {\n isValid = true;\n successMessage = `Connection verified • Status: ${parsedStatus}`;\n } else {\n const statusDesc = getStatusDescription(parsedStatus);\n errorMessage = statusDesc || `Connection failed • Unexpected status: ${parsedStatus}`;\n }\n } else if (resultData?.success !== undefined) {\n if (resultData.success === true) {\n isValid = true;\n successMessage = 'Connection verified';\n } else {\n errorMessage = resultData.reason || 'Connection failed';\n }\n }\n } catch {\n errorMessage = 'Connection failed – Unable to parse response.';\n }\n } else if (result.status !== undefined) {\n const statusDesc = getStatusDescription(result.status);\n errorMessage = statusDesc || `Connection failed • Status: ${result.status}`;\n const sn = Number(result.status);\n if (sn === 401 || sn === 403) errorCode = sn;\n }\n\n // Refresh auth list & notify all IntegrationStatus instances\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n credentials: prev[systemId]?.credentials || {},\n status: isValid ? 'connected' : 'error',\n errorMessage: isValid ? undefined : errorMessage,\n successMessage: isValid ? (successMessage || 'Connection verified') : undefined,\n warningMessage: isValid ? warningMessage : undefined,\n workflowId: isValid ? undefined : workflowId,\n executionId: isValid ? undefined : executionId,\n errorCode: isValid ? undefined : errorCode,\n },\n }));\n } catch (error) {\n await new Promise(resolve => setTimeout(resolve, 3000));\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n credentials: prev[systemId]?.credentials || {},\n status: 'error',\n errorMessage: error instanceof Error ? error.message : 'Connection test failed.',\n },\n }));\n }\n }, [fetchAuthenticatedApps]);\n\n const handleSaveAuth = useCallback(async (appId: string, credentials: Record<string, string>, appName?: string): Promise<boolean> => {\n const fields = Object.entries(credentials)\n .filter(([key, value]) => key?.trim() && value?.trim())\n .map(([key, value]) => ({ key, value }));\n\n const payload = {\n label: `Auth for ${(appName || appId).replace(/_/g, ' ')}`,\n app: {\n name: appName || appId,\n id: appId,\n app_version: '1.0.0',\n },\n fields,\n active: true,\n };\n\n try {\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n method: 'PUT',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (response.ok) {\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n return true;\n }\n return false;\n } catch (error) {\n console.error('Failed to save authentication:', error);\n return false;\n }\n }, [fetchAuthenticatedApps]);\n\n return {\n authStates,\n authenticatedApps,\n loading,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth: fetchAuthenticatedApps,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport {\n Box,\n Typography,\n Tooltip,\n IconButton,\n Avatar,\n CircularProgress,\n} from '@mui/material';\nimport AddIcon from '@mui/icons-material/Add';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport { fetchAuthenticatedApps } from '@/Shuffle-MCPs/authenticatedApps';\nimport { fetchAppsViaApiConfig as fetchApps } from '@/Shuffle-MCPs/appsCache';\nimport { deduplicateAuthApps, backfillAppImages, type AuthAppEntry } from '@/Shuffle-MCPs/auth-utils';\nimport { useAppDetailOptional } from '@/Shuffle-MCPs/AppDetailContext';\nimport { SIEM_PATTERNS, CASES_PATTERNS, EDR_PATTERNS, EMAIL_APP_PATTERNS } from '@/Shuffle-MCPs/ingestionDetection';\n\ninterface Integration {\n id: string;\n name: string;\n icon: string;\n category: string;\n hasValidAuth: boolean;\n authInstances: { label: string; isValidated: boolean }[];\n isActiveOnly?: boolean;\n}\n\ninterface IntegrationStatusProps {\n collapsed: boolean;\n /** When provided, only show integrations whose name is in this list */\n filterApps?: string[];\n /** When provided, the Add button calls this instead of navigating to /onboarding */\n onAddClick?: () => void;\n /** Icon size override (default: 26) */\n iconSize?: number;\n /** When provided, hovering an icon shows a cross-out button that calls this with the app name */\n onDisable?: (name: string) => void;\n /** Set of app names that are currently disabled */\n disabledApps?: Set<string>;\n /** Show all integrations without truncation */\n showAll?: boolean;\n /** Hide the Add Integration button */\n hideAddButton?: boolean;\n /** Hide the \"Integrations\" section header */\n hideHeader?: boolean;\n /** When set, apps matching this category are sorted to the top */\n priorityCategory?: string;\n}\n\nconst PRIORITY_CATEGORY_PATTERNS: Record<string, string[]> = {\n siem: SIEM_PATTERNS,\n case_management: CASES_PATTERNS,\n edr: EDR_PATTERNS,\n email: EMAIL_APP_PATTERNS,\n};\n\nfunction matchesPriorityCategory(appName: string, categoryId: string): boolean {\n const patterns = PRIORITY_CATEGORY_PATTERNS[categoryId];\n if (!patterns) return false;\n const lower = appName.toLowerCase();\n return patterns.some(p => lower.includes(p));\n}\n\n/** Fire this event from anywhere to make all IntegrationStatus instances re-fetch. */\nexport const refreshAllIntegrationStatus = () => {\n window.dispatchEvent(new CustomEvent('integrations-changed'));\n};\n\nexport const IntegrationStatus = ({ collapsed, filterApps, onAddClick, iconSize = 26, onDisable, disabledApps, showAll, hideAddButton, hideHeader, priorityCategory }: IntegrationStatusProps) => {\n const [allIntegrations, setAllIntegrations] = useState<Integration[]>([]);\n const [loading, setLoading] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [failedImages, setFailedImages] = useState<Set<string>>(new Set());\n const [hoveredId, setHoveredId] = useState<string | null>(null);\n const appDetail = useAppDetailOptional();\n\n // Apply filter if provided (case-insensitive name match)\n const integrations = filterApps\n ? allIntegrations.filter(i => filterApps.some(f => f.toLowerCase() === i.name.toLowerCase()))\n : allIntegrations;\n\n const defaultLimit = showAll ? integrations.length : (collapsed ? 3 : 7);\n const displayLimit = showAll ? integrations.length : (expanded ? integrations.length : defaultLimit);\n const hasMore = !showAll && integrations.length > defaultLimit;\n\n // Fetch enabled integrations from API\n const fetchIntegrations = useCallback(async () => {\n setLoading(true);\n try {\n // Use the coalesced shared fetcher so we share a single in-flight\n // request with other consumers (e.g. the incident header source-app\n // logo). Without this, every detail-page navigation triggered 3+\n // identical /apps/authentication requests.\n const authData = (await fetchAuthenticatedApps().catch(() => [])) as unknown as AuthAppEntry[];\n\n let dedupedIntegrations: Integration[] = [];\n const authNameSet = new Set<string>();\n\n if (Array.isArray(authData) && authData.length > 0) {\n const dedupedApps = deduplicateAuthApps(authData);\n await backfillAppImages(dedupedApps);\n\n dedupedIntegrations = dedupedApps\n .map(({ app, instances, hasValidAuth, bestImage }) => {\n authNameSet.add(app.name.toLowerCase());\n return {\n id: app.id,\n name: app.name,\n icon: bestImage || app.large_image || '',\n category: app.categories?.[0] || 'Integration',\n hasValidAuth,\n authInstances: instances,\n isActiveOnly: false,\n };\n });\n }\n\n if (dedupedIntegrations.length < 10) {\n try {\n const appsData = await fetchApps();\n if (Array.isArray(appsData)) {\n const activatedApps = appsData.filter((app: any) => app.activated);\n const slotsRemaining = 10 - dedupedIntegrations.length;\n let added = 0;\n for (const app of activatedApps) {\n if (added >= slotsRemaining) break;\n if (!authNameSet.has((app.name || '').toLowerCase())) {\n authNameSet.add((app.name || '').toLowerCase());\n dedupedIntegrations.push({\n id: app.id || app.name,\n name: app.name,\n icon: app.large_image || '',\n category: app.categories?.[0] || 'Integration',\n hasValidAuth: false,\n authInstances: [],\n isActiveOnly: true,\n });\n added++;\n }\n }\n }\n } catch (_) {\n // Non-critical, ignore\n }\n }\n\n dedupedIntegrations.sort((a, b) => {\n // Priority category apps first\n if (priorityCategory) {\n const aMatch = matchesPriorityCategory(a.name, priorityCategory);\n const bMatch = matchesPriorityCategory(b.name, priorityCategory);\n if (aMatch && !bMatch) return -1;\n if (!aMatch && bMatch) return 1;\n }\n if (a.hasValidAuth && !b.hasValidAuth) return -1;\n if (!a.hasValidAuth && b.hasValidAuth) return 1;\n if (!a.isActiveOnly && b.isActiveOnly) return -1;\n if (a.isActiveOnly && !b.isActiveOnly) return 1;\n return a.name.localeCompare(b.name);\n });\n \n setAllIntegrations(dedupedIntegrations);\n } catch (error) {\n console.error('Failed to fetch integrations:', error);\n } finally {\n setLoading(false);\n }\n }, [priorityCategory]);\n\n // Fetch on mount\n useEffect(() => {\n fetchIntegrations();\n }, [fetchIntegrations]);\n\n // Re-fetch whenever any integration auth changes globally\n useEffect(() => {\n const handler = () => fetchIntegrations();\n window.addEventListener('integrations-changed', handler);\n return () => window.removeEventListener('integrations-changed', handler);\n }, [fetchIntegrations]);\n\n const getStatusColor = (integration: Integration) => {\n if (integration.isActiveOnly) return 'hsl(var(--destructive))';\n return integration.hasValidAuth ? 'hsl(var(--severity-low))' : 'hsl(var(--severity-medium))';\n };\n\n // Icon-only view for both collapsed and expanded states\n const sz = iconSize;\n return (\n <Box sx={{ px: collapsed ? 0 : 1, py: 1 }}>\n {/* Header - only show when expanded */}\n {!collapsed && !hideHeader && (\n <Typography \n sx={{ \n color: 'hsl(var(--muted-foreground))', \n fontSize: '0.7rem', \n fontWeight: 600, \n textTransform: 'uppercase', \n letterSpacing: '0.05em',\n px: 1.5,\n mb: 1,\n }}\n >\n Integrations\n </Typography>\n )}\n \n {/* Icon grid */}\n <Box sx={{ \n display: 'flex', \n flexWrap: 'wrap',\n gap: 0.5,\n justifyContent: collapsed ? 'center' : 'flex-start',\n px: collapsed ? 0 : 1,\n maxHeight: expanded ? 'none' : 80,\n overflow: 'hidden',\n }}>\n {loading ? (\n <CircularProgress size={20} sx={{ color: 'hsl(var(--muted-foreground))' }} />\n ) : (\n <>\n {integrations.slice(0, displayLimit).map((integration) => {\n const isDisabled = disabledApps?.has(integration.name) ?? false;\n const isHovered = hoveredId === integration.id;\n return (\n <Tooltip \n key={integration.id} \n title={onDisable && isHovered ? '' : (\n <Box sx={{ textAlign: 'left', minWidth: 160, p: 0.5 }}>\n <Typography sx={{ fontWeight: 600, fontSize: '0.85rem', color: 'hsl(var(--foreground))' }}>\n {integration.name}\n {isDisabled && <Typography component=\"span\" sx={{ ml: 1, fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))' }}>(disabled)</Typography>}\n </Typography>\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mb: 1, textTransform: 'capitalize' }}>\n {integration.category}\n </Typography>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>\n {integration.authInstances.map((instance, idx) => (\n <Box key={idx} sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>\n <Box \n sx={{ \n width: 7, \n height: 7, \n borderRadius: '50%', \n backgroundColor: instance.isValidated \n ? 'hsl(var(--severity-low))' \n : 'hsl(var(--severity-medium))',\n flexShrink: 0,\n }} \n />\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--foreground))', opacity: 0.9 }}>\n {instance.label}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: instance.isValidated ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))', ml: 'auto' }}>\n {instance.isValidated ? 'Valid' : 'Pending'}\n </Typography>\n </Box>\n ))}\n </Box>\n </Box>\n )}\n placement=\"bottom\"\n arrow\n >\n <Box\n onMouseEnter={() => onDisable && setHoveredId(integration.id)}\n onMouseLeave={() => onDisable && setHoveredId(null)}\n sx={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: onDisable ? 'default' : 'pointer',\n textDecoration: 'none',\n opacity: isDisabled ? 0.35 : 1,\n transition: 'opacity 0.15s ease',\n '&:hover': onDisable ? {} : {\n transform: 'scale(1.1)',\n transition: 'transform 0.15s ease',\n },\n }}\n >\n {/* Icon — rendered as link only when not in disable mode */}\n <Box\n onClick={!onDisable && appDetail ? () => appDetail.openApp(integration.name) : undefined}\n sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', textDecoration: 'none', cursor: !onDisable && appDetail ? 'pointer' : 'default' }}\n >\n {integration.icon && !failedImages.has(integration.id) ? (\n <Box\n component=\"img\"\n src={integration.icon}\n alt={integration.name}\n sx={{\n width: sz,\n height: sz,\n borderRadius: '50%',\n objectFit: 'contain',\n backgroundColor: 'hsl(var(--muted))',\n p: 0.25,\n filter: isDisabled ? 'grayscale(1)' : 'none',\n transition: 'filter 0.15s ease',\n }}\n onError={() => {\n setFailedImages(prev => new Set(prev).add(integration.id));\n }}\n />\n ) : (\n <Avatar\n sx={{\n width: sz,\n height: sz,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: sz * 0.4 + 'px',\n color: 'hsl(var(--foreground))',\n filter: isDisabled ? 'grayscale(1)' : 'none',\n }}\n >\n {integration.name.charAt(0).toUpperCase()}\n </Avatar>\n )}\n </Box>\n\n {/* Status dot */}\n {!isDisabled && (\n <Box\n sx={{\n position: 'absolute',\n bottom: -1,\n right: -1,\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: getStatusColor(integration),\n border: '1.5px solid hsl(var(--card))',\n pointerEvents: 'none',\n }}\n />\n )}\n\n {/* Hover cross-out overlay */}\n {onDisable && isHovered && (\n <Box\n onClick={() => onDisable(integration.name)}\n sx={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: isDisabled\n ? 'hsla(var(--severity-low) / 0.25)'\n : 'hsla(var(--destructive) / 0.75)',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease',\n }}\n >\n {isDisabled ? (\n /* Re-enable: checkmark */\n <svg width={sz * 0.45} height={sz * 0.45} viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M2 6l3 3 5-5\" stroke=\"hsl(var(--severity-low))\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n ) : (\n /* Disable: X */\n <svg width={sz * 0.45} height={sz * 0.45} viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M2 2l8 8M10 2l-8 8\" stroke=\"white\" strokeWidth=\"1.8\" strokeLinecap=\"round\"/>\n </svg>\n )}\n </Box>\n )}\n </Box>\n </Tooltip>\n );\n })}\n \n {hasMore && !expanded && (\n <Tooltip title={`Show all ${integrations.length} integrations`} placement=\"bottom\">\n <Avatar\n onClick={() => setExpanded(true)}\n sx={{\n width: 26,\n height: 26,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: '0.65rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n },\n }}\n >\n +{integrations.length - defaultLimit}\n </Avatar>\n </Tooltip>\n )}\n \n {expanded && hasMore && (\n <Tooltip title=\"Show less\" placement=\"bottom\">\n <Avatar\n onClick={() => setExpanded(false)}\n sx={{\n width: 26,\n height: 26,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: '0.65rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n },\n }}\n >\n −\n </Avatar>\n </Tooltip>\n )}\n \n {/* Add button */}\n {!hideAddButton && (\n <Tooltip title=\"Add Integration\" placement=\"bottom\">\n {onAddClick ? (\n <IconButton\n size=\"small\"\n onClick={onAddClick}\n sx={{ \n width: 26,\n height: 26,\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n borderRadius: '50%',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n borderStyle: 'solid',\n },\n }}\n >\n <AddIcon sx={{ fontSize: 14 }} />\n </IconButton>\n ) : (\n <IconButton\n size=\"small\"\n component={RouterLink}\n to=\"/onboarding\"\n sx={{ \n width: 26,\n height: 26,\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n borderRadius: '50%',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n borderStyle: 'solid',\n },\n }}\n >\n <AddIcon sx={{ fontSize: 14 }} />\n </IconButton>\n )}\n </Tooltip>\n )}\n </>\n )}\n </Box>\n </Box>\n );\n};\n","/**\n * Shared, request-coalescing fetcher for `/api/v1/apps/authentication`.\n *\n * Multiple components on a single page (sidebar `IntegrationStatus`, the\n * incident header source-app logo, the Forward dialog, the Automations\n * dialog, etc.) all need the authenticated-apps list. Without coordination\n * they each fired their own HTTP request on mount, producing 3+ identical\n * requests on every incident detail load.\n *\n * This helper:\n * 1. Coalesces concurrent in-flight calls into a single Promise so\n * simultaneous mounts only trigger one network round-trip.\n * 2. Caches the resolved JSON for a short TTL so a follow-up mount within\n * that window can read the result synchronously instead of refetching.\n * 3. Exposes an `invalidateAuthenticatedAppsCache()` so code paths that\n * mutate authentications (delete, reauth, etc.) can force a refresh.\n *\n * The cache key includes the optional `Org-Id` header value so cross-org\n * lookups stay isolated from the active org's data.\n */\n\nimport { getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\nexport interface AuthenticatedAppRaw {\n id?: string;\n active?: boolean;\n label?: string;\n app?: {\n name?: string;\n id?: string;\n large_image?: string;\n small_image?: string;\n categories?: string[];\n [key: string]: unknown;\n };\n validation?: { valid?: boolean; [key: string]: unknown };\n fields?: Array<{ key: string; value: string }>;\n [key: string]: unknown;\n}\n\ninterface CacheEntry {\n promise?: Promise<AuthenticatedAppRaw[]>;\n data?: AuthenticatedAppRaw[];\n fetchedAt?: number;\n}\n\nconst TTL_MS = 30_000;\nconst cache = new Map<string, CacheEntry>();\n\nconst cacheKey = (crossOrgId?: string | null): string => crossOrgId || '';\n\nconst doFetch = async (crossOrgId?: string | null): Promise<AuthenticatedAppRaw[]> => {\n // getAuthHeader() now scopes to the active org by default; pass crossOrgId\n // explicitly to override when reading from a different tenant.\n const headers: Record<string, string> = {\n ...getAuthHeader(crossOrgId ?? undefined),\n };\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers,\n });\n if (!response.ok) return [];\n const result = await response.json();\n const data = result?.data || result;\n return Array.isArray(data) ? data : [];\n};\n\n/**\n * Get the raw authenticated-apps list. Returns the cached value if it is\n * still within the TTL; otherwise fires (or joins) a single network request.\n */\nexport const fetchAuthenticatedApps = (crossOrgId?: string | null): Promise<AuthenticatedAppRaw[]> => {\n const key = cacheKey(crossOrgId);\n const entry = cache.get(key) || {};\n\n // Fresh cache hit — return it without touching the network.\n if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {\n return Promise.resolve(entry.data);\n }\n // In-flight request — join it instead of firing a duplicate.\n if (entry.promise) return entry.promise;\n\n const promise = doFetch(crossOrgId)\n .then((data) => {\n cache.set(key, { data, fetchedAt: Date.now() });\n return data;\n })\n .catch((err) => {\n // On failure, drop the in-flight promise so the next caller can retry.\n cache.delete(key);\n throw err;\n });\n\n cache.set(key, { ...entry, promise });\n return promise;\n};\n\n/**\n * Invalidate the cached entry for one (or all) cross-org keys. Call after\n * mutating authentications (delete, create, reauth) so the next read fires\n * a fresh request.\n */\nexport const invalidateAuthenticatedAppsCache = (crossOrgId?: string | null) => {\n if (crossOrgId === undefined) {\n cache.clear();\n return;\n }\n cache.delete(cacheKey(crossOrgId));\n};\n","/**\n * Shared, request-coalescing fetcher for `/api/v1/apps`.\n *\n * The demo page (and the real app) renders many components that each need\n * the user's apps list — `ShuffleMCP`, `AgentUI`, `AppDetailDrawer`,\n * `useAppLookup`, `IntegrationStatus`. Without coordination they fire 5+\n * identical `/api/v1/apps` requests on mount.\n *\n * This module mirrors `authenticatedApps.ts`:\n * 1. Coalesces concurrent in-flight calls into a single Promise.\n * 2. Caches the resolved JSON for a short TTL.\n * 3. Exposes `invalidateAppsCache()` for callers that mutate apps.\n *\n * The cache key includes baseUrl + path + apiKey + orgId so multi-tenant /\n * multi-region setups stay isolated.\n */\n\nimport { API_CONFIG, getAuthHeader } from './api';\n\nexport interface FetchAppsOptions {\n baseUrl: string;\n path?: string;\n apiKey?: string | null;\n orgId?: string | null;\n}\n\ninterface CacheEntry {\n promise?: Promise<any[]>;\n data?: any[];\n fetchedAt?: number;\n}\n\nconst TTL_MS = 30_000;\nconst cache = new Map<string, CacheEntry>();\n\nconst cacheKey = (o: FetchAppsOptions): string =>\n `${o.baseUrl}|${o.path || '/api/v1/apps'}|${o.apiKey || ''}|${o.orgId || ''}`;\n\nconst doFetch = async (o: FetchAppsOptions): Promise<any[]> => {\n const headers: Record<string, string> = {};\n if (o.apiKey) headers['Authorization'] = `Bearer ${o.apiKey}`;\n if (o.orgId) headers['Org-Id'] = o.orgId;\n\n const response = await fetch(`${o.baseUrl}${o.path || '/api/v1/apps'}`, {\n credentials: 'include',\n headers,\n });\n if (!response.ok) return [];\n const data = await response.json();\n if (Array.isArray(data)) return data;\n return Array.isArray(data?.data) ? data.data : [];\n};\n\n/**\n * Get the apps list. Returns the cached value if it is still within the\n * TTL; otherwise fires (or joins) a single network request.\n */\nexport const fetchApps = (opts: FetchAppsOptions): Promise<any[]> => {\n const key = cacheKey(opts);\n const entry = cache.get(key) || {};\n\n if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {\n return Promise.resolve(entry.data);\n }\n if (entry.promise) return entry.promise;\n\n const promise = doFetch(opts)\n .then((data) => {\n cache.set(key, { data, fetchedAt: Date.now() });\n return data;\n })\n .catch((err) => {\n cache.delete(key);\n throw err;\n });\n\n cache.set(key, { ...entry, promise });\n return promise;\n};\n\n/** Invalidate the cached entry for one (or all) keys. */\nexport const invalidateAppsCache = (opts?: FetchAppsOptions) => {\n if (!opts) {\n cache.clear();\n return;\n }\n cache.delete(cacheKey(opts));\n};\n\n/**\n * Convenience wrapper for callers that already use API_CONFIG / getAuthHeader.\n * Coalesces against the same cache as `fetchApps`.\n */\n\nexport const fetchAppsViaApiConfig = (): Promise<any[]> => {\n const headers = getAuthHeader();\n const orgId = headers['Org-Id'] || null;\n return fetchApps({\n baseUrl: API_CONFIG.baseUrl,\n apiKey: API_CONFIG.apiKey,\n orgId,\n });\n};\n","/**\n * Auth-app dedup + image backfill utilities.\n * Inlined into the Shuffle-MCPs library so it has no host-app dependency.\n * (Mirror copy of the helpers in src/lib/utils.ts — keep in sync.)\n */\n\nexport interface AuthAppEntry {\n app: {\n id: string;\n name: string;\n large_image?: string;\n categories?: string[];\n };\n active?: boolean;\n validation?: {\n valid: boolean;\n error?: string;\n };\n label?: string;\n id?: string;\n}\n\nexport interface DeduplicatedApp {\n app: AuthAppEntry['app'];\n hasValidAuth: boolean;\n bestImage: string;\n instances: { label: string; isValidated: boolean }[];\n}\n\nexport function deduplicateAuthApps(apps: AuthAppEntry[]): DeduplicatedApp[] {\n const appMap = new Map<string, DeduplicatedApp>();\n\n apps.forEach(auth => {\n if (!auth.active && !auth.validation?.valid) return;\n const normalizedName = auth.app.name.toLowerCase().trim().replace(/[\\s_\\-]+/g, '_');\n const existing = appMap.get(normalizedName);\n const isValidated = auth.validation?.valid === true;\n const entryImage = auth.app.large_image || '';\n const instance = {\n label: auth.label || auth.id || 'Default',\n isValidated,\n };\n\n if (!existing) {\n appMap.set(normalizedName, {\n app: auth.app,\n hasValidAuth: isValidated,\n bestImage: entryImage,\n instances: [instance],\n });\n } else {\n existing.instances.push(instance);\n if (isValidated) existing.hasValidAuth = true;\n if (!existing.bestImage && entryImage) existing.bestImage = entryImage;\n if (isValidated && !existing.app.large_image && entryImage) {\n existing.app = { ...existing.app, large_image: entryImage };\n }\n }\n });\n\n return Array.from(appMap.values());\n}\n\nconst _imageCache = new Map<string, string>();\nconst _pendingLookups = new Map<string, Promise<string | null>>();\nconst _normalize = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\nexport function seedImageCache(appName: string, imageUrl: string) {\n if (appName && imageUrl) _imageCache.set(_normalize(appName), imageUrl);\n}\n\nexport async function backfillAppImages(dedupedApps: DeduplicatedApp[]): Promise<DeduplicatedApp[]> {\n for (const d of dedupedApps) {\n const norm = _normalize(d.app.name);\n const existingImg = d.bestImage || d.app.large_image;\n if (existingImg) {\n _imageCache.set(norm, existingImg);\n } else if (_imageCache.has(norm)) {\n d.bestImage = _imageCache.get(norm)!;\n d.app = { ...d.app, large_image: d.bestImage };\n }\n }\n\n const missing = dedupedApps.filter(d => !d.bestImage && !d.app.large_image);\n if (missing.length === 0) return dedupedApps;\n\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n\n await Promise.all(missing.map(async (entry) => {\n const norm = _normalize(entry.app.name);\n if (!_pendingLookups.has(norm)) {\n _pendingLookups.set(norm, (async () => {\n try {\n const result = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: entry.app.name, hitsPerPage: 3 },\n });\n const match = (result.hits as any[]).find(\n h => _normalize(h.name || '') === norm\n );\n const url = match?.image_url || null;\n if (url) _imageCache.set(norm, url);\n return url;\n } catch {\n return null;\n } finally {\n _pendingLookups.delete(norm);\n }\n })());\n }\n const url = await _pendingLookups.get(norm);\n if (url) {\n entry.bestImage = url;\n entry.app = { ...entry.app, large_image: url };\n }\n }));\n } catch {\n // ignore\n }\n\n return dedupedApps;\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react';\n\ninterface AppDetailContextType {\n openApp: (appName: string) => void;\n closeApp: () => void;\n currentAppName: string | null;\n isOpen: boolean;\n}\n\nconst AppDetailContext = createContext<AppDetailContextType | undefined>(undefined);\n\nexport const AppDetailProvider = ({ children }: { children: ReactNode }) => {\n const [currentAppName, setCurrentAppName] = useState<string | null>(null);\n\n const openApp = useCallback((appName: string) => {\n setCurrentAppName(appName);\n }, []);\n\n const closeApp = useCallback(() => {\n setCurrentAppName(null);\n }, []);\n\n return (\n <AppDetailContext.Provider value={{ openApp, closeApp, currentAppName, isOpen: currentAppName !== null }}>\n {children}\n </AppDetailContext.Provider>\n );\n};\n\nexport const useAppDetail = () => {\n const context = useContext(AppDetailContext);\n if (!context) {\n throw new Error('useAppDetail must be used within an AppDetailProvider');\n }\n return context;\n};\n\n/** Safe variant: returns null if no provider is mounted. Useful for components used both inside and outside the dashboard. */\nexport const useAppDetailOptional = () => {\n return useContext(AppDetailContext) ?? null;\n};\n","/**\n * Shared app category detection utilities.\n * Used by onboarding (AutomationConfig) and incident automations (CategoryAutomationsDialog).\n */\n\nimport { AuthAppEntry, deduplicateAuthApps } from '@/Shuffle-MCPs/auth-utils';\n\n// ============================================================================\n// Category patterns\n// ============================================================================\nexport const EMAIL_APP_PATTERNS = ['gmail', 'outlook', 'email', 'microsoft_graph', 'office365', 'exchange', 'imap', 'smtp'];\nexport const CASES_PATTERNS = ['jira', 'servicenow', 'zendesk', 'freshdesk', 'pagerduty', 'opsgenie', 'ticket', 'itsm', 'salesforce', 'thehive', 'cortex'];\nexport const EDR_PATTERNS = ['crowdstrike', 'sentinelone', 'carbon black', 'defender', 'cylance', 'sophos', 'trellix', 'vmware', 'tanium', 'falcon', 'edr'];\nexport const SIEM_PATTERNS = ['splunk', 'elastic', 'qradar', 'sentinel', 'chronicle', 'logrhythm', 'sumo logic', 'graylog', 'wazuh', 'siem', 'arcsight'];\nexport const THREAT_INTEL_PATTERNS = ['virustotal', 'shodan', 'alienvault', 'otx', 'threatcrowd', 'urlscan', 'hybrid-analysis', 'abuseipdb', 'greynoise', 'urlhaus', 'malwarebazaar', 'threatfox', 'misp', 'opencti', 'recorded future', 'mandiant', 'crowdstrike intel', 'intel471', 'flashpoint', 'domaintools'];\nexport const COMMUNICATION_PATTERNS_NAMES = ['slack', 'teams', 'discord', 'mattermost', 'telegram', 'webhook'];\nexport const VULN_SCANNER_PATTERNS = ['qualys', 'tenable', 'nessus', 'rapid7', 'nexpose', 'snyk', 'sonarqube', 'trivy', 'grype', 'anchore', 'dependabot', 'aws_inspector', 'azure_defender', 'gcp_scc', 'scout', 'prowler', 'checkov', 'wiz', 'orca', 'lacework', 'prisma'];\n\n// ============================================================================\n// Detection helpers\n// ============================================================================\nexport const isEmailApp = (appName: string): boolean =>\n EMAIL_APP_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isThreatIntelApp = (appName: string): boolean =>\n THREAT_INTEL_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isVulnScannerApp = (appName: string): boolean =>\n VULN_SCANNER_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isIngestionApp = (appName: string): boolean => {\n const name = appName.toLowerCase();\n return isEmailApp(appName) ||\n CASES_PATTERNS.some(p => name.includes(p)) ||\n EDR_PATTERNS.some(p => name.includes(p)) ||\n SIEM_PATTERNS.some(p => name.includes(p));\n};\n\nexport type IngestionCategory = 'email' | 'cases' | 'edr' | 'siem' | 'other';\n\nexport const normalizeAppName = (name: string): string =>\n name.toLowerCase().trim().replace(/[\\s_\\-]+/g, '_');\n\nexport const getIngestionCategory = (appName: string, appCategories?: string[]): IngestionCategory | null => {\n const name = appName.toLowerCase();\n const categories = (appCategories || []).map(c => c.toLowerCase());\n \n if (isEmailApp(name)) return 'email';\n if (CASES_PATTERNS.some(p => name.includes(p)) || categories.includes('cases') || categories.includes('itsm')) return 'cases';\n if (EDR_PATTERNS.some(p => name.includes(p)) || categories.includes('edr') || categories.includes('endpoint')) return 'edr';\n if (SIEM_PATTERNS.some(p => name.includes(p)) || categories.includes('siem')) return 'siem';\n \n return null;\n};\n\n// ============================================================================\n// Workflow-based ingestion detection\n// ============================================================================\n\n/** Name of the workflow that powers automatic ingestion */\nexport const INGEST_TICKETS_WORKFLOW_NAME = 'Ingest Tickets';\n\n/** Name of the workflow that powers forward tickets */\nexport const FORWARD_TICKETS_WORKFLOW_NAME = 'Forward Tickets';\n\n/**\n * Extract normalized app names from a workflow's actions.\n * Returns a Set of normalized app names found in the workflow.\n */\nexport function extractWorkflowAppNames(workflow: any): Set<string> {\n const names = new Set<string>();\n if (!workflow?.actions || !Array.isArray(workflow.actions)) return names;\n\n for (const action of workflow.actions) {\n if (action.app_name) {\n names.add(normalizeAppName(action.app_name));\n }\n if (action.app_id) {\n names.add(normalizeAppName(action.app_id));\n }\n // Handle Singul-type actions with nested app_name in parameters\n if (action.parameters) {\n for (const param of action.parameters) {\n if (param.name === 'app_name' && param.value) {\n names.add(normalizeAppName(param.value));\n }\n }\n }\n }\n return names;\n}\n\n/**\n * Find the 'Ingest Tickets' workflow from a list of workflows.\n * Returns the workflow object or null.\n */\nexport function findIngestTicketsWorkflow(workflows: any[]): any | null {\n return workflows.find(w => w.name === INGEST_TICKETS_WORKFLOW_NAME) || null;\n}\n\n/**\n * Check if a workflow's schedule/trigger is stopped.\n * Returns true if all triggers are stopped or the workflow has no triggers.\n */\nexport function isWorkflowScheduleStopped(workflow: any): boolean {\n if (!workflow) return true;\n const triggers = workflow.triggers;\n if (!Array.isArray(triggers) || triggers.length === 0) return true;\n // If every trigger is explicitly stopped, the workflow is effectively disabled\n return triggers.every(\n (t: any) => (t.status || '').toLowerCase() === 'stopped'\n );\n}\n\n/**\n * Find the 'Forward Tickets' workflow from a list of workflows.\n * Returns the workflow object or null.\n */\nexport function findForwardTicketsWorkflow(workflows: any[]): any | null {\n return workflows.find(w => w.name === FORWARD_TICKETS_WORKFLOW_NAME) || null;\n}\n\n// ============================================================================\n// Validated ingestion app extraction from raw API data\n// ============================================================================\nexport interface ValidatedIngestionApp {\n id: string;\n name: string;\n image?: string;\n validated: boolean;\n enabled: boolean;\n category: IngestionCategory;\n}\n\n/**\n * Extract validated apps from the raw /api/v1/apps/authentication response.\n * Returns deduplicated apps that have valid authentication.\n *\n * Enablement is determined by whether the app appears in the\n * 'Ingest Tickets' workflow's actions (workflows are the source of truth).\n *\n * @param authApiResponse - Raw response from /api/v1/apps/authentication\n * @param workflowAppNames - Set of normalized app names from the Ingest Tickets workflow actions\n */\nexport function extractValidatedIngestionApps(\n authApiResponse: any[],\n workflowAppNames?: Set<string>,\n): ValidatedIngestionApp[] {\n const dedupedApps = deduplicateAuthApps(\n authApiResponse.filter(auth => auth.active || auth.validation?.valid)\n );\n\n const enabledNames = workflowAppNames || new Set<string>();\n\n const apps: ValidatedIngestionApp[] = [];\n\n for (const { app, bestImage, hasValidAuth } of dedupedApps) {\n const category = getIngestionCategory(app.name, app.categories) || 'other';\n const enabled = enabledNames.has(normalizeAppName(app.name));\n\n apps.push({\n id: app.id,\n name: app.name,\n image: bestImage || app.large_image,\n validated: hasValidAuth,\n enabled,\n category,\n });\n }\n\n // Sort: Enabled+Validated > Enabled+Unvalidated > Disabled+Validated > Disabled+Unvalidated, then alphabetically\n apps.sort((a, b) => {\n const aScore = (a.enabled ? 2 : 0) + (a.validated ? 1 : 0);\n const bScore = (b.enabled ? 2 : 0) + (b.validated ? 1 : 0);\n if (aScore !== bScore) return bScore - aScore;\n return a.name.localeCompare(b.name);\n });\n\n return apps;\n}\n","/**\n * AppTitleHeader — Standalone title/header card for an app.\n *\n * Shows avatar (with valid-auth border), name, Verified/Pending chip,\n * categories, and either an \"Activate/Deactivate\" or \"+ Add\" action.\n *\n * Pure presentational component — pass in already-resolved props.\n */\n\nimport { Box, Typography, Avatar, Chip, Button } from '@mui/material';\nimport CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';\nimport { motion } from 'framer-motion';\n\nexport interface AppTitleHeaderProps {\n /** Display name of the app (will be capitalized via CSS). */\n name: string;\n /** Image URL for the app icon. */\n image?: string;\n /** Whether at least one valid authentication exists. */\n hasValidAuth?: boolean;\n /** Whether at least one auth entry exists (valid or not). */\n hasAnyAuth?: boolean;\n /** Whether the host is authenticated — controls Verified/Pending chip + Activate button visibility. */\n isAuthenticated?: boolean;\n /** App categories to display as chips. */\n categories?: string[];\n /** Activation state — `null` hides the Activate button. */\n isActivated?: boolean | null;\n /** Whether activation toggle is in-flight. */\n activateLoading?: boolean;\n /** Called when user clicks Activate/Deactivate. */\n onActivateToggle?: () => void;\n /** When provided, replaces the Activate button with \"+ Add\". */\n onAdd?: () => void;\n}\n\nexport default function AppTitleHeader({\n name,\n image,\n hasValidAuth = false,\n hasAnyAuth = false,\n isAuthenticated = true,\n categories,\n isActivated = null,\n activateLoading = false,\n onActivateToggle,\n onAdd,\n}: AppTitleHeaderProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n mb: 3,\n p: 2.5,\n borderRadius: 3,\n background: 'linear-gradient(135deg, hsl(var(--foreground) / 0.03) 0%, hsl(var(--foreground) / 0.01) 100%)',\n border: '1px solid hsl(var(--border))',\n }}\n >\n <Avatar\n src={image}\n alt={name}\n sx={{\n width: 56,\n height: 56,\n borderRadius: '14px',\n backgroundColor: 'hsl(var(--muted))',\n border: '2px solid',\n borderColor: hasValidAuth\n ? 'hsl(var(--severity-low))'\n : hasAnyAuth\n ? 'hsl(142 76% 36% / 0.3)'\n : 'hsl(var(--border))',\n p: 0.5,\n '& img': { objectFit: 'contain', borderRadius: '10px' },\n }}\n >\n <Typography sx={{ fontSize: '1.2rem', fontWeight: 700 }}>{name.charAt(0).toUpperCase()}</Typography>\n </Avatar>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', textTransform: 'capitalize' }}>\n {name}\n </Typography>\n {isAuthenticated && hasValidAuth && (\n <Chip\n icon={<CheckCircleIcon sx={{ fontSize: 14 }} />}\n label=\"Verified\"\n size=\"small\"\n sx={{ height: 22, backgroundColor: 'hsla(142, 76%, 36%, 0.15)', color: 'hsl(var(--severity-low))', fontWeight: 600, fontSize: '0.7rem', '& .MuiChip-icon': { color: 'hsl(var(--severity-low))' } }}\n />\n )}\n {isAuthenticated && !hasValidAuth && hasAnyAuth && (\n <Chip\n icon={<ErrorOutlineIcon sx={{ fontSize: 14 }} />}\n label=\"Pending\"\n size=\"small\"\n sx={{ height: 22, backgroundColor: 'hsla(38, 92%, 50%, 0.15)', color: 'hsl(var(--severity-medium))', fontWeight: 600, fontSize: '0.7rem', '& .MuiChip-icon': { color: 'hsl(var(--severity-medium))' } }}\n />\n )}\n </Box>\n\n {categories && categories.length > 0 && (\n <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>\n {categories.slice(0, 3).map(cat => (\n <Chip\n key={cat}\n label={cat}\n size=\"small\"\n sx={{ height: 18, fontSize: '0.6rem', fontWeight: 500, backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))', textTransform: 'capitalize' }}\n />\n ))}\n </Box>\n )}\n </Box>\n\n {onAdd && (\n <Button\n onClick={onAdd}\n variant=\"contained\"\n size=\"small\"\n sx={{\n textTransform: 'none', fontWeight: 600, fontSize: '0.72rem', borderRadius: 2, px: 1.5, py: 0.5, minHeight: 0, flexShrink: 0,\n bgcolor: 'hsl(var(--primary))', '&:hover': { bgcolor: 'hsl(var(--primary) / 0.85)' },\n }}\n >\n + Add\n </Button>\n )}\n\n {!onAdd && isAuthenticated && isActivated !== null && onActivateToggle && (\n <Button\n onClick={onActivateToggle}\n disabled={activateLoading}\n variant={isActivated ? 'outlined' : 'contained'}\n size=\"small\"\n sx={{\n textTransform: 'none', fontWeight: 600, fontSize: '0.72rem', borderRadius: 2, px: 1.5, py: 0.5, minHeight: 0, flexShrink: 0,\n ...(isActivated\n ? { color: 'hsl(var(--muted-foreground))', borderColor: 'hsl(var(--border))', '&:hover': { borderColor: 'hsl(var(--destructive))', color: 'hsl(var(--destructive))', bgcolor: 'hsla(var(--destructive) / 0.08)' } }\n : { bgcolor: 'hsl(var(--primary))', '&:hover': { bgcolor: 'hsl(var(--primary) / 0.85)' } }),\n }}\n >\n {activateLoading ? '…' : isActivated ? 'Deactivate' : 'Activate'}\n </Button>\n )}\n </Box>\n </motion.div>\n );\n}\n","/**\n * AppAuthSection — Standalone Authentication block for an app.\n *\n * Wraps the heading/description + AppAuthCard. Pass in the resolved\n * algoliaApp and auth state so this remains presentational.\n */\n\nimport { Box, Typography } from '@mui/material';\nimport { motion } from 'framer-motion';\nimport { AppAuthCard } from '@/Shuffle-MCPs/AppAuthConfig';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\n\nexport interface AppAuthSectionProps {\n /** Display name (used in copy when no auth exists). */\n displayName: string;\n /** Algolia app object — required to render the AuthCard. */\n algoliaApp: AlgoliaSearchApp | null;\n /** Resolved app id (Algolia objectID). When missing the card is hidden. */\n resolvedAlgoliaId: string | null;\n /** Auth state object from useAppAuth. */\n authState: any;\n /** Whether the card is expanded. */\n expanded: boolean;\n onToggle: () => void;\n /** Number of matching auth entries — drives the subtitle copy. */\n authCount: number;\n /** Whether the host is authenticated (no Cloud session = hide form). */\n isAuthenticated?: boolean;\n /** Auth entries already filtered to this app. */\n matchingEntries: any[];\n onAuthChange: any;\n onTestConnection: (appId: string, authId?: string) => any;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n onRefreshAuth: () => void;\n}\n\nexport default function AppAuthSection({\n displayName,\n algoliaApp,\n resolvedAlgoliaId,\n authState,\n expanded,\n onToggle,\n authCount,\n isAuthenticated = true,\n matchingEntries,\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n onRefreshAuth,\n}: AppAuthSectionProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.1 }}>\n <Box sx={{ mb: 3 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem', mb: 0.5 }}>\n Authentication\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))', mb: 1.5 }}>\n {isAuthenticated\n ? authCount > 0\n ? `${authCount} configuration${authCount > 1 ? 's' : ''} found`\n : 'No authentication configured yet'\n : `Connect your ${displayName} account`}\n </Typography>\n {isAuthenticated && algoliaApp && resolvedAlgoliaId && (\n <AppAuthCard\n app={algoliaApp}\n authState={authState}\n isExpanded={expanded}\n onToggle={onToggle}\n onAuthChange={onAuthChange}\n onTestConnection={onTestConnection}\n onSaveAuth={onSaveAuth}\n apiAuthEntries={matchingEntries}\n onRefreshAuth={onRefreshAuth}\n />\n )}\n </Box>\n </motion.div>\n );\n}\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport {\n Box,\n Typography,\n TextField,\n Button,\n Card,\n CardContent,\n Collapse,\n Alert,\n CircularProgress,\n Chip,\n IconButton,\n Link,\n Divider,\n FormControl,\n Select,\n MenuItem,\n Checkbox,\n ListItemText,\n OutlinedInput,\n Tooltip,\n Dialog,\n DialogTitle,\n DialogContent,\n} from '@mui/material';\nimport { motion } from 'framer-motion';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport EditIcon from '@mui/icons-material/Edit';\nimport DeleteOutlineIcon from '@mui/icons-material/DeleteOutlined';\nimport CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport LockIcon from '@mui/icons-material/Lock';\nimport MenuBookIcon from '@mui/icons-material/MenuBook';\nimport CloseIcon from '@mui/icons-material/Close';\nimport type { AlgoliaSearchApp } from '@/Shuffle-MCPs';\nimport { API_CONFIG, getApiUrl, getAuthHeader, isDevEnvironment, isCloudDomain } from '@/Shuffle-MCPs/api';\nimport { getIngestionCategory } from '@/Shuffle-MCPs/ingestionDetection';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nexport type AuthStatus = 'pending' | 'testing' | 'connected' | 'error';\n\nexport interface AppAuthState {\n systemId: string;\n status: AuthStatus;\n credentials: Record<string, string>;\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number; // HTTP status code for credential errors (401, 403, etc.)\n}\n\n// Helper to check if auth type is OAuth2 (includes oauth2-app variant)\nconst isOAuth2Type = (type: string | undefined): boolean => {\n if (!type) return false;\n const lowerType = type.toLowerCase();\n return lowerType === 'oauth2' || lowerType === 'oauth2-app';\n};\n\n// Helper to check if auth type indicates no authentication required\n// Returns true for explicit \"no auth\" types OR apps with no parameters/OAuth config\nconst isNoAuthRequired = (auth: AppAuthentication | undefined): boolean => {\n if (!auth) return false; // No auth object loaded yet = unknown\n const type = auth.type?.toLowerCase() || '';\n // Explicit \"no auth\" types\n if (type === 'none' || type === 'no_auth' || type === 'no authentication' || type === 'no_key') return true;\n // Check if there's nothing to configure (not OAuth, no parameters)\n const isOAuth = type === 'oauth2' || type === 'oauth2-app';\n const hasParameters = auth.parameters && auth.parameters.length > 0;\n const hasOAuthConfig = auth.client_id || auth.client_secret || auth.token_uri;\n // If no OAuth and no parameters, auth is not required\n if (!isOAuth && !hasParameters && !hasOAuthConfig) return true;\n return false;\n};\n\n// URL validation helper\nconst isValidUrl = (value: string): boolean => {\n if (!value) return false;\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n};\n\ninterface AuthParameter {\n description: string;\n example: string;\n id: string;\n name: string;\n required: boolean;\n schema: {\n type: string;\n };\n}\n\ninterface AppAuthentication {\n type: string;\n description?: string;\n redirect_uri?: string;\n token_uri?: string;\n refresh_uri?: string;\n authorization_url?: string;\n // Common alternative field names for the authorization endpoint\n auth_uri?: string;\n authorize_url?: string;\n scope?: string[];\n client_id?: string;\n client_secret?: string;\n parameters?: AuthParameter[];\n}\n\n// API authentication entry (from /api/v1/apps/authentication)\nexport interface ApiAuthEntry {\n id?: string;\n label?: string;\n app: {\n id: string;\n name: string;\n large_image?: string;\n };\n active?: boolean;\n created?: number;\n edited?: number;\n validation?: {\n valid: boolean;\n error?: string;\n last_valid?: number;\n };\n}\n\ninterface DecodedApp {\n name: string;\n description: string;\n authentication: AppAuthentication;\n large_image?: string;\n}\n\ninterface AppAuthConfigProps {\n apps: AlgoliaSearchApp[];\n authStates: Record<string, AppAuthState>;\n authenticatedApps?: ApiAuthEntry[];\n onAuthChange: (appId: string, credentials: Record<string, string>) => void;\n onTestConnection: (appId: string, authenticationId?: string) => void;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n onSelectAuth?: (appId: string, authId: string) => void;\n onRefreshAuth?: () => Promise<void> | void;\n}\n\nexport interface AppAuthCardProps {\n app: AlgoliaSearchApp;\n authState: AppAuthState;\n isExpanded: boolean;\n onToggle: () => void;\n onAuthChange: (appId: string, credentials: Record<string, string>) => void;\n onTestConnection: (appId: string, authenticationId?: string) => void;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n apiAuthEntries: ApiAuthEntry[];\n onSelectAuth?: (appId: string, authId: string) => void;\n /** Called to refresh auth entries (e.g. after OAuth popup closes) */\n onRefreshAuth?: () => Promise<void> | void;\n /** When true, do NOT auto-fill URL fields with the param.example value. */\n disableUrlPrefill?: boolean;\n /** Hide the entire card header row (app icon, name, description, chips, docs, expand). Body stays expanded. */\n hideHeader?: boolean;\n /** Hide the \"Configured / Not configured\" and \"Tested / Not tested\" chips. */\n hideStatusChips?: boolean;\n /** Hide the documentation (book icon) link. */\n hideDocsLink?: boolean;\n}\n\nconst containerVariants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: { staggerChildren: 0.1 },\n },\n};\n\nconst itemVariants = {\n hidden: { opacity: 0, y: 20 },\n visible: { opacity: 1, y: 0, transition: { duration: 0.4 } },\n};\n\nconst ADD_NEW_AUTH = '__add_new__';\n\nexport const AppAuthCard = ({\n app,\n authState,\n isExpanded,\n onToggle,\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n apiAuthEntries,\n onSelectAuth,\n onRefreshAuth,\n disableUrlPrefill,\n hideHeader,\n hideStatusChips,\n hideDocsLink,\n}: AppAuthCardProps) => {\n // Helper to get best default auth: prioritize validated, otherwise last entry\n const getBestDefaultAuth = (entries: ApiAuthEntry[]): string => {\n if (entries.length === 0) return ADD_NEW_AUTH;\n \n // First, find a validated entry\n const validatedEntry = entries.find(e => e.validation?.valid === true);\n if (validatedEntry) {\n return validatedEntry.id || validatedEntry.label || '0';\n }\n \n // Otherwise, use the last entry (assuming API returns in chronological order)\n const lastEntry = entries[entries.length - 1];\n return lastEntry.id || lastEntry.label || '0';\n };\n\n // Track selected auth from dropdown\n const [selectedAuthId, setSelectedAuthId] = useState<string>(() => {\n return getBestDefaultAuth(apiAuthEntries);\n });\n\n // Track if user has made an explicit selection (to prevent auto-override on refresh)\n const [userHasSelected, setUserHasSelected] = useState(false);\n \n // Track test status PER authentication ID for this session\n // This ensures switching between auths shows each one's test result correctly\n type TestStatusValue = 'untested' | 'testing' | 'success' | 'pending_validation' | 'error';\n const [testStatusPerAuth, setTestStatusPerAuth] = useState<Record<string, TestStatusValue>>({});\n \n // Track test messages per auth (error message, success message, warning message)\n const [testMessagesPerAuth, setTestMessagesPerAuth] = useState<Record<string, {\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number;\n }>>({});\n \n // Track which auth ID is currently being tested (to avoid updating wrong auth on switch)\n const [testingAuthId, setTestingAuthId] = useState<string | null>(null);\n \n // Delete auth state\n const [deleteConfirmAuthId, setDeleteConfirmAuthId] = useState<string | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const handleDeleteAuth = async (authId: string) => {\n setDeleting(true);\n try {\n const response = await fetch(getApiUrl(`/api/v1/apps/authentication/${authId}`), {\n method: 'DELETE',\n credentials: 'include',\n headers: { ...getAuthHeader() },\n });\n if (response.ok) {\n // If we deleted the selected auth, reset selection\n if (selectedAuthId === authId) {\n setSelectedAuthId(ADD_NEW_AUTH);\n setUserHasSelected(false);\n }\n if (onRefreshAuth) await onRefreshAuth();\n }\n } catch (err) {\n console.error('Failed to delete auth:', err);\n } finally {\n setDeleting(false);\n setDeleteConfirmAuthId(null);\n }\n };\n\n const localTestStatus = testStatusPerAuth[selectedAuthId] || 'untested';\n \n // Track if the selected auth was already validated BEFORE we started testing\n // This is used to determine if we should trust the 200 response as source of truth\n const [wasPreValidatedPerAuth, setWasPreValidatedPerAuth] = useState<Record<string, boolean>>({});\n\n // Track previous entry count to detect new auths added (e.g. from OAuth popup)\n const prevEntryCountRef = useRef(apiAuthEntries.length);\n // Guard to prevent multiple auto-tests firing\n const autoTestFiredRef = useRef<string | null>(null);\n\n // Update selection when apiAuthEntries changes\n useEffect(() => {\n if (apiAuthEntries.length > 0) {\n // If a new entry was added (count increased), auto-select the newest one\n if (apiAuthEntries.length > prevEntryCountRef.current) {\n const sorted = [...apiAuthEntries].sort((a, b) => {\n const aTime = a.created || a.edited || 0;\n const bTime = b.created || b.edited || 0;\n return bTime - aTime;\n });\n const newestId = sorted[0]?.id || sorted[0]?.label || '0';\n setSelectedAuthId(newestId);\n \n // Auto-test the new auth if not already validated and not already auto-tested\n const newestEntry = sorted[0];\n const alreadyValid = newestEntry?.validation?.valid === true;\n if (!alreadyValid && newestId !== autoTestFiredRef.current) {\n autoTestFiredRef.current = newestId;\n // Small delay to let state settle before firing test\n setTimeout(() => {\n toast({\n title: 'Auto-testing new authentication',\n description: `Verifying connection for ${app.name.replace(/_/g, ' ')}...`,\n });\n setTestingAuthId(newestId);\n onTestConnection(app.objectID, newestId);\n }, 500);\n }\n } else if (!userHasSelected) {\n setSelectedAuthId(getBestDefaultAuth(apiAuthEntries));\n }\n }\n prevEntryCountRef.current = apiAuthEntries.length;\n }, [apiAuthEntries, userHasSelected]);\n \n // Track pre-validation state when auth selection changes (for first-time tests)\n useEffect(() => {\n // Only set pre-validated state if we haven't tracked this auth yet\n if (wasPreValidatedPerAuth[selectedAuthId] === undefined) {\n const currentAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === selectedAuthId\n );\n setWasPreValidatedPerAuth(prev => ({\n ...prev,\n [selectedAuthId]: currentAuth?.validation?.valid === true\n }));\n }\n }, [selectedAuthId, apiAuthEntries]);\n \n // Get the currently selected auth entry (needed for validation check)\n const selectedAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === selectedAuthId\n );\n \n // Helper to update test status for a specific auth\n const setTestStatusForAuth = (authId: string, status: TestStatusValue) => {\n setTestStatusPerAuth(prev => ({ ...prev, [authId]: status }));\n };\n \n // Helper to update test messages for a specific auth\n const setTestMessagesForAuth = (authId: string, messages: {\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number;\n }) => {\n setTestMessagesPerAuth(prev => ({ ...prev, [authId]: messages }));\n };\n \n // Get test messages for current auth\n const localTestMessages = testMessagesPerAuth[selectedAuthId] || {};\n const wasPreValidated = wasPreValidatedPerAuth[selectedAuthId] || false;\n \n // Sync test status with authState when test completes, checking backend validation status\n // IMPORTANT: Only update the auth that was being tested, not the currently selected auth\n useEffect(() => {\n // Only process if we have a testingAuthId (a test was initiated)\n if (!testingAuthId) return;\n \n if (authState.status === 'testing') {\n setTestStatusForAuth(testingAuthId, 'testing');\n // Clear previous messages when starting a new test\n setTestMessagesForAuth(testingAuthId, {});\n } else if (authState.status === 'connected') {\n // Get the auth entry that was being tested\n const testedAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === testingAuthId\n );\n const wasTestedAuthPreValidated = wasPreValidatedPerAuth[testingAuthId] || false;\n \n // If auth was already validated before testing, trust the 200 response\n // (Re-tests don't always update the backend validation status)\n if (wasTestedAuthPreValidated) {\n setTestStatusForAuth(testingAuthId, 'success');\n } else {\n // For newly tested auths, check if backend has validated\n const isBackendValidated = testedAuth?.validation?.valid === true;\n setTestStatusForAuth(testingAuthId, isBackendValidated ? 'success' : 'pending_validation');\n }\n // Store the success/warning messages for this auth\n setTestMessagesForAuth(testingAuthId, {\n successMessage: authState.successMessage,\n warningMessage: authState.warningMessage,\n });\n // Clear testingAuthId after processing completed status\n setTestingAuthId(null);\n } else if (authState.status === 'error') {\n setTestStatusForAuth(testingAuthId, 'error');\n // Store the error details for this auth\n setTestMessagesForAuth(testingAuthId, {\n errorMessage: authState.errorMessage,\n workflowId: authState.workflowId,\n executionId: authState.executionId,\n errorCode: authState.errorCode,\n });\n // Clear testingAuthId after processing completed status\n setTestingAuthId(null);\n }\n }, [authState.status, authState.errorMessage, authState.successMessage, authState.warningMessage, testingAuthId, apiAuthEntries, wasPreValidatedPerAuth]);\n \n // Track credential errors (401/403) to show warning but don't auto-switch\n // User can manually switch back to other auths or add new one\n const isCredentialError = localTestMessages.errorCode === 401 || localTestMessages.errorCode === 403;\n\n const showAddNewForm = selectedAuthId === ADD_NEW_AUTH;\n\n // Compute configured/tested status for the SELECTED auth entry only (not any auth)\n const isConfigured = selectedAuth?.active === true;\n const isTested = selectedAuth?.validation?.valid === true;\n \n // Get last validation timestamp (prefer selected auth, fallback to any validated entry)\n const getLastValidTimestamp = (): number | undefined => {\n if (selectedAuth?.validation?.last_valid) return selectedAuth.validation.last_valid;\n const validEntry = apiAuthEntries.find(a => a.validation?.valid === true && a.validation?.last_valid);\n return validEntry?.validation?.last_valid;\n };\n \n const formatLastValidDate = (): string => {\n const timestamp = getLastValidTimestamp();\n if (!timestamp) return 'Unknown';\n // Detect if timestamp is in seconds or milliseconds\n // If > 10^12, it's likely milliseconds; otherwise seconds\n const ms = timestamp > 1e12 ? timestamp : timestamp * 1000;\n const date = new Date(ms);\n return date.toLocaleDateString(undefined, { \n year: 'numeric', \n month: 'short', \n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n // Local credentials state for the form\n const [localCredentials, setLocalCredentials] = useState<Record<string, string>>(authState.credentials || {});\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n\n // App config fetching for dynamic fields\n const [loading, setLoading] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveSuccess, setSaveSuccess] = useState<boolean | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [appConfig, setAppConfig] = useState<DecodedApp | null>(null);\n\n // Refresh auth entries every time the card is expanded\n useEffect(() => {\n if (isExpanded && onRefreshAuth) {\n onRefreshAuth();\n }\n }, [isExpanded]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n const fetchAppConfig = async () => {\n if (!isExpanded || appConfig) return;\n \n setLoading(true);\n setError(null);\n \n try {\n const response = await fetch(getApiUrl(`/api/v1/apps/${app.objectID}/config`), {\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n },\n });\n \n if (!response.ok) {\n throw new Error('Failed to fetch app configuration');\n }\n \n const data = await response.json();\n \n if (data.success && data.app) {\n const decodedAppString = atob(data.app);\n const decodedApp = JSON.parse(decodedAppString) as DecodedApp;\n console.log('[AppAuthCard] Decoded auth config for', decodedApp.name, ':', JSON.stringify(decodedApp.authentication, null, 2));\n setAppConfig(decodedApp);\n } else {\n throw new Error('Invalid response format');\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load configuration');\n } finally {\n setLoading(false);\n }\n };\n \n fetchAppConfig();\n }, [isExpanded, app.objectID, appConfig]);\n\n const auth = appConfig?.authentication;\n const isOAuth2 = isOAuth2Type(auth?.type);\n\n const [selectedScopes, setSelectedScopes] = useState<string[]>([]);\n\n // Update scopes when auth loads\n useEffect(() => {\n if (auth?.scope) {\n setSelectedScopes(auth.scope);\n }\n }, [auth?.scope]);\n \n // Auto-populate URL fields with example values when auth config loads\n useEffect(() => {\n if (disableUrlPrefill) return;\n if (!auth?.parameters || auth.parameters.length === 0) return;\n \n const urlDefaults: Record<string, string> = {};\n auth.parameters.forEach((param, index) => {\n const fieldKey = param.id || param.name || `param_${index}`;\n const nameOrId = (param.name || param.id || '').toLowerCase();\n \n // Check if this is a URL field and has an example that looks like a URL\n const isUrlField = nameOrId.includes('url') || nameOrId.includes('endpoint') || nameOrId.includes('host');\n const hasUrlExample = param.example && (\n param.example.startsWith('http://') || \n param.example.startsWith('https://')\n );\n \n // Only pre-fill if field is empty and has a URL example\n if (isUrlField && hasUrlExample && !localCredentials[fieldKey]) {\n urlDefaults[fieldKey] = param.example;\n }\n });\n \n // Update credentials with URL defaults if any\n if (Object.keys(urlDefaults).length > 0) {\n setLocalCredentials(prev => ({ ...urlDefaults, ...prev }));\n }\n }, [auth?.parameters, disableUrlPrefill]);\n\n // Sync externally-driven URL/endpoint changes (e.g. provider preset\n // selectors) into the local form state so the field reflects the choice.\n useEffect(() => {\n const incoming = authState.credentials || {};\n setLocalCredentials((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const [k, v] of Object.entries(incoming)) {\n const lk = k.toLowerCase();\n const isUrlish = lk.includes('url') || lk.includes('endpoint') || lk.includes('host');\n if (isUrlish && typeof v === 'string' && v !== prev[k]) {\n next[k] = v;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [authState.credentials]);\n\n const [docsOpen, setDocsOpen] = useState(false);\n const [docsContent, setDocsContent] = useState<string>('');\n const [docsLoading, setDocsLoading] = useState(false);\n const [editingLabel, setEditingLabel] = useState(false);\n const [editLabelValue, setEditLabelValue] = useState('');\n const [savingLabel, setSavingLabel] = useState(false);\n\n const handleRenameAuth = async () => {\n if (!selectedAuth || !editLabelValue.trim()) return;\n setSavingLabel(true);\n try {\n // Build the auth body with all fields but replaced label\n // Fill any sensitive fields with placeholder\n const placeholder = 'Secret. Replaced during app execution!';\n const authBody: Record<string, any> = {\n ...selectedAuth,\n label: editLabelValue.trim(),\n };\n // Ensure fields array values are placeholders\n if (authBody.fields) {\n const newFields: Record<string, any> = {};\n for (const [key, val] of Object.entries(authBody.fields)) {\n newFields[key] = typeof val === 'string' ? placeholder : val;\n }\n authBody.fields = newFields;\n }\n\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n method: 'PUT',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n body: JSON.stringify(authBody),\n });\n\n if (response.ok) {\n setEditingLabel(false);\n if (onRefreshAuth) await onRefreshAuth();\n toast({ title: 'Label updated', description: `Renamed to \"${editLabelValue.trim()}\"` });\n } else {\n toast({ title: 'Failed to rename', description: 'Could not update the authentication label', variant: 'destructive' });\n }\n } catch (err) {\n toast({ title: 'Error', description: 'Failed to rename authentication', variant: 'destructive' });\n } finally {\n setSavingLabel(false);\n }\n };\n\n const fetchDocs = async () => {\n setDocsLoading(true);\n try {\n const encodedName = encodeURIComponent(app.name);\n const response = await fetch(getApiUrl(`/api/v1/docs/${encodedName}?location=openapi`), {\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n },\n });\n if (response.ok) {\n const data = await response.json();\n setDocsContent(data.reason || data.data || data.content || 'No documentation available.');\n } else {\n setDocsContent('Failed to load documentation.');\n }\n } catch (error) {\n setDocsContent('Error loading documentation.');\n } finally {\n setDocsLoading(false);\n }\n };\n\n const handleOpenDocs = () => {\n setDocsOpen(true);\n fetchDocs();\n };\n\n // Render OAuth2 fields - only for OAuth2 apps\n const renderOAuth2Fields = () => {\n if (!auth || !isOAuth2) return null;\n\n const availableScopes = auth.scope || [];\n\n const hasManualCredentials = !!localCredentials['client_id']?.trim() && !!localCredentials['client_secret']?.trim();\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n {/* Quick Connect Button — always shown for OAuth2 apps. The popup target\n * (https://shuffler.io/appauth) handles the redirect server-side regardless\n * of which host opened it, so there is no reason to gate this on hostname.\n * Previously this was gated on isDevEnvironment() || isCloudDomain(), which\n * meant any consumer of the lib outside the hardcoded ['security.shuffler.io',\n * 'shutdown.no'] / Lovable preview list never saw a Quick Connect button at all. */}\n {true && (\n <>\n <Collapse in={!hasManualCredentials}>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n <Button\n variant=\"outlined\"\n fullWidth\n startIcon={\n app.image_url ? (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 24, height: 24, borderRadius: 1, objectFit: 'contain' }}\n />\n ) : <LockIcon />\n }\n onClick={() => {\n const authUrl = `https://shuffler.io/appauth?app_id=${app.objectID}&source=shuffle`;\n const popup = window.open(authUrl, '_blank', 'width=600,height=700');\n if (!onRefreshAuth) return;\n const baselineCount = (apiAuthEntries || []).length;\n const startedAt = Date.now();\n const MAX_MS = 5 * 60 * 1000; // 5 minutes\n let stopped = false;\n const stop = () => {\n if (stopped) return;\n stopped = true;\n clearInterval(authPollTimer);\n clearInterval(closePollTimer);\n };\n const tick = async () => {\n try { await onRefreshAuth(); } catch {}\n if ((apiAuthEntries || []).length > baselineCount) stop();\n if (Date.now() - startedAt > MAX_MS) stop();\n };\n // Fire immediately, then every 2s regardless of popup state\n tick();\n const authPollTimer = setInterval(tick, 2000);\n const closePollTimer = setInterval(() => {\n // popup may be null if blocked; in that case rely on auth poll + timeout\n if (popup && popup.closed) {\n // One last refresh after window closes\n tick();\n // Keep polling briefly in case backend writes the auth a moment later\n setTimeout(() => { tick(); stop(); }, 4000);\n }\n }, 500);\n }}\n sx={{\n py: 1.5,\n borderColor: 'hsl(var(--primary) / 0.4)',\n color: 'hsl(var(--foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '1rem',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n }}\n >\n Quick Connect with {app.name.replace(/_/g, ' ')}\n </Button>\n\n {/* OR Divider */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>\n <Divider sx={{ flex: 1, borderColor: 'hsl(var(--border))' }} />\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.875rem' }}>OR configure manually</Typography>\n <Divider sx={{ flex: 1, borderColor: 'hsl(var(--border))' }} />\n </Box>\n </Box>\n </Collapse>\n {hasManualCredentials && (\n <Button\n variant=\"text\"\n size=\"small\"\n onClick={() => {\n setLocalCredentials({});\n onAuthChange(app.objectID, {});\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'none',\n fontSize: '0.8rem',\n alignSelf: 'flex-start',\n p: 0,\n minWidth: 0,\n '&:hover': { color: 'hsl(var(--foreground))', backgroundColor: 'transparent' },\n }}\n >\n ← Use Quick Connect instead\n </Button>\n )}\n </>\n )}\n\n {/* Manual OAuth2 Fields */}\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))' }}>\n Redirect URL: <Typography component=\"span\" sx={{ color: 'hsl(var(--primary))', fontWeight: 600 }}>\n {auth.redirect_uri || 'https://shuffler.io/set_authentication'}\n </Typography>\n </Typography>\n\n <TextField\n label=\"Client ID\"\n placeholder=\"Enter your Client ID\"\n value={localCredentials['client_id'] || ''}\n onChange={(e) => handleCredentialChange('client_id', e.target.value)}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n />\n\n <TextField\n label=\"Client Secret\"\n type=\"password\"\n placeholder=\"Enter your Client Secret\"\n value={localCredentials['client_secret'] || ''}\n onChange={(e) => handleCredentialChange('client_secret', e.target.value)}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n />\n\n {/* Scopes */}\n {availableScopes.length > 0 && (\n <FormControl fullWidth size=\"small\">\n <Select\n multiple\n value={selectedScopes}\n onChange={(e) => {\n const value = e.target.value as string[];\n setSelectedScopes(value);\n handleCredentialChange('scopes', value.join(' '));\n }}\n input={<OutlinedInput />}\n renderValue={(selected) => selected.length === 0 ? 'Select Scopes' : `${selected.length} scope(s) selected`}\n displayEmpty\n sx={{\n backgroundColor: 'action.hover',\n borderRadius: 2,\n color: 'text.primary',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'divider' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'text.disabled' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'primary.main' },\n '& .MuiSvgIcon-root': { color: 'text.secondary' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n maxHeight: 300,\n },\n },\n },\n }}\n >\n {availableScopes.map((scope) => (\n <MenuItem key={scope} value={scope} sx={{ color: 'hsl(var(--foreground))' }}>\n <Checkbox \n checked={selectedScopes.indexOf(scope) > -1}\n sx={{ color: 'hsl(var(--muted-foreground))', '&.Mui-checked': { color: 'hsl(var(--primary))' } }}\n />\n <ListItemText primary={scope} sx={{ '& .MuiTypography-root': { color: 'hsl(var(--foreground))' } }} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n )}\n </Box>\n </Box>\n );\n };\n\n // Render parameter fields - for non-OAuth2 apps with parameters\n const renderParameterFields = () => {\n if (isOAuth2) return null;\n if (!auth?.parameters || auth.parameters.length === 0) return null;\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n {auth.parameters.map((param, index) => {\n // Use param.id if available, otherwise fallback to name or index\n const fieldKey = param.id || param.name || `param_${index}`;\n return (\n <TextField\n key={fieldKey}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {param.name}\n {param.required && (\n <Typography component=\"span\" sx={{ color: 'hsl(var(--destructive))', fontSize: '0.8rem' }}>*</Typography>\n )}\n </Box>\n }\n type={param.name.toLowerCase().includes('password') || param.name.toLowerCase().includes('secret') || param.name.toLowerCase().includes('key') ? 'password' : 'text'}\n placeholder={param.example || `Enter ${param.name}`}\n value={localCredentials[fieldKey] || ''}\n onChange={(e) => handleCredentialChange(fieldKey, e.target.value)}\n error={!!fieldErrors[fieldKey]}\n helperText={fieldErrors[fieldKey] || param.description}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: 2,\n '& fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n '& .MuiFormHelperText-root': { color: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--muted-foreground))' },\n }}\n />\n );\n })}\n </Box>\n );\n };\n\n // No longer rendering fallback API key field - apps without parameters don't need auth config\n\n // Validate a single field\n const validateField = (key: string, value: string): string | null => {\n const lowerKey = key.toLowerCase();\n if (lowerKey.includes('url') || lowerKey === 'url') {\n if (!value) return 'URL is required';\n if (!isValidUrl(value)) return 'Please enter a valid URL (e.g., https://example.com)';\n }\n return null;\n };\n\n // Check if all required fields are valid for saving\n const isFormValid = (): boolean => {\n // Check for any field errors\n if (Object.values(fieldErrors).some(err => err)) return false;\n \n // Validate all current credentials\n for (const [key, value] of Object.entries(localCredentials)) {\n const error = validateField(key, value);\n if (error) return false;\n }\n \n // Check required parameters are filled\n if (auth?.parameters && auth.parameters.length > 0) {\n for (let i = 0; i < auth.parameters.length; i++) {\n const param = auth.parameters[i];\n const fieldKey = param.id || param.name || `param_${i}`;\n if (param.required && !localCredentials[fieldKey]?.trim()) return false;\n }\n // At least one parameter must have a value\n const hasAnyValue = auth.parameters.some((param, index) => {\n const fieldKey = param.id || param.name || `param_${index}`;\n return localCredentials[fieldKey]?.trim();\n });\n if (!hasAnyValue) return false;\n }\n // Apps without parameters don't need validation - they work without auth\n \n return true;\n };\n\n const handleSave = async () => {\n setSaving(true);\n setSaveSuccess(null);\n const success = await onSaveAuth(app.objectID, localCredentials);\n setSaving(false);\n setSaveSuccess(success);\n if (success) {\n setUserHasSelected(false); // Allow auto-selection to pick up new auth\n setLocalCredentials({}); // Clear form after success\n setFieldErrors({}); // Clear errors\n }\n };\n\n // Helper to update local credentials and notify parent\n const handleCredentialChange = (key: string, value: string) => {\n // Ignore empty keys\n if (!key || key.trim() === '') return;\n \n const updated = { ...localCredentials, [key]: value };\n setLocalCredentials(updated);\n onAuthChange(app.objectID, updated);\n \n // Validate the field\n const error = validateField(key, value);\n setFieldErrors(prev => ({\n ...prev,\n [key]: error || '',\n }));\n };\n\n return (\n <motion.div variants={itemVariants} style={{ width: '100%', maxWidth: '100%' }}>\n <Card\n sx={{\n background: 'hsl(var(--card) / 0.9)',\n border: '2px solid',\n borderColor: isTested\n ? 'hsl(var(--severity-low) / 0.5)'\n : authState.status === 'error'\n ? 'hsl(var(--destructive) / 0.3)'\n : 'hsl(var(--severity-medium) / 0.3)',\n borderRadius: 3,\n backdropFilter: 'blur(10px)',\n overflow: 'hidden',\n transition: 'all 0.3s ease',\n width: '100%',\n maxWidth: '100%',\n }}\n >\n {!hideHeader && (\n <CardContent\n onClick={onToggle}\n sx={{\n display: 'flex',\n flexDirection: { xs: 'column', sm: 'row' },\n alignItems: { xs: 'flex-start', sm: 'center' },\n gap: { xs: 1.5, sm: 2 },\n cursor: 'pointer',\n p: { xs: 2, sm: 3 },\n '&:last-child': { pb: { xs: 2, sm: 3 } },\n '&:hover': { backgroundColor: 'hsl(var(--muted) / 0.35)' },\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flex: 1, minWidth: 0 }}>\n {app.image_url ? (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{\n width: { xs: 40, sm: 48 },\n height: { xs: 40, sm: 48 },\n borderRadius: 2,\n objectFit: 'contain',\n backgroundColor: 'hsl(var(--muted) / 0.5)',\n p: 1,\n flexShrink: 0,\n }}\n />\n ) : (\n <Box\n sx={{\n width: { xs: 40, sm: 48 },\n height: { xs: 40, sm: 48 },\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsl(var(--muted) / 0.5)',\n borderRadius: 2,\n fontSize: '1.5rem',\n flexShrink: 0,\n }}\n >\n 🔗\n </Box>\n )}\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Typography \n sx={{ \n color: 'hsl(var(--foreground))', \n fontWeight: 600, \n fontSize: { xs: '0.9rem', sm: '1rem' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {app.name.replace(/_/g, ' ')}\n </Typography>\n {app.description && (\n <Typography \n variant=\"caption\" \n sx={{ \n color: 'hsl(var(--muted-foreground))',\n display: { xs: 'none', md: 'block' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n }}\n >\n {app.description}\n </Typography>\n )}\n </Box>\n </Box>\n <Box sx={{ \n display: 'flex', \n alignItems: 'center', \n gap: { xs: 1, sm: 1.5 }, \n flexWrap: 'wrap',\n width: { xs: '100%', sm: 'auto' },\n justifyContent: { xs: 'flex-start', sm: 'flex-end' },\n }}>\n {/* Auth status chip - show \"Auth not required\" for no-auth apps */}\n {!hideStatusChips && (isNoAuthRequired(auth) ? (\n <Chip\n label=\"Auth not required\"\n size=\"small\"\n sx={{\n backgroundColor: 'hsl(var(--severity-info) / 0.15)',\n color: 'hsl(var(--severity-info))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n }}\n />\n ) : (\n <>\n {/* Configured status chip */}\n <Chip\n label={isConfigured ? 'Configured' : 'Not configured'}\n size=\"small\"\n sx={{\n backgroundColor: isConfigured ? 'hsl(var(--severity-medium) / 0.15)' : 'hsl(var(--destructive) / 0.15)',\n color: isConfigured ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n }}\n />\n {/* Tested status chip */}\n <Tooltip \n title={isTested ? `Last validated: ${formatLastValidDate()}` : ''} \n arrow\n disableHoverListener={!isTested}\n >\n <Chip\n label={isTested ? 'Tested' : 'Not tested'}\n size=\"small\"\n sx={{\n backgroundColor: isTested ? 'hsl(var(--severity-low) / 0.15)' : 'hsl(var(--muted) / 0.8)',\n color: isTested ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n cursor: isTested ? 'help' : 'default',\n }}\n />\n </Tooltip>\n </>\n ))}\n {!hideDocsLink && (\n <Tooltip title=\"View documentation\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n handleOpenDocs();\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { \n color: 'hsl(var(--severity-info))',\n backgroundColor: 'hsl(var(--severity-info) / 0.1)',\n },\n }}\n >\n <MenuBookIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n <IconButton\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n transform: isExpanded ? 'rotate(180deg)' : 'none',\n transition: 'transform 0.3s ease',\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n </Box>\n </CardContent>\n )}\n\n <Collapse in={isExpanded}>\n <Box\n sx={{\n px: { xs: 2, sm: 3 },\n pb: { xs: 2, sm: 3 },\n pt: 2,\n borderTop: '1px solid hsl(var(--border))',\n }}\n >\n {/* Auth Selection Dropdown - always at top */}\n {apiAuthEntries.length > 0 && (\n <Box sx={{ mb: 3 }}>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))', mb: 1 }}>\n Select authentication\n </Typography>\n <FormControl fullWidth size=\"small\">\n <Select\n value={selectedAuthId}\n onChange={(e) => {\n const value = e.target.value as string;\n setSelectedAuthId(value);\n // Track that user has made an explicit selection\n setUserHasSelected(true);\n if (value !== ADD_NEW_AUTH && onSelectAuth) {\n onSelectAuth(app.objectID, value);\n }\n }}\n sx={{\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n color: 'hsl(var(--foreground))',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n '& .MuiSvgIcon-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n },\n },\n },\n }}\n >\n {/* Sort by created date - most recent first */}\n {[...apiAuthEntries]\n .sort((a, b) => {\n const aTime = a.created || a.edited || 0;\n const bTime = b.created || b.edited || 0;\n return bTime - aTime; // Descending (newest first)\n })\n .map((authEntry, index) => {\n const isLatest = index === 0 && apiAuthEntries.length > 1;\n const entryId = authEntry.id || authEntry.label || index.toString();\n const entryLabel = authEntry.label || `Auth ${index + 1}`;\n const isActive = authEntry.active === true;\n const isValid = authEntry.validation?.valid === true;\n \n // Format timestamp for tooltips\n const formatTimestamp = (ts?: number): string => {\n if (!ts) return 'Unknown';\n const date = ts > 1e12 ? new Date(ts) : new Date(ts * 1000);\n return date.toLocaleString();\n };\n \n const configuredDate = authEntry.created || authEntry.edited;\n const lastValidDate = authEntry.validation?.last_valid;\n \n return (\n <MenuItem key={entryId} value={entryId} sx={{ color: 'hsl(var(--foreground))', py: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, width: '100%', minWidth: 0 }}>\n <Box sx={{ display: 'flex', gap: 0.5, flexShrink: 0 }}>\n <Tooltip \n title={isActive ? `Created: ${formatTimestamp(configuredDate)}` : 'Not configured'}\n arrow\n placement=\"top\"\n >\n <Chip\n label={isActive ? 'Configured' : 'Not configured'}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n backgroundColor: isActive ? 'hsl(var(--severity-medium) / 0.15)' : 'hsl(var(--destructive) / 0.15)',\n color: isActive ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))',\n }}\n />\n </Tooltip>\n <Tooltip \n title={lastValidDate ? `Last valid: ${formatTimestamp(lastValidDate)}` : 'Never validated'}\n arrow\n placement=\"top\"\n >\n <Chip\n label={isValid ? 'Tested' : 'Not tested'}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n backgroundColor: isValid ? 'hsl(var(--severity-low) / 0.15)' : 'hsl(var(--muted) / 0.8)',\n color: isValid ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))',\n }}\n />\n </Tooltip>\n {isLatest && (\n <Chip\n label=\"Latest\"\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--infra-email) / 0.15)',\n color: 'hsl(var(--infra-email))',\n }}\n />\n )}\n </Box>\n <Typography sx={{ \n flex: 1, \n overflow: 'hidden', \n textOverflow: 'ellipsis', \n whiteSpace: 'nowrap',\n minWidth: 0,\n }}>\n {entryLabel}\n </Typography>\n {/* Delete button for non-validated entries */}\n {!isValid && (\n <Tooltip title=\"Delete authentication\" arrow placement=\"top\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n setDeleteConfirmAuthId(entryId);\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n p: 0.5,\n ml: 0.5,\n flexShrink: 0,\n '&:hover': {\n color: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n <DeleteOutlineIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </MenuItem>\n );\n })}\n <Divider sx={{ borderColor: 'hsl(var(--border))', my: 1 }} />\n <MenuItem value={ADD_NEW_AUTH} sx={{ color: 'hsl(var(--primary))', fontWeight: 600 }}>\n + Add new authentication\n </MenuItem>\n </Select>\n </FormControl>\n\n {/* Delete confirmation dialog */}\n <Dialog\n open={!!deleteConfirmAuthId}\n onClose={() => setDeleteConfirmAuthId(null)}\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 3,\n minWidth: 360,\n },\n },\n }}\n >\n <DialogTitle sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, pb: 1 }}>\n Delete Authentication\n </DialogTitle>\n <DialogContent>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', mb: 3 }}>\n Are you sure you want to delete this authentication? This action cannot be undone.\n </Typography>\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={() => setDeleteConfirmAuthId(null)}\n disabled={deleting}\n sx={{\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'none',\n '&:hover': {\n borderColor: 'hsl(var(--border) / 0.8)',\n backgroundColor: 'hsl(var(--muted) / 0.5)',\n },\n }}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={() => {\n if (deleteConfirmAuthId) handleDeleteAuth(deleteConfirmAuthId);\n }}\n disabled={deleting}\n sx={{\n backgroundColor: 'hsl(var(--destructive))',\n color: 'hsl(var(--destructive-foreground))',\n textTransform: 'none',\n fontWeight: 600,\n '&:hover': { backgroundColor: 'hsl(var(--destructive) / 0.9)' },\n '&.Mui-disabled': {\n backgroundColor: 'hsl(var(--destructive) / 0.3)',\n color: 'hsl(var(--destructive-foreground) / 0.5)',\n },\n }}\n >\n {deleting ? 'Deleting...' : 'Delete'}\n </Button>\n </Box>\n </DialogContent>\n </Dialog>\n\n {/* Show selected auth info if not adding new */}\n {!showAddNewForm && selectedAuth && (\n <Box sx={{ \n mt: 2, \n p: 0,\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: 3,\n border: '1px solid hsl(var(--border))',\n overflow: 'hidden',\n }}>\n {/* Active authentication header */}\n <Box sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: { xs: 2, sm: 2.5 },\n py: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background-surface))',\n }}>\n <Box sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: localTestStatus === 'success' \n ? 'hsl(var(--severity-low))' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium))'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive))'\n : 'hsl(var(--muted-foreground))',\n boxShadow: localTestStatus === 'success' \n ? '0 0 8px hsl(var(--severity-low) / 0.6)'\n : localTestStatus === 'pending_validation'\n ? '0 0 8px hsl(var(--severity-medium) / 0.6)'\n : localTestStatus === 'error'\n ? '0 0 8px hsl(var(--destructive) / 0.6)'\n : '0 0 8px hsl(var(--muted-foreground) / 0.4)',\n }} />\n <Typography sx={{ \n color: 'hsl(var(--muted-foreground))', \n fontSize: '0.75rem',\n fontWeight: 500,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}>\n {localTestStatus === 'success' \n ? 'Verified Authentication' \n : localTestStatus === 'pending_validation'\n ? 'Awaiting Backend Validation'\n : localTestStatus === 'error'\n ? 'Test Failed'\n : 'Pending Verification'}\n </Typography>\n </Box>\n\n {/* Main content area — always stacked vertically for drawer contexts */}\n <Box sx={{ \n display: 'flex', \n flexDirection: 'column',\n alignItems: 'stretch', \n gap: 2,\n p: { xs: 2, sm: 2.5 },\n }}>\n {/* Auth name with icon */}\n <Box sx={{ \n display: 'flex', \n alignItems: 'center', \n gap: 1.5, \n minWidth: 0,\n flex: 1,\n }}>\n <Box sx={{\n width: 36,\n height: 36,\n borderRadius: 2,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: localTestStatus === 'success' \n ? 'hsl(var(--severity-low) / 0.1)' \n : localTestStatus === 'error'\n ? 'hsl(var(--destructive) / 0.1)'\n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium) / 0.1)'\n : isTested\n ? 'hsl(var(--severity-low) / 0.1)'\n : isConfigured\n ? 'hsl(var(--severity-medium) / 0.1)' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground) / 0.1)',\n border: `1px solid ${\n localTestStatus === 'success' \n ? 'hsl(var(--severity-low) / 0.2)' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium) / 0.2)'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive) / 0.2)'\n : isTested\n ? 'hsl(var(--severity-low) / 0.2)'\n : isConfigured\n ? 'hsl(var(--severity-medium) / 0.2)' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground) / 0.2)'\n }`,\n flexShrink: 0,\n }}>\n <CheckCircleIcon sx={{ \n color: localTestStatus === 'success' \n ? 'hsl(var(--severity-low))' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium))'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive))'\n : isTested\n ? 'hsl(var(--severity-low))'\n : isConfigured\n ? 'hsl(var(--severity-medium))' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground))', \n fontSize: 20 \n }} />\n </Box>\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {editingLabel ? (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }} onClick={e => e.stopPropagation()}>\n <TextField\n value={editLabelValue}\n onChange={e => setEditLabelValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') handleRenameAuth();\n if (e.key === 'Escape') setEditingLabel(false);\n }}\n size=\"small\"\n autoFocus\n sx={{\n '& .MuiOutlinedInput-root': {\n height: 28,\n fontSize: '0.85rem',\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiOutlinedInput-input': { py: 0.25, px: 1 },\n }}\n />\n <Button\n size=\"small\"\n variant=\"contained\"\n onClick={handleRenameAuth}\n disabled={savingLabel || !editLabelValue.trim()}\n sx={{\n minWidth: 0,\n px: 1.5,\n py: 0.25,\n fontSize: '0.7rem',\n textTransform: 'none',\n bgcolor: 'hsl(var(--primary))',\n '&:hover': { bgcolor: 'hsl(var(--primary) / 0.9)' },\n }}\n >\n {savingLabel ? <CircularProgress size={12} sx={{ color: 'inherit' }} /> : 'Save'}\n </Button>\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => setEditingLabel(false)}\n sx={{\n minWidth: 0,\n px: 1,\n py: 0.25,\n fontSize: '0.7rem',\n textTransform: 'none',\n color: 'hsl(var(--muted-foreground))',\n }}\n >\n Cancel\n </Button>\n </Box>\n ) : (\n <>\n <Typography sx={{ \n color: 'hsl(var(--foreground))', \n fontWeight: 600, \n fontSize: { xs: '0.9rem', sm: '0.95rem' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n lineHeight: 1.3,\n }}>\n {selectedAuth.label || 'Selected authentication'}\n </Typography>\n <Tooltip title=\"Rename authentication\" arrow>\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n setEditLabelValue(selectedAuth.label || '');\n setEditingLabel(true);\n }}\n sx={{\n p: 0.3,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--primary))' },\n }}\n >\n <EditIcon sx={{ fontSize: 14 }} />\n </IconButton>\n </Tooltip>\n </>\n )}\n </Box>\n <Typography sx={{ \n color: localTestStatus === 'success' \n ? 'hsl(var(--severity-low))' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium))'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive))'\n : isTested\n ? 'hsl(var(--severity-low))'\n : isConfigured\n ? 'hsl(var(--severity-medium))' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground))', \n fontSize: '0.75rem',\n mt: 0.25,\n fontWeight: (localTestStatus !== 'untested' || isTested || isConfigured) ? 500 : 400,\n }}>\n {localTestStatus === 'success' \n ? '✓ Connection verified' \n : localTestStatus === 'pending_validation'\n ? '⏳ Test passed, awaiting backend validation'\n : localTestStatus === 'error'\n ? '✗ Test failed'\n : localTestStatus === 'testing'\n ? 'Testing...'\n : 'Not tested in this session'}\n </Typography>\n </Box>\n </Box>\n\n {/* Test Connection button */}\n <Button\n variant={authState.status === 'testing' ? 'contained' : 'outlined'}\n size=\"medium\"\n onClick={(e) => {\n e.stopPropagation();\n // Track which auth is being tested so results go to the right auth\n setTestingAuthId(selectedAuthId);\n onTestConnection(app.objectID, selectedAuthId !== ADD_NEW_AUTH ? selectedAuthId : undefined);\n }}\n disabled={authState.status === 'testing'}\n startIcon={\n authState.status === 'testing' \n ? <CircularProgress size={16} sx={{ color: 'inherit' }} />\n : <CheckCircleIcon sx={{ fontSize: 18 }} />\n }\n sx={{\n borderColor: authState.status === 'testing' ? 'transparent' : 'hsl(var(--primary) / 0.5)',\n color: authState.status === 'testing' ? 'hsl(var(--foreground))' : 'hsl(var(--primary))',\n background: authState.status === 'testing' \n ? 'linear-gradient(90deg, hsl(var(--primary) / 0.3) 0%, hsl(var(--primary) / 0.5) 50%, hsl(var(--primary) / 0.3) 100%)'\n : 'transparent',\n backgroundSize: authState.status === 'testing' ? '200% 100%' : 'auto',\n animation: authState.status === 'testing' ? 'shimmer 1.5s infinite linear' : 'none',\n fontWeight: 600,\n textTransform: 'none',\n px: 3,\n py: 1,\n borderRadius: 2,\n flexShrink: 0,\n minWidth: 160,\n width: '100%',\n transition: 'all 0.3s ease',\n '@keyframes shimmer': {\n '0%': { backgroundPosition: '200% 0' },\n '100%': { backgroundPosition: '-200% 0' },\n },\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: authState.status === 'testing' ? undefined : 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n color: authState.status === 'testing' ? 'hsl(var(--foreground))' : 'hsl(var(--muted-foreground))',\n borderColor: authState.status === 'testing' ? 'transparent' : 'hsl(var(--border))',\n },\n }}\n >\n {authState.status === 'testing' ? 'Testing Connection...' : 'Test Connection'}\n </Button>\n </Box>\n\n {/* Status messages - only show for current test session */}\n {localTestStatus === 'error' && localTestMessages.errorMessage && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--destructive))' },\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, width: '100%' }}>\n <Typography sx={{ fontSize: '0.875rem', flex: 1 }}>\n {localTestMessages.errorMessage}\n </Typography>\n {localTestMessages.workflowId && localTestMessages.executionId && (\n <Button\n variant=\"outlined\"\n size=\"small\"\n href={`https://shuffler.io/workflows/${localTestMessages.workflowId}?execution_id=${localTestMessages.executionId}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n borderColor: 'hsl(var(--destructive) / 0.5)',\n color: 'hsl(var(--destructive))',\n textTransform: 'none',\n fontSize: '0.75rem',\n py: 0.5,\n px: 1.5,\n flexShrink: 0,\n '&:hover': {\n borderColor: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n View Execution\n </Button>\n )}\n </Box>\n </Alert>\n </Box>\n )}\n {localTestStatus === 'success' && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity={localTestMessages.warningMessage ? \"warning\" : \"success\"}\n sx={{\n backgroundColor: localTestMessages.warningMessage \n ? 'hsl(var(--severity-medium) / 0.1)' \n : 'hsl(var(--severity-low) / 0.1)',\n color: localTestMessages.warningMessage ? 'hsl(var(--severity-medium))' : 'hsl(var(--severity-low))',\n border: localTestMessages.warningMessage \n ? '1px solid hsl(var(--severity-medium) / 0.2)' \n : '1px solid hsl(var(--severity-low) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { \n color: localTestMessages.warningMessage ? 'hsl(var(--severity-medium))' : 'hsl(var(--severity-low))' \n },\n }}\n >\n {localTestMessages.warningMessage ? (\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n {localTestMessages.successMessage || 'Connection probably working'}\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9 }}>\n {localTestMessages.warningMessage}\n </Typography>\n </Box>\n ) : (\n localTestMessages.successMessage || 'Connection verified successfully'\n )}\n </Alert>\n </Box>\n )}\n {localTestStatus === 'pending_validation' && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity=\"warning\"\n sx={{\n backgroundColor: 'hsl(var(--severity-medium) / 0.1)',\n color: 'hsl(var(--severity-medium))',\n border: '1px solid hsl(var(--severity-medium) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-medium))' },\n }}\n >\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n Test passed (Status 200), but not marked as validated\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9, mb: 1 }}>\n The API returned success, but Shuffle hasn't confirmed the validation yet. This could mean credentials are correct but the app needs additional setup.\n </Typography>\n <Link \n href={`${API_CONFIG.baseUrl}/admin?tab=app_auth`}\n target=\"_blank\"\n sx={{ \n color: 'hsl(var(--severity-medium))', \n fontWeight: 500,\n fontSize: '0.85rem',\n textDecoration: 'underline',\n '&:hover': { opacity: 0.8 }\n }}\n >\n Check status in Admin → App Authentication\n </Link>\n </Box>\n </Alert>\n </Box>\n )}\n </Box>\n )}\n </Box>\n )}\n\n {/* Show form when no auths exist or \"Add new\" is selected */}\n {(apiAuthEntries.length === 0 || showAddNewForm) && (\n <Box sx={{ \n p: 3, \n backgroundColor: 'hsl(var(--muted))', \n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n }}>\n {/* Show credential error notice if switched due to 401/403 */}\n {isCredentialError && (\n <Alert\n severity=\"warning\"\n sx={{\n backgroundColor: 'hsl(var(--severity-medium) / 0.1)',\n color: 'hsl(var(--severity-medium))',\n border: '1px solid hsl(var(--severity-medium) / 0.2)',\n borderRadius: 2,\n mb: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-medium))' },\n }}\n >\n <Typography sx={{ fontSize: '0.875rem' }}>\n {localTestMessages.errorCode === 401 \n ? 'Previous credentials were invalid or expired. Please enter new credentials.'\n : 'Access was denied with the previous credentials. Please re-authenticate with valid permissions.'}\n </Typography>\n </Alert>\n )}\n <Typography variant=\"subtitle2\" sx={{ color: 'hsl(var(--primary))', fontWeight: 600, mb: 2 }}>\n {apiAuthEntries.length === 0 ? 'Configure Authentication' : 'Add New Authentication'}\n </Typography>\n \n {loading ? (\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', py: 4 }}>\n <CircularProgress size={32} sx={{ color: 'hsl(var(--primary))' }} />\n <Typography sx={{ ml: 2, color: 'hsl(var(--muted-foreground))' }}>\n Loading configuration...\n </Typography>\n </Box>\n ) : error ? (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n {error}\n </Alert>\n ) : isNoAuthRequired(auth) ? (\n <Alert\n severity=\"info\"\n sx={{\n backgroundColor: 'hsl(var(--severity-info) / 0.1)',\n color: 'hsl(var(--severity-info))',\n border: '1px solid hsl(var(--severity-info) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-info))' },\n }}\n >\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n No authentication required\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9 }}>\n This app works without credentials. You can use it directly.\n </Typography>\n </Box>\n </Alert>\n ) : (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n {/* Render dynamic fields based on auth type */}\n {renderOAuth2Fields()}\n {renderParameterFields()}\n\n {authState.status === 'error' && authState.errorMessage && (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, width: '100%' }}>\n <Typography sx={{ fontSize: '0.875rem', flex: 1 }}>\n {authState.errorMessage}\n </Typography>\n {authState.workflowId && authState.executionId && (\n <Button\n variant=\"outlined\"\n size=\"small\"\n href={`https://shuffler.io/workflows/${authState.workflowId}?execution_id=${authState.executionId}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n borderColor: 'hsl(var(--destructive) / 0.5)',\n color: 'hsl(var(--destructive))',\n textTransform: 'none',\n fontSize: '0.75rem',\n py: 0.5,\n px: 1.5,\n flexShrink: 0,\n '&:hover': {\n borderColor: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n View Execution\n </Button>\n )}\n </Box>\n </Alert>\n )}\n\n {/* Success message removed per user request */}\n\n {saveSuccess === false && (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n Failed to save authentication. Please try again.\n </Alert>\n )}\n\n {/* Save button for non-OAuth2 apps */}\n {!isOAuth2 && (\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', pt: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"medium\"\n onClick={(e) => {\n e.stopPropagation();\n handleSave();\n }}\n disabled={saving || !isFormValid()}\n sx={{\n borderColor: isFormValid() ? 'hsl(var(--primary) / 0.5)' : 'hsl(var(--border))',\n color: isFormValid() ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '0.9rem',\n px: 3,\n py: 1,\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n },\n }}\n >\n {saving ? 'Saving...' : 'Save Authentication'}\n </Button>\n </Box>\n )}\n\n {/* Save & Authenticate button for OAuth2 apps with manual credentials */}\n {isOAuth2 && (() => {\n const hasClientId = !!localCredentials['client_id']?.trim();\n const hasClientSecret = !!localCredentials['client_secret']?.trim();\n const hasScopes = selectedScopes.length > 0;\n const hasAuthUrl = !!auth?.authorization_url;\n const allFilled = hasClientId && hasClientSecret && (!auth?.scope?.length || hasScopes);\n\n // Build the direct OAuth2 authorization URL with state\n const buildOAuth2Url = (): string | null => {\n if (!localCredentials['client_id']?.trim()) return null;\n \n // Resolve authorization URL from multiple possible fields,\n // or derive from token_uri (common pattern: /token → /authorize)\n const authorizationUrl = auth?.authorization_url \n || auth?.auth_uri \n || auth?.authorize_url\n || (auth?.token_uri ? auth.token_uri.replace(/\\/token\\b.*$/, '/authorize') : null);\n \n if (!authorizationUrl) return null;\n \n const redirectUri = auth?.redirect_uri || 'https://shuffler.io/set_authentication';\n const scopes = selectedScopes.join(' ');\n const clientId = localCredentials['client_id'].trim();\n const clientSecret = localCredentials['client_secret']?.trim() || '';\n\n // Build state parameter matching Shuffle's expected format\n const stateParams = new URLSearchParams({\n workflow_id: '',\n reference_action_id: app.objectID,\n app_name: app.name,\n app_id: app.objectID,\n app_version: app.app_version || '1.0.0',\n authentication_url: auth?.token_uri || '',\n scope: scopes,\n client_id: clientId,\n client_secret: clientSecret,\n org_id: 'undefined',\n oauth_url: auth?.token_uri?.replace(/\\/token.*$/, '') || '',\n refresh_uri: auth?.refresh_uri || auth?.token_uri || '',\n });\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n prompt: 'login',\n scope: scopes,\n state: stateParams.toString(),\n access_type: 'offline',\n });\n\n console.log('[OAuth2] Built direct auth URL:', `${authorizationUrl}?${params.toString()}`);\n return `${authorizationUrl}?${params.toString()}`;\n };\n\n return (\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', pt: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"medium\"\n startIcon={\n app.image_url ? (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 20, height: 20, borderRadius: 0.5, objectFit: 'contain' }}\n />\n ) : (\n <LockIcon sx={{ fontSize: 18 }} />\n )\n }\n onClick={(e) => {\n e.stopPropagation();\n // Open OAuth2 popup directly — no save step needed\n // The OAuth redirect callback handles credential storage\n const directUrl = buildOAuth2Url();\n const popupUrl = directUrl || `https://shuffler.io/appauth?app_id=${app.objectID}&source=shuffle`;\n const popup = window.open(popupUrl, '_blank', 'width=600,height=700');\n if (popup && onRefreshAuth) {\n const authPollTimer = setInterval(() => {\n onRefreshAuth();\n }, 3000);\n const closePollTimer = setInterval(() => {\n if (popup.closed) {\n clearInterval(closePollTimer);\n clearInterval(authPollTimer);\n onRefreshAuth();\n }\n }, 500);\n }\n }}\n disabled={!allFilled}\n sx={{\n borderColor: allFilled ? 'hsl(var(--primary) / 0.5)' : 'hsl(var(--border))',\n color: allFilled ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '0.9rem',\n px: 3,\n py: 1,\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n },\n }}\n >\n Authenticate\n </Button>\n </Box>\n );\n })()}\n </Box>\n )}\n </Box>\n )}\n </Box>\n </Collapse>\n </Card>\n\n {/* Documentation Modal */}\n <Dialog\n open={docsOpen}\n onClose={() => setDocsOpen(false)}\n maxWidth=\"md\"\n fullWidth\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 3,\n maxHeight: '80vh',\n },\n },\n }}\n >\n <DialogTitle\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n borderBottom: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>\n {app.image_url && (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 32, height: 32, borderRadius: 1, objectFit: 'contain' }}\n />\n )}\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n {app.name.replace(/_/g, ' ')} Documentation\n </Typography>\n </Box>\n <IconButton onClick={() => setDocsOpen(false)} sx={{ color: 'hsl(var(--muted-foreground))' }}>\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n <DialogContent sx={{ pt: 3 }}>\n {docsLoading ? (\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', py: 6 }}>\n <CircularProgress size={32} sx={{ color: 'hsl(var(--primary))' }} />\n <Typography sx={{ ml: 2, color: 'hsl(var(--muted-foreground))' }}>\n Loading documentation...\n </Typography>\n </Box>\n ) : (\n <Box\n sx={{\n color: 'hsl(var(--foreground))',\n '& h1, & h2, & h3, & h4': { color: 'hsl(var(--foreground))', mt: 3, mb: 2 },\n '& p': { mb: 2, lineHeight: 1.7 },\n '& code': {\n backgroundColor: 'hsl(var(--muted))',\n px: 1,\n py: 0.5,\n borderRadius: 1,\n fontSize: '0.875rem',\n },\n '& pre': {\n backgroundColor: 'hsl(var(--background))',\n p: 2,\n borderRadius: 2,\n overflow: 'auto',\n },\n '& a': { color: 'hsl(var(--primary))' },\n '& ul, & ol': { pl: 3, mb: 2 },\n '& li': { mb: 1 },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{docsContent}</ReactMarkdown>\n </Box>\n )}\n </DialogContent>\n </Dialog>\n </motion.div>\n );\n};\n\nexport const AppAuthConfig = ({\n apps,\n authStates,\n authenticatedApps = [],\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n onSelectAuth,\n onRefreshAuth,\n}: AppAuthConfigProps) => {\n // Helper to find ALL API auth entries for an app\n const getApiAuthEntries = (app: AlgoliaSearchApp): ApiAuthEntry[] => {\n const normalize = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n return authenticatedApps\n .filter(auth => normalize(auth.app?.name || '') === normalize(app.name))\n .map(auth => ({\n ...auth,\n app: {\n ...auth.app,\n large_image: auth.app?.large_image || app.image_url,\n },\n }));\n };\n\n // Helper to check if app is configured (has any auth entry)\n const isAppConfigured = (app: AlgoliaSearchApp): boolean => {\n const entries = getApiAuthEntries(app);\n return entries.some(e => e.active === true);\n };\n\n // Helper to check if app is validated (data is already pre-processed to invalidate old entries)\n const isAppValidated = (app: AlgoliaSearchApp): boolean => {\n const entries = getApiAuthEntries(app);\n return entries.some(e => e.validation?.valid === true);\n };\n\n // Keep initial sort order stable - only sort once when authenticatedApps is loaded\n const initialSortRef = useRef<AlgoliaSearchApp[] | null>(null);\n const authAppsLoadedRef = useRef<boolean>(false);\n \n // Reset sort ref when authenticatedApps first loads with data\n if (!authAppsLoadedRef.current && authenticatedApps.length > 0) {\n authAppsLoadedRef.current = true;\n initialSortRef.current = null; // Force re-sort\n }\n \n if (initialSortRef.current === null && apps.length > 0 && authenticatedApps.length > 0) {\n // Sort priority: \n // 1. Category-matched apps (email, siem, edr, cases) first\n // 2. Within each group: Not Configured > Not Tested > Tested\n const getPriority = (app: AlgoliaSearchApp): number => {\n const isSourceCategory = getIngestionCategory(app.name, app.categories) !== null;\n const configured = isAppConfigured(app);\n const validated = isAppValidated(app);\n \n // Category apps get priority 0-2, non-category apps get 3-5\n const base = isSourceCategory ? 0 : 3;\n if (!configured) return base; // Not Configured - top of group\n if (!validated) return base + 1; // Configured but Not Tested - middle\n return base + 2; // Tested - bottom of group\n };\n \n initialSortRef.current = [...apps].sort((a, b) => {\n return getPriority(a) - getPriority(b);\n });\n }\n\n // Use the stable initial sort, or fall back to apps if not yet initialized\n const sortedApps = initialSortRef.current || apps;\n\n // Find first non-validated app for auto-expand (prefer not configured, then not tested)\n const firstNotConfigured = sortedApps.find(app => !isAppConfigured(app));\n const firstNotValidated = sortedApps.find(app => !isAppValidated(app));\n const defaultExpanded = firstNotConfigured?.objectID || firstNotValidated?.objectID || sortedApps[0]?.objectID || false;\n\n const [expanded, setExpanded] = useState<string | false>(defaultExpanded);\n\n if (apps.length === 0) {\n return (\n <Alert\n severity=\"info\"\n sx={{\n backgroundColor: 'hsl(var(--primary) / 0.1)',\n color: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary) / 0.3)',\n borderRadius: 2,\n }}\n >\n No integrations selected. Go back and select at least one integration.\n </Alert>\n );\n }\n\n // Count validated vs total\n const validatedCount = sortedApps.filter(app => isAppValidated(app)).length;\n const totalCount = sortedApps.length;\n\n return (\n <Box sx={{ width: '100%', maxWidth: '100%', overflow: 'hidden' }}>\n <Typography\n variant=\"h5\"\n sx={{\n color: 'hsl(var(--foreground))',\n fontWeight: 700,\n mb: 1,\n fontSize: { xs: '1.25rem', sm: '1.5rem' },\n }}\n >\n Configure Authentication\n </Typography>\n <Typography\n variant=\"body1\"\n sx={{ mb: 2, color: 'hsl(var(--muted-foreground))', fontSize: { xs: '0.875rem', sm: '1rem' } }}\n >\n Set up credentials for each integration. Apps with orange borders need configuration.\n </Typography>\n <Chip\n label={`${validatedCount}/${totalCount} validated`}\n size=\"small\"\n sx={{\n mb: 3,\n background: validatedCount === totalCount \n ? 'hsl(var(--severity-low) / 0.15)' \n : 'hsl(var(--severity-medium) / 0.15)',\n color: validatedCount === totalCount ? 'hsl(var(--severity-low))' : 'hsl(var(--severity-medium))',\n fontWeight: 600,\n }}\n />\n\n <motion.div variants={containerVariants} initial=\"hidden\" animate=\"visible\">\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%', maxWidth: '100%' }}>\n {sortedApps.map((app) => {\n const authState = authStates[app.objectID] || { systemId: app.objectID, status: 'pending' as const, credentials: {} };\n const isExpanded = expanded === app.objectID;\n const apiAuthEntries = getApiAuthEntries(app);\n\n return (\n <AppAuthCard\n key={app.objectID}\n app={app}\n authState={authState}\n isExpanded={isExpanded}\n onToggle={() => setExpanded(isExpanded ? false : app.objectID)}\n onAuthChange={onAuthChange}\n onTestConnection={onTestConnection}\n onSaveAuth={onSaveAuth}\n apiAuthEntries={apiAuthEntries}\n onSelectAuth={onSelectAuth}\n onRefreshAuth={onRefreshAuth}\n />\n );\n })}\n </Box>\n </motion.div>\n </Box>\n );\n};\n","/**\n * TryMcpSection — Standalone \"Try MCP\" block.\n *\n * Wraps the heading + AppMcpChat. Pass in the resolved app props.\n */\n\nimport { Box, Typography } from '@mui/material';\nimport { motion } from 'framer-motion';\nimport AppMcpChat from '@/Shuffle-MCPs/AppMcpChat';\n\nexport interface TryMcpSectionProps {\n appName: string;\n /** Image URL used as the chat avatar. */\n appIcon?: string;\n /** Resolved app id (Algolia objectID or Shuffle id). */\n appId: string;\n /** App categories — used to pick suggested actions. */\n categories?: string[];\n}\n\nexport default function TryMcpSection({ appName, appIcon, appId, categories }: TryMcpSectionProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.15 }}>\n <Box sx={{ mt: 5, mb: 3 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem', mb: 1.5 }}>\n Try MCP\n </Typography>\n <AppMcpChat\n appName={appName}\n appIcon={appIcon}\n appId={appId}\n categories={categories}\n />\n </Box>\n </motion.div>\n );\n}\n","import { useState, useRef, useMemo } from 'react';\nimport {\n Box,\n Typography,\n Avatar,\n CircularProgress,\n Chip,\n InputBase,\n} from '@mui/material';\nimport AgentIcon from '@/Shuffle-MCPs/AgentIcon';\nimport PlayArrowRoundedIcon from '@mui/icons-material/PlayArrowRounded';\nimport RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport {\n THREAT_INTEL_PATTERNS,\n EMAIL_APP_PATTERNS,\n EDR_PATTERNS,\n SIEM_PATTERNS,\n CASES_PATTERNS,\n COMMUNICATION_PATTERNS_NAMES,\n} from '@/Shuffle-MCPs/ingestionDetection';\n\ninterface AppMcpChatProps {\n appName: string;\n appIcon?: string;\n appId?: string;\n categories?: string[];\n}\n\ntype RunState = 'idle' | 'running' | 'done';\n\n/** Category-based suggestion prompts — natural, actionable questions.\n * Keys are lowercase fragments that we match against app category strings. */\nconst CATEGORY_SUGGESTIONS: Record<string, string[]> = {\n 'threat': [\n 'Is 1.2.3.4 a known bad actor?',\n 'Check if this domain is malicious',\n 'Look up threat indicators for a hash',\n ],\n 'siem': [\n 'Show me the latest critical alerts',\n 'Any unusual login attempts today?',\n 'Summarize recent security events',\n ],\n 'email': [\n 'Did I get a message from my team yesterday?',\n 'Find emails with attachments from last week',\n 'Check for any phishing reports',\n ],\n 'communication': [\n 'Did I get a message from my team yesterday?',\n 'Send a status update to the channel',\n 'Check for unread notifications',\n ],\n 'edr': [\n 'Is this endpoint compromised?',\n 'Show recent detections on workstations',\n 'Isolate a suspicious host',\n ],\n 'endpoint': [\n 'Is this endpoint compromised?',\n 'Show recent detections on workstations',\n 'Isolate a suspicious host',\n ],\n 'cloud': [\n 'List my running instances',\n 'Any public S3 buckets detected?',\n 'Check IAM policy changes today',\n ],\n 'ticket': [\n 'What tickets are assigned to me?',\n 'Create a new incident ticket',\n 'Show open high-priority issues',\n ],\n 'itsm': [\n 'What tickets are assigned to me?',\n 'Create a new incident ticket',\n 'Show open high-priority issues',\n ],\n 'case': [\n 'What cases are assigned to me?',\n 'Create a new incident case',\n 'Show open high-priority cases',\n ],\n 'vulnerab': [\n 'Any new critical CVEs this week?',\n 'Check vulnerability status for this asset',\n 'Show unpatched systems',\n ],\n 'network': [\n 'Any unusual outbound connections?',\n 'Check firewall rule changes',\n 'Show top talkers in the last hour',\n ],\n 'identity': [\n 'Show recent failed login attempts',\n 'Is this user account locked out?',\n 'List users with admin privileges',\n ],\n 'intel': [\n 'Is 1.2.3.4 a known bad actor?',\n 'Check if this domain is malicious',\n 'Look up threat indicators for a hash',\n ],\n};\n\nconst DEFAULT_SUGGESTIONS = [\n 'What can you do?',\n 'Show me recent activity',\n 'Run a quick check',\n];\n\n/** Infer category keys from the app name using known patterns */\nfunction inferCategoryKeysFromName(appName: string): string[] {\n const name = appName.toLowerCase();\n const keys: string[] = [];\n if (THREAT_INTEL_PATTERNS.some(p => name.includes(p))) keys.push('threat', 'intel');\n if (EMAIL_APP_PATTERNS.some(p => name.includes(p))) keys.push('email');\n if (EDR_PATTERNS.some(p => name.includes(p))) keys.push('edr', 'endpoint');\n if (SIEM_PATTERNS.some(p => name.includes(p))) keys.push('siem');\n if (CASES_PATTERNS.some(p => name.includes(p))) keys.push('ticket', 'case');\n if (COMMUNICATION_PATTERNS_NAMES.some(p => name.includes(p))) keys.push('communication');\n return keys;\n}\n\nfunction getSuggestions(appName: string, categories?: string[]): string[] {\n const matched: string[] = [];\n\n // 1. Match from explicit categories\n if (categories && categories.length > 0) {\n for (const cat of categories) {\n const normalized = cat.toLowerCase();\n for (const [key, prompts] of Object.entries(CATEGORY_SUGGESTIONS)) {\n if (normalized.includes(key) || key.includes(normalized)) {\n matched.push(...prompts);\n }\n }\n }\n }\n\n // 2. Fallback: infer from the app name itself\n if (matched.length === 0) {\n const inferred = inferCategoryKeysFromName(appName);\n for (const inferredKey of inferred) {\n const prompts = CATEGORY_SUGGESTIONS[inferredKey];\n if (prompts) matched.push(...prompts);\n }\n }\n\n if (matched.length === 0) return DEFAULT_SUGGESTIONS;\n\n const unique = [...new Set(matched)];\n return unique.slice(0, 4);\n}\n\n/** Pick a short display label from categories, or infer from app name */\nfunction getPrimaryCategory(appName: string, categories?: string[]): string | null {\n if (categories && categories.length > 0) {\n const skip = ['other', 'general', 'integration'];\n const filtered = categories.filter(c => !skip.includes(c.toLowerCase()));\n if (filtered.length > 0) return filtered[0];\n return categories[0];\n }\n // Infer from name\n const name = appName.toLowerCase();\n if (THREAT_INTEL_PATTERNS.some(p => name.includes(p))) return 'Threat Intel';\n if (EMAIL_APP_PATTERNS.some(p => name.includes(p))) return 'Email';\n if (EDR_PATTERNS.some(p => name.includes(p))) return 'EDR';\n if (SIEM_PATTERNS.some(p => name.includes(p))) return 'SIEM';\n if (CASES_PATTERNS.some(p => name.includes(p))) return 'Ticketing';\n if (COMMUNICATION_PATTERNS_NAMES.some(p => name.includes(p))) return 'Communication';\n return null;\n}\n\nconst AppMcpChat = ({ appName, appIcon, appId, categories }: AppMcpChatProps) => {\n const [input, setInput] = useState('');\n const [runState, setRunState] = useState<RunState>('idle');\n const [query, setQuery] = useState('');\n const [result, setResult] = useState('');\n const [isError, setIsError] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const suggestions = useMemo(() => getSuggestions(appName, categories), [appName, categories]);\n const primaryCategory = useMemo(() => getPrimaryCategory(appName, categories), [appName, categories]);\n const MIN_INPUT_LENGTH = 6;\n const runAction = async () => {\n const trimmed = input.trim();\n if (trimmed.length < MIN_INPUT_LENGTH || runState === 'running') return;\n\n setQuery(trimmed);\n setInput('');\n setRunState('running');\n setResult('');\n setIsError(false);\n\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(appName)}/mcp`),\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: crypto.randomUUID(),\n method: 'tools/call',\n params: {\n tool_name: appName,\n tool_id: appId || appName,\n input: { text: trimmed },\n },\n }),\n }\n );\n\n // Read raw text first to handle non-JSON responses safely\n const rawText = await response.text();\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n setIsError(true);\n setResult(`Error ${response.status}: ${rawText || response.statusText}`);\n } else if (!contentType?.includes('application/json')) {\n // Got HTML or other non-JSON back\n if (rawText.trim().startsWith('<!') || rawText.includes('<html')) {\n setIsError(true);\n setResult(`Received an unexpected HTML response (status ${response.status}). This may indicate an auth redirect or server issue.`);\n } else {\n setResult(rawText);\n }\n } else {\n const data = JSON.parse(rawText);\n let content = '';\n\n if (typeof data === 'string') {\n content = data;\n } else if (data?.result) {\n // Extract message if result is an object with a message field\n if (typeof data.result === 'object' && data.result !== null) {\n if (data.result.message) {\n content = data.result.message;\n }\n // Append remaining fields as context if there's more than just message\n const rest = { ...data.result };\n delete rest.message;\n if (Object.keys(rest).length > 0) {\n const extra = JSON.stringify(rest, null, 2);\n content = content\n ? `${content}\\n\\n\\`\\`\\`json\\n${extra}\\n\\`\\`\\``\n : `\\`\\`\\`json\\n${extra}\\n\\`\\`\\``;\n }\n } else {\n content = String(data.result);\n }\n } else if (data?.response) {\n content = typeof data.response === 'string' ? data.response : JSON.stringify(data.response, null, 2);\n } else if (data?.message) {\n content = data.message;\n } else {\n content = `\\`\\`\\`json\\n${JSON.stringify(data, null, 2)}\\n\\`\\`\\``;\n }\n\n if (content) {\n setResult(content);\n } else {\n setResult('No output returned.');\n }\n }\n } catch (err) {\n setIsError(true);\n setResult(`Could not connect. ${err instanceof Error ? err.message : 'Unknown error'}`);\n } finally {\n setRunState('done');\n }\n };\n\n const reset = () => {\n setRunState('idle');\n setQuery('');\n setResult('');\n setIsError(false);\n setInput('');\n setTimeout(() => inputRef.current?.focus(), 50);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n runAction();\n }\n };\n\n const displayName = appName.replace(/_/g, ' ');\n\n return (\n <Box\n sx={{\n borderRadius: 3,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background))',\n overflow: 'hidden',\n }}\n >\n <AnimatePresence mode=\"wait\">\n {/* ── IDLE ── */}\n {runState === 'idle' && (\n <motion.div\n key=\"idle\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n >\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2.5 }}>\n {/* Label */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box\n sx={{\n width: 28,\n height: 28,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsl(var(--primary) / 0.1)',\n border: '1px solid hsl(var(--primary) / 0.2)',\n flexShrink: 0,\n }}\n >\n {appIcon ? (\n <Avatar\n src={appIcon}\n sx={{ width: 18, height: 18, '& img': { objectFit: 'contain' } }}\n />\n ) : (\n <AgentIcon size={16} />\n )}\n </Box>\n <Typography sx={{ fontSize: '0.8rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n Try it out\n </Typography>\n {primaryCategory && (\n <Chip\n label={primaryCategory}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 600,\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'capitalize',\n }}\n />\n )}\n <Chip\n label=\"MCP\"\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n letterSpacing: '0.06em',\n ml: 'auto',\n }}\n />\n </Box>\n\n {/* Command input */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--card))',\n px: 1.5,\n py: 0.75,\n transition: 'border-color 0.15s ease, box-shadow 0.15s ease',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary) / 0.5)',\n boxShadow: '0 0 0 3px hsl(var(--primary) / 0.08)',\n },\n }}\n >\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--primary))', fontWeight: 600, userSelect: 'none', fontFamily: \"'JetBrains Mono', monospace\" }}>\n ›\n </Typography>\n <InputBase\n inputRef={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={`Ask ${displayName} something…`}\n fullWidth\n sx={{\n fontSize: '0.82rem',\n color: 'hsl(var(--foreground))',\n '& input::placeholder': {\n color: 'hsl(var(--muted-foreground))',\n opacity: 0.7,\n },\n }}\n />\n <Box\n component=\"button\"\n onClick={runAction}\n disabled={input.trim().length < MIN_INPUT_LENGTH}\n title={input.trim().length < MIN_INPUT_LENGTH ? `Enter at least ${MIN_INPUT_LENGTH} characters` : undefined}\n sx={{\n all: 'unset',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 30,\n height: 30,\n borderRadius: '8px',\n flexShrink: 0,\n cursor: input.trim().length >= MIN_INPUT_LENGTH ? 'pointer' : 'not-allowed',\n backgroundColor: input.trim().length >= MIN_INPUT_LENGTH ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: input.trim().length >= MIN_INPUT_LENGTH ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n transition: 'all 0.15s ease',\n '&:hover': input.trim().length >= MIN_INPUT_LENGTH ? {\n filter: 'brightness(1.1)',\n } : {},\n }}\n >\n <PlayArrowRoundedIcon sx={{ fontSize: 18 }} />\n </Box>\n </Box>\n\n {/* Quick actions */}\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75 }}>\n {suggestions.map((s) => (\n <Chip\n key={s}\n label={s}\n size=\"small\"\n onClick={() => {\n setInput(s);\n inputRef.current?.focus();\n }}\n sx={{\n height: 26,\n fontSize: '0.7rem',\n fontWeight: 500,\n cursor: 'pointer',\n backgroundColor: 'transparent',\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n transition: 'all 0.15s ease',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n borderStyle: 'solid',\n borderColor: 'hsl(var(--primary) / 0.3)',\n },\n }}\n />\n ))}\n </Box>\n </Box>\n </motion.div>\n )}\n\n {/* ── RUNNING ── */}\n {runState === 'running' && (\n <motion.div\n key=\"running\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n >\n <Box sx={{ p: 3, display: 'flex', alignItems: 'center', gap: 2 }}>\n <CircularProgress size={20} thickness={5} sx={{ color: 'hsl(var(--primary))' }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n Executing…\n </Typography>\n <Typography\n sx={{\n fontSize: '0.72rem',\n color: 'hsl(var(--muted-foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontFamily: \"'JetBrains Mono', monospace\",\n }}\n >\n › {query}\n </Typography>\n </Box>\n </Box>\n </motion.div>\n )}\n\n {/* ── DONE ── */}\n {runState === 'done' && (\n <motion.div\n key=\"done\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n >\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2 }}>\n {/* Status bar */}\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {isError ? (\n <ErrorOutlineIcon sx={{ fontSize: 18, color: 'hsl(0 70% 55%)' }} />\n ) : (\n <CheckCircleOutlineIcon sx={{ fontSize: 18, color: 'hsl(145 60% 45%)' }} />\n )}\n <Typography sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {isError ? 'Failed' : 'Completed'}\n </Typography>\n </Box>\n <Chip\n icon={<RestartAltIcon sx={{ fontSize: 14 }} />}\n label=\"Run again\"\n size=\"small\"\n onClick={reset}\n sx={{\n height: 26,\n fontSize: '0.7rem',\n fontWeight: 500,\n cursor: 'pointer',\n backgroundColor: 'transparent',\n color: 'hsl(var(--muted-foreground))',\n border: '1px solid hsl(var(--border))',\n transition: 'all 0.15s ease',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n },\n }}\n />\n </Box>\n\n {/* Query echo */}\n <Typography\n sx={{\n fontSize: '0.72rem',\n color: 'hsl(var(--muted-foreground))',\n fontFamily: \"'JetBrains Mono', monospace\",\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n › {query}\n </Typography>\n\n {/* Output */}\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n backgroundColor: 'hsl(var(--card))',\n border: '1px solid',\n borderColor: isError ? 'hsl(0 60% 50% / 0.25)' : 'hsl(var(--border))',\n maxHeight: 340,\n overflowY: 'auto',\n '&::-webkit-scrollbar': { width: 4 },\n '&::-webkit-scrollbar-track': { background: 'transparent' },\n '&::-webkit-scrollbar-thumb': {\n background: 'hsl(var(--border))',\n borderRadius: 2,\n },\n '& p': {\n fontSize: '0.8rem',\n lineHeight: 1.65,\n color: 'hsl(var(--foreground))',\n m: 0,\n '&:not(:last-child)': { mb: 1 },\n },\n '& pre': {\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1,\n p: 1.5,\n overflow: 'auto',\n fontSize: '0.72rem',\n fontFamily: \"'JetBrains Mono', monospace\",\n my: 1,\n },\n '& code': {\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n backgroundColor: 'hsl(var(--muted))',\n px: 0.5,\n borderRadius: 0.5,\n },\n '& pre code': { backgroundColor: 'transparent', p: 0 },\n '& ul, & ol': {\n pl: 2,\n fontSize: '0.8rem',\n color: 'hsl(var(--foreground))',\n },\n '& a': {\n color: 'hsl(var(--primary))',\n textDecoration: 'underline',\n },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {result}\n </ReactMarkdown>\n </Box>\n </Box>\n </motion.div>\n )}\n </AnimatePresence>\n </Box>\n );\n};\n\nexport default AppMcpChat;\n","import singulAgentIcon from '@/assets/singul-agent-icon.png';\n\ninterface AgentIconProps {\n size?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Renders the Singul agent icon — use this everywhere instead of 🤖.\n */\nconst AgentIcon = ({ size = 16, className, style }: AgentIconProps) => (\n <img\n src={singulAgentIcon}\n alt=\"AI Agent\"\n width={size}\n height={size}\n className={className}\n style={{ borderRadius: '3px', objectFit: 'contain', ...style }}\n />\n);\n\nexport default AgentIcon;\n","/**\n * SingulActionsPreview — Standalone \"Try individual actions\" block.\n *\n * Renders the action picker (grouped by category), curl/python toggle,\n * editable snippet, Play button (calls Shuffle Tools `execute_python` or\n * the http app `curl` action) and a response area that streams in.\n *\n * Self-contained — pass in the app name + categories. Optionally pass\n * `activeOrgId` so multi-org curl previews include the right Org-Id header.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport {\n Box,\n Typography,\n Chip,\n Button,\n Autocomplete,\n TextField,\n IconButton,\n Tooltip,\n Avatar,\n} from '@mui/material';\nimport PlayArrowIcon from '@mui/icons-material/PlayArrow';\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy';\nimport CheckIcon from '@mui/icons-material/Check';\nimport LockIcon from '@mui/icons-material/Lock';\nimport { Code2, Terminal } from 'lucide-react';\nimport { API_CONFIG, getApiUrl, getAuthHeader, getTrackedOrgId } from '@/Shuffle-MCPs/api';\nimport JsonView from 'react18-json-view';\nimport 'react18-json-view/src/style.css';\nimport 'react18-json-view/src/dark.css';\n\n/** Recursively parse JSON-looking strings into objects/arrays so JsonView can collapse them. */\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n } catch { /* ignore */ }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\ninterface SingulAction {\n name: string;\n label: string;\n category: string;\n fields: { name: string; value: string }[];\n}\n\n/** Default starter fields per canonical action (lowercased snake_case key). */\nconst ACTION_DEFAULT_FIELDS: Record<string, { name: string; value: string }[]> = {\n list_messages: [{ name: 'channel', value: '#general' }, { name: 'limit', value: '10' }],\n send_message: [{ name: 'channel', value: '#general' }, { name: 'message', value: 'Hello from Shuffle' }],\n get_message: [{ name: 'message_id', value: '' }],\n search_messages: [{ name: 'query', value: 'incident' }],\n list_attachments: [{ name: 'message_id', value: '' }],\n get_attachment: [{ name: 'attachment_id', value: '' }],\n get_contact: [{ name: 'email', value: 'user@example.com' }],\n\n search: [{ name: 'query', value: 'event.type:login' }, { name: 'time_range', value: '24h' }],\n list_alerts: [{ name: 'severity', value: 'high' }],\n close_alert: [{ name: 'alert_id', value: '' }],\n get_alert: [{ name: 'alert_id', value: '' }],\n create_detection: [{ name: 'name', value: 'My detection' }, { name: 'query', value: 'event.type:login AND result:failure' }],\n add_to_lookup_list: [{ name: 'list_name', value: 'blocked_ips' }, { name: 'value', value: '1.2.3.4' }],\n isolate_endpoint: [{ name: 'host_id', value: '' }],\n\n block_hash: [{ name: 'hash', value: 'd41d8cd98f00b204e9800998ecf8427e' }],\n search_hosts: [{ name: 'query', value: 'hostname:laptop-*' }],\n isolate_host: [{ name: 'host_id', value: '' }],\n unisolate_host: [{ name: 'host_id', value: '' }],\n trigger_host_scan: [{ name: 'host_id', value: '' }],\n\n list_tickets: [{ name: 'status', value: 'open' }],\n get_ticket: [{ name: 'ticket_id', value: '' }],\n create_ticket: [{ name: 'title', value: 'New incident' }, { name: 'description', value: '' }, { name: 'priority', value: 'medium' }],\n close_ticket: [{ name: 'ticket_id', value: '' }],\n add_comment: [{ name: 'ticket_id', value: '' }, { name: 'comment', value: 'Investigation update' }],\n update_ticket: [{ name: 'ticket_id', value: '' }, { name: 'status', value: 'in_progress' }],\n search_tickets: [{ name: 'query', value: 'status:open' }],\n\n list_assets: [{ name: 'limit', value: '50' }],\n get_asset: [{ name: 'asset_id', value: '' }],\n search_assets: [{ name: 'query', value: 'os:windows' }],\n search_users: [{ name: 'query', value: 'department:finance' }],\n search_endpoints: [{ name: 'query', value: 'os:windows' }],\n search_vulnerabilities: [{ name: 'severity', value: 'critical' }],\n\n get_ioc: [{ name: 'value', value: '1.2.3.4' }],\n search_ioc: [{ name: 'query', value: 'malicious.com' }],\n create_ioc: [{ name: 'type', value: 'ipv4' }, { name: 'value', value: '1.2.3.4' }],\n update_ioc: [{ name: 'ioc_id', value: '' }, { name: 'value', value: '1.2.3.4' }],\n delete_ioc: [{ name: 'ioc_id', value: '' }],\n\n reset_password: [{ name: 'user_id', value: '' }],\n enable_user: [{ name: 'user_id', value: '' }],\n disable_user: [{ name: 'user_id', value: '' }],\n get_identity: [{ name: 'user_id', value: '' }],\n search_identity: [{ name: 'query', value: 'department:finance' }],\n get_kms_key: [{ name: 'key_id', value: '' }],\n\n get_rules: [],\n allow_ip: [{ name: 'ip', value: '1.2.3.4' }],\n block_ip: [{ name: 'ip', value: '1.2.3.4' }],\n\n answer_question: [{ name: 'question', value: 'What is this alert about?' }],\n run_action: [{ name: 'app', value: 'jira' }, { name: 'action', value: 'create_ticket' }],\n run_llm: [{ name: 'prompt', value: 'Summarize this incident' }, { name: 'model', value: 'gpt-4o-mini' }],\n\n update_info: [{ name: 'key', value: '' }, { name: 'value', value: '' }],\n get_info: [{ name: 'key', value: '' }],\n get_status: [],\n get_version: [],\n get_health: [],\n get_config: [{ name: 'key', value: '' }],\n get_configs: [],\n get_configs_by_type: [{ name: 'type', value: '' }],\n get_configs_by_name: [{ name: 'name', value: '' }],\n run_script: [{ name: 'script', value: 'whoami' }],\n};\n\n/** Default categories + their action labels (canonical order). */\nconst ACTION_CATEGORIES: { name: string; action_labels: string[] }[] = [\n { name: 'Communication', action_labels: ['List Messages', 'Send Message', 'Get Message', 'Search messages', 'List Attachments', 'Get Attachment', 'Get Contact'] },\n { name: 'SIEM', action_labels: ['Search', 'List Alerts', 'Close Alert', 'Get Alert', 'Create detection', 'Add to lookup list', 'Isolate endpoint'] },\n { name: 'Eradication', action_labels: ['List Alerts', 'Close Alert', 'Get Alert', 'Create detection', 'Block hash', 'Search Hosts', 'Isolate host', 'Unisolate host', 'Trigger host scan'] },\n { name: 'Cases', action_labels: ['List tickets', 'Get ticket', 'Create ticket', 'Close ticket', 'Add comment', 'Update ticket', 'Search tickets'] },\n { name: 'Assets', action_labels: ['List Assets', 'Get Asset', 'Search Assets', 'Search Users', 'Search endpoints', 'Search vulnerabilities'] },\n { name: 'Intel', action_labels: ['Get IOC', 'Search IOC', 'Create IOC', 'Update IOC', 'Delete IOC'] },\n { name: 'IAM', action_labels: ['Reset Password', 'Enable user', 'Disable user', 'Get Identity', 'Get Asset', 'Search Identity', 'Get KMS Key'] },\n { name: 'Network', action_labels: ['Get Rules', 'Allow IP', 'Block IP'] },\n { name: 'AI', action_labels: ['Answer Question', 'Run Action', 'Run LLM'] },\n { name: 'Internal', action_labels: ['Answer Question', 'Run Action', 'Run LLM'] },\n { name: 'Other', action_labels: ['Update Info', 'Get Info', 'Get Status', 'Get Version', 'Get Health', 'Get Config', 'Get Configs', 'Get Configs by type', 'Get Configs by name', 'Run script'] },\n];\n\nconst labelToName = (label: string) =>\n label.trim().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '');\n\n/** Flat list of ALL actions across every category, preserving order. */\nconst ALL_ACTIONS: SingulAction[] = ACTION_CATEGORIES.flatMap((cat) =>\n cat.action_labels.map((label) => {\n const name = labelToName(label);\n return {\n name,\n label,\n category: cat.name,\n fields: ACTION_DEFAULT_FIELDS[name] ?? [],\n };\n }),\n);\n\n/** Pick the best matching default category for an app, given its raw categories. */\nfunction pickDefaultCategory(categories?: string[]): string {\n if (!categories || categories.length === 0) return 'Other';\n const known = ACTION_CATEGORIES.map((c) => c.name.toLowerCase());\n for (const cat of categories) {\n const n = cat.toLowerCase();\n const direct = known.find((k) => k === n);\n if (direct) return ACTION_CATEGORIES.find((c) => c.name.toLowerCase() === direct)!.name;\n const partial = known.find((k) => n.includes(k) || k.includes(n));\n if (partial) return ACTION_CATEGORIES.find((c) => c.name.toLowerCase() === partial)!.name;\n }\n return 'Other';\n}\n\nfunction buildSingulCurl(\n appName: string,\n action: SingulAction | null,\n opts?: { apiKey?: string | null; orgId?: string | null; baseUrl?: string },\n): string {\n const act = action?.name || '{action}';\n const body = {\n app: appName || '<appname>',\n action: act,\n fields: action?.fields.length ? action.fields : [{ name: 'field1', value: 'value1' }],\n };\n const token = opts?.apiKey || 'YOUR_TOKEN';\n const orgLine = opts?.orgId ? `\\n -H \"Org-Id: ${opts.orgId}\" \\\\` : '';\n const base = (opts?.baseUrl || '').replace(/\\/+$/, '');\n return `curl -X POST ${base}/api/v1/singul \\\\\n -H \"Authorization: Bearer ${token}\" \\\\${orgLine}\n -d '${JSON.stringify(body, null, 2)}'`;\n}\n\nfunction buildSingulPython(\n appName: string,\n action: SingulAction | null,\n opts?: { apiKey?: string | null; baseUrl?: string },\n): string {\n const act = action?.name || 'send_message';\n const app = appName || '<appname>';\n const fields = action?.fields.length ? action.fields : [];\n const fieldsStr = JSON.stringify(fields);\n const token = opts?.apiKey || 'APIKEY';\n const base = (opts?.baseUrl || '').replace(/\\/+$/, '');\n return `from shufflepy import Singul\n\nsingul = Singul(\n \"${token}\",\n url=\"${base}\",\n)\n\nresponse = singul.run(\"${app}\", action=\"${act}\", fields=${fieldsStr})\n\nprint(response)`;\n}\n\ntype SnippetLang = 'curl' | 'python';\n\n/** HTML-escape user content before injecting into a highlighted <pre>. */\nconst escapeHtml = (s: string) =>\n s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\n/** Single-pass tokenizer-based highlighter. We MUST NOT run successive regex\n * passes over already-highlighted HTML, because the inline `style=\"color:hsl(...)\"`\n * attributes contain words/numbers that later passes would happily re-match\n * (e.g. `hsl` matches `\\w+(?=\\()`, digits inside `280` match `\\d+`). */\nfunction highlightSnippet(code: string, lang: SnippetLang): string {\n const COL = {\n string: 'hsl(140 60% 65%)',\n keyword: 'hsl(280 70% 75%)',\n func: 'hsl(45 90% 65%)',\n number: 'hsl(20 90% 65%)',\n flag: 'hsl(200 80% 70%)',\n builtin: 'hsl(0 70% 70%)',\n comment: 'hsl(var(--muted-foreground))',\n };\n const PY_KEYWORDS = new Set([\n 'import', 'from', 'as', 'def', 'return', 'if', 'else', 'elif', 'for',\n 'while', 'in', 'None', 'True', 'False', 'print', 'class', 'with', 'try', 'except',\n ]);\n const wrap = (color: string, text: string) =>\n `<span style=\"color:${color}\">${escapeHtml(text)}</span>`;\n\n const out: string[] = [];\n let i = 0;\n const n = code.length;\n while (i < n) {\n const ch = code[i];\n // Strings\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n let j = i + 1;\n while (j < n && code[j] !== quote) {\n if (code[j] === '\\\\' && j + 1 < n) j += 2;\n else j++;\n }\n j = Math.min(j + 1, n);\n out.push(wrap(COL.string, code.slice(i, j)));\n i = j;\n continue;\n }\n // Python comments\n if (lang === 'python' && ch === '#') {\n let j = i;\n while (j < n && code[j] !== '\\n') j++;\n out.push(wrap(COL.comment, code.slice(i, j)));\n i = j;\n continue;\n }\n // Curl flags ( -X / --header ), only at start of token\n if (lang === 'curl' && ch === '-' && (i === 0 || /\\s/.test(code[i - 1]))) {\n let j = i + 1;\n if (code[j] === '-') j++;\n while (j < n && /[\\w-]/.test(code[j])) j++;\n out.push(wrap(COL.flag, code.slice(i, j)));\n i = j;\n continue;\n }\n // Numbers\n if (/\\d/.test(ch)) {\n let j = i;\n while (j < n && /[\\d.]/.test(code[j])) j++;\n out.push(wrap(COL.number, code.slice(i, j)));\n i = j;\n continue;\n }\n // Identifiers / keywords / function calls\n if (/[A-Za-z_]/.test(ch)) {\n let j = i;\n while (j < n && /[\\w]/.test(code[j])) j++;\n const word = code.slice(i, j);\n if (lang === 'python' && PY_KEYWORDS.has(word)) {\n out.push(wrap(COL.keyword, word));\n } else if (lang === 'curl' && word === 'curl') {\n out.push(wrap(COL.builtin, word));\n } else if (code[j] === '(') {\n out.push(wrap(COL.func, word));\n } else {\n out.push(escapeHtml(word));\n }\n i = j;\n continue;\n }\n // Plain char (operators, whitespace, punctuation)\n out.push(escapeHtml(ch));\n i++;\n }\n return out.join('');\n}\n\n\n\nconst SingulActionsPreview = ({\n appName,\n appIcon,\n categories,\n activeOrgId,\n onAuthenticate,\n}: {\n appName: string;\n appIcon?: string;\n categories?: string[];\n activeOrgId?: string | null;\n /** Optional click handler invoked when the user presses the\n * \"Authenticate {App}\" button surfaced after an\n * `action: \"app_authentication\"` response. */\n onAuthenticate?: (appName: string) => void;\n}) => {\n const defaultCategory = useMemo(() => pickDefaultCategory(categories), [categories]);\n const actions = ALL_ACTIONS;\n // Sort so that the app's default category appears first, rest follow original order.\n const sortedActions = useMemo(() => {\n const inCat = actions.filter((a) => a.category === defaultCategory);\n const rest = actions.filter((a) => a.category !== defaultCategory);\n return [...inCat, ...rest];\n }, [actions, defaultCategory]);\n const isDisabled = false;\n const [selected, setSelected] = useState<SingulAction | null>(null);\n const [lang, setLang] = useState<SnippetLang>('curl');\n const [snippet, setSnippet] = useState<string>('');\n\n const curlOpts = useMemo(() => {\n const apiKey = API_CONFIG.apiKey;\n const trackedOrg = getTrackedOrgId();\n const orgId = trackedOrg && activeOrgId && trackedOrg !== activeOrgId ? trackedOrg : null;\n const baseUrl = API_CONFIG.baseUrl;\n return { apiKey, orgId, baseUrl };\n }, [activeOrgId]);\n\n const buildSnippet = useCallback(\n (action: SingulAction | null, l: SnippetLang) =>\n l === 'python' ? buildSingulPython(appName, action, curlOpts) : buildSingulCurl(appName, action, curlOpts),\n [appName, curlOpts],\n );\n\n useEffect(() => {\n const initial = sortedActions[0] || null;\n setSelected(initial);\n setSnippet(buildSnippet(initial, lang));\n }, [appName, sortedActions, curlOpts, lang, buildSnippet]);\n\n const handleSelect = (action: SingulAction | null) => {\n setSelected(action);\n setSnippet(buildSnippet(action, lang));\n };\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(snippet);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n toast.error('Copy failed');\n }\n };\n\n const [playLoading, setPlayLoading] = useState(false);\n const [playResult, setPlayResult] = useState<string | null>(null);\n const responseRef = useRef<HTMLDivElement | null>(null);\n const [copied, setCopied] = useState(false);\n\n const scrollToResponse = () => {\n requestAnimationFrame(() => {\n responseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n });\n };\n\n const handlePlay = async () => {\n if (!snippet || playLoading) return;\n setPlayLoading(true);\n setPlayResult('');\n scrollToResponse();\n try {\n const body = lang === 'python'\n ? {\n name: 'execute_python',\n app_id: '3e2bdf9d5069fe3f4746c29d68785a6a',\n environment: 'Cloud',\n parameters: [{ name: 'code', value: snippet, schema: { type: 'string' } }],\n app_name: 'Shuffle Tools',\n app_version: '1.2.0',\n }\n : {\n name: 'curl',\n app_id: 'ebfe7d5c80000676588f86731db0a555',\n environment: 'Cloud',\n parameters: [{ name: 'statement', value: snippet, schema: { type: 'string' } }],\n app_name: 'http',\n app_version: '1.4.0',\n };\n const path = lang === 'python' ? '/api/v1/apps/3e2bdf9d5069fe3f4746c29d68785a6a/run?delete=true' : '/api/v1/apps/http/run?delete=true';\n const res = await fetch(getApiUrl(path), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...getAuthHeader() },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n let output = data?.result;\n if (typeof output === 'string') {\n try { output = JSON.stringify(JSON.parse(output), null, 2); } catch {}\n } else if (output != null) {\n output = JSON.stringify(output, null, 2);\n } else {\n output = JSON.stringify(data, null, 2);\n }\n setPlayResult(output);\n const parsed = (() => { try { return JSON.parse(data?.result || '{}'); } catch { return null; } })();\n if (parsed?.success === false) {\n toast.error(parsed.reason || 'Run failed');\n } else {\n toast.success(`Ran ${selected?.name || lang}`);\n }\n } catch (err: any) {\n const msg = err?.message || 'Run failed';\n setPlayResult(msg);\n toast.error(msg);\n } finally {\n setPlayLoading(false);\n scrollToResponse();\n }\n };\n\n const lineCount = useMemo(() => Math.max(snippet.split('\\n').length, 1), [snippet]);\n\n return (\n <Box sx={{ mt: 5, mb: 3, opacity: isDisabled ? 0.55 : 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.5 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem' }}>\n Try individual actions\n </Typography>\n <Chip\n label=\"Preview\"\n size=\"small\"\n sx={{ height: 18, fontSize: '0.6rem', fontWeight: 500, backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' }}\n />\n </Box>\n\n <Box\n sx={{\n position: 'relative',\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n background: 'linear-gradient(180deg, hsl(var(--muted) / 0.35) 0%, hsl(var(--background) / 0.6) 100%)',\n pointerEvents: isDisabled ? 'none' : 'auto',\n overflow: 'hidden',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n inset: -1,\n borderRadius: 2,\n padding: '1px',\n background: 'linear-gradient(135deg, hsl(var(--primary) / 0.35), transparent 40%, hsl(var(--primary) / 0.15))',\n WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',\n WebkitMaskComposite: 'xor',\n maskComposite: 'exclude',\n pointerEvents: 'none',\n },\n }}\n >\n {isDisabled ? (\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', fontStyle: 'italic', textAlign: 'center', py: 1 }}>\n No category detected for this app\n </Typography>\n ) : (\n <>\n <Box sx={{ display: 'flex', gap: 1, mb: 1.5, alignItems: 'center' }}>\n <Autocomplete\n size=\"small\"\n disableClearable\n options={sortedActions}\n value={selected ?? sortedActions[0]}\n onChange={(_, v) => v && handleSelect(v as SingulAction)}\n groupBy={(o: SingulAction) => o.category}\n getOptionLabel={(o: SingulAction | null) => o?.label ?? ''}\n isOptionEqualToValue={(a, b) => a?.name === b?.name && a?.category === b?.category}\n renderOption={(props, option) => (\n <li {...props} key={`${option.category}-${option.name}`}>\n <Box sx={{ display: 'flex', flexDirection: 'column' }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--foreground))' }}>{option.label}</Typography>\n <Typography sx={{ fontFamily: \"'JetBrains Mono', monospace\", fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))' }}>\n {option.name}\n </Typography>\n </Box>\n </li>\n )}\n sx={{\n flex: 1,\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--card))',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.75rem',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--primary))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n border: '1px solid hsl(var(--border))',\n '& .MuiAutocomplete-groupLabel': {\n backgroundColor: 'hsl(var(--muted) / 0.6)',\n color: 'hsl(var(--muted-foreground))',\n fontSize: '0.65rem',\n fontWeight: 600,\n textTransform: 'uppercase',\n letterSpacing: 0.6,\n lineHeight: '24px',\n },\n },\n },\n }}\n renderInput={(params) => (\n <TextField {...params} placeholder=\"Select action\" />\n )}\n />\n </Box>\n\n {/* Code card */}\n <Box\n sx={{\n position: 'relative',\n borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background))',\n overflow: 'hidden',\n boxShadow: '0 8px 24px -12px hsl(var(--primary) / 0.25)',\n }}\n >\n {/* Header bar — matches ApiCallViewer */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 2,\n py: 1,\n borderBottom: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--card))',\n }}\n >\n <Code2 size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />\n <Typography\n sx={{\n fontSize: '0.7rem',\n fontWeight: 600,\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Action\n </Typography>\n {selected && (\n <Chip\n label={selected.name}\n size=\"small\"\n sx={{\n height: 18,\n fontSize: '0.6rem',\n fontWeight: 700,\n fontFamily: \"'JetBrains Mono', monospace\",\n bgcolor: 'hsla(var(--severity-medium) / 0.15)',\n color: 'hsl(var(--severity-medium))',\n '& .MuiChip-label': { px: 0.75 },\n }}\n />\n )}\n <Box sx={{ flex: 1 }} />\n {/* Language toggle (cURL / Python) */}\n <Box sx={{ display: 'flex', gap: 0.5 }}>\n {(['curl', 'python'] as SnippetLang[]).map((m) => (\n <Chip\n key={m}\n label={m === 'curl' ? 'cURL' : 'Python'}\n icon={m === 'curl' ? <Terminal size={12} /> : <Code2 size={12} />}\n size=\"small\"\n onClick={() => setLang(m)}\n sx={{\n height: 22,\n fontSize: '0.6rem',\n fontWeight: 600,\n cursor: 'pointer',\n bgcolor: lang === m ? 'hsl(var(--primary) / 0.12)' : 'transparent',\n color: lang === m ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n border: lang === m ? '1px solid hsl(var(--primary) / 0.3)' : '1px solid transparent',\n '& .MuiChip-icon': {\n color: lang === m ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n },\n '&:hover': {\n bgcolor: lang === m ? 'hsl(var(--primary) / 0.15)' : 'hsl(var(--muted))',\n },\n }}\n />\n ))}\n </Box>\n <Tooltip title={copied ? 'Copied!' : 'Copy'} arrow>\n <IconButton size=\"small\" onClick={handleCopy} sx={{ color: 'hsl(var(--muted-foreground))' }}>\n {copied ? <CheckIcon sx={{ fontSize: 14 }} /> : <ContentCopyIcon sx={{ fontSize: 14 }} />}\n </IconButton>\n </Tooltip>\n <Button\n size=\"small\"\n onClick={handlePlay}\n disabled={playLoading}\n startIcon={!playLoading && <PlayArrowIcon sx={{ fontSize: 14 }} />}\n sx={{\n height: 26,\n minWidth: 0,\n px: 1.5,\n fontSize: '0.65rem',\n fontWeight: 600,\n textTransform: 'none',\n color: 'hsl(var(--primary-foreground))',\n backgroundColor: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary))',\n boxShadow: '0 0 12px -2px hsl(var(--primary) / 0.6)',\n '& .MuiButton-startIcon': { mr: 0.5 },\n '&:hover': { backgroundColor: 'hsl(var(--primary) / 0.9)', boxShadow: '0 0 16px -2px hsl(var(--primary) / 0.7)' },\n '&.Mui-disabled': { color: 'hsl(var(--primary-foreground) / 0.7)', backgroundColor: 'hsl(var(--primary) / 0.45)', boxShadow: 'none', borderColor: 'hsl(var(--primary) / 0.45)' },\n }}\n >\n {playLoading ? 'Running…' : 'Play'}\n </Button>\n </Box>\n\n {/* Editor area with line numbers */}\n <Box sx={{ display: 'flex', minHeight: 270 }}>\n <Box\n aria-hidden\n sx={{\n userSelect: 'none',\n py: 1.5,\n pl: 1.25,\n pr: 1,\n textAlign: 'right',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n color: 'hsl(var(--muted-foreground) / 0.6)',\n borderRight: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--muted) / 0.25)',\n minWidth: 36,\n }}\n >\n {Array.from({ length: lineCount }, (_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </Box>\n <Box sx={{ flex: 1, position: 'relative', minHeight: 270 }}>\n <Box\n aria-hidden\n sx={{\n position: 'absolute',\n inset: 0,\n m: 0,\n p: 1.5,\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n pointerEvents: 'none',\n overflow: 'hidden',\n }}\n dangerouslySetInnerHTML={{ __html: highlightSnippet(snippet, lang) + '\\n' }}\n />\n <Box\n component=\"textarea\"\n value={snippet}\n onChange={(e: any) => setSnippet(e.target.value)}\n spellCheck={false}\n sx={{\n position: 'relative',\n width: '100%',\n height: '100%',\n minHeight: 270,\n resize: 'vertical',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n color: 'transparent',\n WebkitTextFillColor: 'transparent',\n backgroundColor: 'transparent',\n border: 'none',\n p: 1.5,\n m: 0,\n outline: 'none',\n caretColor: 'hsl(var(--primary))',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n overflow: 'auto',\n '&::selection': { color: 'inherit', backgroundColor: 'hsl(var(--primary) / 0.3)' },\n }}\n />\n </Box>\n </Box>\n </Box>\n </>\n )}\n\n {(playLoading || playResult !== null) && (() => {\n const parsedResult = (() => {\n if (!playResult) return null;\n try {\n const p = JSON.parse(playResult);\n return typeof p === 'object' && p !== null ? p : null;\n } catch { return null; }\n })();\n const needsAuth = !!parsedResult && (\n parsedResult.action === 'app_authentication' ||\n parsedResult.app_authentication === true\n );\n const pretty = appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const handleAuthClick = () => {\n if (onAuthenticate) {\n onAuthenticate(appName);\n return;\n }\n if (typeof document === 'undefined') return;\n const target = document.getElementById('app-auth-section');\n if (target) {\n target.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n return (\n <Box ref={responseRef} sx={{ mt: 1.5 }}>\n {needsAuth && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n mb: 1,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}\n >\n <LockIcon sx={{ color: 'hsl(var(--severity-medium))', fontSize: 22 }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {typeof parsedResult?.reason === 'string' && parsedResult.reason\n ? parsedResult.reason\n : `Connect your ${pretty} account so this action can run, then try again.`}\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={appIcon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n onClick={handleAuthClick}\n sx={{ height: 36, textTransform: 'none', fontWeight: 600, flexShrink: 0 }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n )}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mb: 0.5 }}>\n <Box sx={{ width: 6, height: 6, borderRadius: '50%', backgroundColor: needsAuth ? 'hsl(var(--severity-medium))' : 'hsl(140 60% 55%)' }} />\n <Typography sx={{ fontFamily: \"'JetBrains Mono', monospace\", fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', letterSpacing: 0.4 }}>\n response\n </Typography>\n </Box>\n {parsedResult ? (\n <Box\n sx={{\n p: 1.5,\n maxHeight: 320,\n overflow: 'auto',\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n fontFamily: \"'JetBrains Mono', ui-monospace, monospace\",\n '& .json-view': {\n fontSize: '0.72rem !important',\n fontFamily: 'inherit !important',\n bgcolor: 'transparent !important',\n },\n }}\n >\n <JsonView\n src={deepParseJsonStrings(parsedResult)}\n dark\n collapsed={2}\n collapseStringMode=\"word\"\n collapseStringsAfterLength={120}\n enableClipboard\n displaySize\n />\n </Box>\n ) : (\n <Box\n component=\"pre\"\n sx={{\n p: 1.5,\n maxHeight: 240,\n overflow: 'auto',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.7rem',\n lineHeight: 1.5,\n color: 'hsl(var(--foreground))',\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n m: 0,\n }}\n >\n {playLoading && !playResult ? 'Running…' : playResult}\n </Box>\n )}\n </Box>\n );\n })()}\n </Box>\n </Box>\n );\n};\n\nexport default SingulActionsPreview;\n","/**\n * AppSearchDrawer — Reusable drawer for searching apps.\n * Selecting an app opens the AppDetailDrawer for full configuration.\n */\n\nimport { useState, useEffect } from 'react';\nimport { Box, Typography, IconButton, Drawer, Avatar, Tooltip } from '@mui/material';\nimport CloseIcon from '@mui/icons-material/Close';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { ShuffleMCP, AppDetailDrawer } from '@/Shuffle-MCPs';\nimport type { AppSelectedEvent } from '@/Shuffle-MCPs';\nimport { API_CONFIG } from '@/Shuffle-MCPs/api';\nimport { ShufflePipelinesBanner } from '@/Shuffle-MCPs/ShufflePipelinesBanner';\n\n\n// Singul styles — compact dark theme\nconst singulStyles = {\n container: { width: '100%' },\n inputWrapper: {\n backgroundColor: 'hsl(var(--background-elevated))',\n borderRadius: '12px',\n border: '1px solid hsl(var(--border))',\n },\n input: {\n backgroundColor: 'transparent',\n color: 'hsl(var(--foreground))',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 16px',\n fontSize: '14px',\n },\n searchIcon: { color: 'hsl(var(--muted-foreground))' },\n spinner: {\n borderColor: 'hsl(var(--border))',\n borderTopColor: 'hsl(var(--primary))',\n },\n resultsContainer: { marginTop: '12px', gap: '10px' },\n dropdownItem: {\n backgroundColor: 'hsl(var(--input))',\n border: '1px solid hsl(var(--border))',\n borderRadius: '12px',\n padding: '14px',\n color: 'hsl(var(--foreground))',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n },\n dropdownItemHover: {\n borderColor: 'hsl(var(--primary) / 0.5)',\n backgroundColor: 'hsl(var(--accent) / 0.08)',\n },\n selectedItem: {\n backgroundColor: 'hsl(var(--primary) / 0.1)',\n borderColor: 'hsl(var(--primary))',\n },\n appIcon: {\n width: '36px',\n height: '36px',\n borderRadius: '8px',\n backgroundColor: 'hsl(var(--muted))',\n objectFit: 'contain' as const,\n padding: '4px',\n },\n appName: { fontSize: '13px', fontWeight: 600, color: 'hsl(var(--foreground))' },\n appDescription: {\n fontSize: '11px',\n color: 'hsl(var(--muted-foreground))',\n lineHeight: 1.4,\n },\n appCategory: {\n marginTop: '6px',\n padding: '2px 8px',\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--muted-foreground))',\n fontSize: '10px',\n fontWeight: 600,\n textTransform: 'uppercase' as const,\n borderRadius: '4px',\n display: 'inline-block',\n width: 'fit-content',\n },\n checkbox: { border: '2px solid hsl(var(--border))' },\n checkboxChecked: { backgroundColor: 'hsl(var(--primary))', borderColor: 'hsl(var(--primary))' },\n emptyState: {\n padding: '24px',\n color: 'hsl(var(--muted-foreground))',\n textAlign: 'center' as const,\n fontSize: '13px',\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: '12px',\n border: '1px solid hsl(var(--border))',\n gridColumn: '1 / -1',\n },\n};\n\ninterface ConnectionPathApp {\n name: string;\n icon: string;\n hasValidAuth?: boolean;\n isActiveOnly?: boolean;\n}\n\ninterface AppSearchDrawerProps {\n open: boolean;\n onClose: () => void;\n initialQuery?: string;\n title?: string;\n subtitle?: string;\n anchor?: 'left' | 'right';\n width?: number;\n /** Show the Shuffle Pipelines banner above search results */\n showPipelinesBanner?: boolean;\n /** If provided, selecting an app calls this instead of opening AppDetailDrawer */\n onQuickSelect?: (app: { name: string; icon: string; categories: string[]; id: string | null }) => void;\n /** If provided, called before default behavior. Return true to prevent opening detail drawer. */\n onSelectOverride?: (app: { name: string; icon: string; categories: string[] }) => boolean;\n /** Called when the detail drawer closes, with the app name that was being configured */\n onDetailClose?: (appName: string) => void;\n /** When set, replaces Activate with \"+ Add\" in the detail drawer */\n onAddToCanvas?: (appInfo: { name: string; icon: string; algoliaId: string | null }) => void;\n /** When set, apps matching this category are sorted to the top in user's apps */\n priorityCategory?: string;\n /** Apps currently in the connection path diagram — shown first in the drawer */\n connectionPathApps?: ConnectionPathApp[];\n /** Apps to pin at the top of the ShuffleMCP search results (deduped by name). */\n pinnedApps?: Array<{ name: string; image_url: string; categories?: string[]; objectID?: string }>;\n /** Highlight (pulsing ring) the matching app card after `highlightDelayMs` */\n highlightAppName?: string;\n /** Delay before the highlight kicks in (default 5000ms) */\n highlightDelayMs?: number;\n /** Enable multi-select: clicking apps toggles them in/out of the selection,\n * drawer stays open, and the picker shows checkboxes + a primary-bordered\n * highlight on already-chosen rows. */\n multiSelect?: boolean;\n /** Currently chosen apps (used to highlight rows in multi-select mode).\n * Match is by objectID first, then by normalized name. */\n selectedApps?: Array<{ name: string; id?: string | null; icon?: string }>;\n /** Fires whenever the selection changes in multi-select mode. */\n onSelectionChange?: (apps: Array<{ name: string; id: string | null; icon: string; categories: string[] }>) => void;\n}\n\n\nexport default function AppSearchDrawer({\n open,\n onClose,\n initialQuery = '',\n title = 'Add Integration',\n subtitle = 'Search and configure a tool',\n anchor = 'right',\n width = 560,\n showPipelinesBanner = false,\n onQuickSelect,\n onSelectOverride,\n onDetailClose,\n onAddToCanvas,\n priorityCategory,\n connectionPathApps,\n pinnedApps,\n highlightAppName,\n highlightDelayMs = 5000,\n multiSelect = false,\n selectedApps,\n onSelectionChange,\n}: AppSearchDrawerProps) {\n const [detailAppName, setDetailAppName] = useState<string | null>(null);\n const [detailAppId, setDetailAppId] = useState<string | null>(null);\n const [highlightActive, setHighlightActive] = useState(false);\n\n // Activate highlight only after the delay, so users get a chance to find\n // the app on their own before we draw attention to it.\n useEffect(() => {\n setHighlightActive(false);\n if (!open || !highlightAppName) return;\n const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);\n return () => clearTimeout(t);\n }, [open, highlightAppName, highlightDelayMs]);\n\n const handleClose = () => {\n setDetailAppName(null);\n setDetailAppId(null);\n onClose();\n };\n\n // Project caller-supplied selection to the AlgoliaSearchApp shape that\n // ShuffleMCP's `selectedApps` prop expects. Only `objectID` and `name` are\n // used for matching; the rest are placeholders.\n const projectedSelectedApps = (selectedApps || []).map((a) => ({\n objectID: a.id || `name:${(a.name || '').toLowerCase().replace(/[\\s-]+/g, '_')}`,\n name: a.name,\n image_url: a.icon || '',\n description: '',\n categories: [],\n creator: '',\n app_version: '1.0.0',\n time_edited: 0,\n generated: false,\n invalid: false,\n priority: 0,\n actions: 0,\n tags: [],\n accessible_by: [],\n action_labels: [],\n triggers: [],\n verified: true,\n })) as any[];\n\n const handleAppSelected = (detail: AppSelectedEvent) => {\n const algoliaId = (detail.app as any).objectID || null;\n const appInfo = {\n name: detail.app.name,\n icon: detail.app.image_url || '',\n categories: detail.app.categories || [],\n id: algoliaId,\n };\n\n // Multi-select mode: toggle in/out of the chosen list, keep the drawer open.\n if (multiSelect && onSelectionChange) {\n const norm = (s: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const current = selectedApps || [];\n const targetSlug = norm(appInfo.name);\n const exists = current.some(\n (a) => (a.id && a.id === appInfo.id) || norm(a.name) === targetSlug,\n );\n const next = exists\n ? current.filter(\n (a) => !((a.id && a.id === appInfo.id) || norm(a.name) === targetSlug),\n ).map((a) => ({\n name: a.name,\n id: a.id ?? null,\n icon: a.icon || '',\n categories: [] as string[],\n }))\n : [\n ...current.map((a) => ({\n name: a.name,\n id: a.id ?? null,\n icon: a.icon || '',\n categories: [] as string[],\n })),\n appInfo,\n ];\n onSelectionChange(next);\n return;\n }\n\n if (onQuickSelect) {\n onQuickSelect(appInfo);\n onClose();\n return;\n }\n if (onSelectOverride?.(appInfo)) {\n return;\n }\n setDetailAppName(detail.app.name);\n setDetailAppId(algoliaId);\n };\n\n\n return (\n <>\n <Drawer\n anchor={anchor}\n open={open && detailAppName === null}\n onClose={handleClose}\n sx={{\n zIndex: 9999,\n '& .MuiDrawer-paper': {\n width,\n maxWidth: '100vw',\n height: '100vh',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: anchor === 'right' ? '1px solid hsl(var(--border))' : 'none',\n borderRight: anchor === 'left' ? '1px solid hsl(var(--border))' : 'none',\n },\n }}\n >\n {/* Header */}\n <Box\n sx={{\n px: 3,\n py: 2,\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n }}\n >\n <Box sx={{ flex: 1 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', lineHeight: 1.2 }}>\n {title}\n </Typography>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.75rem' }}>\n {subtitle}\n </Typography>\n </Box>\n <IconButton\n size=\"small\"\n onClick={handleClose}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--foreground))' } }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n\n {/* Search body */}\n <Box sx={{ flex: 1, boxSizing: 'border-box', overflow: 'hidden', p: 3, minHeight: 0, display: 'flex', flexDirection: 'column' }}>\n \n\n {/* Connection path apps — shown first */}\n {connectionPathApps && connectionPathApps.length > 0 && (\n <Box sx={{ mb: 2.5 }}>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.7rem', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em', mb: 1 }}>\n In this usecase\n </Typography>\n <Box sx={{ display: 'flex', gap: 1.5, flexWrap: 'wrap' }}>\n {connectionPathApps.map((app) => (\n <Tooltip key={app.name} title={app.name.replace(/_/g, ' ')} arrow placement=\"bottom\">\n <Box\n onClick={() => handleAppSelected({ app: { name: app.name, image_url: app.icon, categories: [] } } as any)}\n sx={{\n position: 'relative',\n cursor: 'pointer',\n transition: 'transform 0.15s ease',\n '&:hover': { transform: 'scale(1.1)' },\n }}\n >\n <Avatar\n src={app.icon}\n alt={app.name}\n sx={{ width: 32, height: 32, borderRadius: '8px', backgroundColor: 'hsl(var(--muted))' }}\n variant=\"rounded\"\n />\n <Box\n sx={{\n position: 'absolute',\n bottom: -2,\n right: -2,\n width: 9,\n height: 9,\n borderRadius: '50%',\n backgroundColor: app.hasValidAuth ? 'hsl(var(--severity-low))' : app.isActiveOnly ? 'hsl(var(--destructive))' : 'hsl(var(--severity-medium))',\n border: '1.5px solid hsl(var(--card))',\n }}\n />\n </Box>\n </Tooltip>\n ))}\n </Box>\n </Box>\n )}\n\n <Box\n sx={{\n flex: 1,\n minHeight: 0,\n overflow: 'hidden',\n '& .singul-container, & .singul-search-bar-container': {\n height: '100%',\n minHeight: 0,\n },\n '& .singul-search-bar-container': {\n display: 'flex',\n flexDirection: 'column',\n },\n '& .singul-results-container': {\n flex: 1,\n minHeight: 0,\n maxHeight: 'none',\n overflowY: 'auto',\n },\n '& .singul-results-grid': {\n gridAutoRows: '75px',\n gap: '12px',\n },\n '& .singul-results-grid .singul-dropdown-item': {\n minHeight: 75,\n maxHeight: 75,\n height: 75,\n padding: '14px 16px',\n alignItems: 'center',\n overflow: 'hidden',\n },\n '& .singul-results-grid .singul-app-info': {\n alignItems: 'center',\n gap: '12px',\n },\n '& .singul-results-grid .singul-app-icon': {\n width: 40,\n height: 40,\n borderRadius: 8,\n padding: 4,\n },\n ...(highlightActive && highlightAppName ? {\n [`& .singul-dropdown-item[data-app-name=\"${highlightAppName}\"]`]: {\n borderColor: 'hsl(var(--primary)) !important',\n boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 18px 2px hsl(var(--primary) / 0.55)',\n animation: 'shuffleHighlightPulse 1.6s ease-in-out infinite',\n },\n '@keyframes shuffleHighlightPulse': {\n '0%, 100%': { boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 12px 1px hsl(var(--primary) / 0.4)' },\n '50%': { boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 24px 4px hsl(var(--primary) / 0.75)' },\n },\n } : {}),\n }}\n >\n <AnimatePresence mode=\"wait\">\n <motion.div\n key=\"search\"\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: -20 }}\n transition={{ duration: 0.2 }}\n style={{ height: '100%', minHeight: 0 }}\n >\n <ShuffleMCP\n apiKey={API_CONFIG.apiKey || undefined}\n apiBaseUrl={API_CONFIG.baseUrl}\n placeholder={initialQuery ? `Search ${initialQuery} integrations...` : 'Search integrations...'}\n layout=\"grid\"\n gridColumns={2}\n inline={true}\n initialFilterQuery={initialQuery}\n hitsPerPage={12}\n showDescription={false}\n showCategories={true}\n showCheckbox={multiSelect}\n multiSelect={multiSelect}\n selectedApps={multiSelect ? projectedSelectedApps : undefined}\n preventDefault={true}\n onAppSelected={handleAppSelected}\n onSelectionChange={multiSelect && onSelectionChange ? (apps) => {\n onSelectionChange(\n apps.map((a: any) => ({\n name: a.name,\n id: (a.objectID && !String(a.objectID).startsWith('name:') && !String(a.objectID).startsWith('pinned-')) ? a.objectID : null,\n icon: a.image_url || '',\n categories: a.categories || [],\n }))\n );\n } : undefined}\n pinnedApps={pinnedApps?.map(p => ({\n name: p.name,\n image_url: p.image_url,\n categories: p.categories || [],\n objectID: p.objectID || `pinned-${p.name}`,\n description: '',\n creator: '',\n app_version: '1.0.0',\n time_edited: 0,\n generated: false,\n invalid: false,\n priority: 0,\n actions: 0,\n tags: [],\n accessible_by: [],\n action_labels: [],\n triggers: [],\n verified: true,\n }))}\n customStyles={singulStyles}\n />\n </motion.div>\n </AnimatePresence>\n </Box>\n </Box>\n </Drawer>\n\n {/* App detail drawer — opens when an app is selected from search */}\n <AppDetailDrawer\n open={open && detailAppName !== null}\n onClose={() => {\n const name = detailAppName;\n setDetailAppName(null);\n setDetailAppId(null);\n if (name) onDetailClose?.(name);\n }}\n appName={detailAppName}\n appId={detailAppId}\n anchor={anchor}\n width={width}\n onRefresh={onClose}\n onAddToCanvas={onAddToCanvas}\n />\n </>\n );\n}\n","import { Box, Typography, Chip } from '@mui/material';\nimport shuffleIcon from '@/assets/shuffle-icon.png';\n\nexport function ShufflePipelinesBanner() {\n return (\n <Box\n component=\"a\"\n href=\"/detection\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n p: 2,\n mb: 2,\n borderRadius: 2.5,\n background: 'linear-gradient(135deg, hsla(25, 100%, 50%, 0.08) 0%, hsla(25, 100%, 50%, 0.03) 100%)',\n border: '1px solid hsla(25, 100%, 50%, 0.2)',\n textDecoration: 'none',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n '&:hover': {\n border: '1px solid hsla(25, 100%, 50%, 0.4)',\n background: 'linear-gradient(135deg, hsla(25, 100%, 50%, 0.12) 0%, hsla(25, 100%, 50%, 0.05) 100%)',\n },\n }}\n >\n <Box\n component=\"img\"\n src={shuffleIcon}\n alt=\"Shuffle\"\n sx={{ width: 36, height: 36, borderRadius: '10px', flexShrink: 0 }}\n />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontWeight: 700, fontSize: '0.85rem', color: 'hsl(var(--foreground))', lineHeight: 1.3 }}>\n Shuffle Pipelines\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', lineHeight: 1.4 }}>\n Do not have a SIEM? Shuffle can ingest, parse, and correlate your logs and events directly — no external SIEM required.\n </Typography>\n </Box>\n <Chip\n label=\"Built-in\"\n size=\"small\"\n sx={{\n height: 22,\n fontSize: '0.65rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--primary) / 0.15)',\n color: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary) / 0.3)',\n flexShrink: 0,\n }}\n />\n </Box>\n );\n}\n\nexport default ShufflePipelinesBanner;\n","/**\n * AgentUI — Standalone \"start + debug agents\" surface.\n *\n * TypeScript port and modernization of the legacy Shuffle Core\n * `AgentUI.jsx`. One component, two modes:\n *\n * 1. **Starter** — large hero prompt (\"What do you want to do?\")\n * with attached MCP/app chips. Submits to `/api/v1/agent`.\n * 2. **Debugger** — compact header + decision timeline driven by\n * `/api/v1/streams/results`, with question/continuation forms\n * and per-decision raw-JSON inspection.\n *\n * Mode switches automatically when an execution is started or when\n * `?execution_id=...&authorization=...` is present in the URL.\n *\n * Self-contained: uses {@link AppSearchDrawer} for app picking,\n * {@link runAgent} for the JSON-RPC call, and the library's\n * {@link toast} facade for notifications.\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Avatar,\n AvatarGroup,\n Box,\n Button,\n // ButtonGroup removed (replaced by chip tabs)\n Chip,\n CircularProgress,\n IconButton,\n InputBase,\n MenuItem,\n Popover,\n Select,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport AddIcon from '@mui/icons-material/Add';\nimport AttachFileIcon from '@mui/icons-material/AttachFile';\nimport CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport CheckIcon from '@mui/icons-material/Check';\nimport ErrorIcon from '@mui/icons-material/Error';\nimport HourglassDisabledIcon from '@mui/icons-material/HourglassDisabled';\nimport PauseIcon from '@mui/icons-material/Pause';\nimport PlayArrowRoundedIcon from '@mui/icons-material/PlayArrowRounded';\nimport RefreshIcon from '@mui/icons-material/Refresh';\nimport ScheduleIcon from '@mui/icons-material/Schedule';\nimport RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport StopCircleIcon from '@mui/icons-material/StopCircle';\nimport ThumbUpIcon from '@mui/icons-material/ThumbUp';\nimport ThumbDownIcon from '@mui/icons-material/ThumbDown';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport SendIcon from '@mui/icons-material/Send';\nimport WarningIcon from '@mui/icons-material/Warning';\nimport CloseIcon from '@mui/icons-material/Close';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkBreaks from 'remark-breaks';\n\n// Normalize agent answer text so react-markdown renders it correctly:\n// - Decode literal escape sequences (\"\\n\", \"\\t\", \"\\r\") that come back\n// double-encoded in some JSON payloads.\n// - Strip surrounding quotes if the value is itself a JSON-encoded string.\n// - Trim leading/trailing whitespace.\nconst normalizeMarkdown = (raw: unknown): string => {\n if (raw == null) return '';\n let s = typeof raw === 'string' ? raw : (() => {\n try { return JSON.stringify(raw, null, 2); } catch { return String(raw); }\n })();\n // If the whole thing is a JSON-encoded string, decode it once.\n if (s.length > 1 && s.startsWith('\"') && s.endsWith('\"')) {\n try { s = JSON.parse(s); } catch { /* keep as-is */ }\n }\n // Convert literal \"\\n\" / \"\\t\" / \"\\r\" sequences into real characters.\n s = s.replace(/\\\\r\\\\n/g, '\\n').replace(/\\\\n/g, '\\n').replace(/\\\\t/g, '\\t').replace(/\\\\\"/g, '\"');\n return s.trim();\n};\nimport JsonView from 'react18-json-view';\nimport 'react18-json-view/src/style.css';\nimport 'react18-json-view/src/dark.css';\n\n/** Recursively parse JSON-looking strings into objects/arrays so JsonView can collapse them. */\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n } catch { /* ignore */ }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\nimport AgentIcon from '@/Shuffle-MCPs/AgentIcon';\nimport AppSearchDrawer from '@/Shuffle-MCPs/AppSearchDrawer';\nimport AppDetailDrawer from '@/Shuffle-MCPs/AppDetailDrawer';\nimport LockIcon from '@mui/icons-material/Lock';\nimport { getApiUrl, getAuthHeader, API_CONFIG } from '@/Shuffle-MCPs/api';\nimport { fetchApps } from '@/Shuffle-MCPs/appsCache';\nimport { resolveApps } from '@/Shuffle-MCPs/resolveApp';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport { runAgent } from '@/Shuffle-MCPs/agentRun';\nimport { parseScheduleHint } from '@/Shuffle-MCPs/scheduleHint';\nimport AgentRunDiagnosisBanner from '@/Shuffle-MCPs/AgentRunDiagnosisBanner';\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport interface AgentUIApp {\n /** App slug, e.g. \"http\", \"shuffle_tools\", \"gmail\". */\n name: string;\n /** Algolia objectID / Shuffle app id (preferred). */\n id?: string;\n /** Optional preview icon URL. */\n icon?: string;\n}\n\nexport interface AgentUIProps {\n /** Controlled list of apps. When provided, overrides defaultApps and disables auto-load. */\n apps?: AgentUIApp[];\n /** Initial chip set under the prompt. Used only when `apps` is not provided. */\n defaultApps?: AgentUIApp[];\n /**\n * When true (default) and neither `apps` nor `defaultApps` is provided, fetch the\n * caller's authenticated apps via `/api/v1/apps/authentication` (requires an API\n * token to be set on `API_CONFIG`).\n */\n autoLoadApps?: boolean;\n /** Hero title above the prompt. */\n title?: string;\n /** Optional subtitle/description shown under the title. */\n subtitle?: React.ReactNode;\n /** Placeholder shown in the empty prompt. */\n placeholder?: string;\n /** Pre-fill the prompt with this text. */\n defaultInput?: string;\n /** Submit immediately on mount when `defaultInput` is provided. */\n autoSubmit?: boolean;\n /** Hide the centered hero icon (compact mode). */\n hideHeroIcon?: boolean;\n /** Replace the default AgentIcon with a custom node (e.g. brand logo). */\n heroIcon?: React.ReactNode;\n /** Pixel size of the hero icon container. Default 84. */\n heroIconSize?: number;\n /** Maximum width of the centered card. */\n maxWidth?: number;\n /** Compact mode: hides the hero icon, shrinks padding. */\n compact?: boolean;\n /** Hide the \"Select Apps / MCPs\" chip row entirely. */\n hideAppPicker?: boolean;\n /** Hide the paperclip image-attachment button. */\n hideAttach?: boolean;\n /** Disable the \"Start\" tab in the run switcher (e.g. when viewing a fixed execution). */\n disableStartTab?: boolean;\n /** Label on the \"Select Apps / MCPs\" chip. */\n appPickerLabel?: string;\n /** Title on the AppSearchDrawer. */\n appPickerTitle?: string;\n /** Subtitle on the AppSearchDrawer. */\n appPickerSubtitle?: string;\n /** Tooltip on the submit button. Default: \"⌘+Enter to send\". */\n submitTooltip?: string;\n /** Custom icon for the submit button. */\n submitIcon?: React.ReactNode;\n /**\n * When provided, the submit button + Cmd/Ctrl+Enter call this instead of\n * running the agent. Used for \"edit existing scheduled workflow\" mode where\n * the same starter UI is reused for editing the prompt + apps.\n */\n submitOverride?: (info: { input: string; apps: Array<{ name: string; id?: string; icon?: string }> }) => void | Promise<void>;\n /** When set, renders the submit control as a wider labelled button instead of the icon-only send button. */\n submitLabel?: string;\n /** Force-disable the schedule (clock) button. Optional tooltip override. */\n disableSchedule?: boolean;\n disableScheduleTooltip?: string;\n /** Placeholder for the post-finish continuation field. */\n continuationPlaceholder?: string;\n /** Read `?execution_id` & `?authorization` from window URL on mount. */\n readUrlParams?: boolean;\n /**\n * Optional explicit execution to attach to on mount. Overrides URL params\n * and skips the starter — useful when embedding to monitor a known run.\n */\n executionId?: string;\n /** Authorization token paired with `executionId`. */\n authorization?: string;\n /**\n * Pre-loaded execution payload. When provided, AgentUI skips the starter\n * and renders Simple/Detailed views immediately — no `/streams/results`\n * fetch, no `authorization` token required. Useful for embedding inside\n * a list/drawer that already has the execution data in hand. If the run\n * is still EXECUTING and an `authorization` is also present, polling\n * continues normally.\n */\n initialExecution?: {\n execution_id?: string;\n authorization?: string;\n status?: string;\n started_at?: number | string;\n completed_at?: number | string;\n results?: any[];\n workflow?: { id?: string; name?: string };\n [k: string]: any;\n };\n /** Called whenever a run finishes (success or failure). */\n onRun?: (info: { input: string; success: boolean; executionId?: string; error?: string }) => void;\n /** Called whenever the active top-level view changes (start / simple / detailed). */\n onViewChange?: (view: 'start' | 'simple' | 'detailed') => void;\n /**\n * Called when the user saves a recurring schedule (cron expression) for the\n * current prompt. When omitted, a toast is shown indicating scheduling is\n * not wired up in this embed.\n */\n onSchedule?: (info: {\n cron: string;\n input: string;\n apps?: Array<{ name: string; id?: string; icon?: string }>;\n onStep?: (event: { id: 'name' | 'workflow' | 'schedule'; state: 'active' | 'done' | 'error'; detail?: string }) => void;\n }) => void | Promise<void>;\n /**\n * Optional Shuffle API key. When provided, all `/api/v1/*` calls made by\n * this component (agent run, polling, app autoload, icon fallback) use it\n * via `Authorization: Bearer <apiKey>`. When omitted, falls back to the\n * shared `API_CONFIG` (browser session / `localStorage.shuffle_api_key`).\n */\n apiKey?: string;\n /**\n * Optional Shuffle backend base URL (e.g. `https://shuffler.io`). When\n * omitted, falls back to the shared `API_CONFIG.baseUrl`. Useful when\n * embedding `AgentUI` inside another app that targets a different region.\n */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header on every call. */\n orgId?: string;\n /** Optional className forwarded to the root container. */\n className?: string;\n /** Style overrides merged into the root container sx. */\n sx?: SxProps<Theme>;\n /** Style overrides for the inner content card (the column under the run-switcher). */\n contentSx?: SxProps<Theme>;\n}\n\ninterface ExecutionData {\n execution_id?: string;\n authorization?: string;\n status?: string;\n started_at?: number;\n completed_at?: number;\n results?: any[];\n workflow?: { id?: string; name?: string };\n [k: string]: any;\n}\n\ninterface AgentDecision {\n action?: string;\n category?: string;\n reason?: string;\n fields?: Array<{ key?: string; value?: string }>;\n details?: any;\n run_details?: {\n id?: string;\n status?: string;\n started_at?: number;\n completed_at?: number;\n raw_response?: string;\n };\n [k: string]: any;\n}\n\ninterface TimelineItem {\n label?: string;\n type: 'agent' | 'decision' | 'processing';\n category?: string;\n status?: string;\n start_time?: number;\n end_time?: number;\n details?: any;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nconst validateJson = (raw: unknown): { valid: boolean; result: any } => {\n if (raw == null) return { valid: false, result: null };\n if (typeof raw === 'object') return { valid: true, result: raw };\n if (typeof raw !== 'string') return { valid: false, result: raw };\n try {\n return { valid: true, result: JSON.parse(raw) };\n } catch {\n return { valid: false, result: raw };\n }\n};\n\n/**\n * Detect whether a single decision came back asking for app authentication.\n * Returns the app name (and optional id from `details.tool` when prefixed\n * \"app:<id>:<name>\") so the caller can render an inline \"Authenticate X\"\n * banner. Returns null when the decision did not request auth.\n */\nconst extractAuthRequest = (decision: any): { appName: string; appId: string | null } | null => {\n if (!decision || typeof decision !== 'object') return null;\n const raw = decision?.run_details?.raw_response;\n let parsed: any = null;\n if (typeof raw === 'string') {\n try { parsed = JSON.parse(raw); } catch { parsed = null; }\n } else if (raw && typeof raw === 'object') {\n parsed = raw;\n }\n const needsAuth = parsed && (parsed.action === 'app_authentication' || parsed.app_authentication === true);\n if (!needsAuth) return null;\n let appName: string | undefined = parsed.app || parsed.app_name || parsed.appname;\n let appId: string | null = null;\n if (!appName && typeof decision?.tool === 'string') {\n const t = decision.tool;\n if (t.startsWith('app:')) {\n const parts = t.split(':');\n appId = parts[1] || null;\n appName = parts[2] || t;\n } else {\n appName = t;\n }\n }\n if (!appName) {\n const f = (decision?.fields || []).find((x: any) => x?.key === 'app' || x?.key === 'app_name');\n if (f?.value) appName = f.value;\n }\n if (!appName) return null;\n return { appName, appId };\n};\n\nconst STATUS_COLORS = {\n finished: 'hsl(142, 71%, 45%)',\n warning: 'hsl(38, 92%, 50%)',\n error: 'hsl(0, 72%, 55%)',\n running: 'hsl(var(--primary))',\n};\n\nconst buildToolName = (apps: AgentUIApp[]): string => {\n if (!apps.length) return 'API';\n return apps\n .map((a) => {\n const slug = a.name.toLowerCase().replace(/\\s+/g, '_').replace(/-/g, '_');\n return a.id ? `app:${a.id}:${slug}` : slug;\n })\n .join(',');\n};\n\n// ── Inner: timeline item ──────────────────────────────────────────────────────\n\nconst StatusIcon: React.FC<{ status?: string }> = ({ status }) => {\n const s = (status || '').toUpperCase();\n let node: React.ReactNode;\n let label: string;\n if (s === 'RUNNING' || s === 'EXECUTING' || s === '') {\n node = <CircularProgress size={18} sx={{ color: STATUS_COLORS.running }} />;\n label = 'Running';\n } else if (s === 'WAITING') {\n node = <PauseIcon sx={{ color: STATUS_COLORS.running, fontSize: 20 }} />;\n label = 'Waiting for input';\n } else if (s === 'FINISHED' || s === 'SUCCESS') {\n node = <CheckCircleIcon sx={{ color: STATUS_COLORS.finished, fontSize: 20 }} />;\n label = 'Finished successfully';\n } else if (s === 'ABORTED' || s === 'FAILURE') {\n node = <ErrorIcon sx={{ color: STATUS_COLORS.error, fontSize: 20 }} />;\n label = s === 'ABORTED' ? 'Aborted' : 'Failed';\n } else if (s === 'IGNORED' || s === 'IGNORE') {\n node = <WarningIcon sx={{ color: STATUS_COLORS.warning, fontSize: 20 }} />;\n label = 'Ignored — skipped after run finished';\n } else {\n node = <HourglassDisabledIcon sx={{ color: 'hsl(var(--muted-foreground))', fontSize: 20 }} />;\n label = 'Pending';\n }\n return (\n <Tooltip title={label} arrow>\n <Box sx={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>\n {node}\n </Box>\n </Tooltip>\n );\n};\n\n\ninterface TimelineRowProps {\n item: TimelineItem;\n index: number;\n open: boolean;\n onToggle: () => void;\n appsById: Record<string, AgentUIApp>;\n totalDuration: number;\n originalStartTime: number;\n maxWidth: number;\n questionAnswers: Record<string, { index: number; value: string }>;\n setQuestionAnswers: React.Dispatch<React.SetStateAction<Record<string, { index: number; value: string }>>>;\n onSubmitQuestions: (decisionId: string, answers: Record<string, any>, isContinuation?: boolean) => void;\n onRerunAgent: () => void;\n onRerunDecision: (decision: any) => void;\n agentRequestLoading: boolean;\n getFormUrl?: (decisionId: string) => string | null;\n runFinished?: boolean;\n onAuthenticateApp?: (appName: string, appId?: string | null) => void;\n isAppAuthenticated?: (appName: string) => boolean;\n /** When true, briefly draw attention to this row + its output. Used after\n * a \"jump to evidence\" click from the diagnosis banner. */\n highlight?: boolean;\n}\n\nconst TimelineRow: React.FC<TimelineRowProps> = ({\n item, index, open, onToggle, appsById, totalDuration, originalStartTime,\n maxWidth, questionAnswers, setQuestionAnswers, onSubmitQuestions,\n onRerunAgent, onRerunDecision, agentRequestLoading, getFormUrl, runFinished,\n onAuthenticateApp, isAppAuthenticated, highlight = false,\n}) => {\n const [submitAttempted, setSubmitAttempted] = useState(false);\n const validate = validateJson(item.details);\n const itemStart = item.start_time || 0;\n const itemEnd = item.end_time || itemStart;\n const hasTiming = itemStart > 0 && itemEnd >= itemStart;\n const dur = hasTiming ? Math.max(0, itemEnd - itemStart) : 0;\n const offset = totalDuration > 0 && hasTiming ? ((itemStart - originalStartTime) / totalDuration) * maxWidth : 0;\n const width = totalDuration > 0 && hasTiming ? Math.max(4, (dur / totalDuration) * maxWidth) : 0;\n\n // Adapt label based on action/category\n let displayType = item.type as string;\n let displayLabel = item.label?.replace(/_/g, ' ') || '';\n const details = item.details as AgentDecision | undefined;\n const isProcessing = item.category === 'processing';\n if (isProcessing) {\n displayType = 'processing';\n } else if (details?.reason) {\n displayLabel = details.reason;\n }\n if (!isProcessing) {\n if (details?.action === 'finish' || item.category === 'finish' || details?.action === 'finalise') {\n displayType = 'finalise';\n } else if (item.category === 'ask' || details?.action === 'ask') {\n displayType = 'question';\n } else if (details?.action === 'add_tool') {\n displayType = 'add tool';\n }\n }\n\n // Resolve app icon for the tool used. `details.tool` may be a name or an ID.\n // Skip finalise/question/finish actions — they use the agent's \"core\" tool.\n let toolApp: AgentUIApp | undefined;\n const skipToolIcon =\n item.category === 'finalise' || item.category === 'finish' || item.category === 'ask' ||\n details?.action === 'finalise' || details?.action === 'finish' || details?.action === 'ask';\n if (!skipToolIcon && details?.tool && typeof details.tool === 'string' && details.tool !== 'singul' && details.tool !== 'core') {\n const raw = details.tool;\n let tn = raw.toLowerCase().replace(/[\\s-]+/g, '_');\n if (tn.startsWith('app:')) tn = tn.split(':')[2] || tn;\n toolApp = appsById[raw] || appsById[tn];\n }\n\n // Question fields. A field counts as \"answered\" when either the upstream\n // payload already carries an `answer` value on the field itself, or the\n // user has typed an answer locally in `questionAnswers`.\n const questions: { question: string; index: number; preAnswer?: string }[] = [];\n if (item.category === 'ask' || details?.action === 'ask') {\n for (const f of details?.fields || []) {\n if (f.key === 'question' && f.value) {\n const preAnswer = typeof (f as any).answer === 'string' ? (f as any).answer.trim() : '';\n questions.push({ question: f.value, index: questions.length + 1, preAnswer: preAnswer || undefined });\n }\n }\n }\n const questionsAnswered = questions.every(\n (q) => q.preAnswer || questionAnswers[q.question]?.value\n );\n const unansweredQuestions = questions.filter(\n (q) => !q.preAnswer && !questionAnswers[q.question]?.value\n );\n\n // If the run as a whole has finished, treat any still-RUNNING/WAITING rows\n // (typically an unanswered ASK that the agent moved past) as ignored so we\n // don't keep highlighting them with the orange \"running\" bar.\n const effectiveStatus =\n runFinished && (item.status === 'RUNNING' || item.status === 'WAITING')\n ? 'IGNORED'\n : item.status;\n const barColor = isProcessing ? 'hsl(var(--muted-foreground) / 0.45)' :\n effectiveStatus === 'IGNORED' ? STATUS_COLORS.warning :\n effectiveStatus === 'FINISHED' ? STATUS_COLORS.finished :\n effectiveStatus === 'FAILURE' || effectiveStatus === 'ABORTED' ? STATUS_COLORS.error :\n STATUS_COLORS.running;\n\n return (\n <Box\n data-timeline-index={index}\n sx={{\n borderTop: index === 0 ? 'none' : '1px solid hsl(var(--border))',\n bgcolor: highlight\n ? 'hsla(var(--severity-medium) / 0.12)'\n : open\n ? 'hsl(var(--muted) / 0.3)'\n : 'transparent',\n transition: 'background 0.6s ease, box-shadow 0.6s ease',\n scrollMarginTop: 96,\n position: 'relative',\n boxShadow: highlight ? 'inset 0 0 0 2px hsla(var(--severity-medium) / 0.55)' : 'none',\n }}\n >\n <Box\n onClick={isProcessing ? undefined : onToggle}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: 2,\n py: 1.25,\n cursor: isProcessing ? 'default' : 'pointer',\n '&:hover': isProcessing ? {} : { bgcolor: 'hsl(var(--muted) / 0.4)' },\n }}\n >\n <Box sx={{ width: 24, display: 'flex', justifyContent: 'center' }}>\n {isProcessing ? (\n <Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: 'hsl(var(--muted-foreground) / 0.5)' }} />\n ) : (\n <StatusIcon status={effectiveStatus} />\n )}\n </Box>\n <Box sx={{ width: 24, display: 'flex', justifyContent: 'center' }}>\n {isProcessing ? (\n <Box sx={{ width: 22 }} />\n ) : toolApp?.icon ? (\n <Tooltip title={(toolApp.name || '').replace(/_/g, ' ')} arrow>\n <Avatar src={toolApp.icon} sx={{ width: 22, height: 22, bgcolor: 'transparent' }} variant=\"rounded\" />\n </Tooltip>\n ) : item.category === 'finalise' || details?.action === 'finish' ? (\n <Tooltip title=\"Final answer\" arrow>\n <CheckIcon sx={{ color: STATUS_COLORS.finished, fontSize: 18 }} />\n </Tooltip>\n ) : (\n <Box sx={{ width: 22 }} />\n )}\n </Box>\n\n <Chip\n label={displayType}\n size=\"small\"\n sx={{\n height: 22,\n bgcolor: isProcessing ? 'transparent' : 'hsl(var(--muted))',\n color: isProcessing ? 'hsl(var(--muted-foreground))' : 'hsl(var(--foreground))',\n border: isProcessing ? '1px dashed hsl(var(--border))' : 'none',\n fontSize: '0.7rem',\n fontWeight: 500,\n textTransform: 'capitalize',\n minWidth: 80,\n fontStyle: isProcessing ? 'italic' : 'normal',\n }}\n />\n <Box sx={{\n flex: 1,\n minWidth: 0,\n fontSize: '0.85rem',\n color: 'hsl(var(--foreground))',\n maxHeight: 60,\n overflow: 'hidden',\n '& p': { margin: 0 },\n '& pre, & code': { fontSize: '0.78rem' },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline', textUnderlineOffset: '2px' },\n '& a:hover': { opacity: 0.85 },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(displayLabel)}</Markdown>\n </Box>\n <Tooltip title={hasTiming ? `Duration: ${dur.toFixed(2)}s · ${new Date(itemStart * 1000).toLocaleString()}` : 'No timing data'}>\n <Box sx={{ width: maxWidth, position: 'relative', height: 10, flexShrink: 0 }}>\n {dur > 0 && (\n <Box sx={{\n position: 'absolute',\n left: Math.max(0, offset),\n width,\n height: 8,\n top: 1,\n bgcolor: barColor,\n borderRadius: 1,\n transition: 'all 0.2s ease',\n }} />\n )}\n </Box>\n </Tooltip>\n <Box sx={{ width: 60, fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', textAlign: 'right' }}>\n {dur > 0 ? `${dur.toFixed(2)}s` : ''}\n </Box>\n {/* Per-row actions: Approve/Deny, Rerun */}\n <Box\n sx={{ display: 'flex', alignItems: 'center', gap: 0.25, ml: 1, minWidth: 96, justifyContent: 'flex-end' }}\n onClick={(e) => {\n // Only swallow the click when it actually lands on a button —\n // otherwise the empty area inside this row-actions box would\n // block the parent's expand/collapse toggle.\n if ((e.target as HTMLElement).closest('button, a')) e.stopPropagation();\n }}\n >\n {item.type === 'decision'\n && details?.run_details?.status === 'WAITING'\n && (item.category === 'ask' || details?.action === 'ask')\n && questions.length === 0 && (\n <>\n <Tooltip title=\"Approve this step\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={() => {\n if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: 'true' });\n }}\n sx={{ color: STATUS_COLORS.finished }}\n >\n <ThumbUpIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip title=\"Deny this step\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={() => {\n if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: 'false' });\n }}\n sx={{ color: STATUS_COLORS.error }}\n >\n <ThumbDownIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n </>\n )}\n {item.type === 'agent' && null}\n {item.type === 'decision' && (() => {\n const action = details?.action;\n const cat = item.category;\n const isApiAction =\n action !== 'ask' && cat !== 'ask' &&\n action !== 'finish' && action !== 'finalise' && cat !== 'finish' && cat !== 'finalise' &&\n cat !== 'processing' &&\n action !== 'add_tool';\n if (!isApiAction) return null;\n return (\n <Tooltip title=\"Rerun from this decision (clears all decisions after it)\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading || !details?.run_details?.id}\n onClick={() => details && onRerunDecision(details)}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <RestartAltIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n );\n })()}\n {item.type === 'decision' && (details?.run_details as any)?.debug_url && (\n <Tooltip title=\"Open debug URL\">\n <span>\n <IconButton\n size=\"small\"\n onClick={() => window.open((details!.run_details as any).debug_url, '_blank', 'noopener,noreferrer')}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n )}\n </Box>\n </Box>\n\n {/* Question form (for ASK decisions) */}\n {questions.length > 0 && !runFinished && (item.status === 'RUNNING' || item.status === 'WAITING') && (\n <Box sx={{ px: 4, pb: 2 }}>\n {(() => {\n const trySubmit = () => {\n if (agentRequestLoading) return;\n if (!questionsAnswered) {\n setSubmitAttempted(true);\n return;\n }\n if (details?.run_details?.id) {\n onSubmitQuestions(details.run_details.id, questionAnswers);\n }\n };\n return (\n <>\n {questions.map((q, qi) => {\n const value = questionAnswers[q.question]?.value || '';\n const isMissing = submitAttempted && !value;\n return (\n <Box key={qi} sx={{ mt: 2 }}>\n <Box sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', mb: 1 }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n <TextField\n fullWidth\n multiline\n minRows={2}\n placeholder=\"Your answer here…\"\n value={value}\n error={isMissing}\n helperText={isMissing ? 'Please answer this question' : undefined}\n onChange={(e) => {\n const v = e.target.value;\n setQuestionAnswers((prev) => ({\n ...prev,\n [q.question]: { index: qi, value: v },\n }));\n }}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n trySubmit();\n }\n }}\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': { bgcolor: 'hsl(var(--card))' },\n }}\n />\n </Box>\n );\n })}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 2 }}>\n <Tooltip title={!questionsAnswered ? 'Please answer all questions first' : ''} placement=\"top\" arrow>\n <span>\n <Button\n variant=\"contained\"\n size=\"small\"\n disabled={agentRequestLoading || !questionsAnswered}\n onClick={trySubmit}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'hsl(var(--primary-foreground))' }} /> : undefined}\n >\n {agentRequestLoading ? 'Submitting…' : 'Submit'}\n </Button>\n </span>\n </Tooltip>\n {details?.run_details?.id && getFormUrl && getFormUrl(details.run_details.id) && (\n <Tooltip title=\"Answer in the Form UI\" placement=\"right\">\n <IconButton\n size=\"small\"\n onClick={() => {\n const url = getFormUrl(details.run_details!.id!);\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n }}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon sx={{ fontSize: 18 }} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </>\n );\n })()}\n </Box>\n )}\n\n {/* Unanswered questions (read-only) when the run finished without an answer */}\n {open && runFinished && unansweredQuestions.length > 0 && (\n <Box sx={{ px: 4, pb: 2 }}>\n <Typography sx={{ fontSize: '0.7rem', textTransform: 'uppercase', letterSpacing: 0.5, color: 'hsl(var(--muted-foreground))', mb: 1 }}>\n {unansweredQuestions.length === 1 ? 'Question (unanswered)' : 'Questions (unanswered)'}\n </Typography>\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n display: 'flex', flexDirection: 'column', gap: 1.5,\n }}>\n {unansweredQuestions.map((q, qi) => (\n <Box key={qi} sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', '& p': { my: 0.5 } }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n ))}\n </Box>\n </Box>\n )}\n\n {/* App authentication required banner — surfaces whenever the upstream\n tool returned `action: \"app_authentication\"`. Always visible\n (regardless of expand state) so users do not have to click into\n a failed step to discover that auth is missing. */}\n {(() => {\n const req = extractAuthRequest(details);\n if (!req) return null;\n if (isAppAuthenticated?.(req.appName)) return null;\n const pretty = req.appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const slug = req.appName.toLowerCase().replace(/[\\s-]+/g, '_');\n const appId = req.appId || appsById[req.appName]?.id || appsById[slug]?.id || null;\n const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : '') || '';\n return (\n <Box sx={{ px: 4, pb: 2 }}>\n <Box sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}>\n <LockIcon sx={{ color: 'hsl(var(--severity-medium))', fontSize: 22 }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n Connect your {pretty} account so the agent can complete this step, then rerun the decision.\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={icon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n disabled={!onAuthenticateApp}\n onClick={(e) => {\n e.stopPropagation();\n onAuthenticateApp?.(req.appName, appId);\n }}\n sx={{\n height: 36, textTransform: 'none', fontWeight: 600,\n }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n </Box>\n );\n })()}\n\n {/* Raw JSON */}\n {open && (\n <Box sx={{ px: 4, pb: 2 }}>\n <Box\n sx={{\n p: 2,\n borderRadius: 1.5,\n border: highlight\n ? '1px solid hsl(var(--severity-medium))'\n : '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n boxShadow: highlight\n ? '0 0 0 3px hsla(var(--severity-medium) / 0.25)'\n : 'none',\n transition: 'border-color 0.6s ease, box-shadow 0.6s ease',\n overflow: 'auto',\n maxHeight: 400,\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n '& .json-view': {\n fontSize: '0.72rem !important',\n fontFamily: 'inherit !important',\n bgcolor: 'transparent !important',\n },\n }}\n >\n {validate.valid && validate.result && typeof validate.result === 'object' ? (\n <JsonView\n src={deepParseJsonStrings(validate.result)}\n dark\n collapsed={2}\n collapseStringMode=\"word\"\n collapseStringsAfterLength={120}\n enableClipboard\n displaySize\n />\n ) : (\n <Box component=\"pre\" sx={{ m: 0, fontSize: '0.72rem', color: 'hsl(var(--foreground))' }}>\n <code>{String(item.details ?? '')}</code>\n </Box>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n};\n\n// ── Main component ────────────────────────────────────────────────────────────\n\n\nconst AgentUI: React.FC<AgentUIProps> = ({\n apps,\n defaultApps,\n autoLoadApps = true,\n title = 'What do you want to do?',\n subtitle,\n placeholder = 'Describe a task, e.g. \"Get my emails for today and summarise them\"',\n defaultInput = '',\n autoSubmit = false,\n hideHeroIcon = false,\n heroIcon,\n heroIconSize = 84,\n maxWidth = 900,\n compact = false,\n hideAppPicker = false,\n hideAttach = false,\n disableStartTab = false,\n appPickerLabel = 'Select Apps / MCPs',\n appPickerTitle = 'Select Apps / MCPs',\n appPickerSubtitle = 'Pick the tools the agent is allowed to use for this run',\n submitTooltip = '⌘+Enter to send',\n submitIcon,\n submitOverride,\n submitLabel,\n disableSchedule,\n disableScheduleTooltip,\n continuationPlaceholder = 'Add more details to continue this task…',\n readUrlParams = true,\n executionId,\n authorization,\n initialExecution,\n onRun,\n onViewChange,\n onSchedule,\n apiKey,\n apiBaseUrl,\n orgId,\n className,\n sx,\n contentSx,\n}) => {\n // Per-instance API target. Props win over the shared API_CONFIG so the\n // component can be embedded against a different Shuffle backend without\n // mutating global state.\n const resolveUrl = useCallback(\n (path: string) => (apiBaseUrl ? `${apiBaseUrl.replace(/\\/+$/, '')}${path}` : getApiUrl(path)),\n [apiBaseUrl],\n );\n const resolveHeaders = useCallback((): Record<string, string> => {\n const h: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : { ...getAuthHeader() };\n if (orgId) h['Org-Id'] = orgId;\n return h;\n }, [apiKey, orgId]);\n const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;\n const navigate = useNavigate();\n const [actionInput, setActionInput] = useState(defaultInput);\n const BUILTIN_DEFAULT_APPS: AgentUIApp[] = [\n { name: 'http' },\n { name: 'shuffle_tools' },\n ];\n const [chosenApps, setChosenApps] = useState<AgentUIApp[]>(apps ?? defaultApps ?? BUILTIN_DEFAULT_APPS);\n // Apps the caller has authenticated — used to resolve icons by name and as\n // suggestions in the picker. NOT auto-selected as `chosenApps`.\n const [availableApps, setAvailableApps] = useState<AgentUIApp[]>([]);\n // Apps actually allowed for the current execution, derived from the agent's\n // `allowed_actions` field (format: \"app:<id>:<name>\"). Falls back to\n // `chosenApps` when the field is missing (legacy runs).\n const [executionApps, setExecutionApps] = useState<AgentUIApp[]>([]);\n // Icons resolved on-demand for tools referenced in the timeline that are\n // NOT in chosenApps/executionApps. Resolution order:\n // 1) /api/v1/apps cache — match by id, then by lowercase+underscore name\n // 2) Algolia — match by objectID, then by name\n const [resolvedToolApps, setResolvedToolApps] = useState<Record<string, AgentUIApp>>({});\n const [appSearchOpen, setAppSearchOpen] = useState(false);\n const [authDrawerApp, setAuthDrawerApp] = useState<{ name: string; id?: string | null } | null>(null);\n const [agentRequestLoading, setAgentRequestLoading] = useState(false);\n const [execution, setExecution] = useState<ExecutionData | null>(null);\n const [agentData, setAgentData] = useState<{ decisions?: AgentDecision[]; original_input?: string; status?: string; started_at?: number; completed_at?: number; [k: string]: any }>({});\n const [agentActionResult, setAgentActionResult] = useState<any>(null);\n const [showStarter, setShowStarter] = useState(true);\n const [scheduleAnchor, setScheduleAnchor] = useState<HTMLElement | null>(null);\n const [scheduleCron, setScheduleCron] = useState('0 * * * *');\n const [scheduleSaving, setScheduleSaving] = useState(false);\n const [scheduleSteps, setScheduleSteps] = useState<Array<{ id: 'name' | 'workflow' | 'schedule'; state: 'pending' | 'active' | 'done' | 'error'; detail?: string }>>([\n { id: 'name', state: 'pending' },\n { id: 'workflow', state: 'pending' },\n { id: 'schedule', state: 'pending' },\n ]);\n // Structured recurrence controls (Google-Calendar style). These compile\n // down to a 5-field cron expression in `scheduleCron`. The advanced cron\n // text field at the bottom of the popover lets power users override.\n type SchedFreq = 'minutes' | 'hours' | 'days' | 'weeks' | 'months';\n const [schedFreq, setSchedFreq] = useState<SchedFreq>('hours');\n const [schedInterval, setSchedInterval] = useState<number>(1);\n const [schedHour, setSchedHour] = useState<number>(9);\n const [schedMinute, setSchedMinute] = useState<number>(0);\n // Cron day-of-week: 0=Sun .. 6=Sat\n const [schedWeekdays, setSchedWeekdays] = useState<Set<number>>(() => new Set([1]));\n const [schedDayOfMonth, setSchedDayOfMonth] = useState<number>(1);\n const [schedAdvancedOpen, setSchedAdvancedOpen] = useState<boolean>(false);\n // When the user clicks a preset chip or types a custom cron, we mark the\n // structured controls \"dirty\" so the auto-compile effect doesn't clobber\n // it on the same render.\n const cronManualOverrideRef = useRef<boolean>(false);\n const [openIndexes, setOpenIndexes] = useState<Set<number>>(new Set());\n // Briefly pulses a row + its output box after the diagnosis banner's\n // \"Where this was found\" jump. Cleared on a timer.\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n const [questionAnswers, setQuestionAnswers] = useState<Record<string, { index: number; value: string }>>({});\n const [simpleSubmitAttempted, setSimpleSubmitAttempted] = useState(false);\n const [continuationText, setContinuationText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [searchParams, setSearchParams] = useSearchParams();\n const initialViewParam = searchParams.get('agentView');\n const [viewMode, setViewMode] = useState<'simple' | 'detailed'>(\n initialViewParam === 'detailed' ? 'detailed' : 'simple'\n );\n const [attachedImages, setAttachedImages] = useState<{ dataUrl: string; name: string }[]>([]);\n const [nowTick, setNowTick] = useState(() => Math.floor(Date.now() / 1000));\n // Local fallback start timestamp captured the moment we first see an\n // execution_id, so the \"Agent is working… Xs\" counter starts ticking\n // immediately — even before the backend echoes `started_at` back to us.\n const [localRunStart, setLocalRunStart] = useState<number | null>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n // Tracks the execution_id we currently want to display. Used to discard\n // stale poll responses from a previous run after the user has started a\n // new one (otherwise an in-flight fetch can repaint the old execution).\n const activeExecutionIdRef = useRef<string | null>(null);\n // AbortController for the in-flight POST /api/v1/agent request, plus a\n // generation counter so a slow request that resolves AFTER the user clicks\n // \"Cancel and go to Start\" cannot repaint the UI or swap tabs back.\n const runAbortRef = useRef<AbortController | null>(null);\n const runGenerationRef = useRef(0);\n // Sticky flag set when the user manually clicks the \"Start\" tab while a run\n // is loaded. Prevents downstream effects (URL sync, initialExecution attach,\n // etc.) from flipping back to Simple/Detailed when a poll response lands.\n // Cleared the moment the user actually submits a new run.\n const userPickedStartRef = useRef(false);\n // Mirror of state used inside async callbacks (e.g. submitInput) so we can\n // snapshot prior values for rollback without making the callback re-render\n // on every state change.\n const stateRef = useRef({\n execution: null as ExecutionData | null,\n agentData: {} as any,\n agentActionResult: null as any,\n openIndexes: new Set<number>(),\n questionAnswers: {} as Record<string, { index: number; value: string }>,\n continuationText: '',\n localRunStart: null as number | null,\n showStarter: true,\n });\n\n // Mirror state into stateRef on every render so async callbacks can read the\n // current values without taking them as dependencies.\n stateRef.current.execution = execution;\n stateRef.current.agentData = agentData;\n stateRef.current.agentActionResult = agentActionResult;\n stateRef.current.openIndexes = openIndexes;\n stateRef.current.questionAnswers = questionAnswers;\n stateRef.current.continuationText = continuationText;\n stateRef.current.localRunStart = localRunStart;\n stateRef.current.showStarter = showStarter;\n\n // Reset / capture the local run start. Seed as soon as the user submits\n // (so the counter ticks from t=0 even before /agent returns), and keep it\n // pinned until the run is cleared. Without this, the \"0s/1s\" counter\n // freezes because the backend's `started_at` keeps catching up to `now`\n // on every poll.\n useEffect(() => {\n if (execution?.execution_id || agentRequestLoading) {\n setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1000));\n } else {\n setLocalRunStart(null);\n }\n }, [execution?.execution_id, agentRequestLoading]);\n\n // Tick every second while anything run-related is in flight. Deps are\n // intentionally minimal so the interval is NOT torn down and recreated on\n // every poll response — that was making the \"Xs\" counter look frozen at 1s.\n useEffect(() => {\n const status = (execution?.status || agentData?.status || '').toUpperCase();\n const TERMINAL = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'];\n if (TERMINAL.includes(status)) return;\n const id = setInterval(() => setNowTick(Math.floor(Date.now() / 1000)), 1000);\n return () => clearInterval(id);\n }, [execution?.status, agentData?.status]);\n\n\n const readImageAsDataUrl = (file: File): Promise<{ dataUrl: string; name: string } | null> =>\n new Promise((resolve) => {\n if (!file.type.startsWith('image/')) {\n resolve(null);\n return;\n }\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result;\n resolve(typeof result === 'string' ? { dataUrl: result, name: file.name || 'Pasted image' } : null);\n };\n reader.onerror = () => resolve(null);\n reader.readAsDataURL(file);\n });\n\n const handleImagesSelected = async (files: FileList | File[] | null) => {\n if (!files) return;\n const arr = Array.from(files);\n const nonImages = arr.some((f) => !f.type.startsWith('image/'));\n if (nonImages) setError('Only image files can be attached.');\n const results = await Promise.all(arr.map(readImageAsDataUrl));\n const valid = results.filter((r): r is { dataUrl: string; name: string } => r !== null);\n if (valid.length > 0) {\n setAttachedImages((prev) => [...prev, ...valid]);\n setError(null);\n }\n };\n\n const appsById = useMemo(() => {\n const m: Record<string, AgentUIApp> = {};\n const add = (a: AgentUIApp) => {\n if (!a?.name) return;\n const slug = a.name.toLowerCase().replace(/[\\s-]+/g, '_');\n if (!m[slug] || (!m[slug].icon && a.icon)) m[slug] = a;\n if (a.id) {\n if (!m[a.id] || (!m[a.id].icon && a.icon)) m[a.id] = a;\n }\n };\n for (const a of chosenApps) add(a);\n for (const a of executionApps) add(a);\n for (const [k, v] of Object.entries(resolvedToolApps)) {\n if (!m[k] || (!m[k].icon && v.icon)) m[k] = v;\n add(v);\n }\n return m;\n }, [chosenApps, executionApps, resolvedToolApps]);\n\n // Predicate used by the auth banners — an app is considered authenticated\n // when it appears in the caller's `availableApps` list (which is populated\n // from /api/v1/apps/authentication and only includes valid entries).\n const isAppAuthenticated = useCallback((appName: string) => {\n if (!appName) return false;\n const norm = (s: string) => s.toLowerCase().replace(/[\\s-]+/g, '_');\n const target = norm(appName);\n return availableApps.some((a) => norm(a.name || '') === target);\n }, [availableApps]);\n\n // Unique apps (across all decisions) that returned `app_authentication`\n // and are not yet authenticated. Powers the Simple-view banners.\n const pendingAuthApps = useMemo(() => {\n const decisions: any[] = (agentData?.decisions as any[]) || [];\n const seen = new Set<string>();\n const out: { appName: string; appId: string | null; icon: string }[] = [];\n for (const d of decisions) {\n const req = extractAuthRequest(d);\n if (!req) continue;\n const slug = req.appName.toLowerCase().replace(/[\\s-]+/g, '_');\n if (seen.has(slug)) continue;\n if (isAppAuthenticated(req.appName)) continue;\n seen.add(slug);\n const appId = req.appId || appsById[req.appName]?.id || appsById[slug]?.id || null;\n const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : '') || '';\n out.push({ appName: req.appName, appId, icon });\n }\n return out;\n }, [agentData, appsById, isAppAuthenticated]);\n\n // Sync controlled `apps` prop into local state.\n useEffect(() => {\n if (apps) setChosenApps(apps);\n }, [apps]);\n\n // Resolve icons for tools referenced in the timeline that aren't already\n // covered by chosenApps/executionApps. Lookup order:\n // 1) /api/v1/apps cache — by id, then by lowercase+underscore name\n // 2) Algolia — by objectID, then by name\n useEffect(() => {\n const decisions = (agentData as any)?.decisions || [];\n if (!Array.isArray(decisions) || decisions.length === 0) return;\n\n const norm = (s: string) => s.toLowerCase().replace(/[\\s-]+/g, '_');\n // Collect unique tool tokens (raw + slug variant) that we haven't resolved.\n const wanted: { raw: string; slug: string }[] = [];\n const seen = new Set<string>();\n const consider = (raw: string) => {\n if (!raw || typeof raw !== 'string') return;\n let slug = norm(raw);\n if (slug.startsWith('app:')) slug = slug.split(':')[2] || slug;\n if (appsById[raw]?.icon || appsById[slug]?.icon) return;\n if (resolvedToolApps[raw]?.icon || resolvedToolApps[slug]?.icon) return;\n const key = `${raw}|${slug}`;\n if (seen.has(key)) return;\n seen.add(key);\n wanted.push({ raw, slug });\n };\n for (const dec of decisions) {\n const action = dec?.action || dec?.details?.action;\n const category = dec?.category || dec?.details?.category;\n // Tool tokens — skip terminal/ask steps.\n if (action !== 'finish' && action !== 'finalise' && action !== 'ask' &&\n category !== 'finish' && category !== 'finalise' && category !== 'ask') {\n const tool = dec?.details?.tool ?? dec?.tool;\n if (tool && tool !== 'singul' && tool !== 'core') consider(tool);\n }\n // App auth requests — banner needs the icon too.\n const req = extractAuthRequest(dec);\n if (req?.appName) consider(req.appName);\n }\n if (wanted.length === 0) return;\n\n let cancelled = false;\n (async () => {\n // Single general-purpose resolver — checks authenticated apps,\n // /api/v1/apps and Algolia in order so we get an icon even when the\n // app isn't activated yet.\n const tokens = Array.from(new Set(wanted.flatMap((w) => [w.raw, w.slug])));\n const resolved = await resolveApps(tokens);\n if (cancelled) return;\n\n const found: Record<string, AgentUIApp> = {};\n for (const { raw, slug } of wanted) {\n const r = resolved[raw] || resolved[slug];\n if (!r) continue;\n const app: AgentUIApp = { id: r.id, name: r.name || slug, icon: r.image || '' };\n found[raw] = app;\n found[slug] = app;\n }\n\n if (Object.keys(found).length === 0) return;\n setResolvedToolApps((prev) => ({ ...prev, ...found }));\n })();\n\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify((agentData as any)?.decisions?.map((d: any) => [d?.details?.tool || d?.tool, extractAuthRequest(d)?.appName]) || []), appsById]);\n\n // Sideload missing app icons via Algolia (same source as the picker), so\n // built-in/default chips like \"http\" and \"shuffle_tools\" show their logo\n // even when the caller didn't pass one in.\n useEffect(() => {\n const missing = chosenApps.filter((a) => !a.icon && a.name);\n if (missing.length === 0) return;\n let cancelled = false;\n const norm = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\n (async () => {\n // Pass 1 — try Algolia (public, works without an API key).\n const resolved: Record<string, string> = {};\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n await Promise.all(missing.map(async (a) => {\n const known = availableApps.find((x) => norm(x.name) === norm(a.name));\n if (known?.icon) { resolved[a.name] = known.icon; return; }\n try {\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: a.name.replace(/_/g, ' '), hitsPerPage: 3 },\n });\n const match = (res.hits as any[]).find((h) => norm(h.name || '') === norm(a.name))\n || (res.hits as any[])[0];\n if (match?.image_url) resolved[a.name] = match.image_url;\n } catch { /* fall through to /api/v1/apps */ }\n }));\n } catch { /* fall through to /api/v1/apps */ }\n\n // Pass 2 — for anything Algolia didn't resolve, fall back to /api/v1/apps\n // so built-in chips (http, shuffle_tools) still get their logo even when\n // Algolia is blocked or offline.\n const stillMissing = missing.filter((a) => !resolved[a.name]);\n if (stillMissing.length > 0) {\n try {\n const baseUrl = apiBaseUrl ? apiBaseUrl.replace(/\\/+$/, '') : API_CONFIG.baseUrl;\n const apps = await fetchApps({\n baseUrl,\n apiKey: apiKey || API_CONFIG.apiKey,\n orgId: orgId || null,\n });\n if (Array.isArray(apps)) {\n for (const a of stillMissing) {\n const m = apps.find((x: any) => norm(x.name || '') === norm(a.name));\n const img = m?.large_image || m?.image_url || m?.image;\n if (img) resolved[a.name] = img;\n }\n }\n } catch { /* chips will just show initials */ }\n }\n\n if (cancelled) return;\n setChosenApps((prev) => prev.map((a) => {\n if (a.icon) return a;\n const icon = resolved[a.name];\n return icon ? { ...a, icon } : a;\n }));\n })();\n return () => { cancelled = true; };\n }, [chosenApps, availableApps, resolveUrl, resolveHeaders]);\n\n // Auto-load the caller's authenticated apps when nothing was passed in\n // and an API token is configured. Skipped when controlled or `defaultApps`\n // were provided explicitly.\n useEffect(() => {\n if (!autoLoadApps) return;\n if (apps || defaultApps) return;\n if (!hasApiKey) return;\n let cancelled = false;\n (async () => {\n try {\n const resp = await fetch(resolveUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers: { ...resolveHeaders() },\n });\n if (!resp.ok) return;\n const result = await resp.json();\n const list = Array.isArray(result) ? result : (result?.data || []);\n const seen = new Set<string>();\n const loaded: AgentUIApp[] = [];\n for (const entry of list) {\n const app = entry?.app || entry;\n const name: string | undefined = app?.name;\n if (!name) continue;\n const valid = entry?.active || entry?.validation?.valid || entry?.hasValidAuth;\n if (valid === false) continue;\n const key = name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n loaded.push({\n name,\n id: app?.id || entry?.id,\n icon: app?.large_image || app?.image_url || app?.image || entry?.bestImage || '',\n });\n }\n if (!cancelled && loaded.length) setAvailableApps(loaded);\n } catch {\n // silent — caller can still pick apps manually\n }\n })();\n return () => { cancelled = true; };\n }, [autoLoadApps, apps, defaultApps, hasApiKey, resolveUrl, resolveHeaders]);\n\n\n // Derive the apps actually allowed for the current execution from the\n // agent's `allowed_actions` field. Format: \"app:<id>:<name>\". Resolves\n // icons via `availableApps` (in-memory) first, then falls back to the\n // global `/api/v1/apps` cache by id (preferred) or name.\n useEffect(() => {\n const raw = (agentData as any)?.allowed_actions;\n if (!Array.isArray(raw) || raw.length === 0) {\n setExecutionApps([]);\n return;\n }\n const parsed: { id: string; name: string }[] = [];\n const seen = new Set<string>();\n for (const entry of raw) {\n if (typeof entry !== 'string') continue;\n const parts = entry.split(':');\n if (parts.length < 3 || parts[0] !== 'app') continue;\n const id = parts[1] || '';\n const name = parts.slice(2).join(':') || '';\n if (!name && !id) continue;\n const key = `${id}|${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n parsed.push({ id, name });\n }\n if (parsed.length === 0) {\n setExecutionApps([]);\n return;\n }\n\n // First pass: resolve from availableApps without any network call.\n const resolveFromAvailable = (id: string, name: string): AgentUIApp => {\n const byId = id ? availableApps.find((a) => a.id === id) : undefined;\n const byName = !byId && name\n ? availableApps.find((a) => (a.name || '').toLowerCase() === name.toLowerCase())\n : undefined;\n const hit = byId || byName;\n return { id: id || hit?.id, name: hit?.name || name, icon: hit?.icon };\n };\n const initial = parsed.map(({ id, name }) => resolveFromAvailable(id, name));\n setExecutionApps(initial);\n\n // Second pass: fill missing icons from the global apps cache (covers\n // apps that the user has not authenticated yet). Lookup order:\n // 1) /api/v1/apps — by id, then by lowercase+underscore name\n // 2) Algolia — by objectID, then by name\n if (initial.every((a) => !!a.icon)) return;\n let cancelled = false;\n const norm = (s: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n (async () => {\n let next = initial;\n // Pass A — /api/v1/apps cache.\n try {\n const all = await fetchApps({\n baseUrl: API_CONFIG.baseUrl,\n apiKey: apiKey || API_CONFIG.apiKey,\n orgId: orgId || null,\n });\n if (!cancelled && Array.isArray(all) && all.length > 0) {\n const byIdMap = new Map<string, any>();\n const byNameMap = new Map<string, any>();\n for (const a of all) {\n if (a?.id) byIdMap.set(String(a.id), a);\n if (a?.name) byNameMap.set(norm(String(a.name)), a);\n }\n next = next.map((a) => {\n if (a.icon) return a;\n const hit = (a.id && byIdMap.get(a.id)) || byNameMap.get(norm(a.name || ''));\n if (!hit) return a;\n return {\n id: a.id || hit.id,\n name: hit.name || a.name,\n icon: hit.large_image || hit.image_url || hit.image || a.icon,\n } as AgentUIApp;\n });\n }\n } catch { /* fall through to Algolia */ }\n\n // Pass B — Algolia (objectID, then name) for anything still missing.\n const stillMissing = next.filter((a) => !a.icon);\n if (stillMissing.length > 0) {\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const resolved: Record<string, { name: string; icon: string; id: string }> = {};\n await Promise.all(stillMissing.map(async (a) => {\n try {\n if (a.id) {\n try {\n const obj = await (client as any).getObject({ indexName: 'appsearch', objectID: a.id });\n if (obj?.image_url) {\n resolved[a.id || a.name] = { name: obj.name || a.name, icon: obj.image_url, id: obj.objectID || a.id };\n return;\n }\n } catch { /* not an objectID — fall through */ }\n }\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: (a.name || '').replace(/_/g, ' '), hitsPerPage: 3 },\n });\n const hits = (res.hits as any[]) || [];\n const match = hits.find((h) => norm(h.name || '') === norm(a.name || '')) || hits[0];\n if (match?.image_url) {\n resolved[a.id || a.name] = { name: match.name || a.name, icon: match.image_url, id: match.objectID || a.id || '' };\n }\n } catch { /* skip */ }\n }));\n if (Object.keys(resolved).length > 0) {\n next = next.map((a) => {\n if (a.icon) return a;\n const r = resolved[a.id || a.name];\n return r ? { id: r.id || a.id, name: r.name || a.name, icon: r.icon } : a;\n });\n }\n } catch { /* algolia unavailable */ }\n }\n\n if (!cancelled) setExecutionApps(next);\n })();\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify((agentData as any)?.allowed_actions || []), availableApps]);\n\n // ── Fetch execution result (poll-friendly) ──\n const getExecution = useCallback(async (executionId: string, authorization: string) => {\n if (!executionId || !authorization) return;\n try {\n const resp = await fetch(resolveUrl('/api/v1/streams/results'), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders() },\n body: JSON.stringify({ execution_id: executionId, authorization }),\n });\n // Discard stale responses: if the user has since started a different\n // run (or cleared this one), do not write old data back into state.\n // Discard stale responses: only accept when the ref still matches the\n // execution we fetched. (Submitting a new run briefly clears the ref;\n // any in-flight poll from the previous run must be dropped, not written\n // back into state — otherwise the UI snaps to the old execution.)\n if (activeExecutionIdRef.current !== executionId) return;\n if (!resp.ok) {\n setError(`Could not fetch execution (${resp.status}).`);\n return;\n }\n const json = await resp.json();\n if (activeExecutionIdRef.current !== executionId) return;\n if (json?.success === false) {\n setError(json.reason || 'Failed to load agent data.');\n return;\n }\n setExecution({ ...json, execution_id: executionId, authorization });\n\n // Find AI Agent result for the timeline\n let actionResult: any = null;\n if (Array.isArray(json?.results)) {\n actionResult =\n json.results.find((r: any) => r?.action?.app_name === 'AI Agent') || json.results[0];\n } else {\n actionResult = json;\n }\n setAgentActionResult(actionResult);\n const v = validateJson(actionResult?.result);\n if (v.valid) setAgentData({ ...v.result, started_at: json.started_at, completed_at: json.completed_at, status: json.status });\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Network error.');\n }\n }, []);\n\n // Attach to an explicit execution (props) or one passed via URL params.\n // Props take precedence over URL params.\n useEffect(() => {\n let eid: string | null = null;\n let auth: string | null = null;\n if (executionId && authorization) {\n eid = executionId;\n auth = authorization;\n } else if (readUrlParams) {\n const params = new URLSearchParams(window.location.search);\n eid = params.get('execution_id');\n auth = params.get('authorization');\n }\n if (eid && auth) {\n if (!userPickedStartRef.current) setShowStarter(false);\n activeExecutionIdRef.current = eid;\n setExecution({ execution_id: eid, authorization: auth, status: 'EXECUTING' });\n getExecution(eid, auth);\n }\n }, [readUrlParams, executionId, authorization, getExecution]);\n\n // Attach to a pre-loaded execution (e.g. embedded inside a list/drawer\n // that already has the run data). Skips the starter and seeds Simple/\n // Detailed views directly — no `/streams/results` fetch, no\n // `authorization` token required.\n useEffect(() => {\n if (!initialExecution || !initialExecution.execution_id) return;\n if (!userPickedStartRef.current) setShowStarter(false);\n activeExecutionIdRef.current = initialExecution.execution_id;\n setExecution(initialExecution as ExecutionData);\n let actionResult: any = null;\n if (Array.isArray(initialExecution.results)) {\n actionResult =\n initialExecution.results.find((r: any) => r?.action?.app_name === 'AI Agent') ||\n initialExecution.results[0];\n } else {\n actionResult = initialExecution;\n }\n setAgentActionResult(actionResult);\n const v = validateJson(actionResult?.result);\n if (v.valid) {\n setAgentData({\n ...v.result,\n started_at: initialExecution.started_at,\n completed_at: initialExecution.completed_at,\n status: initialExecution.status,\n });\n }\n setError(null);\n\n // Sideloaded executions from the listing endpoint sometimes ship a\n // placeholder result body like `{ success: false, reason: \"Result too\n // large to handle ...\", extra: \"replace\" }` instead of the real agent\n // output. Detect that and re-fetch the full payload directly from\n // /api/v1/streams/results so the timeline renders properly.\n const needsReplace = (() => {\n const r = v.valid ? v.result : null;\n if (!r || typeof r !== 'object') return false;\n if (r.success === false && typeof r.reason === 'string' && /too large/i.test(r.reason)) return true;\n if (r.extra === 'replace') return true;\n return false;\n })();\n if (needsReplace && initialExecution.authorization && initialExecution.execution_id) {\n getExecution(initialExecution.execution_id, initialExecution.authorization);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialExecution?.execution_id]);\n\n // Poll while running. Continue indefinitely until we see a terminal status\n // (FINISHED / FAILURE / ABORTED). We never give up on our own — long\n // executions just keep streaming results back.\n useEffect(() => {\n if (!execution?.execution_id || !execution?.authorization) return;\n const status = (execution.status || '').toUpperCase();\n const TERMINAL = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'];\n if (TERMINAL.includes(status)) return;\n const id = setInterval(() => {\n getExecution(execution.execution_id!, execution.authorization!);\n }, 3000);\n return () => clearInterval(id);\n }, [execution?.execution_id, execution?.authorization, execution?.status, getExecution]);\n\n // ── Submit input ──\n const submitInput = useCallback(async (text: string) => {\n if (!text.trim()) return;\n if (text.trim().length < 6) {\n setError('Please enter at least 6 characters before starting the agent.');\n toast({\n title: 'Input too short',\n description: 'The agent needs at least 6 characters to start.',\n variant: 'destructive',\n });\n return;\n }\n setError(null);\n setAgentRequestLoading(true);\n\n // Mint a generation id for THIS submit. If the user aborts before the\n // request resolves, abortAgent() will bump runGenerationRef so the stale\n // resolution below short-circuits instead of swapping tabs back.\n const myGeneration = ++runGenerationRef.current;\n // Cancel any previous in-flight controller, then install a fresh one so\n // abortAgent() can actually kill the underlying fetch.\n try { runAbortRef.current?.abort(); } catch { /* noop */ }\n const controller = new AbortController();\n runAbortRef.current = controller;\n\n // Snapshot prior run state so a failed network request does not leave\n // the user staring at an empty page with no way to retry. We only\n // commit the destructive reset once the new run has been accepted.\n const prevExecution = stateRef.current.execution;\n const prevAgentData = stateRef.current.agentData;\n const prevAgentActionResult = stateRef.current.agentActionResult;\n const prevOpenIndexes = stateRef.current.openIndexes;\n const prevQuestionAnswers = stateRef.current.questionAnswers;\n const prevContinuationText = stateRef.current.continuationText;\n const prevLocalRunStart = stateRef.current.localRunStart;\n const prevActiveExecutionId = activeExecutionIdRef.current;\n const prevShowStarter = stateRef.current.showStarter;\n const prevViewMode = viewMode;\n\n // Hard reset NOW — kill the previous run's poll loop, blank the\n // execution/timeline state, drop the previous execution_id +\n // agentView from the URL, and reset the view to simple. Otherwise\n // the previous run's poll keeps writing into state during the\n // in-flight request and the user sees the old \"Detailed\" tab flash\n // back in.\n activeExecutionIdRef.current = null;\n setExecution(null);\n setAgentData({ original_input: text.trim() });\n setAgentActionResult(null);\n setExecutionApps([]);\n setResolvedToolApps({});\n setHighlightedIndex(null);\n setOpenIndexes(new Set());\n setQuestionAnswers({});\n setContinuationText('');\n setSimpleSubmitAttempted(false);\n \n setError(null);\n setLocalRunStart(null);\n setViewMode('simple');\n setShowStarter(false);\n // The user is starting a new run — drop any sticky \"manual Start\" pin so\n // future polls/effects can populate Simple/Detailed normally.\n userPickedStartRef.current = false;\n if (readUrlParams && typeof window !== 'undefined') {\n try {\n const url = new URL(window.location.href);\n url.searchParams.delete('execution_id');\n url.searchParams.delete('authorization');\n url.searchParams.delete('agentView');\n window.history.replaceState({}, '', url.toString());\n } catch { /* noop */ }\n }\n\n const result = await runAgent({\n input: text.trim(),\n skipPolling: true,\n signal: controller.signal,\n ...(apiKey ? { apiKey } : {}),\n ...(apiBaseUrl ? { apiBaseUrl } : {}),\n ...(orgId ? { orgId } : {}),\n // Send a single comma-separated `tool_name` in the format\n // `app:<objectID>:<slug>,app:<objectID>:<slug>` so the backend resolves\n // the exact app versions instead of guessing by slug.\n ...(chosenApps.length > 0 ? { toolName: buildToolName(chosenApps) } : {}),\n ...(attachedImages.length > 0 ? { images: attachedImages.map((img) => {\n const m = /^data:([^;]+);base64,(.*)$/.exec(img.dataUrl);\n return m ? { mimeType: m[1], data: m[2], name: img.name } : { mimeType: 'image/png', data: img.dataUrl, name: img.name };\n }) } : {}),\n });\n\n // If the user aborted while we were waiting, drop this result on the floor.\n // Do NOT touch UI state — abortAgent() already reset us to the Start tab.\n if (myGeneration !== runGenerationRef.current || controller.signal.aborted) {\n // Best-effort: if the backend still managed to spawn an execution\n // before our fetch was aborted, ask it to abort that execution too.\n const raw: any = (result as any)?.rawData;\n const eid = raw?.execution_id;\n const auth = raw?.authorization;\n const wfId = raw?.workflow?.id;\n if (eid && wfId) {\n try {\n fetch(\n resolveUrl(`/api/v1/workflows/${wfId}/executions/${eid}/abort`),\n {\n method: 'GET',\n credentials: 'include',\n headers: { ...resolveHeaders(), ...(auth ? { Authorization: `Bearer ${auth}` } : {}) },\n },\n ).catch(() => { /* noop */ });\n } catch { /* noop */ }\n }\n return;\n }\n\n setAgentRequestLoading(false);\n\n if (!result.success) {\n // Restore the previous run so the user can try Rerun again.\n setError(result.error || 'Agent run failed.');\n activeExecutionIdRef.current = prevActiveExecutionId;\n setExecution(prevExecution);\n setAgentData(prevAgentData);\n setAgentActionResult(prevAgentActionResult);\n setOpenIndexes(prevOpenIndexes);\n setQuestionAnswers(prevQuestionAnswers);\n setContinuationText(prevContinuationText);\n setLocalRunStart(prevLocalRunStart);\n setShowStarter(prevShowStarter);\n setViewMode(prevViewMode);\n onRun?.({ input: text, success: false, error: result.error });\n return;\n }\n\n // Success — start the live timer for the new run. The destructive\n // reset already happened up-front, so all we need to do here is\n // seed the timer reference for elapsed-time rendering.\n const browserStart = Math.floor(Date.now() / 1000);\n setNowTick(browserStart);\n setLocalRunStart(browserStart);\n\n const raw = result.rawData as any;\n const eid = raw?.execution_id;\n const auth = raw?.authorization;\n if (eid && auth) {\n // Seed an EXECUTING stub so the poll effect starts immediately,\n // then kick off the first fetch. The poller continues until terminal.\n activeExecutionIdRef.current = eid;\n setExecution({ execution_id: eid, authorization: auth, status: 'EXECUTING' });\n // Reflect the new execution in the URL so the run is shareable/refreshable.\n if (readUrlParams && typeof window !== 'undefined') {\n try {\n const url = new URL(window.location.href);\n url.searchParams.set('execution_id', eid);\n url.searchParams.set('authorization', auth);\n window.history.replaceState({}, '', url.toString());\n } catch { /* noop */ }\n }\n getExecution(eid, auth);\n onRun?.({ input: text, success: true, executionId: eid });\n } else {\n // Direct response (no async execution): synthesize a single-step view\n setExecution({\n execution_id: eid || crypto.randomUUID(),\n authorization: auth,\n status: 'FINISHED',\n results: [{ action: { app_name: 'AI Agent' }, result: raw }],\n });\n const v = validateJson(raw);\n if (v.valid) {\n setAgentData({ ...v.result, status: 'FINISHED', original_input: text });\n } else {\n setAgentData({ original_input: text, status: 'FINISHED', message: result.content });\n }\n onRun?.({ input: text, success: true, executionId: eid });\n }\n }, [chosenApps, getExecution, onRun, attachedImages, readUrlParams, viewMode]);\n\n // Auto-submit on mount when caller provides a defaultInput + autoSubmit.\n const autoSubmittedRef = useRef(false);\n useEffect(() => {\n if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {\n autoSubmittedRef.current = true;\n submitInput(defaultInput);\n }\n }, [autoSubmit, defaultInput, executionId, submitInput]);\n\n // ── Submit answers / continuation ──\n const submitQuestions = useCallback(async (\n decisionId: string,\n answers: Record<string, any>,\n isContinuation?: boolean,\n ) => {\n if (!execution?.execution_id || !execution?.authorization) return;\n\n let newArgument: Record<string, string> = {};\n if (isContinuation) {\n newArgument = { ...answers };\n } else {\n for (const k in answers) {\n if (k === 'approve') {\n newArgument[k] = answers[k];\n break;\n }\n const a = answers[k];\n newArgument[`question_${a.index}`] = a.value;\n }\n }\n\n setAgentRequestLoading(true);\n const wfId = execution.workflow?.id || execution.execution_id;\n const params = new URLSearchParams({\n reference_execution: execution.execution_id,\n authorization: execution.authorization,\n answer: 'true',\n note: JSON.stringify(newArgument),\n agentic: 'true',\n decision_id: decisionId,\n });\n try {\n const resp = await fetch(resolveUrl(`/api/v1/workflows/${wfId}/run?${params.toString()}`), {\n method: 'GET',\n credentials: 'include',\n headers: { ...resolveHeaders() },\n });\n const json = await resp.json();\n if (json.success === false) {\n toast({ title: 'Failed to submit', description: json.reason || 'Try again later.', variant: 'destructive' });\n } else {\n // No success toast — the UI updates inline.\n setQuestionAnswers({});\n setContinuationText('');\n setTimeout(() => {\n getExecution(execution.execution_id!, execution.authorization!);\n }, 600);\n }\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n } finally {\n setAgentRequestLoading(false);\n }\n }, [execution, getExecution]);\n\n // ── Rerun the whole agent with the original input ──\n // Instead of silently re-submitting (which leaves the user staring at the\n // same screen wondering if anything happened), bounce them back to the\n // Start tab with the prompt + tools pre-filled so they can review and\n // hit Start themselves.\n const rerunAgent = useCallback(() => {\n const input =\n agentData?.original_input ||\n actionInput ||\n (() => {\n const msgs = (agentData as any)?.input?.messages || [];\n const m = msgs.find((m: any) => m?.role === 'user' && !String(m?.role).includes('USER CONTEXT'));\n return m?.content || '';\n })();\n if (input && typeof input === 'string') {\n setActionInput(input);\n }\n if (executionApps.length > 0) {\n setChosenApps(executionApps);\n }\n // When the Start tab is hidden (e.g. embedded in the execution drawer),\n // there is no Start view to bounce to — just resubmit immediately with\n // the previous prompt + tools.\n if (disableStartTab) {\n if (input && typeof input === 'string' && input.trim().length >= 6) {\n submitInput(input);\n }\n return;\n }\n setShowStarter(true);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n return next;\n }, { replace: true });\n }, [agentData, actionInput, executionApps, setSearchParams, disableStartTab, submitInput]);\n\n // ── Abort the currently running agent execution ──\n // If the agent has not produced an execution_id yet (i.e. the initial\n // /run request is still in flight or failed silently), we simply discard\n // the in-flight UI state and bounce the user back to the Start tab so\n // they can try again. Once an execution_id exists, we ask the backend to\n // abort the workflow execution; the existing poll loop will then pick up\n // the ABORTED status on its next tick.\n const abortAgent = useCallback(async () => {\n const execId = execution?.execution_id;\n const auth = execution?.authorization;\n const wfId = (execution as any)?.workflow?.id;\n\n // Bump the run-generation counter and abort any in-flight POST /agent\n // request immediately. This guarantees a slow initial request that\n // resolves AFTER the user clicks \"Cancel\" cannot repaint the UI or\n // swap tabs back to the run view.\n runGenerationRef.current += 1;\n try { runAbortRef.current?.abort(); } catch { /* noop */ }\n runAbortRef.current = null;\n\n // Helper: wipe local run state and return to the Start tab.\n const resetToStart = () => {\n activeExecutionIdRef.current = null;\n setExecution(null);\n setAgentData({});\n setAgentRequestLoading(false);\n setShowStarter(true);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n next.delete('execution_id');\n next.delete('authorization');\n return next;\n }, { replace: true });\n };\n\n // Agent never produced an execution — nothing to abort server-side.\n if (!execId || !wfId) {\n resetToStart();\n toast({ title: 'Run aborted', description: 'The agent had not started yet — reset to Start.' });\n return;\n }\n\n try {\n const resp = await fetch(\n resolveUrl(`/api/v1/workflows/${wfId}/executions/${execId}/abort`),\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n ...resolveHeaders(),\n ...(auth ? { Authorization: `Bearer ${auth}` } : {}),\n },\n },\n );\n if (!resp.ok) {\n const txt = await resp.text().catch(() => '');\n toast({ title: 'Abort failed', description: txt || `HTTP ${resp.status}`, variant: 'destructive' });\n return;\n }\n toast({ title: 'Aborting run', description: 'The execution will be set to ABORTED shortly.' });\n // Nudge the poll loop to refresh sooner so the UI reflects the change.\n setTimeout(() => getExecution(execId, auth!), 500);\n setTimeout(() => getExecution(execId, auth!), 2500);\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n }\n }, [execution, resolveUrl, resolveHeaders, getExecution, setSearchParams]);\n\n\n // Build a popout URL to answer the agent's question in the standalone Form UI.\n // Mirrors the legacy AgentUI behavior so users can hand off to /forms/...\n const getFormUrl = useCallback((decisionId: string): string | null => {\n const wfId = (execution as any)?.workflow?.id;\n const auth = execution?.authorization;\n const execId = execution?.execution_id;\n const sourceNode = agentActionResult?.action?.id;\n if (!wfId || !auth || !execId || !sourceNode || !decisionId) return null;\n const backend = apiBaseUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n const params = new URLSearchParams({\n authorization: auth,\n reference_execution: execId,\n source_node: sourceNode,\n decision_id: decisionId,\n ...(backend ? { backend_url: backend } : {}),\n });\n return `/forms/${wfId}?${params.toString()}`;\n }, [execution, agentActionResult, apiBaseUrl]);\n\n // ── Rerun a single decision (clears decisions after it on the backend) ──\n const rerunDecision = useCallback(async (decision: any) => {\n if (!execution?.execution_id) {\n toast({ title: 'No execution loaded', description: 'Cannot rerun this decision.', variant: 'destructive' });\n return;\n }\n if (!agentActionResult?.action) {\n toast({ title: 'Missing action context', description: 'Could not locate the agent action node.', variant: 'destructive' });\n return;\n }\n const decisionId = decision?.run_details?.id;\n if (!decisionId) {\n toast({ title: 'Missing decision id', description: 'This decision cannot be rerun.', variant: 'destructive' });\n return;\n }\n const body: any = { ...agentActionResult.action };\n body.source_execution = execution.execution_id;\n body.source_workflow = execution.workflow?.id;\n setAgentRequestLoading(true);\n try {\n const resp = await fetch(resolveUrl(`/api/v1/apps/agent/run?rerun=true&decision_id=${encodeURIComponent(decisionId)}`), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders() },\n body: JSON.stringify(body),\n });\n const json = await resp.json().catch(() => ({}));\n if (json?.success === false) {\n toast({ title: 'Rerun failed', description: json.reason || 'Try again later.', variant: 'destructive' });\n } else {\n toast({ title: 'Rerunning decision', description: 'The agent will continue from this step.' });\n setTimeout(() => getExecution(execution.execution_id!, execution.authorization!), 800);\n setTimeout(() => getExecution(execution.execution_id!, execution.authorization!), 5000);\n }\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n } finally {\n setAgentRequestLoading(false);\n }\n }, [execution, agentActionResult, getExecution]);\n\n // ── Build timeline ──\n const { timeline, originalStartTime, totalDuration, finishDecisionId, finishAnswer } = useMemo(() => {\n // Backend may return Unix milliseconds (UnixMillis) or seconds. Normalize to seconds.\n const toSec = (t: any): number => {\n const n = Number(t) || 0;\n // Preserve sub-second precision so durations < 1s render as e.g. \"0.8s\"\n // instead of being floored to 0.\n return n > 1e12 ? n / 1000 : n;\n };\n const overallStatus = (execution?.status || agentData?.status || '').toUpperCase();\n const runIsFinished = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(overallStatus);\n const runEndSec = toSec(agentData?.completed_at || execution?.completed_at);\n // When the whole run has ended, cap any unfinished decisions at the run's\n // end time (or the latest known timestamp) so they stop counting up.\n let fallbackEnd = Date.now() / 1000;\n if (runIsFinished) {\n let maxKnown = runEndSec || 0;\n for (const dec of agentData?.decisions || []) {\n const rd = dec.run_details || {};\n maxKnown = Math.max(maxKnown, toSec(rd.completed_at), toSec(rd.started_at));\n }\n fallbackEnd = maxKnown || fallbackEnd;\n }\n\n const items: TimelineItem[] = [\n {\n label: 'AI Agent',\n type: 'agent',\n category: 'agent',\n details: agentData,\n status: execution?.status || agentData?.status,\n start_time: toSec(agentData?.started_at || execution?.started_at),\n end_time: toSec(agentData?.completed_at || execution?.completed_at),\n },\n ];\n\n let finishId = '';\n let finishAns = '';\n for (const dec of agentData?.decisions || []) {\n const rd = dec.run_details || {};\n const decStartSec = toSec(rd.started_at);\n const decEndSec = toSec(rd.completed_at);\n // Only fall back to \"now\"/run-end when we actually know when the\n // decision started — otherwise the bar would stretch from epoch 0\n // to now and look like a full-width row.\n const startTime = decStartSec || 0;\n const endTime = decEndSec || (decStartSec ? fallbackEnd : 0);\n items.push({\n label: dec.action,\n type: 'decision',\n category: dec.category,\n status: rd.status,\n start_time: startTime,\n end_time: endTime,\n details: dec,\n });\n if (dec.action === 'finish' || dec.category === 'finish' || dec.details?.action === 'finalise' || dec.action === 'finalise') {\n finishId = rd.id || '';\n const reasonText = (dec.reason || '').trim();\n const fieldText = (Array.isArray(dec.fields) && dec.fields.length > 0 ? (dec.fields[0]?.value || '') : '').trim();\n // Prefer whichever has more substance. Sometimes the field value is a\n // short headline like \"Task Failed\" while the real explanation lives\n // in `reason` — surface that to the user instead of the headline.\n if (fieldText && reasonText && reasonText.length > fieldText.length * 1.5) {\n finishAns = reasonText;\n } else {\n finishAns = fieldText || reasonText;\n }\n }\n }\n\n // Sort: Agent row pinned to top, Finalise pinned to bottom, everything\n // else preserves insertion order (the index `i` from the decisions array).\n // Timestamps are intentionally NOT used — they're often missing or 0,\n // which would scatter rows unpredictably.\n const isFinalise = (it: TimelineItem) => {\n const det: any = it.details || {};\n const cat = (it.category || '').toLowerCase();\n const act = (det.action || '').toLowerCase();\n return cat === 'finish' || cat === 'finalise' || act === 'finish' || act === 'finalise';\n };\n const rank = (it: TimelineItem) => {\n if (it.type === 'agent') return 0;\n if (isFinalise(it)) return 2;\n return 1;\n };\n const sortItems = (arr: TimelineItem[]) => {\n const indexed = arr.map((it, i) => ({ it, i }));\n indexed.sort((a, b) => {\n const ra = rank(a.it);\n const rb = rank(b.it);\n if (ra !== rb) return ra - rb;\n return a.i - b.i;\n });\n arr.length = 0;\n arr.push(...indexed.map((x) => x.it));\n };\n sortItems(items);\n\n // Insert \"processing\" placeholder rows inline between consecutive decisions\n // when there is meaningful dead time (the agent is thinking / the LLM is\n // generating the next step). Walk the already-sorted items list and splice\n // the Thinking rows in-place so they stay between the two decisions whose\n // gap they represent. Do NOT re-sort afterwards — that would clump them.\n const withProcessing: TimelineItem[] = [];\n const agentItem = items.find((it) => it.type === 'agent');\n const runStart = agentItem?.start_time || 0;\n const runEnd = agentItem?.end_time || 0;\n let prevDecEnd = runStart;\n const pushThinking = (from: number, to: number) => {\n if (from > 0 && to > 0 && to - from >= 0.5) {\n withProcessing.push({\n label: '',\n type: 'decision',\n category: 'processing',\n status: 'FINISHED',\n start_time: from,\n end_time: to,\n details: undefined as any,\n });\n }\n };\n for (const it of items) {\n if (it.type === 'decision') {\n const decStart = it.start_time || 0;\n // Insert Thinking before this decision (works for first decision after\n // run start, gaps between decisions, and the gap before Finalise).\n pushThinking(prevDecEnd, decStart);\n withProcessing.push(it);\n prevDecEnd = it.end_time || decStart || prevDecEnd;\n } else {\n withProcessing.push(it);\n }\n }\n // Tail: if the last decision finished well before the run ended and there\n // was no Finalise, surface that trailing dead time too.\n if (runEnd > 0) pushThinking(prevDecEnd, runEnd);\n items.length = 0;\n items.push(...withProcessing);\n\n const start = items.reduce((acc, it) => Math.min(acc, it.start_time || acc), Infinity);\n const end = items.reduce((acc, it) => Math.max(acc, it.end_time || acc), 0);\n const startSafe = start === Infinity ? 0 : start;\n const total = Math.max(1, end - startSafe);\n return { timeline: items, originalStartTime: startSafe, totalDuration: total, finishDecisionId: finishId, finishAnswer: finishAns };\n }, [agentData, execution?.status, execution?.started_at, execution?.completed_at]);\n\n\n const toggleOpen = (i: number) =>\n setOpenIndexes((prev) => {\n const next = new Set(prev);\n if (next.has(i)) next.delete(i); else next.add(i);\n return next;\n });\n\n const handlePrimarySubmit = useCallback(() => {\n if (submitOverride) {\n submitOverride({ input: actionInput, apps: chosenApps });\n } else {\n submitInput(actionInput);\n }\n }, [submitOverride, actionInput, chosenApps, submitInput]);\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n handlePrimarySubmit();\n }\n };\n\n // restart() removed — Start tab now toggles via goToTab() while preserving the execution.\n\n\n // The three top-level \"tabs\": Start (the prompt form), Simple summary,\n // and Detailed timeline. They're all available once an execution exists,\n // so the user can flip back and forth without losing the run.\n type TabKey = 'start' | 'simple' | 'detailed';\n const activeTab: TabKey = showStarter ? 'start' : viewMode;\n const hasExecution = !!execution?.execution_id;\n const showRunSwitcher = hasExecution || agentRequestLoading;\n useEffect(() => {\n onViewChange?.(activeTab);\n }, [activeTab, onViewChange]);\n const goToTab = (t: TabKey) => {\n if (t === 'start') {\n // Seed the starter form with the current run's prompt + tools so the\n // user can tweak and resubmit instead of starting from a blank slate.\n const runInput =\n agentData?.original_input ||\n (() => {\n const msgs = (agentData as any)?.input?.messages || [];\n const m = msgs.find((m: any) => m?.role === 'user');\n return m?.content || '';\n })();\n if (runInput && typeof runInput === 'string') {\n setActionInput(runInput);\n }\n if (executionApps.length > 0) {\n setChosenApps(executionApps);\n }\n setShowStarter(true);\n // Pin: user manually chose Start. Stay here even when polls land or\n // initialExecution is re-attached, until they explicitly start a new run\n // or click Simple/Detailed themselves.\n userPickedStartRef.current = true;\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n return next;\n }, { replace: true });\n } else {\n setShowStarter(false);\n userPickedStartRef.current = false;\n setViewMode(t);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set('agentView', t);\n return next;\n }, { replace: true });\n }\n };\n\n // Schedule guardrails: do not allow scheduling when the run required a\n // continuation (the oneshot prompt did not work) or did not perform any\n // actual app/tool actions (nothing meaningful would run on a schedule).\n const { scheduleDisabledReasons } = useMemo(() => {\n const decisions: any[] = (agentData?.decisions as any[]) || [];\n const runStatus = String(execution?.status || agentData?.status || '').toUpperCase();\n const isNotFinished = runStatus !== '' && !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(runStatus);\n const NON_ACTION_CATS = new Set(['finish', 'finalise', 'ask', 'agent', 'processing']);\n const NON_ACTION_ACTIONS = new Set(['finish', 'finalise', 'ask']);\n const finishCount = decisions.filter(\n (d) => d?.action === 'finish' || d?.action === 'finalise' || d?.category === 'finish' || d?.category === 'finalise',\n ).length;\n const continuedAfterFinish = decisions.some((d) =>\n Array.isArray(d?.fields) && d.fields.some((f: any) => String(f?.key || '').toLowerCase() === 'continue' && f?.value),\n );\n const hadContinuation = finishCount > 1 || continuedAfterFinish;\n const actionCount = decisions.filter((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n if (NON_ACTION_CATS.has(cat)) return false;\n if (NON_ACTION_ACTIONS.has(act)) return false;\n return true;\n }).length;\n // A decision failed if its run_details.status is FAILURE/ABORTED, or the\n // parsed raw_response reports success: false. We deliberately ignore\n // ASK/FINISH categories — those are agent-internal control steps.\n const failedDecision = decisions.some((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n if (NON_ACTION_CATS.has(cat) || NON_ACTION_ACTIONS.has(act)) return false;\n const status = String(d?.run_details?.status || '').toUpperCase();\n if (status === 'FAILURE' || status === 'ABORTED') return true;\n const raw = d?.run_details?.raw_response;\n let parsed: any = null;\n if (typeof raw === 'string') {\n try { parsed = JSON.parse(raw); } catch { parsed = null; }\n } else if (raw && typeof raw === 'object') {\n parsed = raw;\n }\n if (parsed && parsed.success === false) return true;\n if (parsed && parsed.action === 'app_authentication') return true;\n return false;\n });\n // A question was answered if an ASK decision has an \"answer\" field, OR if\n // its run finished (the agent submits answers to advance ask runs from\n // WAITING to FINISHED). Either way the prompt cannot run unattended.\n const answeredQuestion = decisions.some((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n const isAsk = cat === 'ask' || act === 'ask';\n if (!isAsk) return false;\n const hasAnswerField = Array.isArray(d?.fields)\n && d.fields.some((f: any) => String(f?.key || '').toLowerCase() === 'answer' && f?.value);\n const status = String(d?.run_details?.status || '').toUpperCase();\n return hasAnswerField || status === 'FINISHED';\n });\n const reasons: string[] = [];\n if (isNotFinished) {\n reasons.push('Wait for the agent to finish before scheduling.');\n } else if (showStarter) {\n // On the Start view, a finished + validated run is always considered\n // ready to schedule. Quality gates (continuations, missing actions,\n // failed steps, manual answers) are only surfaced in Simple/Detailed\n // views where the user is actively reviewing the run.\n } else {\n if (hadContinuation) {\n reasons.push('This run needed a follow-up message to continue, so the one-shot prompt did not succeed on its own. Refine the prompt until it finishes in one go before scheduling.');\n }\n if (actionCount === 0) {\n reasons.push('This run did not perform any app or tool actions, so a scheduled run would have nothing meaningful to do.');\n }\n if (failedDecision) {\n reasons.push('A decision in this run failed. Fix the failing step (for example, authenticate the app or correct the input) and rerun successfully before scheduling.');\n }\n if (answeredQuestion) {\n reasons.push('A question in this run was answered manually. Scheduled runs are unattended, so refine the prompt so the agent does not need to ask anything before scheduling.');\n }\n }\n return { scheduleDisabledReasons: reasons };\n }, [agentData, execution?.status, showStarter]);\n\n // Detect natural-language scheduling intent in the prompt (e.g. \"daily at 6 am\",\n // \"next monday at 2am\", \"every 15 minutes\"). Used to highlight the Schedule\n // button and pre-seed the cron picker.\n const scheduleHint = useMemo(() => parseScheduleHint(actionInput), [actionInput]);\n // Track which hint we last auto-applied so we never overwrite a manual pick.\n const lastAppliedHintRef = useRef<string | null>(null);\n useEffect(() => {\n if (!scheduleHint) return;\n if (scheduleAnchor) return; // never override while popover is open\n if (lastAppliedHintRef.current === scheduleHint.cron) return;\n setScheduleCron(scheduleHint.cron);\n lastAppliedHintRef.current = scheduleHint.cron;\n }, [scheduleHint, scheduleAnchor]);\n\n // Compile structured recurrence controls into a 5-field cron expression.\n // Skipped if the user has manually overridden via preset chip / advanced\n // cron text field — that override is cleared whenever they touch a\n // structured control again.\n useEffect(() => {\n if (cronManualOverrideRef.current) return;\n const m = Math.max(0, Math.min(59, schedMinute));\n const h = Math.max(0, Math.min(23, schedHour));\n const n = Math.max(1, Math.floor(schedInterval || 1));\n let cron = '';\n if (schedFreq === 'minutes') {\n cron = `*/${n} * * * *`;\n } else if (schedFreq === 'hours') {\n cron = `${m} */${n} * * *`;\n } else if (schedFreq === 'days') {\n cron = n === 1 ? `${m} ${h} * * *` : `${m} ${h} */${n} * *`;\n } else if (schedFreq === 'weeks') {\n // Cron has no native \"every N weeks\", so we use the weekday set and\n // surface a small note in the UI when interval > 1.\n const days = schedWeekdays.size > 0\n ? [...schedWeekdays].sort((a, b) => a - b).join(',')\n : '*';\n cron = `${m} ${h} * * ${days}`;\n } else if (schedFreq === 'months') {\n const dom = Math.max(1, Math.min(31, schedDayOfMonth));\n cron = n === 1 ? `${m} ${h} ${dom} * *` : `${m} ${h} ${dom} */${n} *`;\n }\n if (cron) setScheduleCron(cron);\n }, [schedFreq, schedInterval, schedHour, schedMinute, schedWeekdays, schedDayOfMonth]);\n\n const scheduleDisabledReason = scheduleDisabledReasons[0] || '';\n const scheduleDisabledTooltip: React.ReactNode = scheduleDisabledReasons.length > 1 ? (\n <Box>\n <Box sx={{ fontWeight: 600, mb: 0.5 }}>Cannot schedule for {scheduleDisabledReasons.length} reasons:</Box>\n <Box sx={{ m: 0 }}>\n {scheduleDisabledReasons.map((r, i) => (\n <Box key={i} sx={{ mb: 0.5, display: 'flex', gap: 0.75 }}>\n <Box component=\"span\" sx={{ fontWeight: 700, flexShrink: 0 }}>{i + 1}.</Box>\n <Box component=\"span\">{r}</Box>\n </Box>\n ))}\n </Box>\n </Box>\n ) : scheduleDisabledReasons.length === 1 ? `Cannot schedule: ${scheduleDisabledReasons[0]}` : '';\n\n // Rendered inline (not a nested component) so it isn't remounted on every\n // parent re-render — the live duration ticker would otherwise reset hover\n // state every second and swallow clicks.\n const tabBar = (\n <Box sx={{\n display: 'flex', alignItems: 'center', gap: 1.5,\n p: 1,\n borderRadius: 999,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n width: 'fit-content',\n alignSelf: 'center',\n position: 'sticky',\n top: 8,\n zIndex: 5,\n boxShadow: '0 4px 16px rgba(0,0,0,0.25)',\n }}>\n <Box sx={{ display: 'inline-flex', gap: 0.25, p: 0.25, borderRadius: 999, bgcolor: 'hsl(var(--muted) / 0.6)' }}>\n {(['start', 'simple', 'detailed'] as TabKey[]).map((t) => {\n const active = activeTab === t;\n const label = t === 'start' ? 'Start' : t === 'simple' ? 'Simple' : 'Detailed';\n const disabled = (t === 'start' && disableStartTab) || ((t === 'simple' || t === 'detailed') && !hasExecution);\n return (\n <Box\n key={t}\n component=\"button\"\n type=\"button\"\n onClick={() => { if (!disabled) goToTab(t); }}\n disabled={disabled}\n sx={{\n all: 'unset', cursor: disabled ? 'not-allowed' : 'pointer',\n px: 1.75, py: 0.5,\n borderRadius: 999,\n fontSize: '0.8rem',\n fontWeight: 600,\n color: active ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n bgcolor: active ? 'hsl(var(--primary))' : 'transparent',\n opacity: disabled ? 0.4 : 1,\n transition: 'background 0.12s ease, color 0.12s ease',\n '&:hover': (active || disabled) ? {} : { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n {label}\n </Box>\n );\n })}\n </Box>\n <Tooltip title=\"Reload execution data\">\n <span>\n <IconButton\n size=\"small\"\n onClick={() => execution?.execution_id && execution?.authorization && getExecution(execution.execution_id, execution.authorization)}\n disabled={!hasExecution}\n sx={{\n width: 30, height: 30,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <RefreshIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n <Box sx={{ width: '1px', height: 20, bgcolor: 'hsl(var(--border))', mx: 0.25 }} />\n <Tooltip title={scheduleDisabledTooltip || 'Schedule this prompt to run repeatedly on a cron schedule'}>\n <span>\n <IconButton\n size=\"small\"\n onClick={(e) => { if (!scheduleDisabledReason) setScheduleAnchor(e.currentTarget); }}\n disabled={Boolean(scheduleDisabledReason)}\n sx={{\n width: 30, height: 30,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n '&.Mui-disabled': { opacity: 0.4, color: 'hsl(var(--muted-foreground))' },\n }}\n >\n <ScheduleIcon sx={{ fontSize: 16 }} />\n </IconButton>\n </span>\n </Tooltip>\n <Popover\n open={Boolean(scheduleAnchor)}\n anchorEl={scheduleAnchor}\n onClose={() => setScheduleAnchor(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{\n paper: {\n sx: {\n mt: 1,\n p: 2,\n width: 360,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n boxShadow: '0 8px 24px hsl(0 0% 0% / 0.35)',\n },\n },\n }}\n >\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, mb: 0.5 }}>\n Schedule recurring run\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', mb: 1.5 }}>\n Choose how often this prompt should run. The schedule keeps running until you remove it.\n </Typography>\n {scheduleHint && (\n <Box\n sx={{\n mb: 1.5,\n p: 1,\n borderRadius: 1.5,\n border: '1px solid hsl(var(--primary) / 0.4)',\n bgcolor: 'hsl(var(--primary) / 0.08)',\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <ScheduleIcon sx={{ fontSize: 16, color: 'hsl(var(--primary))' }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mb: 0.25 }}>\n Detected from your prompt\n </Box>\n <Box sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {scheduleHint.label}\n </Box>\n <Box sx={{ fontSize: '0.68rem', fontFamily: 'monospace', color: 'hsl(var(--muted-foreground))' }}>\n {scheduleHint.cron}\n </Box>\n </Box>\n {scheduleCron !== scheduleHint.cron && (\n <Button\n size=\"small\"\n onClick={() => { cronManualOverrideRef.current = true; setScheduleCron(scheduleHint.cron); }}\n sx={{\n height: 28,\n textTransform: 'none',\n fontSize: '0.7rem',\n color: 'hsl(var(--primary))',\n '&:hover': { bgcolor: 'hsl(var(--primary) / 0.12)' },\n }}\n >\n Use\n </Button>\n )}\n </Box>\n )}\n {/* Structured recurrence builder (Google Calendar style) */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n Repeat every\n </Typography>\n <TextField\n size=\"small\"\n type=\"number\"\n value={schedInterval}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedInterval(Math.max(1, Number(e.target.value) || 1)); }}\n slotProps={{ htmlInput: { min: 1, max: 999, style: { padding: '6px 8px', width: 48, textAlign: 'center', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n <Select\n size=\"small\"\n value={schedFreq}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedFreq(e.target.value as SchedFreq); }}\n sx={{\n flex: 1,\n fontSize: '0.8rem',\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n '& .MuiSelect-icon': { color: 'hsl(var(--muted-foreground))' },\n '& .MuiSelect-select': { py: '6px' },\n }}\n MenuProps={{ slotProps: { paper: { sx: { bgcolor: 'hsl(var(--popover))', color: 'hsl(var(--foreground))', border: '1px solid hsl(var(--border))' } } } }}\n >\n <MenuItem value=\"minutes\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'minute' : 'minutes'}</MenuItem>\n <MenuItem value=\"hours\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'hour' : 'hours'}</MenuItem>\n <MenuItem value=\"days\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'day' : 'days'}</MenuItem>\n <MenuItem value=\"weeks\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'week' : 'weeks'}</MenuItem>\n <MenuItem value=\"months\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'month' : 'months'}</MenuItem>\n </Select>\n </Box>\n\n {(schedFreq === 'days' || schedFreq === 'weeks' || schedFreq === 'months') && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n At\n </Typography>\n <TextField\n size=\"small\"\n type=\"time\"\n value={`${String(schedHour).padStart(2, '0')}:${String(schedMinute).padStart(2, '0')}`}\n onChange={(e) => {\n cronManualOverrideRef.current = false;\n const [hh, mm] = (e.target.value || '09:00').split(':').map(Number);\n setSchedHour(Number.isFinite(hh) ? hh : 9);\n setSchedMinute(Number.isFinite(mm) ? mm : 0);\n }}\n slotProps={{ htmlInput: { style: { padding: '6px 8px', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n </Box>\n )}\n\n {schedFreq === 'weeks' && (\n <Box sx={{ mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', mb: 0.75 }}>\n Repeat on\n </Typography>\n <Box sx={{ display: 'flex', gap: 0.5 }}>\n {(['S', 'M', 'T', 'W', 'T', 'F', 'S'] as const).map((label, i) => {\n const active = schedWeekdays.has(i);\n return (\n <Box\n key={i}\n role=\"button\"\n tabIndex={0}\n onClick={() => {\n cronManualOverrideRef.current = false;\n setSchedWeekdays((prev) => {\n const next = new Set(prev);\n if (next.has(i)) next.delete(i); else next.add(i);\n return next;\n });\n }}\n sx={{\n width: 30,\n height: 30,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: '0.75rem',\n fontWeight: 600,\n userSelect: 'none',\n bgcolor: active ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: active ? 'hsl(var(--primary-foreground))' : 'hsl(var(--foreground))',\n border: '1px solid',\n borderColor: active ? 'hsl(var(--primary))' : 'hsl(var(--border))',\n transition: 'background-color 120ms',\n '&:hover': { bgcolor: active ? 'hsl(var(--primary))' : 'hsl(var(--muted) / 0.7)' },\n }}\n >\n {label}\n </Box>\n );\n })}\n </Box>\n {schedInterval > 1 && (\n <Typography sx={{ fontSize: '0.68rem', color: 'hsl(var(--muted-foreground))', mt: 0.75 }}>\n Cron does not support every {schedInterval} weeks natively — this will run weekly on the selected days.\n </Typography>\n )}\n </Box>\n )}\n\n {schedFreq === 'months' && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n On day\n </Typography>\n <TextField\n size=\"small\"\n type=\"number\"\n value={schedDayOfMonth}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedDayOfMonth(Math.max(1, Math.min(31, Number(e.target.value) || 1))); }}\n slotProps={{ htmlInput: { min: 1, max: 31, style: { padding: '6px 8px', width: 56, textAlign: 'center', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n of the month\n </Typography>\n </Box>\n )}\n\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mt: 0.5, mb: 0.5 }}>\n Quick presets\n </Typography>\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, mb: 0.5 }}>\n {([\n ['Every 15 min', '*/15 * * * *'],\n ['Hourly', '0 * * * *'],\n ['Daily 9am', '0 9 * * *'],\n ['Weekdays 9am', '0 9 * * 1-5'],\n ['Weekly Mon', '0 9 * * 1'],\n ['Monthly 1st', '0 9 1 * *'],\n ] as const).map(([label, expr]) => (\n <Chip\n key={expr}\n label={label}\n size=\"small\"\n onClick={() => { cronManualOverrideRef.current = true; setScheduleCron(expr); }}\n sx={{\n fontSize: '0.7rem',\n bgcolor: scheduleCron === expr ? 'hsl(var(--primary) / 0.15)' : 'hsl(var(--muted))',\n color: scheduleCron === expr ? 'hsl(var(--primary))' : 'hsl(var(--foreground))',\n border: scheduleCron === expr ? '1px solid hsl(var(--primary))' : '1px solid transparent',\n '&:hover': { bgcolor: 'hsl(var(--muted) / 0.8)' },\n }}\n />\n ))}\n </Box>\n\n <Box sx={{ mt: 1.25 }}>\n <Box\n role=\"button\"\n tabIndex={0}\n onClick={() => setSchedAdvancedOpen((v) => !v)}\n sx={{\n fontSize: '0.7rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n userSelect: 'none',\n '&:hover': { color: 'hsl(var(--foreground))' },\n }}\n >\n {schedAdvancedOpen ? '▾' : '▸'} Advanced — edit cron expression\n </Box>\n {schedAdvancedOpen && (\n <TextField\n size=\"small\"\n fullWidth\n value={scheduleCron}\n onChange={(e) => { cronManualOverrideRef.current = true; setScheduleCron(e.target.value); }}\n placeholder=\"0 9 * * 1-5\"\n slotProps={{ htmlInput: { style: { fontFamily: 'monospace', fontSize: '0.78rem', padding: '6px 8px' } } }}\n sx={{\n mt: 0.75,\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n )}\n <Typography sx={{ fontSize: '0.68rem', fontFamily: 'monospace', color: 'hsl(var(--muted-foreground))', mt: 0.75 }}>\n cron: {scheduleCron || '—'}\n </Typography>\n </Box>\n {scheduleSaving && (\n <Box sx={{ mt: 2, display: 'flex', flexDirection: 'column', gap: 0.75, p: 1.25, borderRadius: 1, bgcolor: 'hsl(var(--muted))', border: '1px solid hsl(var(--border))' }}>\n {scheduleSteps.map((s) => {\n const label =\n s.id === 'name' ? 'Generating name & description'\n : s.id === 'workflow' ? 'Creating workflow'\n : 'Enabling schedule';\n const color =\n s.state === 'done' ? 'hsl(var(--primary))'\n : s.state === 'error' ? 'hsl(var(--destructive))'\n : s.state === 'active' ? 'hsl(var(--foreground))'\n : 'hsl(var(--muted-foreground))';\n return (\n <Box key={s.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.78rem', color }}>\n <Box sx={{ width: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n {s.state === 'active' && <CircularProgress size={12} sx={{ color: 'hsl(var(--primary))' }} />}\n {s.state === 'done' && <Box sx={{ fontSize: '0.85rem', lineHeight: 1, color: 'hsl(var(--primary))' }}>✓</Box>}\n {s.state === 'error' && <Box sx={{ fontSize: '0.85rem', lineHeight: 1, color: 'hsl(var(--destructive))' }}>!</Box>}\n {s.state === 'pending' && <Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: 'hsl(var(--muted-foreground))', opacity: 0.4 }} />}\n </Box>\n <Box component=\"span\" sx={{ fontFamily: 'inherit' }}>\n {label}\n {s.detail && s.state !== 'pending' && (\n <Box component=\"span\" sx={{ ml: 0.75, color: 'hsl(var(--muted-foreground))', fontFamily: 'monospace', fontSize: '0.72rem' }}>\n — {s.detail}\n </Box>\n )}\n </Box>\n </Box>\n );\n })}\n </Box>\n )}\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1, mt: 2 }}>\n <Button\n size=\"small\"\n onClick={() => setScheduleAnchor(null)}\n disabled={scheduleSaving}\n sx={{ height: 36, color: 'hsl(var(--muted-foreground))', textTransform: 'none' }}\n >\n Cancel\n </Button>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!scheduleCron.trim() || scheduleSaving}\n onClick={async () => {\n const cron = scheduleCron.trim();\n console.log('[AgentUI] Save schedule clicked', { cron, hasOnSchedule: typeof onSchedule === 'function', inputLen: actionInput?.length });\n if (!cron) return;\n setScheduleSteps([\n { id: 'name', state: 'pending' },\n { id: 'workflow', state: 'pending' },\n { id: 'schedule', state: 'pending' },\n ]);\n setScheduleSaving(true);\n try {\n if (onSchedule) {\n await onSchedule({\n cron,\n input: actionInput || '',\n apps: chosenApps.filter((a) => !!a?.name).map((a) => ({ name: a.name, id: a.id, icon: a.icon })),\n onStep: (ev) => {\n setScheduleSteps((prev) => prev.map((p) => p.id === ev.id ? { ...p, state: ev.state, detail: ev.detail } : p));\n },\n });\n toast({ title: 'Schedule saved', description: 'This prompt will now run on the selected schedule.' });\n setScheduleAnchor(null);\n } else {\n toast({ title: 'Scheduling not configured', description: 'No handler is wired up for scheduled runs in this view.', variant: 'destructive' });\n setScheduleAnchor(null);\n }\n } catch (err) {\n console.error('[AgentUI] Schedule failed', err);\n toast({ title: 'Failed to save schedule', description: err instanceof Error ? err.message : String(err), variant: 'destructive' });\n } finally {\n setScheduleSaving(false);\n }\n }}\n sx={{\n height: 36, textTransform: 'none',\n bgcolor: 'hsl(var(--primary))', color: 'hsl(var(--primary-foreground))',\n '&:hover': { bgcolor: 'hsl(var(--primary))', filter: 'brightness(1.1)' },\n }}\n >\n {scheduleSaving ? <CircularProgress size={14} sx={{ color: 'inherit' }} /> : 'Save schedule'}\n </Button>\n </Box>\n </Popover>\n </Box>\n );\n\n // ── Render ──\n return (\n <Box\n className={className}\n sx={[\n { width: '100%', display: 'flex', justifyContent: 'center', pb: 4 },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n >\n <Box\n sx={[\n { width: '100%', maxWidth, display: 'flex', flexDirection: 'column', gap: 3 },\n ...(Array.isArray(contentSx) ? contentSx : contentSx ? [contentSx] : []),\n ]}\n >\n {showRunSwitcher && tabBar}\n {showStarter ? (\n <Box\n component=\"form\"\n onSubmit={(e) => { e.preventDefault(); handlePrimarySubmit(); }}\n sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: compact ? 2 : 3, py: compact ? 2 : 4 }}\n >\n {!hideHeroIcon && !compact && (\n <Box sx={{\n width: heroIconSize, height: heroIconSize, borderRadius: 3,\n bgcolor: 'hsl(var(--card))',\n border: '1px solid hsl(var(--border))',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n boxShadow: '0 8px 24px rgba(0,0,0,0.25)',\n }}>\n {heroIcon ?? <AgentIcon size={Math.round(heroIconSize * 0.67)} />}\n </Box>\n )}\n <Typography component=\"h1\" sx={{\n fontSize: compact ? { xs: '1.25rem', md: '1.5rem' } : { xs: '1.75rem', md: '2.25rem' },\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n textAlign: 'center',\n letterSpacing: '-0.01em',\n }}>\n {title}\n </Typography>\n {subtitle && (\n <Typography sx={{\n fontSize: '0.95rem',\n color: 'hsl(var(--muted-foreground))',\n textAlign: 'center',\n mt: -1,\n maxWidth: 600,\n }}>\n {subtitle}\n </Typography>\n )}\n\n <Box sx={{\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n borderRadius: attachedImages.length > 0 ? 4 : '28px',\n border: '1.5px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n px: 3,\n py: 1.75,\n transition: 'border-color 0.15s ease, box-shadow 0.15s ease, border-radius 0.15s ease',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary))',\n boxShadow: '0 0 0 3px hsla(var(--primary) / 0.12)',\n },\n }}>\n {attachedImages.length > 0 && (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75 }}>\n {attachedImages.map((img, idx) => (\n <Box key={`${img.name}-${idx}`} sx={{\n display: 'inline-flex', alignItems: 'center', gap: 1,\n p: 0.5, pr: 1, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n maxWidth: '100%',\n }}>\n <Box component=\"img\" src={img.dataUrl} alt={img.name} sx={{ width: 32, height: 32, borderRadius: 1, objectFit: 'cover', flexShrink: 0 }} />\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--foreground))', maxWidth: 190, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {img.name}\n </Typography>\n <IconButton size=\"small\" onClick={() => setAttachedImages((prev) => prev.filter((_, i) => i !== idx))} sx={{ p: 0.25, color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--destructive))' } }} aria-label=\"Remove attached image\">\n <CloseIcon sx={{ fontSize: 12 }} />\n </IconButton>\n </Box>\n ))}\n </Box>\n )}\n <Box sx={{ display: 'flex', alignItems: 'flex-end', gap: 1, width: '100%' }}>\n <InputBase\n inputRef={inputRef}\n autoFocus\n multiline\n minRows={1}\n maxRows={6}\n fullWidth\n value={actionInput}\n onChange={(e) => setActionInput(e.target.value)}\n placeholder={placeholder}\n onKeyDown={onKeyDown}\n onPaste={(e) => {\n const items = e.clipboardData?.items;\n if (!items) return;\n const files: File[] = [];\n for (const item of Array.from(items)) {\n if (item.kind === 'file' && item.type.startsWith('image/')) {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n handleImagesSelected(files);\n }\n }}\n disabled={agentRequestLoading}\n sx={{\n fontSize: '1rem',\n color: 'hsl(var(--foreground))',\n '& textarea::placeholder': { color: 'hsl(var(--muted-foreground))', opacity: 0.7 },\n }}\n />\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n style={{ display: 'none' }}\n onChange={(e) => {\n handleImagesSelected(e.target.files);\n if (e.target) e.target.value = '';\n }}\n />\n {(() => {\n const allowWithoutExecution = showStarter;\n const promptTooShort = showStarter && (actionInput || '').trim().length < 6;\n const canSchedule = (hasExecution || allowWithoutExecution) && !scheduleDisabledReason && !promptTooShort && !disableSchedule;\n const hintActive = Boolean(scheduleHint) && canSchedule;\n const tip: React.ReactNode = disableSchedule\n ? (disableScheduleTooltip || 'Scheduling is disabled while editing')\n : scheduleDisabledReason\n ? scheduleDisabledTooltip\n : promptTooShort\n ? 'Type at least 6 characters of prompt before scheduling.'\n : hintActive\n ? `Detected schedule: ${scheduleHint!.label}. Click to review and save.`\n : 'Schedule this prompt to run repeatedly on a cron schedule';\n return (\n <Tooltip title={tip} placement=\"top\" arrow>\n <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5 }}>\n <IconButton\n type=\"button\"\n onClick={(e) => { if (canSchedule) setScheduleAnchor(e.currentTarget); }}\n disabled={!canSchedule || agentRequestLoading}\n sx={{\n height: 36,\n minWidth: 36,\n px: hintActive ? 1.25 : 0,\n width: hintActive ? 'auto' : 36,\n borderRadius: hintActive ? 999 : '50%',\n gap: hintActive ? 0.75 : 0,\n color: hintActive ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n bgcolor: hintActive ? 'hsl(var(--primary) / 0.12)' : 'transparent',\n border: hintActive ? '1px solid hsl(var(--primary) / 0.5)' : '1px solid transparent',\n '&:hover': hintActive\n ? { bgcolor: 'hsl(var(--primary) / 0.2)', color: 'hsl(var(--primary))' }\n : { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n '&.Mui-disabled': { opacity: 0.4, color: 'hsl(var(--muted-foreground))' },\n transition: 'all 160ms ease',\n }}\n >\n <ScheduleIcon sx={{ fontSize: 18 }} />\n {hintActive && (\n <Box\n component=\"span\"\n sx={{\n fontSize: '0.72rem',\n fontWeight: 600,\n lineHeight: 1,\n whiteSpace: 'nowrap',\n maxWidth: 180,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {scheduleHint!.label}\n </Box>\n )}\n </IconButton>\n </Box>\n </Tooltip>\n );\n })()}\n {!hideAttach && (\n <IconButton\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n disabled={agentRequestLoading}\n title={attachedImages.length > 0 ? `Add image (${attachedImages.length} attached)` : 'Attach image'}\n sx={{\n width: 36, height: 36,\n color: attachedImages.length > 0 ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n bgcolor: attachedImages.length > 0 ? 'hsla(var(--primary) / 0.1)' : 'transparent',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <AttachFileIcon sx={{ fontSize: 18 }} />\n </IconButton>\n )}\n <Tooltip title={submitTooltip} placement=\"top\" arrow>\n <span>\n {submitLabel ? (\n <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>\n <Tooltip title=\"Try this prompt without saving\" placement=\"top\" arrow>\n <IconButton\n type=\"button\"\n onClick={() => submitInput(actionInput)}\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: 'transparent',\n border: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n '&:hover': { bgcolor: 'hsl(var(--muted))' },\n '&.Mui-disabled': { color: 'hsl(var(--muted-foreground))' },\n }}\n >\n <PlayArrowRoundedIcon />\n </IconButton>\n </Tooltip>\n <Button\n type=\"submit\"\n variant=\"contained\"\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'inherit' }} /> : null}\n sx={{\n height: 36,\n px: 2,\n textTransform: 'none',\n fontSize: '0.85rem',\n fontWeight: 600,\n boxShadow: 'none',\n bgcolor: 'hsl(var(--primary))',\n color: 'hsl(var(--primary-foreground))',\n '&:hover': { bgcolor: 'hsl(var(--primary))', filter: 'brightness(1.1)', boxShadow: 'none' },\n '&.Mui-disabled': { bgcolor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n {submitLabel}\n </Button>\n </Box>\n ) : (\n <IconButton\n type=\"submit\"\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: actionInput.trim().length >= 3 ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: actionInput.trim().length >= 3 ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n '&:hover': actionInput.trim().length >= 3 ? { filter: 'brightness(1.1)', bgcolor: 'hsl(var(--primary))' } : {},\n '&.Mui-disabled': { bgcolor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n {agentRequestLoading ? <CircularProgress size={16} sx={{ color: 'inherit' }} /> : (submitIcon ?? <PlayArrowRoundedIcon />)}\n </IconButton>\n )}\n </span>\n </Tooltip>\n </Box>\n </Box>\n\n {!hideAppPicker && (\n <Box sx={{ display: 'flex', justifyContent: 'center' }}>\n <Box sx={{\n display: 'inline-flex', flexWrap: 'wrap', alignItems: 'center', gap: 0.5,\n p: 0.5,\n borderRadius: 999,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n maxWidth: '100%',\n }}>\n <Tooltip title={agentRequestLoading ? 'Locked while the agent is running' : ''}>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={() => { if (!agentRequestLoading) setAppSearchOpen(true); }}\n disabled={agentRequestLoading}\n sx={{\n all: 'unset', cursor: agentRequestLoading ? 'not-allowed' : 'pointer',\n display: 'inline-flex', alignItems: 'center', gap: 0.5,\n px: 1.5, py: 0.5,\n borderRadius: 999,\n fontSize: '0.8rem', fontWeight: 500,\n color: 'hsl(var(--muted-foreground))',\n bgcolor: 'transparent',\n opacity: agentRequestLoading ? 0.5 : 1,\n transition: 'color 0.12s ease, background-color 0.12s ease, opacity 0.12s ease',\n '&:hover': agentRequestLoading ? {} : { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted) / 0.5)' },\n }}\n >\n <AddIcon sx={{ fontSize: 14 }} />\n {appPickerLabel}\n </Box>\n </Tooltip>\n {chosenApps.map((app, i) => {\n const slug = (app.name || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const NO_AUTH = new Set(['http', 'shuffle_tools', 'shuffle-tools', 'tools', 'singul', 'core', 'webhook', 'email']);\n const needsAuth = !NO_AUTH.has(slug) && !isAppAuthenticated(app.name || '');\n return (\n <Tooltip\n key={`${app.name}-${i}`}\n title={needsAuth ? `${(app.name || '').replace(/_/g, ' ')} is not authenticated yet — click to set it up` : ''}\n arrow\n >\n <Box\n onClick={needsAuth && !agentRequestLoading ? () => setAuthDrawerApp({ name: app.name, id: app.id || null }) : undefined}\n sx={{\n display: 'inline-flex', alignItems: 'center', gap: 0.5,\n pl: 0.5, pr: 0.75, py: 0.25,\n borderRadius: 999,\n bgcolor: needsAuth ? 'hsl(var(--severity-medium) / 0.12)' : 'hsl(var(--muted) / 0.6)',\n border: needsAuth ? '1px solid hsl(var(--severity-medium) / 0.55)' : '1px solid transparent',\n fontSize: '0.8rem',\n color: 'hsl(var(--foreground))',\n cursor: needsAuth && !agentRequestLoading ? 'pointer' : 'default',\n transition: 'background-color 0.12s ease',\n '&:hover': needsAuth && !agentRequestLoading ? { bgcolor: 'hsl(var(--severity-medium) / 0.18)' } : {},\n }}\n >\n <Avatar\n src={app.icon || undefined}\n alt={app.name}\n variant=\"rounded\"\n sx={{ width: 18, height: 18, bgcolor: 'transparent' }}\n />\n <Typography sx={{ fontSize: '0.8rem', mx: 0.25, textTransform: 'capitalize' }}>\n {app.name.replace(/_/g, ' ')}\n </Typography>\n {needsAuth && (\n <WarningIcon sx={{ fontSize: 14, color: 'hsl(var(--severity-medium))', mr: 0.25 }} />\n )}\n <IconButton\n size=\"small\"\n onClick={(e) => { e.stopPropagation(); setChosenApps((prev) => prev.filter((_, idx) => idx !== i)); }}\n disabled={agentRequestLoading}\n sx={{ p: 0.125, color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--destructive))' }, '&.Mui-disabled': { opacity: 0.4 } }}\n >\n <CloseIcon sx={{ fontSize: 12 }} />\n </IconButton>\n </Box>\n </Tooltip>\n );\n })}\n </Box>\n </Box>\n )}\n\n {/* Pre-run auth advisory — non-blocking. Lists chosen apps that\n are not yet authenticated and offers a one-click CTA to open\n the app drawer to set them up. The agent can still run\n without these — Shuffle will request auth mid-run if needed. */}\n {!hideAppPicker && (() => {\n const NO_AUTH = new Set(['http', 'shuffle_tools', 'shuffle-tools', 'tools', 'singul', 'core', 'webhook', 'email']);\n const unauthed = chosenApps.filter((a) => {\n const slug = (a.name || '').toLowerCase().replace(/[\\s-]+/g, '_');\n return !NO_AUTH.has(slug) && !isAppAuthenticated(a.name || '');\n });\n if (unauthed.length === 0) return null;\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: -0.5 }}>\n <Box sx={{\n display: 'inline-flex', alignItems: 'center', gap: 1,\n px: 1.25, py: 0.5,\n borderRadius: 999,\n border: '1px solid hsl(var(--severity-medium) / 0.45)',\n bgcolor: 'hsl(var(--severity-medium) / 0.08)',\n fontSize: '0.75rem',\n color: 'hsl(var(--foreground))',\n maxWidth: '100%',\n }}>\n <WarningIcon sx={{ fontSize: 14, color: 'hsl(var(--severity-medium))' }} />\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {unauthed.length === 1\n ? `${unauthed[0].name.replace(/_/g, ' ')} is not authenticated.`\n : `${unauthed.length} apps are not authenticated.`}\n </Typography>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={() => setAuthDrawerApp({ name: unauthed[0].name, id: unauthed[0].id || null })}\n sx={{\n all: 'unset', cursor: 'pointer',\n fontSize: '0.75rem', fontWeight: 600,\n color: 'hsl(var(--primary))',\n textTransform: 'capitalize',\n '&:hover': { textDecoration: 'underline' },\n }}\n >\n Set up {unauthed[0].name.replace(/_/g, ' ')} →\n </Box>\n </Box>\n </Box>\n );\n })()}\n\n\n {error && (\n <Box sx={{\n width: '100%', p: 1.5, borderRadius: 1.5,\n border: '1px solid hsl(var(--destructive) / 0.4)',\n bgcolor: 'hsl(var(--destructive) / 0.08)',\n color: 'hsl(var(--destructive))',\n fontSize: '0.85rem',\n }}>{error}</Box>\n )}\n </Box>\n ) : (\n <Box>\n {/* Status row */}\n <Box sx={{\n display: 'flex', alignItems: 'center', gap: 2,\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n mb: 2,\n }}>\n <AvatarGroup max={4} sx={{ '& .MuiAvatar-root': { width: 28, height: 28, borderColor: 'hsl(var(--border))', fontSize: '0.7rem' } }}>\n {(executionApps.length > 0 ? executionApps : chosenApps).map((app, i) => (\n <Tooltip key={i} title={(app.name || '').replace(/_/g, ' ')}>\n <Avatar\n src={app.icon || undefined}\n alt={app.name}\n variant=\"rounded\"\n onClick={() => navigate(`/apps/${encodeURIComponent((app.name || '').toLowerCase().replace(/\\s+/g, '_'))}`)}\n sx={{\n bgcolor: 'hsl(var(--muted))',\n cursor: 'pointer',\n transition: 'transform 0.15s ease, border-color 0.15s ease',\n '&:hover': { transform: 'scale(1.08)', borderColor: 'hsl(var(--primary)) !important' },\n }}\n />\n </Tooltip>\n ))}\n </AvatarGroup>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {agentData?.original_input || actionInput || 'Agent run'}\n </Typography>\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))' }}>\n Status: {execution?.status || agentData?.status || '—'} · {execution?.execution_id?.slice(0, 8) || ''}\n </Typography>\n </Box>\n {(() => {\n const topStatus = String(execution?.status || agentData?.status || '').toUpperCase();\n const topRunning = !!(execution?.execution_id || agentRequestLoading) && !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(topStatus);\n return topRunning ? (\n <Tooltip title={execution?.execution_id ? 'Abort this execution' : 'Cancel and return to Start'}>\n <span>\n <IconButton\n size=\"small\"\n onClick={abortAgent}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--destructive))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <StopCircleIcon sx={{ fontSize: 18 }} />\n </IconButton>\n </span>\n </Tooltip>\n ) : null;\n })()}\n <Tooltip title=\"Rerun with the same prompt and tools\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={rerunAgent}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--primary))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <RestartAltIcon sx={{ fontSize: 18 }} />\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n\n {error && (\n <Box sx={{\n p: 1.5, borderRadius: 1.5, mb: 2,\n border: '1px solid hsl(var(--destructive) / 0.4)',\n bgcolor: 'hsl(var(--destructive) / 0.08)',\n color: 'hsl(var(--destructive))',\n fontSize: '0.85rem',\n }}>{error}</Box>\n )}\n\n {/* Shared diagnosis banner — same component used by drawers and\n incident pages, so the user sees identical reasoning here. */}\n <AgentRunDiagnosisBanner\n run={execution}\n sx={{ px: 0, pb: 0, mb: 2 }}\n onJumpToEvidence={(decisionIndex) => {\n // Locate the timeline row for the offending decision and\n // expand + scroll to it on the detailed view, regardless of\n // whether the user is currently on Simple or Detailed.\n const dec = (agentData?.decisions || [])[decisionIndex];\n let rowIndex = -1;\n if (dec) {\n rowIndex = timeline.findIndex((it) => it.details === dec);\n if (rowIndex < 0 && dec.run_details?.id) {\n rowIndex = timeline.findIndex(\n (it) => (it.details as any)?.run_details?.id === dec.run_details.id\n );\n }\n }\n // Fall back to the agent row (0) if we cannot resolve.\n const targetIndex = rowIndex >= 0 ? rowIndex : 0;\n setOpenIndexes((prev) => {\n const next = new Set(prev);\n next.add(targetIndex);\n return next;\n });\n goToTab('detailed');\n // Pulse the row + its output box so the user can see exactly\n // which step the diagnosis was pulled from. Auto-clears after\n // a couple seconds; re-clicking restarts the pulse.\n setHighlightedIndex(targetIndex);\n window.setTimeout(() => {\n setHighlightedIndex((curr) => (curr === targetIndex ? null : curr));\n }, 2800);\n // Wait for the detailed view to mount, then scroll the row\n // into view. requestAnimationFrame x2 ensures layout has\n // settled after the tab switch.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const el = document.querySelector(\n `[data-timeline-index=\"${targetIndex}\"]`\n ) as HTMLElement | null;\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n });\n });\n }}\n />\n\n {/* Simple summary view */}\n {viewMode === 'simple' && (\n <Box sx={{\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n p: 2.5,\n display: 'flex',\n flexDirection: 'column',\n gap: 1.5,\n }}>\n {(() => {\n const status = (execution?.status || agentData?.status || 'EXECUTING').toUpperCase();\n const decisionCount = (agentData?.decisions || []).length;\n const isRunning = !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(status);\n const rawStartedAt = agentData?.started_at || execution?.started_at || 0;\n // Normalize: backend may return Unix milliseconds (UnixMillis) or seconds.\n const startedAtSec = rawStartedAt > 1e12 ? Math.floor(rawStartedAt / 1000) : rawStartedAt;\n // Prefer our locally-captured start while the run is in\n // progress — the backend's `started_at` is sometimes\n // restamped on every poll, which made the counter look\n // frozen at \"1s\". Once finished, prefer the backend value\n // so the displayed total matches the recorded run.\n const effectiveStart = isRunning\n ? (localRunStart || startedAtSec || 0)\n : (startedAtSec || localRunStart || 0);\n let durationSec: number | null = null;\n if (isRunning && effectiveStart) {\n durationSec = Math.max(0, nowTick - effectiveStart);\n } else if (totalDuration && totalDuration > 0) {\n durationSec = totalDuration;\n }\n // Detect a pending ASK decision (agent waiting on a user answer)\n const pendingAsk = (agentData?.decisions || []).slice().reverse().find((d) => {\n const isAsk = d.category === 'ask' || d.action === 'ask';\n const st = (d.run_details?.status || '').toUpperCase();\n return isAsk && (st === 'RUNNING' || st === 'WAITING');\n });\n const pendingQuestions: { question: string; index: number }[] = [];\n if (pendingAsk) {\n for (const f of pendingAsk.fields || []) {\n if (f.key === 'question' && f.value) {\n pendingQuestions.push({ question: f.value, index: pendingQuestions.length + 1 });\n }\n }\n }\n const pendingAnswered = pendingQuestions.every((q) => questionAnswers[q.question]?.value);\n\n return (\n <>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {isRunning ? (\n <CircularProgress size={16} sx={{ color: 'hsl(var(--primary))' }} />\n ) : status === 'FINISHED' ? (\n <CheckCircleIcon sx={{ fontSize: 18, color: 'hsl(142 70% 45%)' }} />\n ) : (\n <ErrorIcon sx={{ fontSize: 18, color: 'hsl(var(--destructive))' }} />\n )}\n <Typography sx={{ fontSize: '0.9rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {isRunning ? 'Agent is working…' : status === 'FINISHED' ? 'Run finished' : `Run ${status.toLowerCase()}`}\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {decisionCount} step{decisionCount === 1 ? '' : 's'}\n {durationSec != null ? ` · ${Math.round(durationSec)}s` : ''}\n </Typography>\n <Box sx={{ flexGrow: 1 }} />\n </Box>\n {pendingAuthApps.map(({ appName, appId, icon }) => {\n const pretty = appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n return (\n <Box\n key={`auth-${appName}`}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}\n >\n <LockIcon sx={{ color: 'hsl(var(--severity-medium))', fontSize: 22 }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n Connect your {pretty} account so the agent can complete this step, then rerun.\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={icon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n onClick={() => setAuthDrawerApp({ name: appName, id: appId })}\n sx={{\n height: 36, textTransform: 'none', fontWeight: 600,\n }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n );\n })}\n {finishAnswer ? (\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n fontSize: '0.9rem',\n color: 'hsl(var(--foreground))',\n '& > *:first-of-type': { mt: 0 },\n '& > *:last-child': { mb: 0 },\n '& p': { my: 1, lineHeight: 1.55 },\n '& h1, & h2, & h3, & h4': { mt: 2, mb: 1, fontWeight: 600, lineHeight: 1.3 },\n '& h1': { fontSize: '1.15rem' },\n '& h2': { fontSize: '1.05rem' },\n '& h3, & h4': { fontSize: '0.95rem' },\n '& ul': { my: 1, pl: 3, listStyleType: 'disc', listStylePosition: 'outside' },\n '& ol': { my: 1, pl: 3, listStyleType: 'decimal', listStylePosition: 'outside' },\n '& ul ul': { listStyleType: 'circle' },\n '& ul ul ul': { listStyleType: 'square' },\n '& li': { my: 0.25, display: 'list-item' },\n '& li::marker': { color: 'hsl(var(--muted-foreground))' },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': {\n px: 0.5, py: 0.125, borderRadius: 0.5,\n bgcolor: 'hsl(var(--muted))',\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n fontSize: '0.82em',\n },\n '& pre': {\n p: 1.5, my: 1, borderRadius: 1,\n bgcolor: 'hsl(var(--muted))',\n overflowX: 'auto',\n fontSize: '0.82rem',\n },\n '& pre code': { p: 0, bgcolor: 'transparent' },\n '& blockquote': {\n borderLeft: '3px solid hsl(var(--border))',\n pl: 1.5, my: 1, color: 'hsl(var(--muted-foreground))',\n },\n '& table': { borderCollapse: 'collapse', my: 1, fontSize: '0.85rem' },\n '& th, & td': { border: '1px solid hsl(var(--border))', px: 1, py: 0.5 },\n '& hr': { border: 0, borderTop: '1px solid hsl(var(--border))', my: 1.5 },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(finishAnswer)}</Markdown>\n </Box>\n ) : pendingAsk && pendingQuestions.length > 0 ? (\n (() => {\n const trySimpleSubmit = () => {\n if (agentRequestLoading) return;\n if (!pendingAnswered) {\n setSimpleSubmitAttempted(true);\n return;\n }\n if (pendingAsk.run_details?.id) {\n submitQuestions(pendingAsk.run_details.id, questionAnswers);\n }\n };\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n {pendingQuestions.map((q, qi) => {\n const value = questionAnswers[q.question]?.value || '';\n const isMissing = simpleSubmitAttempted && !value;\n return (\n <Box key={qi}>\n <Box sx={{ fontSize: '0.9rem', color: 'hsl(var(--foreground))', mb: 1, '& p': { my: 0.5 } }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n <TextField\n fullWidth\n multiline\n minRows={2}\n placeholder=\"Your answer here…\"\n value={value}\n error={isMissing}\n helperText={isMissing ? 'Please answer this question' : undefined}\n onChange={(e) => {\n const v = e.target.value;\n setQuestionAnswers((prev) => ({\n ...prev,\n [q.question]: { index: qi, value: v },\n }));\n }}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n trySimpleSubmit();\n }\n }}\n size=\"small\"\n sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'hsl(var(--background))' } }}\n />\n </Box>\n );\n })}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Tooltip title={!pendingAnswered ? 'Please answer all questions first' : ''} placement=\"top\" arrow>\n <span>\n <Button\n variant=\"contained\"\n size=\"small\"\n disabled={agentRequestLoading || !pendingAnswered}\n onClick={trySimpleSubmit}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'hsl(var(--primary-foreground))' }} /> : undefined}\n >\n {agentRequestLoading ? 'Submitting…' : 'Submit'}\n </Button>\n </span>\n </Tooltip>\n {pendingAsk.run_details?.id && getFormUrl(pendingAsk.run_details.id) && (\n <Tooltip title=\"Answer in the Form UI\" placement=\"right\">\n <IconButton\n size=\"small\"\n onClick={() => {\n const url = getFormUrl(pendingAsk.run_details!.id!);\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n }}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon sx={{ fontSize: 18 }} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </Box>\n );\n })()\n ) : isRunning ? (\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n Waiting for the agent to produce the first step.\n </Typography>\n ) : (\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n No final answer was returned. Open Detailed to inspect each step.\n </Typography>\n )}\n\n {!isRunning && (\n <Box>\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => setViewMode('detailed')}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none', px: 0 }}\n >\n View detailed timeline →\n </Button>\n </Box>\n )}\n </>\n );\n })()}\n </Box>\n )}\n\n {/* Detailed timeline view */}\n {viewMode === 'detailed' && (() => {\n const detailedStatus = (execution?.status || agentData?.status || 'EXECUTING').toUpperCase();\n const detailedIsRunning = !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(detailedStatus);\n const detailedRunFinished = !detailedIsRunning;\n return (\n <Box sx={{\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n overflow: 'hidden',\n }}>\n {timeline.length === 0 || (timeline.length === 1 && agentRequestLoading) ? (\n <Box sx={{ p: 4, textAlign: 'center', color: 'hsl(var(--muted-foreground))', fontSize: '0.85rem' }}>\n <CircularProgress size={20} sx={{ mb: 1 }} />\n <Typography sx={{ fontSize: '0.85rem' }}>Waiting for agent response…</Typography>\n </Box>\n ) : (\n <>\n {timeline.map((item, i) => (\n <TimelineRow\n key={i}\n item={item}\n index={i}\n open={openIndexes.has(i)}\n onToggle={() => toggleOpen(i)}\n appsById={appsById}\n totalDuration={totalDuration}\n originalStartTime={originalStartTime}\n maxWidth={210}\n questionAnswers={questionAnswers}\n setQuestionAnswers={setQuestionAnswers}\n onSubmitQuestions={submitQuestions}\n onRerunAgent={rerunAgent}\n onRerunDecision={rerunDecision}\n agentRequestLoading={agentRequestLoading}\n getFormUrl={getFormUrl}\n runFinished={detailedRunFinished}\n onAuthenticateApp={(name, id) => setAuthDrawerApp({ name, id })}\n isAppAuthenticated={isAppAuthenticated}\n highlight={highlightedIndex === i}\n />\n ))}\n {detailedRunFinished && (\n <Box sx={{\n borderTop: '1px solid hsl(var(--border))',\n p: 2.5,\n display: 'flex',\n flexDirection: 'column',\n gap: 1.5,\n bgcolor: 'hsl(var(--muted) / 0.2)',\n }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {detailedStatus === 'FINISHED' ? (\n <CheckCircleIcon sx={{ fontSize: 18, color: 'hsl(142 70% 45%)' }} />\n ) : (\n <ErrorIcon sx={{ fontSize: 18, color: 'hsl(var(--destructive))' }} />\n )}\n <Typography sx={{ fontSize: '0.9rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {detailedStatus === 'FINISHED' ? 'Run finished' : `Run ${detailedStatus.toLowerCase()}`}\n </Typography>\n </Box>\n {finishAnswer && (\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n fontSize: '0.9rem',\n color: 'hsl(var(--foreground))',\n '& > *:first-of-type': { mt: 0 },\n '& > *:last-child': { mb: 0 },\n '& p': { my: 1, lineHeight: 1.55 },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': {\n px: 0.5, py: 0.125, borderRadius: 0.5,\n bgcolor: 'hsl(var(--muted))',\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n fontSize: '0.82em',\n },\n '& pre': {\n p: 1.5, my: 1, borderRadius: 1,\n bgcolor: 'hsl(var(--muted))',\n overflowX: 'auto',\n fontSize: '0.82rem',\n },\n '& pre code': { p: 0, bgcolor: 'transparent' },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(finishAnswer)}</Markdown>\n </Box>\n )}\n </Box>\n )}\n </>\n )}\n </Box>\n );\n })()}\n\n {/* Continuation form (after a finish decision) */}\n {finishDecisionId && (\n <Box sx={{ mt: 3, display: 'flex', justifyContent: 'center' }}>\n <Box sx={{ width: '100%', maxWidth: 640 }}>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', mb: 0.75, textAlign: 'center' }}>\n Continue this agent run with more details\n </Typography>\n <Box\n component=\"form\"\n onSubmit={(e) => {\n e.preventDefault();\n if (continuationText.trim()) {\n submitQuestions(finishDecisionId, { continue: continuationText }, true);\n }\n }}\n sx={{\n display: 'flex', alignItems: 'flex-end', gap: 1,\n p: 1.25, borderRadius: 999,\n border: '1.5px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary))',\n boxShadow: '0 0 0 3px hsla(var(--primary) / 0.12)',\n },\n }}\n >\n <InputBase\n fullWidth\n multiline\n minRows={1}\n maxRows={4}\n placeholder={continuationPlaceholder}\n value={continuationText}\n onChange={(e) => setContinuationText(e.target.value)}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n if (continuationText.trim() && !agentRequestLoading) {\n submitQuestions(finishDecisionId, { continue: continuationText }, true);\n }\n }\n }}\n disabled={agentRequestLoading}\n sx={{ fontSize: '0.9rem', color: 'hsl(var(--foreground))', px: 2 }}\n />\n <IconButton\n type=\"submit\"\n disabled={!continuationText.trim() || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: continuationText.trim() && !agentRequestLoading ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: continuationText.trim() && !agentRequestLoading ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n '&:hover': continuationText.trim() && !agentRequestLoading ? { filter: 'brightness(1.1)', bgcolor: 'hsl(var(--primary))' } : {},\n }}\n >\n {agentRequestLoading ? <CircularProgress size={16} sx={{ color: 'inherit' }} /> : <SendIcon sx={{ fontSize: 18 }} />}\n </IconButton>\n </Box>\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n <AppSearchDrawer\n open={appSearchOpen}\n onClose={() => setAppSearchOpen(false)}\n title={appPickerTitle}\n subtitle={appPickerSubtitle}\n multiSelect\n selectedApps={chosenApps.map((a) => ({ name: a.name, id: a.id || null, icon: a.icon }))}\n onSelectionChange={(next) => {\n setChosenApps(\n next.map((app) => {\n const known = availableApps.find(\n (a) => a.name?.toLowerCase() === app.name?.toLowerCase(),\n );\n return {\n name: app.name,\n icon: app.icon || known?.icon,\n id: app.id || known?.id || undefined,\n };\n }),\n );\n }}\n />\n\n <AppDetailDrawer\n open={!!authDrawerApp}\n onClose={() => setAuthDrawerApp(null)}\n appName={authDrawerApp?.name || null}\n appId={authDrawerApp?.id || null}\n activeOrgId={orgId || null}\n />\n </Box>\n </Box>\n );\n};\n\nexport default AgentUI;\n","/**\n * resolveApp — General-purpose app resolver.\n *\n * Given an app id OR name, look it up across all three known sources and\n * return a unified `{ id, name, image }` triple. Used anywhere we need to\n * render an app chip/icon and only have a free-form identifier (decision\n * `tool`, auth-request `appName`, `app_authentication` payload, etc.).\n *\n * Resolution order (each pass merges in any newly-found fields, so we keep\n * going until id/name/image are all known or all sources are exhausted):\n * 1. /api/v1/apps/authentication — covers user-installed/active apps,\n * including private ones that may not be in the public catalog.\n * 2. /api/v1/apps — covers everything visible to the org (activated\n * and private uploads).\n * 3. Algolia `appsearch` — canonical objectID + public catalog metadata.\n *\n * Results are cached in-memory by normalized key so repeat lookups for the\n * same name/id are free.\n */\n\nimport { fetchAppsViaApiConfig } from './appsCache';\nimport { fetchAuthenticatedApps } from './authenticatedApps';\n\nexport interface ResolvedApp {\n /** Canonical id — Algolia objectID when known, otherwise Shuffle app id. */\n id: string;\n /** Display name (may be raw slug if no source had a friendly name). */\n name: string;\n /** Best available large image URL. Empty string if not found. */\n image: string;\n /** Categories from whichever source provided them. */\n categories?: string[];\n}\n\nconst norm = (s: string): string =>\n (s || '').toLowerCase().trim().replace(/[\\s\\-]+/g, '_');\n\nconst _cache = new Map<string, ResolvedApp>();\nconst _pending = new Map<string, Promise<ResolvedApp | null>>();\n\n/** Returns true when the resolved record is fully populated. */\nconst isComplete = (r: Partial<ResolvedApp>): boolean =>\n Boolean(r.id && r.name && r.image);\n\nconst merge = (\n base: Partial<ResolvedApp>,\n next: Partial<ResolvedApp>,\n): Partial<ResolvedApp> => ({\n id: base.id || next.id,\n name: base.name || next.name,\n image: base.image || next.image,\n categories: base.categories?.length ? base.categories : next.categories,\n});\n\n/**\n * Resolve an app from id-or-name across auth + apps + Algolia.\n * Returns `null` only if all three sources came back empty.\n */\nexport async function resolveApp(idOrName: string): Promise<ResolvedApp | null> {\n if (!idOrName || typeof idOrName !== 'string') return null;\n const slug = norm(idOrName);\n const rawKey = idOrName;\n\n const cached = _cache.get(slug) || _cache.get(rawKey);\n if (cached) return cached;\n\n const inflight = _pending.get(slug);\n if (inflight) return inflight;\n\n const work = (async (): Promise<ResolvedApp | null> => {\n let acc: Partial<ResolvedApp> = {};\n\n // --- Pass 1: authenticated apps -----------------------------------\n try {\n const auths = await fetchAuthenticatedApps();\n const hit = auths.find((a) => {\n const app = a?.app || {};\n return (\n (app.id && (app.id === rawKey || app.id === slug)) ||\n (app.name && norm(String(app.name)) === slug)\n );\n });\n if (hit?.app) {\n acc = merge(acc, {\n id: hit.app.id ? String(hit.app.id) : undefined,\n name: hit.app.name ? String(hit.app.name) : undefined,\n image: hit.app.large_image || hit.app.small_image || '',\n categories: hit.app.categories as string[] | undefined,\n });\n }\n } catch { /* ignore */ }\n\n // --- Pass 2: /api/v1/apps -----------------------------------------\n if (!isComplete(acc)) {\n try {\n const apps = await fetchAppsViaApiConfig();\n const hit = apps.find(\n (a: any) =>\n a?.id === rawKey ||\n a?.id === slug ||\n (a?.name && norm(String(a.name)) === slug),\n );\n if (hit) {\n acc = merge(acc, {\n id: hit.id ? String(hit.id) : undefined,\n name: hit.name ? String(hit.name) : undefined,\n image: hit.large_image || hit.image_url || hit.image || '',\n categories: hit.categories,\n });\n }\n } catch { /* ignore */ }\n }\n\n // --- Pass 3: Algolia ----------------------------------------------\n if (!isComplete(acc)) {\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch(\n 'JNSS5CFDZZ',\n '33e4e3564f4f060e96e0531957bed552',\n );\n // Prefer direct objectID lookup if the input looks like one.\n let match: any = null;\n try {\n const obj = await (client as any).getObject({\n indexName: 'appsearch',\n objectID: rawKey,\n });\n if (obj?.name || obj?.image_url) match = obj;\n } catch { /* not an objectID — fall through */ }\n if (!match) {\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: slug.replace(/_/g, ' '), hitsPerPage: 5 },\n });\n const hits = (res.hits as any[]) || [];\n match = hits.find((h) => norm(h.name || '') === slug) || hits[0];\n }\n if (match) {\n acc = merge(acc, {\n // Algolia objectID is canonical — prefer it for `id` when we\n // didn't already get a real id from auth/apps.\n id: acc.id || match.objectID || match.id,\n name: match.name,\n image: match.image_url,\n categories: match.categories,\n });\n }\n } catch { /* algolia unavailable / rate-limited */ }\n }\n\n if (!acc.id && !acc.name && !acc.image) return null;\n\n const resolved: ResolvedApp = {\n id: acc.id || slug,\n name: acc.name || idOrName,\n image: acc.image || '',\n categories: acc.categories,\n };\n _cache.set(slug, resolved);\n _cache.set(rawKey, resolved);\n return resolved;\n })();\n\n _pending.set(slug, work);\n try {\n return await work;\n } finally {\n _pending.delete(slug);\n }\n}\n\n/** Resolve many at once — convenience wrapper. */\nexport async function resolveApps(\n idsOrNames: string[],\n): Promise<Record<string, ResolvedApp>> {\n const out: Record<string, ResolvedApp> = {};\n await Promise.all(\n idsOrNames.map(async (n) => {\n const r = await resolveApp(n);\n if (r) out[n] = r;\n }),\n );\n return out;\n}\n\n/** Seed the cache (e.g. from chosenApps that already carry an icon). */\nexport function seedResolvedApp(idOrName: string, app: Partial<ResolvedApp>) {\n if (!idOrName || !app) return;\n const slug = norm(idOrName);\n const existing = _cache.get(slug) || _cache.get(idOrName);\n const merged: ResolvedApp = {\n id: app.id || existing?.id || slug,\n name: app.name || existing?.name || idOrName,\n image: app.image || existing?.image || '',\n categories: app.categories || existing?.categories,\n };\n _cache.set(slug, merged);\n _cache.set(idOrName, merged);\n}\n\n/** Clear the resolver cache (e.g. on org change). */\nexport function invalidateResolvedApps() {\n _cache.clear();\n}\n","/**\n * Agent Run Service\n * Shared logic for calling the /api/v1/agent JSON-RPC endpoint\n * and parsing the response into a usable format.\n */\n\nimport { getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\n// ── Request types ──────────────────────────────────────────────────────────────\n\n/**\n * MCP-spec image content block.\n * @see https://modelcontextprotocol.io specification — Image Content\n */\nexport interface AgentImageInput {\n /** Raw base64 (no data URL prefix) */\n data: string;\n /** e.g. \"image/png\", \"image/jpeg\" */\n mimeType: string;\n /** Optional original filename — for UI/debugging only */\n name?: string;\n}\n\nexport interface AgentRunRequest {\n /** The user's prompt / instruction */\n input: string;\n /** Optional: target a single app */\n toolName?: string;\n toolId?: string;\n /** Optional: target multiple apps */\n toolNames?: string[];\n toolIds?: string[];\n /**\n * Optional: one or more attached images. Sent under\n * `params.input.images` as an array of `{ url, detail }` objects,\n * where `url` is a `data:<mime>;base64,<data>` URL.\n */\n images?: AgentImageInput[];\n /** @deprecated Use `images`. Single base64 data URL kept for back-compat. */\n image?: string;\n /**\n * If true, return the initial response immediately without polling for the\n * final execution result. The caller is then responsible for polling\n * `/api/v1/streams/results` itself (e.g. AgentUI's live timeline).\n */\n skipPolling?: boolean;\n /**\n * Optional per-call overrides so callers (e.g. embedded `AgentUI`) can\n * point at a different Shuffle backend without mutating the global\n * `API_CONFIG`. When omitted, falls back to `getApiUrl` / `getAuthHeader`.\n */\n apiKey?: string;\n apiBaseUrl?: string;\n orgId?: string;\n /** Optional AbortSignal so callers can cancel the in-flight request. */\n signal?: AbortSignal;\n}\n\n/** Build URL + headers honouring optional per-call overrides. */\nconst resolveTarget = (\n path: string,\n opts: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): { url: string; headers: Record<string, string> } => {\n const url = opts.apiBaseUrl\n ? `${opts.apiBaseUrl.replace(/\\/+$/, '')}${path}`\n : getApiUrl(path);\n const headers: Record<string, string> = opts.apiKey\n ? { Authorization: `Bearer ${opts.apiKey}` }\n : { ...getAuthHeader() };\n if (opts.orgId) headers['Org-Id'] = opts.orgId;\n return { url, headers };\n};\n\n/** Split a `data:<mime>;base64,<data>` URL into its mime + base64 parts. */\nconst parseDataUrl = (dataUrl: string): AgentImageInput | null => {\n const match = /^data:([^;]+);base64,(.*)$/.exec(dataUrl);\n if (!match) return null;\n return { mimeType: match[1], data: match[2] };\n};\n\n// ── Response types ─────────────────────────────────────────────────────────────\n\nexport interface AgentRunResponse {\n success: boolean;\n /** Parsed, human-readable output content */\n content: string;\n /** The raw parsed JSON (if response was JSON), for further inspection */\n rawData?: unknown;\n /** Error message if success is false */\n error?: string;\n /** HTTP status code of the response */\n status: number;\n}\n\n// ── Response parser ────────────────────────────────────────────────────────────\n\n/**\n * Parse a JSON-RPC agent response into human-readable content.\n * Extracts the most useful information from the nested response structure.\n */\nexport const parseAgentResponse = (data: unknown): string => {\n if (typeof data === 'string') return data;\n if (data == null) return 'No output returned.';\n\n const obj = data as Record<string, unknown>;\n\n // JSON-RPC result field\n if (obj.result !== undefined) {\n const result = obj.result;\n\n if (typeof result === 'string') return result || 'No output returned.';\n\n if (typeof result === 'object' && result !== null) {\n const r = result as Record<string, unknown>;\n const parts: string[] = [];\n\n // Extract message first (most useful field)\n if (r.message && typeof r.message === 'string') {\n parts.push(r.message);\n }\n\n // Append any remaining fields as structured JSON\n const rest = { ...r };\n delete rest.message;\n if (Object.keys(rest).length > 0) {\n parts.push(JSON.stringify(rest, null, 2));\n }\n\n return parts.join('\\n\\n') || 'No output returned.';\n }\n\n return String(result);\n }\n\n // Fallback: top-level message\n if (obj.message && typeof obj.message === 'string') return obj.message;\n\n // Fallback: dump entire response\n return JSON.stringify(data, null, 2);\n};\n\n// ── Execution poller ───────────────────────────────────────────────────────────\n\n/**\n * Poll /api/v1/streams/results for the real execution result.\n * Retries up to `maxAttempts` with `intervalMs` between each.\n */\nconst pollExecutionResult = async (\n executionId: string,\n {\n maxAttempts = 15,\n intervalMs = 2000,\n apiKey,\n apiBaseUrl,\n orgId,\n }: { maxAttempts?: number; intervalMs?: number; apiKey?: string; apiBaseUrl?: string; orgId?: string } = {}\n): Promise<AgentRunResponse> => {\n const { url, headers } = resolveTarget('/api/v1/streams/results', { apiKey, apiBaseUrl, orgId });\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const resp = await fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n execution_id: executionId,\n authorization: executionId,\n }),\n });\n\n if (!resp.ok) {\n // Non-retryable server error\n if (resp.status >= 400 && resp.status < 500) {\n return {\n success: false,\n content: '',\n error: `Error ${resp.status}: Could not fetch execution result.`,\n status: resp.status,\n };\n }\n // Server error — keep polling\n await delay(intervalMs);\n continue;\n }\n\n const rawText = await resp.text();\n if (!rawText || rawText === '{}' || rawText === 'null') {\n // Not ready yet\n await delay(intervalMs);\n continue;\n }\n\n const contentType = resp.headers.get('content-type');\n if (!contentType?.includes('application/json')) {\n return { success: true, content: rawText, status: resp.status };\n }\n\n const data = JSON.parse(rawText);\n\n // Check if execution is still running (no real result yet)\n if (data?.status === 'EXECUTING' || data?.status === 'WAITING') {\n await delay(intervalMs);\n continue;\n }\n\n const content = parseAgentResponse(data);\n return {\n success: true,\n content,\n rawData: data,\n status: resp.status,\n };\n } catch {\n await delay(intervalMs);\n }\n }\n\n return {\n success: false,\n content: '',\n error: `Timed out waiting for execution ${executionId} to complete.`,\n status: 0,\n };\n};\n\nconst delay = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// ── Main function ──────────────────────────────────────────────────────────────\n\n/**\n * Check if the initial response is an execution stub\n * (contains execution_id but no real result content).\n */\nconst isExecutionStub = (data: unknown): data is { execution_id: string } => {\n if (typeof data !== 'object' || data === null) return false;\n const obj = data as Record<string, unknown>;\n return (\n typeof obj.execution_id === 'string' &&\n obj.execution_id.length > 0 &&\n // It's a stub if there's no result/message — just metadata\n obj.result === undefined &&\n obj.message === undefined\n );\n};\n\n/**\n * Run the agent with the given input and optional tool targets.\n * Handles the full lifecycle: build payload → fetch → parse response.\n * If the response is an execution stub, polls for the real result.\n */\nexport const runAgent = async (request: AgentRunRequest): Promise<AgentRunResponse> => {\n const input: Record<string, unknown> = { text: request.input };\n\n // Collect images: prefer explicit `images` array, fall back to legacy `image` data URL.\n const images: AgentImageInput[] = [];\n if (request.images && request.images.length > 0) {\n images.push(...request.images);\n } else if (request.image && request.image.length > 0) {\n const parsed = parseDataUrl(request.image);\n if (parsed) images.push(parsed);\n }\n\n // Sent under `params.input.images` as an array of `{ url, detail }` objects\n // so the agent can accept multiple images. `url` is a data URL.\n if (images.length > 0) {\n input.images = images.map((img) => ({\n url: `data:${img.mimeType};base64,${img.data}`,\n detail: 'auto',\n }));\n }\n\n const params: Record<string, unknown> = { input };\n\n // Single tool target\n if (request.toolName) params.tool_name = request.toolName;\n if (request.toolId) params.tool_id = request.toolId;\n\n // Multiple tool targets\n if (request.toolNames && request.toolNames.length > 0) {\n params.tool_names = request.toolNames;\n }\n if (request.toolIds && request.toolIds.length > 0) {\n params.tool_ids = request.toolIds;\n }\n\n const payload = {\n jsonrpc: '2.0',\n id: crypto.randomUUID(),\n method: 'tools/call',\n params,\n };\n\n const { url: agentUrl, headers: agentHeaders } = resolveTarget('/api/v1/agent', {\n apiKey: request.apiKey,\n apiBaseUrl: request.apiBaseUrl,\n orgId: request.orgId,\n });\n\n try {\n const response = await fetch(agentUrl, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...agentHeaders,\n },\n body: JSON.stringify(payload),\n signal: request.signal,\n });\n\n const rawText = await response.text();\n const contentType = response.headers.get('content-type');\n\n // Non-OK status\n if (!response.ok) {\n return {\n success: false,\n content: '',\n error: `Error ${response.status}: ${rawText || response.statusText}`,\n status: response.status,\n };\n }\n\n // Non-JSON response (HTML redirect, plain text, etc.)\n if (!contentType?.includes('application/json')) {\n if (rawText.trim().startsWith('<!') || rawText.includes('<html')) {\n return {\n success: false,\n content: '',\n error: 'Received an unexpected HTML response. This may indicate an auth redirect or server issue.',\n status: response.status,\n };\n }\n // Plain text is still valid output\n return {\n success: true,\n content: rawText,\n status: response.status,\n };\n }\n\n // JSON response — parse and check for execution stub\n const data = JSON.parse(rawText);\n\n if (isExecutionStub(data)) {\n if (request.skipPolling) {\n // Hand control back to the caller (it will poll itself).\n return {\n success: true,\n content: '',\n rawData: data,\n status: response.status,\n };\n }\n console.log(`[AgentRun] Got execution stub, polling for result: ${data.execution_id}`);\n return pollExecutionResult(data.execution_id, {\n apiKey: request.apiKey,\n apiBaseUrl: request.apiBaseUrl,\n orgId: request.orgId,\n });\n }\n\n const content = parseAgentResponse(data);\n\n return {\n success: true,\n content,\n rawData: data,\n status: response.status,\n };\n } catch (err) {\n const aborted = err instanceof DOMException && err.name === 'AbortError';\n return {\n success: false,\n content: '',\n error: aborted\n ? 'Request aborted by user.'\n : `Network error — could not reach the agent. ${err instanceof Error ? err.message : ''}`,\n status: 0,\n ...(aborted ? { aborted: true } as any : {}),\n };\n }\n};\n","/**\n * scheduleHint — lightweight natural-language detector for scheduling intent\n * inside an agent prompt. Recognises phrases like:\n * \"schedule this\", \"at 6 am\", \"next monday at 2am\",\n * \"daily in the evening\", \"every 15 minutes\", \"weekdays at 9am\",\n * \"every monday\", \"weekly\", \"hourly\", \"tonight at 11pm\"\n *\n * Returns a structured hint that the UI uses to (1) highlight the Schedule\n * button and (2) preselect a cron expression in the schedule popover.\n *\n * NOTE: Intentionally simple — pure heuristics, no LLM. Good enough to surface\n * scheduling as a suggestion; the user always confirms in the popover.\n */\n\nexport interface ScheduleHint {\n /** Suggested cron expression (5-field, UTC-naive — matches existing chips). */\n cron: string;\n /** Human-readable label, e.g. \"Daily at 6:00 AM\" or \"Every Monday at 2:00 AM\". */\n label: string;\n /** Strength of the match — used to decide how loud the UI hint should be. */\n confidence: 'low' | 'medium' | 'high';\n /** The substring of the input that triggered the match (for highlighting). */\n matchedText: string;\n}\n\nconst DAY_NAMES: Record<string, number> = {\n sunday: 0, sun: 0,\n monday: 1, mon: 1,\n tuesday: 2, tue: 2, tues: 2,\n wednesday: 3, wed: 3,\n thursday: 4, thu: 4, thurs: 4,\n friday: 5, fri: 5,\n saturday: 6, sat: 6,\n};\n\nconst PART_OF_DAY: Record<string, number> = {\n morning: 9,\n noon: 12,\n afternoon: 14,\n evening: 18,\n night: 22,\n midnight: 0,\n};\n\nconst DAY_LABEL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n\nconst fmtTime = (h: number, m: number): string => {\n const ampm = h >= 12 ? 'PM' : 'AM';\n const h12 = ((h + 11) % 12) + 1;\n const mm = m.toString().padStart(2, '0');\n return `${h12}:${mm} ${ampm}`;\n};\n\nconst findTime = (text: string): { h: number; m: number; matched: string } | null => {\n // 6am, 6 am, 6:30am, 14:00, 2:30 pm\n const re = /\\b(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm|a\\.m\\.|p\\.m\\.)\\b|\\b(\\d{1,2}):(\\d{2})\\b(?!\\s*(?:am|pm))/i;\n const m = text.match(re);\n if (!m) return null;\n if (m[1]) {\n let h = parseInt(m[1], 10);\n const min = m[2] ? parseInt(m[2], 10) : 0;\n const meridiem = m[3].toLowerCase().replace(/\\./g, '');\n if (meridiem === 'pm' && h < 12) h += 12;\n if (meridiem === 'am' && h === 12) h = 0;\n if (h > 23 || min > 59) return null;\n return { h, m: min, matched: m[0] };\n }\n if (m[4]) {\n const h = parseInt(m[4], 10);\n const min = parseInt(m[5], 10);\n if (h > 23 || min > 59) return null;\n return { h, m: min, matched: m[0] };\n }\n return null;\n};\n\nconst findDay = (text: string): { day: number; matched: string } | null => {\n for (const [name, d] of Object.entries(DAY_NAMES)) {\n const re = new RegExp(`\\\\b${name}\\\\b`, 'i');\n const m = text.match(re);\n if (m) return { day: d, matched: m[0] };\n }\n return null;\n};\n\nconst findPartOfDay = (text: string): { h: number; matched: string } | null => {\n for (const [name, h] of Object.entries(PART_OF_DAY)) {\n const re = new RegExp(`\\\\b${name}\\\\b`, 'i');\n const m = text.match(re);\n if (m) return { h, matched: m[0] };\n }\n return null;\n};\n\nexport const parseScheduleHint = (input: string): ScheduleHint | null => {\n if (!input) return null;\n const text = input.toLowerCase();\n const hits: string[] = [];\n\n // ── 1. Recurrence keywords ──────────────────────────────────────────────\n const everyMin = text.match(/every\\s+(\\d+)\\s*(?:m|min|mins|minute|minutes)\\b/);\n if (everyMin) {\n const n = Math.max(1, Math.min(59, parseInt(everyMin[1], 10)));\n return {\n cron: `*/${n} * * * *`,\n label: `Every ${n} minute${n === 1 ? '' : 's'}`,\n confidence: 'high',\n matchedText: everyMin[0],\n };\n }\n const everyHr = text.match(/every\\s+(\\d+)\\s*(?:h|hr|hrs|hour|hours)\\b/);\n if (everyHr) {\n const n = Math.max(1, Math.min(23, parseInt(everyHr[1], 10)));\n return {\n cron: `0 */${n} * * *`,\n label: `Every ${n} hour${n === 1 ? '' : 's'}`,\n confidence: 'high',\n matchedText: everyHr[0],\n };\n }\n if (/\\bhourly\\b|\\bevery hour\\b/.test(text)) {\n return { cron: '0 * * * *', label: 'Hourly', confidence: 'high', matchedText: 'hourly' };\n }\n\n // ── 2. Time of day (explicit or part-of-day) ────────────────────────────\n const t = findTime(text);\n const part = !t ? findPartOfDay(text) : null;\n const hour = t ? t.h : part ? part.h : null;\n const minute = t ? t.m : 0;\n if (t) hits.push(t.matched);\n if (part) hits.push(part.matched);\n\n // ── 3. Day-of-week ──────────────────────────────────────────────────────\n const day = findDay(text);\n if (day) hits.push(day.matched);\n\n // ── 4. Frequency words ──────────────────────────────────────────────────\n const isDaily = /\\b(daily|every\\s+day|each\\s+day)\\b/.test(text);\n const isWeekly = /\\b(weekly|every\\s+week)\\b/.test(text);\n const isWeekdays = /\\b(weekday|weekdays|every\\s+weekday|workdays?|business\\s+days?)\\b/.test(text);\n const isMonthly = /\\b(monthly|every\\s+month)\\b/.test(text);\n const hasScheduleWord = /\\b(schedule|recurring|recur|repeat|automate|cron)\\b/.test(text);\n if (isDaily) hits.push('daily');\n if (isWeekly) hits.push('weekly');\n if (isWeekdays) hits.push('weekdays');\n if (isMonthly) hits.push('monthly');\n\n // Future word — \"next monday at 2am\" is treated as weekly Monday.\n if (/\\bnext\\b/.test(text)) hits.push('next');\n if (/\\btonight\\b/.test(text) && hour === null) {\n return { cron: '0 21 * * *', label: 'Daily at 9:00 PM (tonight)', confidence: 'medium', matchedText: 'tonight' };\n }\n if (/\\btomorrow\\b/.test(text) && hour !== null) {\n return {\n cron: `${minute} ${hour} * * *`,\n label: `Daily at ${fmtTime(hour, minute)}`,\n confidence: 'medium',\n matchedText: hits.join(' '),\n };\n }\n\n // ── 5. Build cron from collected pieces ─────────────────────────────────\n if (day && hour !== null) {\n return {\n cron: `${minute} ${hour} * * ${day.day}`,\n label: `Every ${DAY_LABEL[day.day]} at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isWeekdays && hour !== null) {\n return {\n cron: `${minute} ${hour} * * 1-5`,\n label: `Weekdays at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isMonthly && hour !== null) {\n return {\n cron: `${minute} ${hour} 1 * *`,\n label: `Monthly on the 1st at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isWeekly) {\n const d = day ? day.day : 1;\n const h = hour ?? 9;\n return {\n cron: `${minute} ${h} * * ${d}`,\n label: `Every ${DAY_LABEL[d]} at ${fmtTime(h, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isDaily || (hour !== null && (isDaily || part || hasScheduleWord || /\\bevery\\b/.test(text)))) {\n const h = hour ?? 9;\n return {\n cron: `${minute} ${h} * * *`,\n label: `Daily at ${fmtTime(h, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (day) {\n return {\n cron: `0 9 * * ${day.day}`,\n label: `Every ${DAY_LABEL[day.day]} at 9:00 AM`,\n confidence: 'medium',\n matchedText: day.matched,\n };\n }\n if (hour !== null) {\n return {\n cron: `${minute} ${hour} * * *`,\n label: `Daily at ${fmtTime(hour, minute)}`,\n confidence: 'medium',\n matchedText: hits.join(' '),\n };\n }\n if (hasScheduleWord) {\n return {\n cron: '0 9 * * *',\n label: 'Schedule this prompt',\n confidence: 'low',\n matchedText: text.match(/\\b(schedule|recurring|recur|repeat|automate|cron)\\b/)?.[0] || 'schedule',\n };\n }\n return null;\n};\n","/**\n * AgentRunDiagnosisBanner — compact, dismissible \"nudge\" shown above an\n * agent run when it failed or its output looks suspicious.\n *\n * Designed to be unobtrusive: a single line with an icon, short message,\n * an optional jump-to-evidence affordance, and a dismiss (X) button that\n * permanently hides the banner for that exact execution.\n *\n * Returns `null` when the run has no failure / warning, or when the user\n * has already dismissed the banner for this execution id.\n */\n\nimport { Box, IconButton, Tooltip, Typography } from '@mui/material';\nimport { AlertTriangle, ArrowUpRight, HelpCircle, X } from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\nimport {\n diagnoseOutputWarning,\n extractDecisionIndex,\n getFailureInfo,\n hasOutputWarning,\n type DiagnosableRun,\n} from './agentDiagnosis';\n\ninterface Props {\n run: DiagnosableRun | null | undefined;\n /** Outer padding wrapper. Defaults to `{ px: 2.5, pb: 0.5 }`. */\n sx?: Record<string, unknown>;\n /** When provided, the banner becomes clickable and asks the host to jump\n * to the underlying decision (e.g. switch to the detailed timeline,\n * expand that row, scroll to it). */\n onJumpToEvidence?: (decisionIndex: number) => void;\n /** Stable id used to persist dismissals per-execution. Falls back to\n * `run.execution_id` if present. When neither is available, dismiss\n * still works for the current mount but is not persisted. */\n executionId?: string;\n}\n\nconst DISMISS_PREFIX = 'agent-diagnosis-dismissed::';\n\nconst readDismissed = (key: string | null): boolean => {\n if (!key || typeof window === 'undefined') return false;\n try {\n return window.localStorage.getItem(DISMISS_PREFIX + key) === '1';\n } catch {\n return false;\n }\n};\n\nconst writeDismissed = (key: string | null) => {\n if (!key || typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(DISMISS_PREFIX + key, '1');\n } catch {\n /* ignore */\n }\n};\n\nconst AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, executionId }: Props) => {\n const dismissKey = useMemo(() => {\n if (executionId) return executionId;\n const fromRun = (run as any)?.execution_id;\n return typeof fromRun === 'string' && fromRun ? fromRun : null;\n }, [executionId, run]);\n\n const [dismissed, setDismissed] = useState<boolean>(() => readDismissed(dismissKey));\n\n // Re-sync if the underlying execution changes.\n useEffect(() => {\n setDismissed(readDismissed(dismissKey));\n }, [dismissKey]);\n\n if (!run || dismissed) return null;\n\n const status = (run.status || '').toUpperCase();\n const isFailed = status === 'FAILED' || status === 'ABORTED';\n const failureInfo = isFailed ? getFailureInfo(run) : null;\n const outputWarning = !isFailed && hasOutputWarning(run);\n const diagnosis = outputWarning ? diagnoseOutputWarning(run) : null;\n\n if (!failureInfo && !diagnosis) return null;\n\n const isCritical = !!failureInfo;\n const tone = isCritical ? 'critical' : 'medium';\n const Icon = isCritical ? AlertTriangle : HelpCircle;\n\n const message = isCritical\n ? failureInfo!.reason\n : `${diagnosis!.title} — ${diagnosis!.remediation}`;\n\n const firstEvidence = diagnosis?.evidence?.[0] || null;\n const jumpDecisionIndex = firstEvidence ? extractDecisionIndex(firstEvidence.path) : null;\n const canJump = !!(onJumpToEvidence && jumpDecisionIndex !== null);\n\n const handleDismiss = (e: React.MouseEvent) => {\n e.stopPropagation();\n writeDismissed(dismissKey);\n setDismissed(true);\n };\n\n const handleJump = () => {\n if (canJump) onJumpToEvidence!(jumpDecisionIndex!);\n };\n\n return (\n <Box sx={{ px: 2.5, pb: 0.5, ...(sx || {}) }}>\n <Box\n {...(canJump\n ? {\n role: 'button' as const,\n tabIndex: 0,\n onClick: handleJump,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleJump();\n }\n },\n }\n : {})}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 1.25,\n py: 0.5,\n borderRadius: 2,\n bgcolor: `hsla(var(--severity-${tone}) / 0.06)`,\n border: `1px solid hsla(var(--severity-${tone}) / 0.18)`,\n cursor: canJump ? 'pointer' : 'default',\n transition: 'background 0.15s ease, border-color 0.15s ease',\n ...(canJump && {\n '&:hover': {\n bgcolor: `hsla(var(--severity-${tone}) / 0.1)`,\n borderColor: `hsla(var(--severity-${tone}) / 0.35)`,\n },\n '&:focus-visible': {\n outline: 'none',\n borderColor: `hsl(var(--severity-${tone}))`,\n boxShadow: `0 0 0 2px hsla(var(--severity-${tone}) / 0.25)`,\n },\n }),\n }}\n >\n <Icon\n size={13}\n style={{ color: `hsl(var(--severity-${tone}))`, flexShrink: 0 }}\n />\n <Typography\n sx={{\n flex: 1,\n minWidth: 0,\n fontSize: '0.74rem',\n color: 'hsl(var(--foreground))',\n lineHeight: 1.4,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n title={message}\n >\n {message}\n </Typography>\n {canJump && (\n <Tooltip title={`Open Decision #${(jumpDecisionIndex ?? 0) + 1} in detailed timeline`} placement=\"top\" arrow>\n <ArrowUpRight\n size={13}\n style={{ color: `hsl(var(--severity-${tone}))`, flexShrink: 0 }}\n />\n </Tooltip>\n )}\n <Tooltip title=\"Dismiss for this execution\" placement=\"top\" arrow>\n <IconButton\n size=\"small\"\n onClick={handleDismiss}\n sx={{\n p: 0.25,\n ml: 0.25,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': {\n color: 'hsl(var(--foreground))',\n bgcolor: 'hsla(var(--foreground) / 0.06)',\n },\n }}\n aria-label=\"Dismiss diagnosis\"\n >\n <X size={12} />\n </IconButton>\n </Tooltip>\n </Box>\n </Box>\n );\n};\n\nexport default AgentRunDiagnosisBanner;\n","/**\n * Shared diagnosis utilities for an agent execution result.\n *\n * Lives in the Shuffle-MCPs lib so every surface that displays an agent run\n * (AgentUI Simple/Detailed view, AgentExecutionDrawer, the incident-side\n * AgentRunResultViewer, the activity feed status pill, ...) uses the EXACT\n * same logic to decide whether the run \"needs review\" and what to tell the\n * user about it.\n *\n * Pure logic — no React, no MUI, no project-side imports.\n */\n\n/** Minimal run shape the diagnoser needs. Compatible with AgentRun and\n * AgentUI's internal ExecutionData. */\nexport interface DiagnosableRun {\n status?: string;\n results?: Array<{ result?: string } | any> | null;\n}\n\n// ---------------------------------------------------------------------------\n// JSON parsing helpers\n// ---------------------------------------------------------------------------\n\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']')) ||\n (trimmed.startsWith('\"') && trimmed.endsWith('\"'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n return parsed;\n } catch {\n return obj;\n }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\n/** Try to parse the result JSON from results[0].result, unwrapping AGENT-type executions. */\nexport const parseRunResult = (\n run: DiagnosableRun\n): { raw: string | null; parsed: any | null } => {\n const firstResult = run.results?.[0]?.result;\n if (!firstResult) return { raw: null, parsed: null };\n\n try {\n let parsed = JSON.parse(firstResult);\n if (\n parsed &&\n typeof parsed === 'object' &&\n parsed.type === 'AGENT' &&\n Array.isArray(parsed.results) &&\n parsed.results.length > 0\n ) {\n const innerResult = parsed.results[0]?.result;\n if (innerResult) {\n try {\n parsed = JSON.parse(innerResult);\n } catch {\n return { raw: innerResult, parsed: null };\n }\n }\n }\n const deepParsed = deepParseJsonStrings(parsed);\n return { raw: firstResult, parsed: deepParsed };\n } catch {\n return { raw: firstResult, parsed: null };\n }\n};\n\n/** Extract failure info from a failed/aborted run. */\nexport const getFailureInfo = (run: DiagnosableRun): { reason: string } | null => {\n const status = run.status?.toUpperCase();\n if (status !== 'FAILED' && status !== 'ABORTED') return null;\n\n const { parsed } = parseRunResult(run);\n if (parsed && typeof parsed === 'object') {\n if (parsed.success === false && parsed.reason) return { reason: parsed.reason };\n if (parsed.message) return { reason: parsed.message };\n if (parsed.error)\n return { reason: typeof parsed.error === 'string' ? parsed.error : JSON.stringify(parsed.error) };\n }\n return null;\n};\n\n/**\n * Restrict the search to the agent's own decision records and final\n * `decision_string`. Walking the full result picks up keywords from the\n * system prompt and produces false-positive \"Auth Failure\" diagnoses.\n */\nconst getDiagnosableScope = (parsed: any): unknown => {\n if (!parsed || typeof parsed !== 'object') return null;\n const scope: Record<string, unknown> = {};\n if (Array.isArray(parsed.decisions)) {\n // Keep positional alignment with parsed.decisions[N] so an evidence\n // path like `run_details[N]...` maps directly back to the Nth\n // decision in the agent's timeline. Decisions without run_details\n // are kept as `null` placeholders (the walker skips nulls).\n const runDetails = parsed.decisions.map((d: any) =>\n d && typeof d === 'object' && d.run_details ? d.run_details : null\n );\n if (runDetails.some((rd: unknown) => rd !== null)) scope.run_details = runDetails;\n }\n if (parsed.decision_string !== undefined) scope.decision_string = parsed.decision_string;\n return Object.keys(scope).length > 0 ? scope : null;\n};\n\n/** Extract the originating decision index (in parsed.decisions / agentData.decisions)\n * from a diagnosis evidence path like `run_details[3].result.error`.\n * Returns null if the path does not start at a decision row. */\nexport const extractDecisionIndex = (path: string | undefined | null): number | null => {\n if (!path) return null;\n const m = /^run_details\\[(\\d+)\\]/.exec(path);\n if (!m) return null;\n const n = Number(m[1]);\n return Number.isFinite(n) ? n : null;\n};\n\n/** Detect if the output content hints at an error/failure even if the run\n * status is \"finished\". Only returns true when `diagnoseOutputWarning`\n * would produce a concrete, actionable diagnosis — never on vague keyword\n * matches alone. */\nexport const hasOutputWarning = (run: DiagnosableRun): boolean => {\n return diagnoseOutputWarning(run) !== null;\n};\n\n// ---------------------------------------------------------------------------\n// Diagnosis\n// ---------------------------------------------------------------------------\n\nexport type DiagnosisEvidence = {\n /** Dotted JSON path inside the parsed run result. */\n path: string;\n /** Trimmed snippet of the value at that path. */\n value: string;\n};\n\nexport type OutputDiagnosis = {\n kind: 'auth' | 'permission' | 'not_found' | 'rate_limit' | 'network' | 'validation' | 'generic';\n status?: number;\n title: string;\n explanation: string;\n remediation: string;\n snippet?: string;\n evidence: DiagnosisEvidence[];\n};\n\ntype ResultEntry = { path: string; value: string };\n\nconst collectEntries = (root: unknown): ResultEntry[] => {\n const out: ResultEntry[] = [];\n const walk = (v: unknown, path: string, depth: number): void => {\n if (depth > 8 || v == null) return;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n out.push({ path, value: String(v) });\n return;\n }\n if (Array.isArray(v)) {\n v.forEach((item, i) => walk(item, `${path}[${i}]`, depth + 1));\n return;\n }\n if (typeof v === 'object') {\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n const next = path ? `${path}.${k}` : k;\n walk(val, next, depth + 1);\n }\n }\n };\n walk(root, '', 0);\n return out;\n};\n\nconst trimEvidenceValue = (v: string, max = 180): string => {\n const cleaned = v.replace(/\\s+/g, ' ').trim();\n return cleaned.length <= max ? cleaned : `${cleaned.slice(0, max).trim()}…`;\n};\n\nexport const diagnoseOutputWarning = (run: DiagnosableRun): OutputDiagnosis | null => {\n const { parsed, raw } = parseRunResult(run);\n if (!parsed || typeof parsed !== 'object') return null;\n\n const scope = getDiagnosableScope(parsed);\n if (!scope) return null;\n\n const entries = collectEntries(scope);\n if (raw && entries.length === 0) entries.push({ path: '', value: raw });\n\n const haystack = entries.map((e) => e.value).join('\\n');\n const lower = haystack.toLowerCase();\n\n const findEvidence = (\n test: (lowerVal: string, val: string) => boolean,\n max = 3\n ): DiagnosisEvidence[] => {\n const out: DiagnosisEvidence[] = [];\n for (const e of entries) {\n if (test(e.value.toLowerCase(), e.value)) {\n out.push({ path: e.path || '(root)', value: trimEvidenceValue(e.value) });\n if (out.length >= max) break;\n }\n }\n return out;\n };\n const findEvidenceByRegex = (re: RegExp, max = 3): DiagnosisEvidence[] =>\n findEvidence((l) => re.test(l), max);\n const findEvidenceByKeywords = (needles: string[], max = 3): DiagnosisEvidence[] =>\n findEvidence((l) => needles.some((n) => l.includes(n.toLowerCase())), max);\n\n let status: number | undefined;\n let statusEvidence: DiagnosisEvidence | null = null;\n const statusPatterns = [\n /\\bhttp[\\s/]?(\\d{3})\\b/i,\n /\\bstatus[\\s:_-]+(\\d{3})\\b/i,\n /\\bstatus[_\\s-]?code[\"\\s:]+(\\d{3})\\b/i,\n /\\bcode[\"\\s:]+(\\d{3})\\b/i,\n /\\[(\\d{3})\\]/,\n /\\((\\d{3})\\)/,\n /\\b(4\\d{2}|5\\d{2})\\b/,\n ];\n outer: for (const re of statusPatterns) {\n for (const e of entries) {\n const m = e.value.match(re);\n if (m) {\n const n = Number(m[1]);\n if (n >= 400 && n < 600) {\n status = n;\n statusEvidence = { path: e.path || '(root)', value: trimEvidenceValue(e.value) };\n break outer;\n }\n }\n }\n }\n\n const findSnippet = (needles: string[]): string | undefined => {\n for (const needle of needles) {\n const i = lower.indexOf(needle);\n if (i >= 0) {\n const start = Math.max(0, i - 40);\n const end = Math.min(haystack.length, i + 160);\n return (\n (start > 0 ? '…' : '') +\n haystack.slice(start, end).trim() +\n (end < haystack.length ? '…' : '')\n );\n }\n }\n return undefined;\n };\n\n const withStatusEvidence = (ev: DiagnosisEvidence[]): DiagnosisEvidence[] => {\n if (!statusEvidence) return ev;\n const dedup = ev.filter((e) => e.path !== statusEvidence!.path);\n return [statusEvidence, ...dedup].slice(0, 3);\n };\n\n if (\n status === 401 ||\n /\\b(unauthori[sz]ed|invalid[_\\s-]*(api[_\\s-]*key|token|credentials?)|authentication[_\\s-]*(failed|required)|missing[_\\s-]*(api[_\\s-]*key|token|authorization)|bearer[_\\s-]*token|expired[_\\s-]*token)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /unauthori[sz]ed|invalid[_\\s-]*(api[_\\s-]*key|token|credentials?)|authentication[_\\s-]*(failed|required)|missing[_\\s-]*(api[_\\s-]*key|token|authorization)|bearer[_\\s-]*token|expired[_\\s-]*token|\\b401\\b/\n );\n return {\n kind: 'auth',\n status,\n title: status === 401 ? 'Authentication failed (HTTP 401)' : 'Authentication failed',\n explanation:\n 'The upstream service rejected the request because the credentials were missing, invalid, or expired.',\n remediation:\n 'Open the integration in Apps → Authentication, reconnect or paste a fresh API key/token, then re-run the action.',\n snippet: findSnippet(['401', 'unauthorized', 'invalid api', 'invalid token', 'authentication']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 403 ||\n /\\b(forbidden|permission[_\\s-]*denied|not[_\\s-]*allowed|access[_\\s-]*denied|insufficient[_\\s-]*(scope|permission|privileges?)|missing[_\\s-]*scope)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /forbidden|permission[_\\s-]*denied|not[_\\s-]*allowed|access[_\\s-]*denied|insufficient[_\\s-]*(scope|permission|privileges?)|missing[_\\s-]*scope|\\b403\\b/\n );\n return {\n kind: 'permission',\n status,\n title: status === 403 ? 'Permission denied (HTTP 403)' : 'Permission denied',\n explanation:\n 'The credentials are valid, but the connected account does not have permission (or scope) to perform this action.',\n remediation:\n 'Re-authenticate the integration with the missing scope, or grant the connected account permission for this resource in the source app.',\n snippet: findSnippet(['403', 'forbidden', 'permission', 'scope', 'access denied']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 429 ||\n /\\b(rate[_\\s-]*limit|too[_\\s-]*many[_\\s-]*requests|quota[_\\s-]*exceeded|throttled)\\b/.test(lower)\n ) {\n const ev = findEvidenceByRegex(\n /rate[_\\s-]*limit|too[_\\s-]*many[_\\s-]*requests|quota[_\\s-]*exceeded|throttled|\\b429\\b/\n );\n return {\n kind: 'rate_limit',\n status,\n title: status === 429 ? 'Rate limited (HTTP 429)' : 'Rate limited',\n explanation: 'The upstream service is throttling requests from this integration.',\n remediation:\n \"Wait a minute and re-run, or reduce how often this action fires. Check the integration's rate-limit settings if the problem keeps happening.\",\n snippet: findSnippet(['429', 'rate limit', 'too many', 'quota', 'throttled']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 404 ||\n /\\b(not[_\\s-]*found|no such|does not exist|unknown[_\\s-]*(id|resource))\\b/.test(lower)\n ) {\n const ev = findEvidenceByRegex(\n /not[_\\s-]*found|no such|does not exist|unknown[_\\s-]*(id|resource)|\\b404\\b/\n );\n return {\n kind: 'not_found',\n status,\n title: status === 404 ? 'Resource not found (HTTP 404)' : 'Resource not found',\n explanation:\n 'The action ran, but the target resource (record, ticket, channel, file) could not be located.',\n remediation:\n 'Verify the ID or path the agent used is correct, and that the connected account can see that resource.',\n snippet: findSnippet(['404', 'not found', 'no such', 'does not exist']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 400 ||\n status === 422 ||\n /\\b(bad[_\\s-]*request|validation[_\\s-]*(error|failed)|invalid[_\\s-]*(parameter|field|argument|body|payload))\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /bad[_\\s-]*request|validation[_\\s-]*(error|failed)|invalid[_\\s-]*(parameter|field|argument|body|payload)|\\b400\\b|\\b422\\b/\n );\n return {\n kind: 'validation',\n status,\n title: status ? `Invalid request (HTTP ${status})` : 'Invalid request',\n explanation:\n 'The upstream service rejected the request because the parameters were missing or malformed.',\n remediation:\n \"Check the action's required fields and the values the agent sent. The Debug section below shows the exact payload.\",\n snippet: findSnippet(['400', '422', 'bad request', 'validation', 'invalid']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n (typeof status === 'number' && status >= 500) ||\n /\\b(timeout|timed[_\\s-]*out|econnrefused|enotfound|network[_\\s-]*error|connection[_\\s-]*(refused|reset|closed)|service[_\\s-]*unavailable|bad[_\\s-]*gateway|gateway[_\\s-]*timeout)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /timeout|timed[_\\s-]*out|econnrefused|enotfound|network[_\\s-]*error|connection[_\\s-]*(refused|reset|closed)|service[_\\s-]*unavailable|bad[_\\s-]*gateway|gateway[_\\s-]*timeout|\\b5\\d{2}\\b/\n );\n return {\n kind: 'network',\n status,\n title: status ? `Upstream error (HTTP ${status})` : 'Network or upstream error',\n explanation:\n 'The integration could not reach the upstream service, or the service returned a server error.',\n remediation:\n \"Re-run the action shortly. If it keeps failing, check the upstream service's status page and the integration's base URL.\",\n snippet: findSnippet(['500', '502', '503', '504', 'timeout', 'timed out', 'unavailable']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n const namedFields: Array<keyof typeof parsed & string> = ['reason', 'error', 'message'];\n let namedReason: string | undefined;\n let namedEvidence: DiagnosisEvidence | null = null;\n for (const k of namedFields) {\n const v = (parsed as Record<string, unknown>)[k];\n if (typeof v === 'string' && v.trim()) {\n namedReason = v;\n namedEvidence = { path: k, value: trimEvidenceValue(v) };\n break;\n }\n }\n\n if ((parsed as { success?: unknown }).success === false || namedReason) {\n const ev: DiagnosisEvidence[] = [];\n if (namedEvidence) ev.push(namedEvidence);\n if ((parsed as { success?: unknown }).success === false) {\n ev.push({ path: 'success', value: 'false' });\n }\n return {\n kind: 'generic',\n status,\n title: status ? `Action failed (HTTP ${status})` : 'Action failed',\n explanation:\n namedReason || 'The action returned a failure but did not include a recognizable error code.',\n remediation: 'Open the Debug section below to see the full response from the integration.',\n snippet: namedReason,\n evidence: withStatusEvidence(ev).slice(0, 3),\n };\n }\n\n // No specific signal found — do NOT surface a generic \"may need review\"\n // banner. It is too vague to be actionable and just adds noise.\n return null;\n};\n","/**\n * AgentRunDrawer — standalone right-side drawer that hosts the canonical\n * `AgentUI` \"Run Agent\" experience plus optional caller-provided slots for\n * Permissions and Local LLM tabs.\n *\n * Replaces the project-only `AgentPermissionsDrawer`. It has zero\n * dependencies on host-app contexts (no react-router, no AuthContext, no\n * project services), so it works when the library is consumed standalone\n * via npm — pass `apiKey` / `apiBaseUrl` / `orgId` to authenticate the\n * embedded `AgentUI`.\n *\n * Design:\n * - Tabs: Run (always), Permissions (if `permissionsSlot`), Local LLM\n * (if `localLLMSlot`). When neither slot is provided, the tab strip is\n * hidden and the drawer shows only the AgentUI.\n * - All colors use HSL tokens so themes flow through. Falls back to\n * reasonable inline values when tokens are missing.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Drawer,\n IconButton,\n Tab,\n Tabs,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport CloseIcon from '@mui/icons-material/Close';\nimport { Play, Server, ShieldCheck } from 'lucide-react';\n\nimport AgentIcon from './AgentIcon';\nimport AgentUI, { type AgentUIProps } from './AgentUI';\n\nexport type AgentRunDrawerTab = 'run' | 'permissions' | 'localLLM';\n\nexport interface AgentRunDrawerProps {\n open: boolean;\n onClose: () => void;\n /** Which tab to focus when the drawer opens. Default: 'run'. */\n initialTab?: AgentRunDrawerTab;\n /** Render content for the Permissions tab. Tab is hidden when omitted. */\n permissionsSlot?: React.ReactNode;\n /** Render content for the Local LLM tab. Tab is hidden when omitted. */\n localLLMSlot?: React.ReactNode;\n /**\n * Custom badge node next to the Local LLM tab label (e.g. a green check\n * when OpenAI auth is detected). Optional.\n */\n localLLMTabBadge?: React.ReactNode;\n /** Tooltip shown when the Permissions tab is rendered but disabled. */\n permissionsDisabled?: boolean;\n permissionsDisabledTooltip?: string;\n /** Forwarded to the embedded AgentUI (apiKey, apiBaseUrl, orgId, etc.). */\n agentUIProps?: Partial<AgentUIProps>;\n /** Drawer width override (default: 480 px on >=sm, full-width on xs). */\n width?: number;\n /** Header title. Default: \"Agent\". */\n title?: string;\n /** Header subtitle. Default: \"Run actions and manage permissions\". */\n subtitle?: string;\n /** Optional className forwarded to the Drawer Paper. */\n className?: string;\n /** Style overrides merged into the Drawer Paper sx. Use to override colors, padding, etc. */\n paperSx?: SxProps<Theme>;\n /** Style overrides for the header bar (icon + title + close). */\n headerSx?: SxProps<Theme>;\n /** Style overrides for the tab strip. */\n tabsSx?: SxProps<Theme>;\n /** Style overrides for the body container that wraps the active tab content. */\n bodySx?: SxProps<Theme>;\n}\n\nconst TAB_ORDER: AgentRunDrawerTab[] = ['run', 'permissions', 'localLLM'];\n\nconst AgentRunDrawer = ({\n open,\n onClose,\n initialTab = 'run',\n permissionsSlot,\n localLLMSlot,\n localLLMTabBadge,\n permissionsDisabled = false,\n permissionsDisabledTooltip = 'Coming soon',\n agentUIProps,\n width = 520,\n title = 'Agent',\n subtitle = 'Run actions and manage permissions',\n className,\n paperSx,\n headerSx,\n tabsSx,\n bodySx,\n}: AgentRunDrawerProps) => {\n const [activeTab, setActiveTab] = useState<AgentRunDrawerTab>(initialTab);\n\n // Reset tab whenever the drawer transitions from closed -> open so each\n // open honors the caller's initialTab (matches the legacy behavior).\n const prevOpenRef = useRef(open);\n useEffect(() => {\n if (open && !prevOpenRef.current) setActiveTab(initialTab);\n prevOpenRef.current = open;\n }, [open, initialTab]);\n\n const visibleTabs = TAB_ORDER.filter((t) => {\n if (t === 'run') return true;\n if (t === 'permissions') return !!permissionsSlot;\n if (t === 'localLLM') return !!localLLMSlot;\n return false;\n });\n const showTabs = visibleTabs.length > 1;\n\n // If the requested tab isn't visible, fall back to the first visible one.\n const safeActiveTab: AgentRunDrawerTab = visibleTabs.includes(activeTab)\n ? activeTab\n : 'run';\n\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n slotProps={{\n paper: {\n className,\n sx: [\n {\n width: { xs: '100%', sm: width },\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: '1px solid hsl(var(--border))',\n boxShadow: '-8px 0 32px hsla(0, 0%, 0%, 0.4)',\n display: 'flex',\n flexDirection: 'column',\n },\n ...(Array.isArray(paperSx) ? paperSx : paperSx ? [paperSx] : []),\n ],\n },\n }}\n >\n {/* Header */}\n <Box\n sx={[\n {\n px: 3,\n py: 2.5,\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n },\n ...(Array.isArray(headerSx) ? headerSx : headerSx ? [headerSx] : []),\n ]}\n >\n <Box\n sx={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsla(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n flexShrink: 0,\n }}\n >\n <AgentIcon size={22} />\n </Box>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontWeight: 600, fontSize: '1.1rem', color: 'hsl(var(--foreground))' }}>\n {title}\n </Typography>\n <Typography sx={{ fontSize: '0.8rem', color: 'hsl(var(--muted-foreground))' }}>\n {subtitle}\n </Typography>\n </Box>\n <IconButton onClick={onClose} size=\"small\" sx={{ color: 'hsl(var(--muted-foreground))' }}>\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n\n {/* Tabs (hidden when only Run is available) */}\n {showTabs && (\n <Box sx={{ borderBottom: '1px solid hsl(var(--border))', flexShrink: 0 }}>\n <Tabs\n value={safeActiveTab}\n onChange={(_, v) => setActiveTab(v as AgentRunDrawerTab)}\n sx={[\n {\n minHeight: 42,\n px: 3,\n '& .MuiTab-root': {\n minHeight: 42,\n textTransform: 'none',\n fontSize: '0.85rem',\n fontWeight: 500,\n color: 'hsl(var(--muted-foreground))',\n '&.Mui-selected': { color: 'hsl(var(--primary))' },\n },\n '& .MuiTabs-indicator': { bgcolor: 'hsl(var(--primary))' },\n },\n ...(Array.isArray(tabsSx) ? tabsSx : tabsSx ? [tabsSx] : []),\n ]}\n >\n {visibleTabs.includes('run') && (\n <Tab\n value=\"run\"\n label=\"Run\"\n icon={<Play size={14} />}\n iconPosition=\"start\"\n sx={{ gap: 0.75 }}\n />\n )}\n {visibleTabs.includes('permissions') && (\n <Tab\n value=\"permissions\"\n label={\n permissionsDisabled ? (\n <Tooltip title={permissionsDisabledTooltip} arrow>\n <Box component=\"span\" sx={{ display: 'inline-flex', alignItems: 'center' }}>\n Permissions\n </Box>\n </Tooltip>\n ) : (\n 'Permissions'\n )\n }\n icon={<ShieldCheck size={14} />}\n iconPosition=\"start\"\n disabled={permissionsDisabled}\n sx={{ gap: 0.75 }}\n />\n )}\n {visibleTabs.includes('localLLM') && (\n <Tab\n value=\"localLLM\"\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n Local LLM\n {localLLMTabBadge}\n </Box>\n }\n icon={<Server size={14} />}\n iconPosition=\"start\"\n sx={{ gap: 0.75 }}\n />\n )}\n </Tabs>\n </Box>\n )}\n\n {/* Body */}\n <Box sx={[{ flex: 1, overflowY: 'auto' }, ...(Array.isArray(bodySx) ? bodySx : bodySx ? [bodySx] : [])]}>\n {safeActiveTab === 'run' && (\n <Box sx={{ px: 2, py: 2 }}>\n <AgentUI\n compact\n hideHeroIcon\n title=\"\"\n subtitle={null}\n {...agentUIProps}\n />\n </Box>\n )}\n {safeActiveTab === 'permissions' && permissionsSlot && (\n <Box sx={{ px: 3, py: 2.5 }}>{permissionsSlot}</Box>\n )}\n {safeActiveTab === 'localLLM' && localLLMSlot && (\n <Box sx={{ px: 3, py: 2.5 }}>{localLLMSlot}</Box>\n )}\n </Box>\n </Drawer>\n );\n};\n\nexport default AgentRunDrawer;\n","/**\n * AgentActivityList — standalone list of agent workflow executions.\n *\n * Self-contained: no project hooks, contexts, or services. Pass\n * `apiKey` / `apiBaseUrl` / `orgId` to authenticate against any Shuffle\n * backend. `onRunClick(run)` is called when a row is clicked — the\n * consumer decides what happens next (typically: open AgentExecutionDrawer).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n InputAdornment,\n MenuItem,\n Select,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport SearchIcon from '@mui/icons-material/Search';\nimport {\n Activity,\n AlertCircle,\n CheckCircle,\n Clock,\n FileText,\n Globe,\n Loader2,\n Server,\n XCircle,\n Zap,\n} from 'lucide-react';\n\nimport {\n searchAgentActivity,\n listAgentScheduleWorkflows,\n getAgentScheduleConfig,\n stopAgentSchedule,\n type AgentRun,\n type AgentScheduleWorkflow,\n} from './agentActivity';\nimport { Pencil, StopCircle } from 'lucide-react';\n\n// ── Status / icon helpers ────────────────────────────────────────────────────\n\nconst STATUS_CONFIG: Record<\n string,\n { icon: React.ReactNode; color: string; label: string }\n> = {\n FINISHED: { icon: <CheckCircle size={16} />, color: 'hsl(var(--severity-low, 142 71% 45%))', label: 'Completed' },\n SUCCESS: { icon: <CheckCircle size={16} />, color: 'hsl(var(--severity-low, 142 71% 45%))', label: 'Completed' },\n FAILED: { icon: <XCircle size={16} />, color: 'hsl(var(--severity-critical, 0 72% 55%))', label: 'Failed' },\n ABORTED: { icon: <XCircle size={16} />, color: 'hsl(var(--severity-critical, 0 72% 55%))', label: 'Aborted' },\n EXECUTING: { icon: <Loader2 size={16} />, color: 'hsl(var(--severity-medium, 38 92% 50%))', label: 'Running' },\n RUNNING: { icon: <Loader2 size={16} />, color: 'hsl(var(--severity-medium, 38 92% 50%))', label: 'Running' },\n WAITING: { icon: <Clock size={16} />, color: 'hsl(var(--severity-info, 217 91% 60%))', label: 'Waiting' },\n};\n\nconst getRunIcon = (run: AgentRun): React.ReactNode => {\n const src = (run.execution_source || '').toLowerCase();\n const arg = (run.execution_argument || '').toLowerCase();\n if (src.includes('schedule') || src.includes('cron')) return <Clock size={18} />;\n if (src.includes('webhook') || src.includes('http')) return <Globe size={18} />;\n if (arg.includes('alert') || arg.includes('detect')) return <Activity size={18} />;\n if (arg.includes('report') || arg.includes('email')) return <FileText size={18} />;\n if (arg.includes('endpoint') || arg.includes('server')) return <Server size={18} />;\n return <Zap size={18} />;\n};\n\nconst getRunIconColor = (run: AgentRun): string => {\n const status = (run.status || '').toUpperCase();\n if (status === 'FINISHED' || status === 'SUCCESS') return 'hsl(var(--severity-low, 142 71% 45%))';\n if (status === 'FAILED' || status === 'ABORTED') return 'hsl(var(--severity-critical, 0 72% 55%))';\n if (status === 'EXECUTING' || status === 'RUNNING') return 'hsl(var(--severity-medium, 38 92% 50%))';\n return 'hsl(var(--primary, 24 100% 50%))';\n};\n\nconst formatDuration = (run: AgentRun): string => {\n if (run.started_at && run.completed_at) {\n const start = Number(run.started_at);\n const end = Number(run.completed_at);\n if (!isNaN(start) && !isNaN(end)) {\n // Backend may return Unix milliseconds or seconds. Normalize to ms\n // while preserving sub-second precision.\n const toMs = (n: number) => (n > 1e12 ? n : n * 1000);\n const ms = Math.max(0, toMs(end) - toMs(start));\n if (ms < 1000) return `${(ms / 1000).toFixed(2)}s`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n }\n }\n if (run.duration) return `${run.duration.toFixed(2)}s`;\n return '';\n};\n\nconst getTimeAgo = (dateStr: string): string => {\n try {\n const ts = isNaN(Number(dateStr)) ? new Date(dateStr).getTime() : Number(dateStr) * 1000;\n if (isNaN(ts)) return dateStr;\n const diffSec = Math.max(0, Math.floor((Date.now() - ts) / 1000));\n if (diffSec < 60) return `${diffSec}s ago`;\n if (diffSec < 3600) return `${Math.floor(diffSec / 60)}m ago`;\n if (diffSec < 86400) return `${Math.floor(diffSec / 3600)}h ago`;\n return `${Math.floor(diffSec / 86400)}d ago`;\n } catch {\n return dateStr;\n }\n};\n\nconst getRunTitle = (run: AgentRun): string => {\n if (run.workflow?.name) return run.workflow.name;\n if (run.execution_argument) {\n try {\n const parsed = JSON.parse(run.execution_argument);\n if (parsed.title) return parsed.title;\n if (parsed.action) return parsed.action;\n if (parsed.name) return parsed.name;\n } catch {\n const clean = run.execution_argument.replace(/[{}\"]/g, '').trim();\n if (clean.length > 0 && clean.length < 80) return clean;\n }\n }\n return `Execution ${run.execution_id?.slice(0, 8) || '—'}`;\n};\n\nconst getRunSubtitle = (run: AgentRun): string => {\n if (run.result) {\n try {\n const p = JSON.parse(run.result);\n if (p.output && typeof p.output === 'string') {\n return p.output.length > 120 ? p.output.slice(0, 120) + '…' : p.output;\n }\n if (p.original_input && typeof p.original_input === 'string') {\n return p.original_input.length > 120 ? p.original_input.slice(0, 120) + '…' : p.original_input;\n }\n if (p.message && typeof p.message === 'string') return p.message;\n } catch {\n if (run.result.length < 120) return run.result;\n }\n }\n return run.execution_source || 'Agent execution';\n};\n\n// ── Run row ──────────────────────────────────────────────────────────────────\n\n/** Extract distinct tools/apps used in this run from results + decisions. */\nconst getRunTools = (run: AgentRun): string[] => {\n const out = new Set<string>();\n const add = (v?: string) => {\n if (!v) return;\n const s = String(v).trim();\n if (!s) return;\n // Skip the agent itself.\n if (/^(ai\\s*agent|shuffle\\s*agent|shuffle_agent)$/i.test(s)) return;\n out.add(s);\n };\n (run.results || []).forEach((r) => {\n add(r?.action?.app_name);\n if (!r?.action?.app_name) add(r?.action?.label);\n });\n (run.decisions || []).forEach((d) => {\n add(typeof d?.tool === 'string' ? d.tool : undefined);\n });\n return Array.from(out).slice(0, 6);\n};\n\ninterface RunRowProps {\n run: AgentRun;\n onClick: () => void;\n sx?: SxProps<Theme>;\n}\n\nconst AgentRunRow = ({ run, onClick, sx }: RunRowProps) => {\n const statusKey = (run.status || '').toUpperCase();\n const cfg = STATUS_CONFIG[statusKey] || STATUS_CONFIG.WAITING;\n const iconColor = getRunIconColor(run);\n const duration = formatDuration(run);\n const tools = getRunTools(run);\n\n return (\n <Box\n onClick={onClick}\n sx={[\n {\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n px: 2.5,\n py: 2,\n cursor: 'pointer',\n transition: 'background 0.15s ease, border-color 0.15s ease',\n '&:hover': {\n bgcolor: 'hsla(var(--muted) / 0.5)',\n borderColor: 'hsl(var(--muted-foreground) / 0.3)',\n },\n },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n >\n <Box\n sx={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: `${iconColor}15`,\n color: iconColor,\n flexShrink: 0,\n }}\n >\n {getRunIcon(run)}\n </Box>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.25 }}>\n <Typography\n sx={{\n fontSize: '0.9rem',\n fontWeight: 500,\n color: 'hsl(var(--foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {getRunTitle(run)}\n </Typography>\n <Box sx={{ display: 'flex', alignItems: 'center', color: cfg.color, flexShrink: 0 }}>\n {cfg.icon}\n </Box>\n </Box>\n\n <Typography\n sx={{\n fontSize: '0.78rem',\n color: 'hsl(var(--muted-foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {getRunSubtitle(run)}\n </Typography>\n\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 0.5 }}>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.7 }}>\n {run.started_at ? getTimeAgo(run.started_at) : '—'}\n </Typography>\n {duration && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>·</Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.7 }}>\n {duration}\n </Typography>\n </>\n )}\n </Box>\n </Box>\n\n {tools.length > 0 && (\n <Box\n sx={{\n display: { xs: 'none', sm: 'flex' },\n alignItems: 'center',\n gap: 0.5,\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n maxWidth: 220,\n flexShrink: 0,\n }}\n >\n {tools.map((t) => (\n <Tooltip key={t} title={t} arrow>\n <Chip\n label={t}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.68rem',\n maxWidth: 120,\n bgcolor: 'hsla(var(--muted) / 0.5)',\n color: 'hsl(var(--muted-foreground))',\n border: '1px solid hsl(var(--border))',\n '& .MuiChip-label': {\n px: 0.75,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n }}\n />\n </Tooltip>\n ))}\n </Box>\n )}\n </Box>\n );\n};\n\n// ── List ─────────────────────────────────────────────────────────────────────\n\nconst STATUS_FILTERS = [\n { label: 'All', value: '' },\n { label: 'Completed', value: 'FINISHED' },\n { label: 'Running', value: 'EXECUTING' },\n { label: 'Failed', value: 'ABORTED' },\n];\n\nexport interface AgentActivityListProps {\n /** Optional Shuffle API key. Falls back to the shared API_CONFIG. */\n apiKey?: string;\n /** Optional Shuffle backend base URL. Falls back to the shared API_CONFIG. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header. */\n orgId?: string;\n /** Called when a run row is clicked. */\n onRunClick?: (run: AgentRun) => void;\n /** Called when \"Edit\" is clicked on a selected scheduled workflow. */\n onEditWorkflow?: (info: { workflowId: string; name: string; prompt: string; apps: Array<{ name: string; id?: string }> }) => void;\n /** Show the search box. Default: true. */\n showSearchBar?: boolean;\n /** Show the status filter chips. Default: true. */\n showStatusChips?: boolean;\n /** Page size. Default: 50. */\n limit?: number;\n /** Empty-state heading. */\n emptyTitle?: string;\n /** Empty-state subtitle. */\n emptySubtitle?: string;\n /** Optional className forwarded to the root container. */\n className?: string;\n /** Style overrides merged into the root container sx. */\n sx?: SxProps<Theme>;\n /** Style overrides for the filter/search toolbar. */\n toolbarSx?: SxProps<Theme>;\n /** Style overrides for each individual run row. */\n rowSx?: SxProps<Theme>;\n}\n\nconst AgentActivityList = ({\n apiKey,\n apiBaseUrl,\n orgId,\n onRunClick,\n \n onEditWorkflow,\n showSearchBar = true,\n showStatusChips = true,\n limit = 50,\n emptyTitle = 'No agent activity found',\n emptySubtitle = 'The agent has not performed any actions yet',\n className,\n sx,\n toolbarSx,\n rowSx,\n}: AgentActivityListProps) => {\n const [runs, setRuns] = useState<AgentRun[]>([]);\n const [cursor, setCursor] = useState('');\n const [hasMore, setHasMore] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState('');\n const [searchQuery, setSearchQuery] = useState('');\n const [debouncedQuery, setDebouncedQuery] = useState('');\n const [agentWorkflows, setAgentWorkflows] = useState<AgentScheduleWorkflow[]>([]);\n const [workflowFilter, setWorkflowFilter] = useState('');\n const [stopOpen, setStopOpen] = useState(false);\n const [stopLoading, setStopLoading] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout>>();\n\n const selectedAgentWorkflow = agentWorkflows.find((w) => w.id === workflowFilter) || null;\n\n const openEditPrompt = useCallback(async () => {\n if (!workflowFilter) return;\n try {\n const { prompt, apps } = await getAgentScheduleConfig(workflowFilter, { apiKey, apiBaseUrl, orgId });\n onEditWorkflow?.({\n workflowId: workflowFilter,\n name: selectedAgentWorkflow?.name || 'Schedule',\n prompt,\n apps,\n });\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Failed to load workflow');\n }\n }, [workflowFilter, selectedAgentWorkflow, apiKey, apiBaseUrl, orgId, onEditWorkflow]);\n\n\n const confirmStop = useCallback(async () => {\n if (!workflowFilter) return;\n setStopLoading(true);\n try {\n await stopAgentSchedule(workflowFilter, { apiKey, apiBaseUrl, orgId });\n setStopOpen(false);\n // Refresh workflow list and clear the filter so list goes back to \"All\".\n const items = await listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId });\n setAgentWorkflows(items);\n setWorkflowFilter('');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Failed to stop schedule');\n } finally {\n setStopLoading(false);\n }\n }, [workflowFilter, apiKey, apiBaseUrl, orgId]);\n\n const updateSearchQuery = useCallback((q: string) => {\n setSearchQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => setDebouncedQuery(q), 350);\n }, []);\n\n useEffect(() => () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n }, []);\n\n const fetchRuns = useCallback(\n async (append = false, cursorParam = '') => {\n setIsLoading(true);\n setError(null);\n try {\n const result = await searchAgentActivity({\n limit,\n status: statusFilter,\n cursor: cursorParam,\n apiKey,\n apiBaseUrl,\n orgId,\n workflowId: workflowFilter || 'AGENT',\n });\n if (result.success) {\n setRuns((prev) => (append ? [...prev, ...result.runs] : result.runs));\n setCursor(result.cursor);\n setHasMore(!!result.cursor && result.runs.length > 0);\n } else {\n setError('Failed to fetch agent activity');\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch agent activity');\n } finally {\n setIsLoading(false);\n }\n },\n [statusFilter, limit, apiKey, apiBaseUrl, orgId, workflowFilter],\n );\n\n useEffect(() => {\n fetchRuns(false, '');\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [statusFilter, apiKey, apiBaseUrl, orgId, workflowFilter]);\n\n // Load the agentic workflow list (workflow_type = AGENT_SCHEDULE) once.\n useEffect(() => {\n let cancelled = false;\n listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId })\n .then((items) => { if (!cancelled) setAgentWorkflows(items); })\n .catch(() => { /* non-fatal — dropdown stays \"All\" only */ });\n return () => { cancelled = true; };\n }, [apiKey, apiBaseUrl, orgId]);\n\n const loadMore = useCallback(() => {\n if (cursor && !isLoading) fetchRuns(true, cursor);\n }, [cursor, isLoading, fetchRuns]);\n\n const filteredRuns = debouncedQuery\n ? runs.filter((r) => {\n const hay = [\n getRunTitle(r),\n getRunSubtitle(r),\n r.execution_id,\n r.execution_source,\n r.status,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n return hay.includes(debouncedQuery.toLowerCase());\n })\n : runs;\n\n return (\n <Box\n className={className}\n sx={[{ display: 'flex', flexDirection: 'column', gap: 2 }, ...(Array.isArray(sx) ? sx : sx ? [sx] : [])]}\n >\n {(showSearchBar || showStatusChips) && (\n <Box sx={[{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 1.5, flexWrap: 'wrap' }, ...(Array.isArray(toolbarSx) ? toolbarSx : toolbarSx ? [toolbarSx] : [])]}>\n <Select\n size=\"small\"\n value={workflowFilter}\n onChange={(e) => setWorkflowFilter(String(e.target.value))}\n displayEmpty\n renderValue={(val) => {\n if (!val) return 'All Agent runs';\n const wf = agentWorkflows.find((w) => w.id === val);\n return wf?.name || 'Selected workflow';\n }}\n sx={{\n height: 36,\n minWidth: 200,\n maxWidth: 260,\n fontSize: '0.85rem',\n bgcolor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n borderRadius: 1.5,\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--muted-foreground) / 0.3)' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n bgcolor: 'hsl(var(--card))',\n border: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n maxHeight: 320,\n },\n },\n },\n }}\n >\n <MenuItem value=\"\" sx={{ fontSize: '0.85rem' }}>All Agent runs</MenuItem>\n {agentWorkflows.map((w) => (\n <MenuItem key={w.id} value={w.id} sx={{ fontSize: '0.85rem' }}>\n {w.name}\n </MenuItem>\n ))}\n </Select>\n {showSearchBar && (\n <TextField\n placeholder=\"Search results...\"\n size=\"small\"\n value={searchQuery}\n onChange={(e) => updateSearchQuery(e.target.value)}\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon sx={{ fontSize: 18, color: 'hsl(var(--muted-foreground))' }} />\n </InputAdornment>\n ),\n },\n }}\n sx={{\n flex: 1,\n maxWidth: 280,\n minWidth: 160,\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--card))',\n borderRadius: 1.5,\n fontSize: '0.85rem',\n height: 36,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--muted-foreground) / 0.3)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n }}\n />\n )}\n {showStatusChips &&\n STATUS_FILTERS.map((f) => (\n <Chip\n key={f.value}\n label={f.label}\n size=\"small\"\n variant={statusFilter === f.value ? 'filled' : 'outlined'}\n onClick={() => setStatusFilter(f.value)}\n sx={{\n fontSize: '0.75rem',\n height: 28,\n borderColor:\n statusFilter === f.value ? 'hsl(var(--primary))' : 'hsl(var(--border))',\n bgcolor:\n statusFilter === f.value ? 'hsla(var(--primary) / 0.15)' : 'transparent',\n color:\n statusFilter === f.value ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n '&:hover': { bgcolor: 'hsl(var(--muted))' },\n }}\n />\n ))}\n {isLoading && runs.length > 0 && (\n <CircularProgress size={16} sx={{ color: 'hsl(var(--primary))', ml: 0.5 }} />\n )}\n </Box>\n )}\n\n {selectedAgentWorkflow && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n }}\n >\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {selectedAgentWorkflow.name}\n </Typography>\n {selectedAgentWorkflow.description && (\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {selectedAgentWorkflow.description}\n </Typography>\n )}\n </Box>\n <Button\n size=\"small\"\n startIcon={<Pencil size={14} />}\n onClick={openEditPrompt}\n sx={{\n height: 36,\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n color: 'hsl(var(--foreground))',\n textTransform: 'none',\n fontSize: '0.8rem',\n px: 1.5,\n '&:hover': { bgcolor: 'hsl(var(--muted))' },\n }}\n >\n Edit\n </Button>\n <Button\n size=\"small\"\n startIcon={<StopCircle size={14} />}\n onClick={() => setStopOpen(true)}\n sx={{\n height: 36,\n border: '1px solid hsl(var(--severity-critical, 0 72% 55%) / 0.4)',\n borderRadius: 1.5,\n color: 'hsl(var(--severity-critical, 0 72% 55%))',\n textTransform: 'none',\n fontSize: '0.8rem',\n px: 1.5,\n '&:hover': { bgcolor: 'hsla(var(--severity-critical, 0 72% 55%) / 0.08)' },\n }}\n >\n Stop schedule\n </Button>\n </Box>\n )}\n\n {isLoading && runs.length === 0 ? (\n <Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>\n <CircularProgress size={28} sx={{ color: 'hsl(var(--primary))' }} />\n </Box>\n ) : error ? (\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', py: 6 }}>\n <AlertCircle size={28} style={{ color: 'hsl(var(--severity-critical, 0 72% 55%))', marginBottom: 8 }} />\n <Typography\n sx={{ color: 'hsl(var(--severity-critical, 0 72% 55%))', fontSize: '0.9rem', mb: 1 }}\n >\n {error}\n </Typography>\n <Button\n size=\"small\"\n onClick={() => fetchRuns(false, '')}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none' }}\n >\n Try again\n </Button>\n </Box>\n ) : filteredRuns.length === 0 ? (\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', py: 8 }}>\n <Activity\n size={40}\n style={{ color: 'hsl(var(--muted-foreground))', marginBottom: 12 }}\n />\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.9rem' }}>\n {emptyTitle}\n </Typography>\n <Typography\n sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.8rem', mt: 0.5, opacity: 0.7 }}\n >\n {emptySubtitle}\n </Typography>\n </Box>\n ) : (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n {filteredRuns.map((run, idx) => (\n <AgentRunRow\n key={run.execution_id || idx}\n run={run}\n onClick={() => onRunClick?.(run)}\n sx={rowSx}\n />\n ))}\n {hasMore && (\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 1 }}>\n <Button\n size=\"small\"\n onClick={loadMore}\n disabled={isLoading}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none', fontSize: '0.8rem' }}\n >\n {isLoading ? <CircularProgress size={14} sx={{ mr: 1 }} /> : null}\n Load more\n </Button>\n </Box>\n )}\n </Box>\n )}\n\n <Dialog\n open={stopOpen}\n onClose={() => (stopLoading ? null : setStopOpen(false))}\n slotProps={{ paper: { sx: { bgcolor: 'hsl(var(--card))', color: 'hsl(var(--foreground))', border: '1px solid hsl(var(--border))' } } }}\n >\n <DialogTitle sx={{ fontSize: '1rem', fontWeight: 600 }}>Stop schedule?</DialogTitle>\n <DialogContent>\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n This will stop \"{selectedAgentWorkflow?.name}\" and delete the scheduled workflow. Past executions remain visible. This cannot be undone.\n </Typography>\n </DialogContent>\n <DialogActions sx={{ px: 3, pb: 2 }}>\n <Button onClick={() => setStopOpen(false)} disabled={stopLoading} sx={{ textTransform: 'none', color: 'hsl(var(--muted-foreground))' }}>\n Cancel\n </Button>\n <Button\n onClick={confirmStop}\n disabled={stopLoading}\n sx={{ textTransform: 'none', bgcolor: 'hsl(var(--severity-critical, 0 72% 55%))', color: 'hsl(var(--primary-foreground))', '&:hover': { bgcolor: 'hsla(var(--severity-critical, 0 72% 55%) / 0.9)' } }}\n >\n {stopLoading ? <CircularProgress size={16} sx={{ color: 'hsl(var(--primary-foreground))', mr: 1 }} /> : null}\n Stop schedule\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n );\n};\n\nexport default AgentActivityList;\nexport { getRunTitle, getRunSubtitle, formatDuration, getTimeAgo, STATUS_CONFIG };\n","/**\n * Agent Activity service — standalone fetcher for agent workflow executions.\n *\n * Self-contained: uses only the lib's API_CONFIG / getApiUrl / getAuthHeader\n * so it works in npm consumers without any project-side hooks or contexts.\n */\n\nimport { API_CONFIG, getApiUrl, getAuthHeader } from './api';\n\nexport interface AgentRunResult {\n action?: {\n app_name?: string;\n label?: string;\n id?: string;\n };\n result?: string;\n status?: string;\n}\n\nexport interface AgentDecision {\n title?: string;\n description?: string;\n status?: string;\n timestamp?: string | number;\n duration?: number;\n action?: string;\n result?: string;\n tool?: string;\n reason?: string;\n category?: string;\n confidence?: number;\n runs?: string | number;\n fields?: unknown;\n approval_required?: boolean;\n run_details?: unknown;\n [key: string]: unknown;\n}\n\nexport interface AgentRun {\n execution_id: string;\n workflow_id: string;\n status: string;\n started_at: string;\n completed_at?: string;\n result?: string;\n results?: AgentRunResult[];\n decisions?: AgentDecision[];\n execution_argument?: string;\n execution_source?: string;\n authorization?: string;\n workflow?: {\n name?: string;\n description?: string;\n actions?: Array<{\n app_name?: string;\n label?: string;\n }>;\n };\n duration?: number;\n}\n\nexport interface AgentActivityResponse {\n success: boolean;\n runs: AgentRun[];\n cursor: string;\n}\n\nexport interface AgentActivityParams {\n cursor?: string;\n limit?: number;\n status?: string;\n startTime?: string;\n endTime?: string;\n suborgRuns?: boolean;\n /** Override the lib's shared apiKey for this call. */\n apiKey?: string;\n /** Override the lib's shared baseUrl for this call. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header. */\n orgId?: string;\n /** Workflow ID to search. Defaults to the synthetic 'AGENT' grouping. */\n workflowId?: string;\n}\n\nconst resolveUrl = (path: string, baseUrl?: string): string =>\n baseUrl ? `${baseUrl.replace(/\\/+$/, '')}${path}` : getApiUrl(path);\n\nconst resolveHeaders = (apiKey?: string, orgId?: string): Record<string, string> => {\n const h: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : { ...getAuthHeader() };\n if (orgId) h['Org-Id'] = orgId;\n return h;\n};\n\n/**\n * Search agent workflow executions (workflow_id = \"AGENT\" by default).\n */\nexport const searchAgentActivity = async (\n params: AgentActivityParams = {}\n): Promise<AgentActivityResponse> => {\n const {\n cursor = '',\n limit = 50,\n status = '',\n startTime = '',\n endTime = '',\n suborgRuns = false,\n apiKey,\n apiBaseUrl,\n orgId,\n workflowId = 'AGENT',\n } = params;\n\n const payload = {\n workflow_id: workflowId,\n cursor,\n limit,\n status,\n start_time: startTime,\n end_time: endTime,\n suborg_runs: suborgRuns,\n };\n\n const response = await fetch(resolveUrl('/api/v1/workflows/search', apiBaseUrl), {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...resolveHeaders(apiKey, orgId),\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch agent activity: ${response.statusText}`);\n }\n\n const data = await response.json();\n return {\n success: data.success ?? false,\n runs: data.runs || [],\n cursor: data.cursor || '',\n };\n};\n\nexport interface AgentScheduleWorkflow {\n id: string;\n name: string;\n description?: string;\n}\n\n/**\n * List workflows of type AGENT_SCHEDULE — used to populate the agentic\n * workflow dropdown in the activity list.\n */\nexport const listAgentScheduleWorkflows = async (\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<AgentScheduleWorkflow[]> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const response = await fetch(resolveUrl('/api/v1/workflows', apiBaseUrl), {\n method: 'GET',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch workflows: ${response.statusText}`);\n }\n const data = await response.json();\n const list: any[] = Array.isArray(data) ? data : (data?.workflows || []);\n return list\n .filter((w) => w && w.workflow_type === 'AGENT_SCHEDULE')\n .map((w) => ({ id: w.id || w._id, name: w.name || 'Untitled', description: w.description }));\n};\n\n/** Find the AI Agent action's `input` parameter inside a workflow. */\nconst findAgentInputParam = (workflow: any): { action: any; param: any } | null => {\n const actions: any[] = workflow?.actions || [];\n for (const a of actions) {\n if ((a?.app_name || '').toLowerCase().includes('ai agent') || a?.app_id === 'shuffle_agent') {\n const params: any[] = a?.parameters || [];\n const p = params.find((x) => x?.name === 'input');\n if (p) return { action: a, param: p };\n }\n }\n return null;\n};\n\n/** Fetch a single workflow by ID. */\nexport const getWorkflow = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<any> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'GET',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n });\n if (!res.ok) throw new Error(`Failed to fetch workflow: ${res.statusText}`);\n return res.json();\n};\n\n/** Read the AI Agent prompt from a scheduled agent workflow. */\nexport const getAgentSchedulePrompt = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<{ workflow: any; prompt: string }> => {\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n return { workflow, prompt: String(found?.param?.value || '') };\n};\n\n/** Read the AI Agent prompt + selected app names from a scheduled agent\n * workflow. Apps are parsed from the AI Agent action's `app_name`\n * parameter (comma-separated list of app names). */\nexport const getAgentScheduleConfig = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<{ workflow: any; prompt: string; apps: Array<{ name: string; id?: string }> }> => {\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n const prompt = String(found?.param?.value || '');\n const action = found?.action;\n const actionParams: any[] = action?.parameters || [];\n const appNameParam = actionParams.find((x) => x?.name === 'app_name');\n const raw = String(appNameParam?.value || '');\n const apps = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((name) => ({ name }));\n return { workflow, prompt, apps };\n};\n\n/** Update the AI Agent prompt on a scheduled agent workflow. Overwrites\n * the `input` parameter with exactly what the caller passes — no merging,\n * no appended boilerplate. */\nexport const updateAgentSchedulePrompt = async (\n workflowId: string,\n newPrompt: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n if (!found) throw new Error('No AI Agent action found on this workflow');\n found.param.value = newPrompt;\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'PUT',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n body: JSON.stringify(workflow),\n });\n if (!res.ok) throw new Error(`Failed to update workflow: ${res.statusText}`);\n};\n\n/** Update both the prompt and the selected apps on a scheduled agent\n * workflow. The `apps` array is written as a comma-separated list of app\n * names to the AI Agent action's `app_name` parameter. */\nexport const updateAgentScheduleConfig = async (\n workflowId: string,\n config: { prompt: string; apps: Array<{ name: string; id?: string }> },\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n if (!found) throw new Error('No AI Agent action found on this workflow');\n found.param.value = config.prompt;\n const action = found.action;\n const appValue = (config.apps || [])\n .filter((a) => !!a?.name)\n .map((a) => a.name)\n .join(',');\n const params_: any[] = action.parameters || [];\n const appNameParam = params_.find((x) => x?.name === 'app_name');\n if (appNameParam) {\n appNameParam.value = appValue;\n } else {\n params_.push({\n name: 'app_name',\n value: appValue,\n required: true,\n description: 'Comma-separated list of app names the agent is allowed to use.',\n });\n action.parameters = params_;\n }\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'PUT',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n body: JSON.stringify(workflow),\n });\n if (!res.ok) throw new Error(`Failed to update workflow: ${res.statusText}`);\n};\n\n/** Stop the schedule entirely by deleting the wrapper workflow. */\nexport const stopAgentSchedule = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const headers = { ...resolveHeaders(apiKey, orgId) };\n\n // 1. Delete the schedule trigger(s) first so the cron stops firing.\n try {\n const workflow = await getWorkflow(workflowId, params);\n const triggers: any[] = workflow?.triggers || [];\n const scheduleIds = triggers\n .filter((t) => (t?.trigger_type || '').toUpperCase() === 'SCHEDULE')\n .map((t) => t?.id || t?.id_ || t?._id_)\n .filter(Boolean);\n await Promise.all(\n scheduleIds.map((sid) =>\n fetch(resolveUrl(`/api/v1/workflows/${workflowId}/schedule/${sid}`, apiBaseUrl), {\n method: 'DELETE',\n credentials: 'include',\n headers,\n }).catch(() => undefined),\n ),\n );\n } catch {\n // Non-fatal — proceed to delete the workflow regardless.\n }\n\n // 2. Delete the workflow itself.\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'DELETE',\n credentials: 'include',\n headers,\n });\n if (!res.ok) throw new Error(`Failed to stop schedule: ${res.statusText}`);\n};\n\n// Re-export so consumers can read base config if needed.\nexport { API_CONFIG };\n\n","/**\n * AgentExecutionDrawer — standalone right-side drawer showing the canonical\n * `AgentUI` Simple/Detailed view for an existing agent run. Pre-loads the\n * execution data via the `initialExecution` prop on `AgentUI`, so no extra\n * `/streams/results` fetch (and no `authorization` token) is required.\n *\n * Self-contained: no project hooks, contexts, or services. Drop-in for both\n * the host app (the `/agent` page) and npm consumers of the lib.\n */\n\nimport { Box, Drawer, IconButton, Tooltip, Typography } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport CloseIcon from '@mui/icons-material/Close';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\n\nimport AgentUI, { type AgentUIProps } from './AgentUI';\nimport AgentIcon from './AgentIcon';\nimport {\n STATUS_CONFIG,\n formatDuration,\n getRunTitle,\n getTimeAgo,\n} from './AgentActivityList';\nimport type { AgentRun } from './agentActivity';\n\nexport interface AgentExecutionDrawerProps {\n open: boolean;\n onClose: () => void;\n /** The run to display. When null and `open=true`, drawer renders empty. */\n run: AgentRun | null;\n /** Drawer width. Default: 720 px on >=sm, full-width on xs. */\n width?: number;\n /** Optional Shuffle API key, forwarded to the embedded AgentUI. */\n apiKey?: string;\n /** Optional Shuffle backend base URL, forwarded to the embedded AgentUI. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID, forwarded to the embedded AgentUI. */\n orgId?: string;\n /** Optional className forwarded to the Drawer Paper. */\n className?: string;\n /** Style overrides merged into the Drawer Paper sx. */\n paperSx?: SxProps<Theme>;\n /** Style overrides for the header bar. */\n headerSx?: SxProps<Theme>;\n /** Style overrides for the body container that wraps the embedded AgentUI. */\n bodySx?: SxProps<Theme>;\n /** Optional content rendered at the top of the body, before the embedded\n * AgentUI. Use this to inject a shared \"Needs attention\" / failure\n * diagnosis banner so the drawer mirrors the timeline status pill. */\n topBanner?: React.ReactNode;\n /** Handler for scheduling the loaded agent prompt from the execution view. */\n onSchedule?: AgentUIProps['onSchedule'];\n}\n\nconst AgentExecutionDrawer = ({\n open,\n onClose,\n run,\n width = 720,\n apiKey,\n apiBaseUrl,\n orgId,\n className,\n paperSx,\n headerSx,\n bodySx,\n topBanner,\n onSchedule,\n}: AgentExecutionDrawerProps) => {\n const statusKey = (run?.status || '').toUpperCase();\n const cfg = STATUS_CONFIG[statusKey] || STATUS_CONFIG.WAITING;\n const duration = run ? formatDuration(run) : '';\n\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n slotProps={{\n paper: {\n className,\n sx: [\n {\n width: { xs: '100%', sm: width },\n maxWidth: '100vw',\n bgcolor: 'hsl(var(--background))',\n color: 'hsl(var(--foreground))',\n backgroundImage: 'none',\n borderLeft: '1px solid hsl(var(--border))',\n },\n ...(Array.isArray(paperSx) ? paperSx : paperSx ? [paperSx] : []),\n ],\n },\n }}\n >\n {/* Header */}\n <Box\n sx={[\n {\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: 2.5,\n py: 1.75,\n borderBottom: '1px solid hsl(var(--border))',\n position: 'sticky',\n top: 0,\n zIndex: 2,\n bgcolor: 'hsl(var(--background))',\n },\n ...(Array.isArray(headerSx) ? headerSx : headerSx ? [headerSx] : []),\n ]}\n >\n <Box\n sx={{\n width: 36,\n height: 36,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsla(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n flexShrink: 0,\n }}\n >\n <AgentIcon size={20} />\n </Box>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, minWidth: 0 }}>\n <Typography\n sx={{\n fontSize: '0.95rem',\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {run ? getRunTitle(run) : 'Agent execution'}\n </Typography>\n {run && (\n <Box sx={{ display: 'flex', alignItems: 'center', color: cfg.color, flexShrink: 0 }}>\n {cfg.icon}\n </Box>\n )}\n </Box>\n {run && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 0.25 }}>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {cfg.label}\n </Typography>\n {run.started_at && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>\n ·\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {getTimeAgo(run.started_at)}\n </Typography>\n </>\n )}\n {duration && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>\n ·\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {duration}\n </Typography>\n </>\n )}\n </Box>\n )}\n </Box>\n {run?.execution_id && (\n <Tooltip title=\"Open in new tab\">\n <IconButton\n component=\"a\"\n href={`/agents?execution_id=${encodeURIComponent(run.execution_id)}${run.authorization ? `&authorization=${encodeURIComponent(run.authorization)}` : ''}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <OpenInNewIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n <Tooltip title=\"Close\">\n <IconButton\n onClick={onClose}\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n\n {/* Body — embedded AgentUI seeded with the pre-loaded run */}\n <Box sx={[{ flex: 1, overflowY: 'auto', pt: 3 }, ...(Array.isArray(bodySx) ? bodySx : bodySx ? [bodySx] : [])]}>\n {topBanner}\n {run ? (\n <AgentUI\n key={run.execution_id}\n initialExecution={{\n execution_id: run.execution_id,\n status: run.status,\n started_at: run.started_at ? Number(run.started_at) : undefined,\n completed_at: run.completed_at ? Number(run.completed_at) : undefined,\n results: run.results,\n workflow: run.workflow,\n authorization: run.authorization,\n }}\n readUrlParams={false}\n autoLoadApps={false}\n hideHeroIcon\n hideAppPicker\n hideAttach\n disableStartTab\n compact\n maxWidth={width - 32}\n apiKey={apiKey}\n apiBaseUrl={apiBaseUrl}\n orgId={orgId}\n onSchedule={onSchedule}\n />\n ) : null}\n </Box>\n </Drawer>\n );\n};\n\nexport default AgentExecutionDrawer;\n","/**\n * useAppLookup — Resolve an app's display name, image, categories,\n * canonical Algolia objectID and matching auth entries from just\n * an app name (or id).\n *\n * Used by the standalone section components (Authentication, Try MCP,\n * Try individual actions) so consumers only need to pass `appName`.\n *\n * Resolution order:\n * 1. Algolia `appsearch` index (best-effort, may 429)\n * 2. /api/v1/apps fallback (private + activated apps)\n * 3. /api/v1/apps/:id/config to enrich with auth schema\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport { fetchAppsViaApiConfig } from '@/Shuffle-MCPs/appsCache';\nimport { useAppAuth } from '@/Shuffle-MCPs/useAppAuth';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\n\nexport interface AppLookupResult {\n loading: boolean;\n displayName: string;\n image: string;\n categories: string[];\n /** Canonical Algolia objectID (or Shuffle private app id). */\n algoliaId: string | null;\n /** Synthesized AlgoliaSearchApp suitable for AppAuthCard. */\n algoliaApp: AlgoliaSearchApp | null;\n /** Auth entries matching this app name. */\n matchingEntries: any[];\n hasValidAuth: boolean;\n hasAnyAuth: boolean;\n authCount: number;\n authState: any;\n // Pass-through helpers from useAppAuth (so consumers do not need a second hook):\n handleAuthChange: any;\n handleTestConnection: (appId: string, authId?: string) => any;\n handleSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n refreshAuth: () => void;\n}\n\nconst norm = (s: string) => s.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\nexport function useAppLookup(appName: string | null): AppLookupResult {\n const [loading, setLoading] = useState(false);\n const [info, setInfo] = useState<{\n name: string;\n description: string;\n image: string;\n categories: string[];\n } | null>(null);\n const [algoliaId, setAlgoliaId] = useState<string | null>(null);\n\n const {\n authStates,\n authenticatedApps,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n } = useAppAuth();\n\n useEffect(() => {\n if (!appName) {\n setInfo(null);\n setAlgoliaId(null);\n return;\n }\n setLoading(true);\n setInfo(null);\n setAlgoliaId(null);\n refreshAuth();\n\n const normalizedName = norm(appName);\n const searchName = appName.replace(/_/g, ' ');\n\n (async () => {\n let id: string | null = null;\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const res = await client.search({\n requests: [{ indexName: 'appsearch', query: searchName, hitsPerPage: 10 }],\n });\n const hits = (res as any)?.results?.[0]?.hits || [];\n const match = hits.find((h: any) => h.name && norm(h.name) === normalizedName) || hits[0];\n if (match) {\n id = match.objectID;\n setAlgoliaId(id);\n setInfo({\n name: match.name || searchName,\n description: match.description || '',\n image: match.image_url || '',\n categories: match.categories || [],\n });\n }\n } catch {}\n\n let appsList: any[] | null = null;\n if (API_CONFIG.apiKey) {\n try {\n const apps = await fetchAppsViaApiConfig();\n if (Array.isArray(apps)) appsList = apps;\n } catch {}\n }\n\n if (!id && appsList) {\n const localMatch = appsList.find((a: any) => norm(a.name || '') === normalizedName);\n if (localMatch?.id) {\n id = localMatch.id;\n setAlgoliaId(localMatch.id);\n setInfo((prev) => prev ?? {\n name: localMatch.name || searchName,\n description: localMatch.description || '',\n image: localMatch.large_image || '',\n categories: localMatch.categories || [],\n });\n }\n }\n\n if (API_CONFIG.apiKey && id) {\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(id)}/config`),\n { credentials: 'include', headers: { ...getAuthHeader() } },\n );\n if (response.ok) {\n const data = await response.json();\n if (data?.name) {\n setInfo((prev) => ({\n name: data.name || prev?.name || searchName,\n description: data.description || prev?.description || '',\n image: data.large_image || prev?.image || '',\n categories: data.categories || prev?.categories || [],\n }));\n }\n }\n } catch {}\n }\n\n setInfo((prev) => prev ?? { name: searchName, description: '', image: '', categories: [] });\n setLoading(false);\n })();\n }, [appName]);\n\n const matchingEntries = useMemo(() => {\n if (!appName) return [];\n return authenticatedApps.filter(\n (auth) => auth.app?.name && norm(auth.app.name) === norm(appName),\n );\n }, [appName, authenticatedApps]);\n\n const image = useMemo(() => {\n if (info?.image) return info.image;\n for (const entry of matchingEntries) {\n const img = (entry as any).app?.large_image || (entry as any).large_image;\n if (img) return img;\n }\n return '';\n }, [info, matchingEntries]);\n\n const algoliaApp: AlgoliaSearchApp | null = useMemo(() => {\n if (!appName) return null;\n return {\n objectID: algoliaId || appName,\n name: appName,\n image_url: image,\n description: info?.description || '',\n categories: info?.categories || [],\n } as AlgoliaSearchApp;\n }, [appName, info, image, algoliaId]);\n\n const displayName = (info?.name || appName || '').replace(/_/g, ' ');\n const authState = authStates[appName || ''] || { systemId: appName || '', status: 'pending' as const, credentials: {} };\n\n return {\n loading,\n displayName,\n image,\n categories: info?.categories || [],\n algoliaId,\n algoliaApp,\n matchingEntries,\n hasValidAuth: matchingEntries.some((e) => e.validation?.valid === true),\n hasAnyAuth: matchingEntries.length > 0,\n authCount: matchingEntries.length,\n authState,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n };\n}\n"],"mappings":"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","names":["useState","useEffect","useRef","useCallback","useMemo","Tooltip","useState","useEffect","useMemo","useRef","Box","Typography","IconButton","CloseIcon","ReactMarkdown","remarkGfm","motion","useState","useCallback","useEffect","useState","useCallback","TTL_MS","cache","cacheKey","doFetch","norm","algoliasearch","url","jsx","useState","useCallback","useState","fetchAuthenticatedApps","useCallback","useEffect","Box","Typography","Avatar","jsx","jsxs","Box","Typography","motion","useState","useEffect","Box","Typography","Button","CircularProgress","Chip","IconButton","Tooltip","motion","CheckCircleIcon","Fragment","jsx","jsxs","useState","useEffect","auth","error","jsxs","Box","Fragment","jsx","Button","Typography","motion","Chip","Tooltip","IconButton","CheckCircleIcon","CircularProgress","jsx","jsxs","motion","Box","Typography","Box","Typography","motion","useState","useRef","Box","Typography","Avatar","CircularProgress","Chip","jsx","ErrorOutlineIcon","motion","ReactMarkdown","remarkGfm","jsx","jsxs","useState","useRef","Box","motion","Avatar","Typography","Chip","CircularProgress","ErrorOutlineIcon","ReactMarkdown","remarkGfm","jsx","jsxs","motion","Box","Typography","useState","useEffect","useMemo","useCallback","useRef","Box","Typography","Chip","Button","TextField","IconButton","Tooltip","Avatar","LockIcon","Fragment","jsx","jsxs","base","useMemo","useState","useCallback","useEffect","useRef","Box","Typography","Chip","TextField","Tooltip","IconButton","Button","LockIcon","Avatar","Fragment","jsx","jsxs","useState","useRef","useEffect","algoliasearch","useMemo","appId","jsxs","Box","jsx","Typography","IconButton","CloseIcon","Fragment","motion","Fragment","jsx","jsxs","useState","useRef","fetchAuthenticatedApps","useCallback","useEffect","norm","useMemo","Tooltip","useState","useEffect","Box","Typography","IconButton","Drawer","Avatar","Tooltip","CloseIcon","motion","AnimatePresence","Fragment","jsx","jsxs","useState","useEffect","norm","Drawer","Box","Typography","IconButton","CloseIcon","Tooltip","Avatar","AnimatePresence","motion","Box","Typography","Chip","jsx","jsxs","Box","Typography","Chip","useCallback","useEffect","useMemo","useRef","useState","Avatar","Box","Button","Chip","CircularProgress","IconButton","InputBase","MenuItem","Select","TextField","Tooltip","Typography","AddIcon","CheckCircleIcon","CheckIcon","PlayArrowRoundedIcon","RestartAltIcon","CloseIcon","remarkGfm","JsonView","LockIcon","base","algoliasearch","Box","IconButton","Tooltip","Typography","useEffect","useMemo","useState","deepParseJsonStrings","jsx","jsxs","useMemo","useState","useEffect","Box","Typography","Tooltip","IconButton","Fragment","jsx","jsxs","deepParseJsonStrings","CircularProgress","CheckCircleIcon","Tooltip","Box","useState","Avatar","CheckIcon","Chip","remarkGfm","IconButton","RestartAltIcon","TextField","Button","Typography","LockIcon","JsonView","resolveUrl","useCallback","resolveHeaders","useRef","useEffect","useMemo","norm","algoliasearch","apps","executionId","authorization","raw","eid","auth","m","Select","MenuItem","CloseIcon","InputBase","PlayArrowRoundedIcon","AddIcon","useEffect","useRef","useState","Box","Drawer","IconButton","Tooltip","Typography","CloseIcon","jsx","jsxs","useState","useRef","useEffect","Drawer","Box","Typography","IconButton","CloseIcon","Tooltip","useCallback","useEffect","useRef","useState","Box","Button","Chip","CircularProgress","Dialog","DialogContent","DialogTitle","MenuItem","Select","TextField","Tooltip","Typography","Server","Fragment","jsx","jsxs","Server","Box","Typography","Tooltip","Chip","useState","useRef","useCallback","useEffect","Select","MenuItem","TextField","CircularProgress","Button","Dialog","DialogTitle","DialogContent","Box","Drawer","IconButton","Tooltip","Typography","CloseIcon","OpenInNewIcon","Fragment","jsx","jsxs","Drawer","Box","Typography","Tooltip","IconButton","OpenInNewIcon","CloseIcon","useEffect","useMemo","useState","norm","useState","useEffect","algoliasearch","useMemo"]}
1
+ {"version":3,"sources":["../index.ts","../ShuffleMCP.tsx","../AppDetailDrawer.tsx","../toast.ts","../datastore.ts","../useAppAuth.ts","../IntegrationStatus.tsx","../authenticatedApps.ts","../auth-utils.ts","../AppDetailContext.tsx","../ingestionDetection.ts","../AppTitleHeader.tsx","../AppAuthSection.tsx","../AppAuthConfig.tsx","../AppFallbackIcon.tsx","../TryMcpSection.tsx","../AppMcpChat.tsx","../AgentIcon.tsx","../SingulActionsPreview.tsx","../SegmentedControl.tsx","../AppSearchDrawer.tsx","../ShufflePipelinesBanner.tsx","../AgentUI.tsx","../resolveApp.ts","../agentRun.ts","../scheduleHint.ts","../AgentRunDiagnosisBanner.tsx","../AgentDiagnosisCtas.tsx","../agentDiagnosis.ts","../AgentRunDrawer.tsx","../AgentActivityList.tsx","../agentActivity.ts","../AgentExecutionDrawer.tsx","../useAppLookup.ts"],"sourcesContent":["/**\n * Local Singul Library — fully self-contained.\n * No host-app `@/` imports remain inside this folder (assets aside).\n */\n\n// Side-effect import: ensures shadcn-style token fallbacks (--card, --background,\n// --border, --foreground, --muted, --primary, etc.) are always defined when any\n// lib component is used standalone in a host app that does NOT define those\n// CSS custom properties. Host overrides still win (defaults use :where(:root),\n// specificity 0).\nimport './shuffle-mcp.css';\n\nexport { ShuffleMCP, default } from './ShuffleMCP';\nexport type { ShuffleMCPHandle } from './ShuffleMCP';\nexport { default as AppDetailDrawer } from './AppDetailDrawer';\nexport { default as AppSearchDrawer } from './AppSearchDrawer';\nexport { default as ShufflePipelinesBanner } from './ShufflePipelinesBanner';\nexport { default as AppTitleHeader } from './AppTitleHeader';\nexport type { AppTitleHeaderProps } from './AppTitleHeader';\nexport { default as AppAuthSection } from './AppAuthSection';\nexport type { AppAuthSectionProps } from './AppAuthSection';\nexport { default as TryMcpSection } from './TryMcpSection';\nexport type { TryMcpSectionProps } from './TryMcpSection';\nexport { default as SingulActionsPreview } from './SingulActionsPreview';\nexport { default as AgentUI } from './AgentUI';\nexport type { AgentUIProps, AgentUIApp } from './AgentUI';\nexport { default as AgentRunDrawer } from './AgentRunDrawer';\nexport type { AgentRunDrawerProps, AgentRunDrawerTab } from './AgentRunDrawer';\nexport { default as AgentActivityList } from './AgentActivityList';\nexport type { AgentActivityListProps } from './AgentActivityList';\nexport { default as AgentExecutionDrawer } from './AgentExecutionDrawer';\nexport type { AgentExecutionDrawerProps } from './AgentExecutionDrawer';\nexport { default as AgentRunDiagnosisBanner } from './AgentRunDiagnosisBanner';\nexport {\n parseRunResult,\n getFailureInfo,\n hasOutputWarning,\n diagnoseOutputWarning,\n} from './agentDiagnosis';\nexport type {\n DiagnosableRun,\n DiagnosisEvidence,\n OutputDiagnosis,\n} from './agentDiagnosis';\nexport { searchAgentActivity } from './agentActivity';\nexport type {\n AgentRun,\n AgentRunResult,\n AgentDecision,\n AgentActivityResponse,\n AgentActivityParams,\n} from './agentActivity';\nexport { useAppLookup } from './useAppLookup';\nexport type { AppLookupResult } from './useAppLookup';\nexport {\n resolveApp,\n resolveApps,\n seedResolvedApp,\n invalidateResolvedApps,\n} from './resolveApp';\nexport type { ResolvedApp } from './resolveApp';\nexport { IntegrationStatus, refreshAllIntegrationStatus } from './IntegrationStatus';\nexport { useAppAuth } from './useAppAuth';\nexport { AppDetailProvider, useAppDetail, useAppDetailOptional } from './AppDetailContext';\nexport { API_CONFIG, getApiUrl, getAuthHeader, isCloud, isOnprem, isCloudDomain } from './api';\nexport { setToastImpl, toast } from './toast';\nexport type {\n AlgoliaSearchApp,\n AppSelectedEvent,\n AppAuthentication,\n CustomStyles,\n ShuffleMCPProps,\n} from './shuffle-mcp.helpers';\n\n// ---------------------------------------------------------------------------\n// Re-exports consumed by @shuffleio/shuffle-core (and other downstream apps).\n// Keep this block in sync when Shuffle-Core starts importing new symbols.\n// ---------------------------------------------------------------------------\n\n// AgentIcon\nexport { default as AgentIcon } from './AgentIcon';\n\n// Auth configuration UI + types\nexport { AppAuthConfig, AppAuthCard } from './AppAuthConfig';\nexport type {\n AuthStatus,\n AppAuthState,\n ApiAuthEntry,\n AppAuthCardProps,\n} from './AppAuthConfig';\n\n// Datastore helpers\nexport {\n setRuntimeOrgId,\n setDatastoreItem,\n setDatastoreItems,\n getDatastoreItem,\n getDatastoreItemPublic,\n getDatastoreByCategory,\n deleteDatastoreItem,\n deleteDatastoreItems,\n DATASTORE_CATEGORIES,\n} from './datastore';\nexport type {\n DatastoreItem,\n CategoryAutomation,\n CategoryConfig,\n DatastoreResponse,\n DatastoreDiagnostics,\n} from './datastore';\n\n// Ingestion detection\nexport {\n EMAIL_APP_PATTERNS,\n CASES_PATTERNS,\n EDR_PATTERNS,\n SIEM_PATTERNS,\n THREAT_INTEL_PATTERNS,\n COMMUNICATION_PATTERNS_NAMES,\n VULN_SCANNER_PATTERNS,\n INGEST_TICKETS_WORKFLOW_NAME,\n FORWARD_TICKETS_WORKFLOW_NAME,\n isEmailApp,\n isThreatIntelApp,\n isVulnScannerApp,\n isIngestionApp,\n normalizeAppName,\n getIngestionCategory,\n extractWorkflowAppNames,\n extractValidatedIngestionApps,\n findIngestTicketsWorkflow,\n findForwardTicketsWorkflow,\n isWorkflowScheduleStopped,\n} from './ingestionDetection';\nexport type {\n IngestionCategory,\n ValidatedIngestionApp,\n} from './ingestionDetection';\n\n// Apps cache\nexport {\n fetchApps,\n fetchAppsViaApiConfig,\n invalidateAppsCache,\n} from './appsCache';\nexport type { FetchAppsOptions } from './appsCache';\n","/**\n * Local Singul Library - React Component\n * This is a local copy for development. Changes here should be merged back to:\n * https://github.com/Shuffle/singul.js\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo, useImperativeHandle } from 'react';\nimport { algoliasearch, SearchClient } from 'algoliasearch';\nimport { Tooltip } from '@mui/material';\nimport type { AlgoliaSearchApp, AppSelectedEvent, ShuffleMCPProps, AppAuthentication } from './shuffle-mcp.helpers';\nimport AppDetailDrawer from './AppDetailDrawer';\nimport './shuffle-mcp.css';\nimport { fetchApps } from './appsCache';\nimport { AppFallbackIcon } from './AppFallbackIcon';\nimport { SegmentedControl } from './SegmentedControl';\n\nconst DEFAULT_ALGOLIA_APP_ID = 'JNSS5CFDZZ';\nconst DEFAULT_ALGOLIA_API_KEY = '33e4e3564f4f060e96e0531957bed552';\nconst DEFAULT_ALGOLIA_INDEX = 'appsearch';\nconst EMPTY_SELECTED_APPS: AlgoliaSearchApp[] = [];\n\nexport interface ShuffleMCPHandle {\n search: (query: string) => void;\n clear: () => void;\n}\n\nexport const ShuffleMCP = React.forwardRef<ShuffleMCPHandle, ShuffleMCPProps>(({\n authToken,\n orgId,\n placeholder = 'Search apps...',\n layout = 'list',\n gridColumns = 3,\n showDescription = false,\n showCategories = false,\n showCheckbox = false,\n multiSelect = false,\n selectedApps = EMPTY_SELECTED_APPS,\n preventDefault = false,\n inline = false,\n initialQuery = '',\n initialFilterQuery,\n hitsPerPage = 15,\n apiKey,\n apiBaseUrl = 'https://shuffler.io',\n authPath = '/api/v1/apps/authentication',\n appAuthPath = '/appauth',\n privateAppsPath = '/api/v1/apps',\n disablePrivateApps = false,\n showSourceFilter = true,\n singulBaseUrl = 'https://singul.io',\n hideAuthStatus = false,\n authenticatedApps: externalAuthenticatedApps,\n pinnedApps,\n algoliaAppId = DEFAULT_ALGOLIA_APP_ID,\n algoliaApiKey = DEFAULT_ALGOLIA_API_KEY,\n algoliaIndexName = DEFAULT_ALGOLIA_INDEX,\n customStyles = {},\n className = '',\n renderItem,\n renderEmptyState,\n renderLoadingState,\n onAppSelected,\n onSelectionChange,\n onSearchChange,\n}, ref) => {\n const [query, setQuery] = useState(initialQuery);\n const [results, setResults] = useState<AlgoliaSearchApp[]>([]);\n const [privateApps, setPrivateApps] = useState<AlgoliaSearchApp[]>([]);\n const [sourceFilter, setSourceFilter] = useState<'all' | 'public' | 'private' | 'authenticated'>('all');\n const [isLoading, setIsLoading] = useState(false);\n const [searchError, setSearchError] = useState<{ rateLimited: boolean; message: string } | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [internalSelectedApps, setInternalSelectedApps] = useState<AlgoliaSearchApp[]>(selectedApps);\n const [authenticatedApps, setAuthenticatedApps] = useState<AppAuthentication[]>(externalAuthenticatedApps || []);\n const [drawerApp, setDrawerApp] = useState<AlgoliaSearchApp | null>(null);\n const hasInitialized = useRef(false);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const searchClient = useRef<SearchClient | null>(null);\n\n // Fetch authenticated apps when apiKey is provided\n const fetchAuthenticatedApps = useCallback(async () => {\n if (!apiKey) return;\n try {\n const response = await fetch(`${apiBaseUrl}${authPath}`, {\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n ...(orgId ? { 'Org-Id': orgId } : {}),\n },\n });\n if (response.ok) {\n const result = await response.json();\n const authData = result.data || result;\n if (Array.isArray(authData)) {\n setAuthenticatedApps(authData);\n }\n }\n } catch (error) {\n console.error('Failed to fetch authenticated apps:', error);\n }\n }, [apiKey, apiBaseUrl, authPath, orgId]);\n\n useEffect(() => {\n fetchAuthenticatedApps();\n }, [fetchAuthenticatedApps]);\n\n // Fetch the user's private apps from /api/v1/apps when apiKey is provided.\n // These get merged into search results so users can find their own apps too.\n useEffect(() => {\n if (disablePrivateApps) {\n setPrivateApps([]);\n return;\n }\n const fetchPrivateApps = async () => {\n try {\n const apps = await fetchApps({\n baseUrl: apiBaseUrl,\n path: privateAppsPath,\n apiKey: apiKey || null,\n orgId: orgId || null,\n });\n // Normalize to AlgoliaSearchApp shape, tagged as 'private' source.\n const normalized: AlgoliaSearchApp[] = apps.map((a: any) => ({\n name: a.name || '',\n description: a.description || '',\n objectID: a.id || a.objectID || `private-${a.name}`,\n creator: a.owner || a.creator || '',\n app_version: a.app_version || '1.0.0',\n image_url: a.large_image || a.image_url || '',\n time_edited: a.edited || 0,\n generated: !!a.generated,\n invalid: !!a.invalid,\n priority: a.priority || 0,\n actions: Array.isArray(a.actions) ? a.actions.length : (a.actions || 0),\n tags: a.tags || [],\n accessible_by: a.accessible_by || [],\n categories: a.categories || [],\n action_labels: a.action_labels || [],\n triggers: a.triggers || [],\n verified: !!a.verified,\n source: 'private',\n }));\n setPrivateApps(normalized);\n } catch (error) {\n console.error('Failed to fetch private apps:', error);\n }\n };\n fetchPrivateApps();\n }, [apiKey, apiBaseUrl, privateAppsPath, disablePrivateApps, orgId]);\n\n // Auto-select validated apps when they're loaded (validated = tests ran successfully)\n useEffect(() => {\n if (authenticatedApps.length > 0 && results.length > 0) {\n const validatedApps = authenticatedApps.filter(auth => auth.validation?.valid);\n const appsToAutoSelect = results.filter(app => \n validatedApps.some(auth => auth.app.name.toLowerCase() === app.name.toLowerCase())\n );\n \n if (appsToAutoSelect.length > 0) {\n const newSelection = [...internalSelectedApps];\n appsToAutoSelect.forEach(app => {\n if (!newSelection.some(a => a.objectID === app.objectID)) {\n newSelection.push(app);\n }\n });\n if (newSelection.length !== internalSelectedApps.length) {\n setInternalSelectedApps(newSelection);\n onSelectionChange?.(newSelection);\n }\n }\n }\n }, [authenticatedApps, results]);\n\n // Sync external authenticatedApps\n useEffect(() => {\n if (externalAuthenticatedApps) {\n setAuthenticatedApps(externalAuthenticatedApps);\n }\n }, [externalAuthenticatedApps]);\n\n // Initialize Algolia client and run initial search\n useEffect(() => {\n searchClient.current = algoliasearch(algoliaAppId, algoliaApiKey);\n \n // Run initial search after client is ready\n if (!hasInitialized.current) {\n hasInitialized.current = true;\n const searchTerm = initialQuery || initialFilterQuery || '';\n setTimeout(() => {\n if (searchClient.current) {\n performSearch(searchTerm);\n onSearchChange?.(initialQuery); // Only report the visible query\n }\n }, 100);\n }\n }, []);\n\n // Sync external selectedApps\n useEffect(() => {\n setInternalSelectedApps(selectedApps);\n }, [selectedApps]);\n\n // Handle click outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setSelectedIndex(-1);\n }\n };\n\n document.addEventListener('click', handleClickOutside);\n return () => document.removeEventListener('click', handleClickOutside);\n }, []);\n\n // Check if an app is configured (found in authentication API with active: true)\n const isAppConfigured = useCallback((app: AlgoliaSearchApp) => {\n return authenticatedApps.some(\n auth => auth.app.name.toLowerCase() === app.name.toLowerCase() && auth.active === true\n );\n }, [authenticatedApps]);\n\n // Check if an app is validated/tested (validation.valid is true)\n const isAppValidated = useCallback((app: AlgoliaSearchApp) => {\n return authenticatedApps.some(\n auth => auth.app.name.toLowerCase() === app.name.toLowerCase() && auth.validation?.valid === true\n );\n }, [authenticatedApps]);\n\n // Get auth state for an app\n const getAppAuthState = useCallback((app: AlgoliaSearchApp) => {\n return {\n configured: isAppConfigured(app),\n validated: isAppValidated(app),\n };\n }, [isAppConfigured, isAppValidated]);\n\n // Perform search\n const performSearch = useCallback(async (searchQuery: string) => {\n if (!searchClient.current) {\n return;\n }\n\n setIsLoading(true);\n try {\n const searchResult = await searchClient.current.searchSingleIndex({\n indexName: algoliaIndexName,\n searchParams: {\n query: searchQuery || '', // Empty string gets top results\n hitsPerPage,\n },\n });\n\n const hits = (searchResult.hits as AlgoliaSearchApp[]).map(h => ({ ...h, source: 'public' as const }));\n setResults(hits);\n setSearchError(null);\n // Open dropdown if we got Algolia hits OR we have private apps to show\n setIsOpen(hits.length > 0 || privateApps.length > 0);\n setSelectedIndex(-1);\n } catch (error: any) {\n // Algolia rate-limit (429) or network error: don't blank out the dropdown\n // if we still have private apps to show from /api/v1/apps.\n console.error('Search failed:', error);\n const status: number | undefined = error?.status ?? error?.statusCode ?? error?.response?.status;\n const rawMessage: string = String(error?.message || error?.name || '');\n const rateLimited = status === 429 || /429|rate.?limit|too many requests/i.test(rawMessage);\n setSearchError({\n rateLimited,\n message: rateLimited\n ? 'Search is temporarily rate limited by Algolia. Please wait a moment and try again.'\n : 'Search is temporarily unavailable. Please try again in a moment.',\n });\n setResults([]);\n setIsOpen(privateApps.length > 0);\n } finally {\n setIsLoading(false);\n }\n }, [hitsPerPage, algoliaIndexName, privateApps.length]);\n\n // Expose imperative methods via ref\n useImperativeHandle(ref, () => ({\n search: (searchQuery: string) => {\n setQuery(searchQuery);\n onSearchChange?.(searchQuery);\n performSearch(searchQuery);\n },\n clear: () => {\n setQuery('');\n performSearch(''); // Show top results when cleared\n },\n getQuery: () => query,\n }), [performSearch, onSearchChange, query]);\n\n // Handle input change\n const handleInputChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.target.value;\n setQuery(value);\n setSelectedIndex(-1);\n onSearchChange?.(value);\n\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n\n debounceTimer.current = setTimeout(() => {\n performSearch(value);\n }, 300);\n }, [performSearch, onSearchChange]);\n\n // Handle app selection\n const selectApp = useCallback((app: AlgoliaSearchApp) => {\n const handoffToken = apiKey || authToken || '';\n const authUrl = `${apiBaseUrl}${appAuthPath}?app_id=${app.objectID}&auth=${handoffToken}&source=shuffle${orgId ? `&org_id=${encodeURIComponent(orgId)}` : ''}`;\n\n if (multiSelect) {\n const isAlreadySelected = internalSelectedApps.some((a) => a.objectID === app.objectID);\n const newSelection = isAlreadySelected\n ? internalSelectedApps.filter((a) => a.objectID !== app.objectID)\n : [...internalSelectedApps, app];\n\n setInternalSelectedApps(newSelection);\n onSelectionChange?.(newSelection);\n } else {\n // If consumer wired up onAppSelected, defer entirely to them.\n if (onAppSelected) {\n onAppSelected({ app, authUrl });\n if (!preventDefault) {\n window.open(authUrl, '_blank');\n }\n } else if (!preventDefault) {\n // New default: open built-in side drawer with the app + its existing\n // authentications, instead of popping a new tab to shuffler.io.\n setDrawerApp(app);\n }\n\n setIsOpen(false);\n }\n }, [authToken, apiKey, apiBaseUrl, appAuthPath, orgId, multiSelect, internalSelectedApps, onAppSelected, onSelectionChange, preventDefault]);\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (!isOpen) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setSelectedIndex((prev) => Math.min(prev + 1, displayResults.length - 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n setSelectedIndex((prev) => Math.max(prev - 1, -1));\n break;\n case 'Enter':\n event.preventDefault();\n if (selectedIndex >= 0 && displayResults[selectedIndex]) {\n selectApp(displayResults[selectedIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n setIsOpen(false);\n setSelectedIndex(-1);\n inputRef.current?.blur();\n break;\n }\n }, [isOpen, results, selectedIndex, selectApp]);\n\n // Check if app is selected. Matches by objectID first, then falls back to\n // normalized name so callers can pre-select apps without knowing the\n // canonical Algolia objectID (e.g. AgentUI's chosenApps).\n const isAppSelected = useCallback((app: AlgoliaSearchApp) => {\n const norm = (s?: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const target = norm(app.name);\n return internalSelectedApps.some(\n (a) => a.objectID === app.objectID || (target && norm(a.name) === target),\n );\n }, [internalSelectedApps]);\n\n\n // Filter the user's private apps client-side by the current query.\n const filteredPrivateApps = useMemo(() => {\n if (privateApps.length === 0) return [];\n const q = query.trim().toLowerCase();\n if (!q) return privateApps;\n return privateApps.filter(a =>\n a.name.toLowerCase().includes(q) ||\n (a.description || '').toLowerCase().includes(q) ||\n (a.categories || []).some(c => c.toLowerCase().includes(q))\n );\n }, [privateApps, query]);\n\n // Merge private + public apps, apply source filter, prepend pinned, dedupe by name.\n const displayResults = useMemo(() => {\n const norm = (n: string) => (n || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n\n let merged: AlgoliaSearchApp[];\n if (sourceFilter === 'public') {\n merged = results;\n } else if (sourceFilter === 'private') {\n merged = filteredPrivateApps;\n } else if (sourceFilter === 'authenticated') {\n const privateNames = new Set(filteredPrivateApps.map(a => norm(a.name)));\n const publicOnly = results.filter(a => !privateNames.has(norm(a.name)));\n merged = [...filteredPrivateApps, ...publicOnly].filter(isAppConfigured);\n } else {\n // 'all' — private apps first (your own tools win), then public, deduped by name\n const privateNames = new Set(filteredPrivateApps.map(a => norm(a.name)));\n const publicOnly = results.filter(a => !privateNames.has(norm(a.name)));\n merged = [...filteredPrivateApps, ...publicOnly];\n }\n\n if (!pinnedApps || pinnedApps.length === 0) return merged;\n const pinnedNames = new Set(pinnedApps.map(a => norm(a.name)));\n return [...pinnedApps, ...merged.filter(a => !pinnedNames.has(norm(a.name)))];\n }, [pinnedApps, results, filteredPrivateApps, sourceFilter, isAppConfigured]);\n\n // Get grid columns style\n const getGridColumnsStyle = useMemo(() => {\n if (layout !== 'grid') return {};\n \n const cols = typeof gridColumns === 'number' ? gridColumns : gridColumns.md || 3;\n return { '--singul-grid-columns': cols } as React.CSSProperties;\n }, [layout, gridColumns]);\n\n // Render individual app item\n const renderAppItem = (app: AlgoliaSearchApp, index: number) => {\n const selected = isAppSelected(app);\n const isHighlighted = index === selectedIndex;\n const authState = getAppAuthState(app);\n\n // Use custom render if provided\n if (renderItem) {\n return (\n <div\n key={app.objectID}\n onClick={() => selectApp(app)}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {renderItem(app, selected, () => selectApp(app), authState)}\n </div>\n );\n }\n\n // Show both chips (configured/not configured AND tested/not tested)\n return (\n <div\n key={app.objectID}\n className={`singul-dropdown-item ${selected ? 'singul-selected' : ''} ${authState.validated ? 'singul-validated' : ''} ${authState.configured ? 'singul-configured' : ''}`}\n data-app-name={app.name}\n data-object-id={app.objectID}\n style={{\n ...customStyles.dropdownItem,\n ...(selected ? customStyles.selectedItem : {}),\n }}\n onClick={() => selectApp(app)}\n >\n <div className=\"singul-app-info\" style={customStyles.appInfo}>\n <div style={{ position: 'relative', flexShrink: 0 }}>\n <AppFallbackIcon\n name={app.name || ''}\n imageUrl={app.image_url}\n size={28}\n className=\"singul-app-icon\"\n style={customStyles.appIcon as React.CSSProperties}\n />\n {/* Color-coded status dot: green=tested, yellow=configured, blue=activated/selected, gray=inactive */}\n {!hideAuthStatus && (\n <span\n className={`singul-status-dot ${\n authState.validated ? 'singul-dot-validated' :\n authState.configured ? 'singul-dot-configured' :\n selected ? 'singul-dot-activated' :\n 'singul-dot-inactive'\n }`}\n />\n )}\n </div>\n <div className=\"singul-app-details\" style={customStyles.appDetails}>\n <span\n className=\"singul-app-name\"\n style={{\n ...customStyles.appName,\n ...(!app.name || /^untitled$/i.test(app.name.trim())\n ? { fontStyle: 'italic', color: 'hsl(var(--muted-foreground))' }\n : {}),\n }}\n >\n {!app.name || /^untitled$/i.test(app.name.trim())\n ? 'Untitled app'\n : app.name.replace(/_/g, ' ')}\n {app.source === 'private' && (\n <Tooltip\n title=\"Private apps are apps you have activated in your organization, or your own custom apps — not just from the public Algolia catalog.\"\n arrow\n enterDelay={100}\n enterNextDelay={100}\n placement=\"top\"\n slotProps={{ popper: { style: { zIndex: 10000 } } }}\n >\n <span className=\"singul-private-badge\">Private</span>\n </Tooltip>\n )}\n </span>\n {showDescription && app.description && (\n <span className=\"singul-app-description\" style={customStyles.appDescription}>\n {app.description}\n </span>\n )}\n {showCategories && app.categories?.[0] && (\n <span className=\"singul-app-category\" style={customStyles.appCategory}>\n {app.categories[0]}\n </span>\n )}\n </div>\n {showCheckbox && (\n <div\n className={`singul-checkbox ${selected ? 'singul-checked' : ''}`}\n style={selected ? customStyles.checkboxChecked : customStyles.checkbox}\n >\n {selected && (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )}\n </div>\n )}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={containerRef}\n className={`singul-container ${inline ? 'singul-inline' : ''} ${className}`}\n style={customStyles.container}\n >\n <div className=\"singul-search-bar-container\">\n <div className=\"singul-search-input-wrapper\" style={customStyles.inputWrapper}>\n <input\n ref={inputRef}\n type=\"text\"\n className=\"singul-search-input\"\n style={customStyles.input}\n placeholder={placeholder}\n value={query}\n onChange={handleInputChange}\n onFocus={() => {\n if (!inline && query.trim() && results.length > 0) {\n setIsOpen(true);\n }\n }}\n onKeyDown={handleKeyDown}\n autoComplete=\"off\"\n />\n <div className=\"singul-search-icon\" style={customStyles.searchIcon}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </svg>\n </div>\n {isLoading && (\n <div className=\"singul-loading-spinner\" style={customStyles.loadingSpinner}>\n {renderLoadingState ? (\n renderLoadingState()\n ) : (\n <div className=\"singul-spinner\" style={customStyles.spinner} />\n )}\n </div>\n )}\n </div>\n\n {/* Source filter — only shown when private apps are loaded */}\n {showSourceFilter && privateApps.length > 0 && (\n <div style={{ margin: '12px 0 8px' }}>\n <SegmentedControl\n ariaLabel=\"Filter by app source\"\n value={sourceFilter}\n onChange={(v) => setSourceFilter(v as typeof sourceFilter)}\n options={[\n { value: 'all', label: 'All', count: results.length + filteredPrivateApps.length, title: 'All available apps — both the public catalog and your private apps.' },\n { value: 'public', label: 'Public', count: results.length, title: 'Public apps from the Shuffle catalog (powered by Algolia).' },\n { value: 'private', label: 'Private', count: filteredPrivateApps.length, title: 'Private apps are apps you have activated in your organization, or your own custom apps — not just from the public Algolia catalog.' },\n { value: 'authenticated', label: 'Authenticated', count: [...filteredPrivateApps, ...results].filter((a, i, arr) => arr.findIndex(x => x.name?.toLowerCase() === a.name?.toLowerCase()) === i).filter(isAppConfigured).length, title: 'Apps you have authenticated and that are ready to use.' },\n ]}\n />\n </div>\n )}\n\n {/* Inline Results Container */}\n {inline && (\n <div\n className={`singul-results-container ${layout === 'grid' ? 'singul-results-grid' : ''}`}\n style={{\n ...customStyles.resultsContainer,\n ...getGridColumnsStyle,\n ...(layout === 'grid' ? { display: 'grid' } : {}),\n }}\n >\n {displayResults.length > 0 ? (\n <>\n {displayResults.map((app, index) => renderAppItem(app, index))}\n <div className=\"singul-end-of-results\" style={{\n padding: '10px 16px',\n color: 'hsl(var(--foreground) / 0.3)',\n textAlign: 'center' as const,\n fontSize: '11px',\n gridColumn: '1 / -1',\n }}>\n Can't find what you're looking for? Try a different search term.\n </div>\n </>\n ) : query.trim() ? (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n {searchError ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'center', color: searchError.rateLimited ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))' }}>\n <strong style={{ fontSize: 13 }}>\n {searchError.rateLimited ? 'Algolia rate limit reached (429)' : 'Search unavailable'}\n </strong>\n <span style={{ fontSize: 12, color: 'hsl(var(--muted-foreground))' }}>{searchError.message}</span>\n </div>\n ) : renderEmptyState ? (\n renderEmptyState()\n ) : (\n <>No integrations match \"{query}\". Try searching for a different app or category.</>\n )}\n </div>\n ) : (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n {searchError ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'center', color: searchError.rateLimited ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))' }}>\n <strong style={{ fontSize: 13 }}>\n {searchError.rateLimited ? 'Algolia rate limit reached (429)' : 'Search unavailable'}\n </strong>\n <span style={{ fontSize: 12, color: 'hsl(var(--muted-foreground))' }}>{searchError.message}</span>\n </div>\n ) : (\n <>Start typing to search integrations...</>\n )}\n </div>\n )}\n </div>\n )}\n\n {/* Dropdown Results (non-inline mode) */}\n {!inline && isOpen && (\n <div\n className={`singul-dropdown ${layout === 'grid' ? 'singul-dropdown-grid' : ''}`}\n style={{\n ...customStyles.dropdown,\n ...getGridColumnsStyle,\n ...(layout === 'grid' ? { display: 'grid' } : {}),\n }}\n >\n {displayResults.length > 0 ? (\n displayResults.map((app, index) => renderAppItem(app, index))\n ) : (\n <div className=\"singul-empty-state\" style={customStyles.emptyState}>\n {searchError ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'center', color: searchError.rateLimited ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))' }}>\n <strong style={{ fontSize: 13 }}>\n {searchError.rateLimited ? 'Algolia rate limit reached (429)' : 'Search unavailable'}\n </strong>\n <span style={{ fontSize: 12, color: 'hsl(var(--muted-foreground))' }}>{searchError.message}</span>\n </div>\n ) : renderEmptyState ? (\n renderEmptyState()\n ) : (\n <>No apps found for \"{query}\"</>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Built-in app config drawer — same drawer used by /incidents Add ingestion source */}\n {drawerApp && (\n <AppDetailDrawer\n open={true}\n appName={drawerApp.name}\n anchor=\"right\"\n width={560}\n onClose={() => setDrawerApp(null)}\n onRefresh={fetchAuthenticatedApps}\n />\n )}\n </div>\n );\n});\n\nShuffleMCP.displayName = 'ShuffleMCP';\n\nexport default ShuffleMCP;\n","/**\n * AppDetailDrawer — Shows app detail content (header, auth, MCP chat, API viewer)\n * inside a drawer. Used from alluvial diagrams and the app search drawer.\n *\n * Accepts either an app name (fetches data) or pre-loaded app info.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport {\n Download,\n Forward,\n CheckCircle2 as CheckCircleIcon,\n X as CloseIcon,\n AlertCircle as ErrorOutlineIcon,\n ExternalLink as OpenInNewIcon,\n Play as PlayArrowIcon\n} from 'lucide-react';\nimport { getDatastoreByCategory, DATASTORE_CATEGORIES } from '@/Shuffle-MCPs/datastore';\nimport {\n Box,\n Typography,\n Avatar,\n Chip,\n IconButton,\n Skeleton,\n Button,\n Divider,\n Drawer,\n Autocomplete,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n} from '@mui/material';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { motion } from 'framer-motion';\nimport { AppAuthCard } from '@/Shuffle-MCPs/AppAuthConfig';\nimport AppMcpChat from '@/Shuffle-MCPs/AppMcpChat';\nimport ApiCallViewer from '@/Shuffle-MCPs/ApiCallViewer';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\nimport { useAppAuth } from '@/Shuffle-MCPs/useAppAuth';\nimport { API_CONFIG, getApiUrl, getAuthHeader, getTrackedOrgId } from '@/Shuffle-MCPs/api';\nimport { fetchAppsViaApiConfig } from '@/Shuffle-MCPs/appsCache';\nimport AppTitleHeader from './AppTitleHeader';\nimport AppAuthSection from './AppAuthSection';\nimport TryMcpSection from './TryMcpSection';\nimport SingulActionsPreview from './SingulActionsPreview';\n// AuthContext detached — consumers can pass `isAuthenticated` as a prop. Defaults to true.\n\ninterface AppInfo {\n name: string;\n description: string;\n large_image?: string;\n categories?: string[];\n authentication?: {\n type?: string;\n parameters?: { id: string; name: string; description: string; example: string; required: boolean }[];\n };\n}\n\n/** Collapsible markdown description */\nconst CollapsibleDescription = ({ description }: { description: string }) => {\n const [expanded, setExpanded] = useState(false);\n return (\n <Box\n onClick={() => setExpanded(prev => !prev)}\n sx={{\n cursor: 'pointer',\n position: 'relative',\n ...(!expanded && {\n maxHeight: '5em',\n overflow: 'hidden',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: 32,\n background: 'linear-gradient(transparent, hsl(var(--card)))',\n pointerEvents: 'none',\n },\n }),\n '& p': { fontSize: '0.78rem', lineHeight: 1.5, color: 'hsl(var(--muted-foreground))', m: 0, '&:not(:last-child)': { mb: 1 } },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': { fontSize: '0.7rem', fontFamily: \"'JetBrains Mono', monospace\", bgcolor: 'hsl(var(--muted))', px: 0.5, borderRadius: 0.5 },\n '& ul, & ol': { pl: 2, fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{description}</ReactMarkdown>\n {!expanded && (\n <Typography sx={{ fontSize: '0.68rem', color: 'hsl(var(--primary))', mt: 0.5, fontWeight: 500 }}>Show more…</Typography>\n )}\n </Box>\n );\n};\n\n/**\n * Singul standard actions catalog, keyed by lowercase category fragment.\n * Mirrors the canonical action names exposed by https://singul.io —\n * each name becomes the `{action}` segment in `POST /api/{action}`.\n * Fields shown here are starter parameters; the full schema lives on\n * the Singul side and is editable in the curl preview below.\n */\n\ninterface AppDetailDrawerProps {\n open: boolean;\n onClose: () => void;\n /** App name to load */\n appName: string | null;\n /** Pre-resolved Algolia objectID — bypasses Algolia lookup when provided (e.g. when the\n * caller already had the hit, like AppSearchDrawer / \"Add Ingestion Source\"). */\n appId?: string | null;\n /** Anchor side */\n anchor?: 'left' | 'right';\n /** Width in px */\n width?: number;\n /** Called when drawer closes so parent can refresh data */\n onRefresh?: () => void;\n /** When set, replaces the Activate button with \"+ Add\" and calls this on click */\n onAddToCanvas?: (appInfo: { name: string; icon: string; algoliaId: string | null }) => void;\n /** Whether the current user is authenticated. Defaults to true. */\n isAuthenticated?: boolean;\n /** Host app's currently active org id. If different from the library's tracked org,\n * an `Org-Id` header is injected into the Singul curl preview. */\n activeOrgId?: string | null;\n}\n\nexport default function AppDetailDrawer({\n open,\n onClose,\n appName,\n appId,\n anchor = 'right',\n width = 520,\n onRefresh,\n onAddToCanvas,\n isAuthenticated = true,\n activeOrgId,\n}: AppDetailDrawerProps) {\n const [appInfo, setAppInfo] = useState<AppInfo | null>(null);\n const [appLoading, setAppLoading] = useState(false);\n const [isActivated, setIsActivated] = useState<boolean | null>(null);\n const [activatedAppId, setActivatedAppId] = useState<string | null>(null);\n const [activateLoading, setActivateLoading] = useState(false);\n const [resolvedAlgoliaId, setResolvedAlgoliaId] = useState<string | null>(null);\n const [authExpanded, setAuthExpanded] = useState(true);\n // Auto-collapse Authentication section when a valid auth exists; expand otherwise.\n // Only fires when validity flips, so user manual toggles are preserved.\n const lastValidAuthRef = useRef<boolean | null>(null);\n const [incidentStats, setIncidentStats] = useState<{ ingested: number; forwarded: number } | null>(null);\n\n const {\n authStates,\n authenticatedApps,\n loading: appAuthLoading,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n } = useAppAuth();\n\n // Fetch app info and refresh auth when opened with a new app\n useEffect(() => {\n if (!open || !appName) return;\n setAppLoading(true);\n setAppInfo(null);\n setIsActivated(null);\n // Seed from caller-provided id (e.g. AppSearchDrawer already has the Algolia hit)\n setResolvedAlgoliaId(appId || null);\n // Always refresh auth when opening a different app\n refreshAuth();\n\n const normalizedName = appName.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n const searchName = appName.replace(/_/g, ' ');\n\n (async () => {\n // Algolia lookup — also runs when caller passed an appId, so we still get\n // the image/description/categories that the caller didn't have.\n let algoliaId: string | null = appId || null;\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const res = await client.search({\n requests: [{ indexName: 'appsearch', query: searchName, hitsPerPage: 10 }],\n });\n const hits = (res as any)?.results?.[0]?.hits || [];\n const match =\n (algoliaId && hits.find((h: any) => h.objectID === algoliaId)) ||\n hits.find((h: any) =>\n h.name?.toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName\n ) ||\n (hits.length > 0 ? hits[0] : null);\n\n if (match) {\n if (!algoliaId) {\n algoliaId = match.objectID;\n setResolvedAlgoliaId(algoliaId);\n }\n setAppInfo({\n name: match.name || searchName,\n description: match.description || '',\n large_image: match.image_url || '',\n categories: match.categories || [],\n });\n }\n } catch {}\n\n // Fallback: if Algolia didn't resolve an id, look it up via /api/v1/apps\n // This also doubles as our activation check below.\n let appsList: any[] | null = null;\n if (API_CONFIG.apiKey) {\n try {\n const apps = await fetchAppsViaApiConfig();\n if (Array.isArray(apps)) appsList = apps;\n } catch {}\n }\n\n if (!algoliaId && appsList) {\n const localMatch = appsList.find((a: any) =>\n (a.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName\n );\n if (localMatch?.id) {\n algoliaId = localMatch.id;\n setResolvedAlgoliaId(localMatch.id);\n setAppInfo(prev => prev ?? {\n name: localMatch.name || searchName,\n description: localMatch.description || '',\n large_image: localMatch.large_image || '',\n categories: localMatch.categories || [],\n authentication: localMatch.authentication,\n });\n }\n }\n\n // Config API — only available when we have an id\n if (API_CONFIG.apiKey && algoliaId) {\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(algoliaId)}/config`),\n { credentials: 'include', headers: { ...getAuthHeader() } }\n );\n if (response.ok) {\n const data = await response.json();\n if (data?.name) {\n setAppInfo(prev => ({ ...prev, ...data, large_image: data.large_image || prev?.large_image || '' }));\n }\n }\n } catch {}\n }\n\n // Activation status from the same /api/v1/apps response\n if (appsList) {\n const activeMatch = appsList.find((a: any) =>\n (a.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '_') === normalizedName && a.activated\n );\n setIsActivated(!!activeMatch);\n setActivatedAppId(activeMatch?.id || null);\n } else {\n setIsActivated(false);\n }\n\n // Last-resort: if we still have no appInfo, seed from the name so the drawer renders\n setAppInfo(prev => prev ?? {\n name: searchName,\n description: '',\n large_image: '',\n categories: [],\n });\n\n setAppLoading(false);\n })();\n }, [open, appName, appId]);\n\n // Fetch incident stats for this app\n useEffect(() => {\n if (!open || !appName || !isAuthenticated) {\n setIncidentStats(null);\n return;\n }\n\n (async () => {\n try {\n const result = await getDatastoreByCategory(DATASTORE_CATEGORIES.INCIDENTS);\n if (!result.success || !result.data) {\n setIncidentStats({ ingested: 0, forwarded: 0 });\n return;\n }\n\n const normalizedAppName = appName.toLowerCase().replace(/[\\s_\\-]+/g, '');\n let ingested = 0;\n let forwarded = 0;\n\n for (const item of result.data) {\n try {\n const parsed = JSON.parse(item.value);\n const productName = (parsed.metadata?.product?.name || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n if (productName && productName === normalizedAppName) {\n ingested++;\n }\n // Check if forwarded to this app (via finding_info dest or similar)\n const forwardDest = (parsed.metadata?.product?.forward_name || parsed.forward_target || '').toLowerCase().replace(/[\\s_\\-]+/g, '');\n if (forwardDest && forwardDest === normalizedAppName) {\n forwarded++;\n }\n } catch {}\n }\n\n setIncidentStats({ ingested, forwarded });\n } catch {\n setIncidentStats({ ingested: 0, forwarded: 0 });\n }\n })();\n }, [open, appName, isAuthenticated]);\n\n const handleClose = () => {\n onRefresh?.();\n onClose();\n };\n\n // Matching auth entries\n const matchingEntries = useMemo(() => {\n if (!appName || !isAuthenticated) return [];\n return authenticatedApps.filter(\n auth => auth.app?.name?.toLowerCase().replace(/[\\s_\\-]+/g, '_') === appName.toLowerCase().replace(/[\\s_\\-]+/g, '_')\n );\n }, [appName, authenticatedApps, isAuthenticated]);\n\n const resolvedImage = useMemo(() => {\n if (appInfo?.large_image) return appInfo.large_image;\n for (const entry of matchingEntries) {\n const img = (entry as any).app?.large_image || (entry as any).large_image;\n if (img) return img;\n }\n return '';\n }, [appInfo, matchingEntries]);\n\n const algoliaApp: AlgoliaSearchApp | null = useMemo(() => {\n if (!appName) return null;\n return {\n objectID: resolvedAlgoliaId || appName,\n name: appName,\n image_url: resolvedImage,\n description: appInfo?.description || '',\n categories: appInfo?.categories || [],\n } as AlgoliaSearchApp;\n }, [appName, appInfo, resolvedImage, resolvedAlgoliaId]);\n\n const authState = authStates[appName || ''] || { systemId: appName || '', status: 'pending' as const, credentials: {} };\n const hasValidAuth = matchingEntries.some(e => e.validation?.valid === true);\n const hasAnyAuth = matchingEntries.length > 0;\n // If the app has any authentication entry, it must already exist in the\n // tenant — Shuffle does not allow auth on an un-activated app. Treat as\n // activated even if `/api/v1/apps` didn't surface an `activated:true` row\n // (name-mismatch / cache lag is common for renamed apps like \"Gmail\" vs\n // \"google_mail\"). This keeps the header from showing a stale \"Activate\"\n // button when the sidebar already shows the app as Verified.\n const effectiveActivated = isActivated === null\n ? (hasAnyAuth ? true : null)\n : (isActivated || hasAnyAuth);\n const authCount = matchingEntries.length;\n const displayName = (appInfo?.name || appName || '').replace(/_/g, ' ');\n\n // Auto-collapse when valid auth appears, auto-expand when it disappears.\n useEffect(() => {\n if (lastValidAuthRef.current === hasValidAuth) return;\n lastValidAuthRef.current = hasValidAuth;\n setAuthExpanded(!hasValidAuth);\n }, [hasValidAuth]);\n\n // Reset tracker when switching apps so the new app starts from current state.\n useEffect(() => {\n lastValidAuthRef.current = null;\n }, [appName]);\n\n const handleActivateToggle = async () => {\n if (!appName || activateLoading) return;\n const wasActivated = isActivated;\n const prevAppId = activatedAppId;\n setIsActivated(!wasActivated);\n setActivateLoading(true);\n try {\n if (wasActivated && prevAppId) {\n const res = await fetch(getApiUrl(`/api/v1/apps/${prevAppId}/deactivate`), {\n method: 'POST', credentials: 'include', headers: { ...getAuthHeader() },\n });\n if (!res.ok) throw new Error('Deactivate failed');\n setActivatedAppId(null);\n toast.success(`${displayName} deactivated`);\n } else {\n const appId = resolvedAlgoliaId;\n if (!appId) throw new Error('App ID not resolved yet');\n const activateRes = await fetch(getApiUrl(`/api/v1/apps/${appId}/activate`), {\n method: 'GET', credentials: 'include', headers: { ...getAuthHeader() },\n });\n if (!activateRes.ok) throw new Error(`Activate failed (${activateRes.status})`);\n setActivatedAppId(appId);\n toast.success(`${displayName} activated`);\n }\n } catch (err: any) {\n console.error('[Activate] Error:', err);\n toast.error(err?.message || 'Activation failed');\n setIsActivated(wasActivated);\n setActivatedAppId(prevAppId);\n } finally {\n setActivateLoading(false);\n }\n };\n\n const isLoadingAll = appLoading || (isAuthenticated && appAuthLoading);\n\n return (\n <Drawer\n anchor={anchor}\n open={open}\n onClose={handleClose}\n sx={{\n '& .MuiDrawer-paper': {\n width,\n maxWidth: '100vw',\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: anchor === 'right' ? '1px solid hsl(var(--border))' : 'none',\n borderRight: anchor === 'left' ? '1px solid hsl(var(--border))' : 'none',\n },\n }}\n >\n {/* Header bar */}\n <Box\n sx={{\n px: 3,\n py: 2,\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n }}\n >\n <Box sx={{ flex: 1 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', lineHeight: 1.2, textTransform: 'capitalize' }}>\n {isLoadingAll ? <Skeleton width={140} /> : displayName}\n </Typography>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.75rem' }}>\n App configuration\n </Typography>\n </Box>\n <IconButton\n size=\"small\"\n onClick={handleClose}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--foreground))' } }}\n >\n <CloseIcon size={16} />\n </IconButton>\n </Box>\n\n {/* Content */}\n <Box sx={{ flex: 1, overflowY: 'auto', p: 3 }}>\n {isLoadingAll ? (\n <Box>\n <Box sx={{ display: 'flex', gap: 2, mb: 3 }}>\n <Skeleton variant=\"circular\" width={56} height={56} />\n <Box sx={{ flex: 1 }}>\n <Skeleton width={180} height={28} />\n <Skeleton width={260} height={18} sx={{ mt: 0.5 }} />\n </Box>\n </Box>\n <Skeleton variant=\"rectangular\" height={160} sx={{ borderRadius: 2 }} />\n </Box>\n ) : (\n <>\n {/* App header */}\n <AppTitleHeader\n name={displayName}\n image={resolvedImage}\n hasValidAuth={hasValidAuth}\n hasAnyAuth={hasAnyAuth}\n isAuthenticated={isAuthenticated}\n categories={appInfo?.categories}\n isActivated={onAddToCanvas ? null : effectiveActivated}\n activateLoading={activateLoading}\n onActivateToggle={handleActivateToggle}\n onAdd={onAddToCanvas && appName ? () => {\n onAddToCanvas({ name: appName, icon: resolvedImage || '', algoliaId: resolvedAlgoliaId });\n onClose();\n } : undefined}\n />\n\n {/* Incident stats */}\n {isAuthenticated && incidentStats && incidentStats.ingested > 0 && (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.08 }}>\n <Box sx={{\n display: 'flex',\n gap: 2,\n mb: 3,\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--muted) / 0.3)',\n }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Download size={14} style={{ color: 'hsl(var(--primary))' }} />\n <Box>\n <Typography sx={{ fontSize: '1.1rem', fontWeight: 700, color: 'hsl(var(--foreground))', lineHeight: 1 }}>\n {incidentStats.ingested}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', fontWeight: 500 }}>\n Incidents ingested\n </Typography>\n </Box>\n </Box>\n {incidentStats.forwarded > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, ml: 2, pl: 2, borderLeft: '1px solid hsl(var(--border))' }}>\n <Forward size={14} style={{ color: 'hsl(var(--severity-low))' }} />\n <Box>\n <Typography sx={{ fontSize: '1.1rem', fontWeight: 700, color: 'hsl(var(--foreground))', lineHeight: 1 }}>\n {incidentStats.forwarded}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', fontWeight: 500 }}>\n Forwarded\n </Typography>\n </Box>\n </Box>\n )}\n </Box>\n </motion.div>\n )}\n\n {/* Authentication section */}\n <Box id=\"app-auth-section\">\n <AppAuthSection\n displayName={displayName}\n algoliaApp={algoliaApp}\n resolvedAlgoliaId={resolvedAlgoliaId}\n authState={authState}\n expanded={authExpanded}\n onToggle={() => setAuthExpanded(prev => !prev)}\n authCount={authCount}\n isAuthenticated={isAuthenticated}\n matchingEntries={matchingEntries}\n onAuthChange={handleAuthChange}\n onTestConnection={(appId, authId) => handleTestConnection(appName || appId, authId)}\n onSaveAuth={(appId, creds) => handleSaveAuth(appId, creds, appName || undefined)}\n onRefreshAuth={refreshAuth}\n />\n </Box>\n\n {/* MCP Chat + individual actions */}\n {isAuthenticated && (\n <>\n <TryMcpSection\n appName={appName || ''}\n appIcon={resolvedImage}\n appId={matchingEntries[0]?.app?.id || matchingEntries[0]?.id || appName || ''}\n categories={appInfo?.categories}\n />\n <SingulActionsPreview appName={appName || ''} appIcon={resolvedImage} categories={appInfo?.categories} activeOrgId={activeOrgId} />\n </>\n )}\n </>\n )}\n </Box>\n </Drawer>\n );\n}\n","/**\n * Tiny toast facade — library version. Mirrors the sonner-style surface\n * (`toast(...)`, `toast.success`, `toast.error`, `toast.info`, `toast.warning`)\n * plus the legacy `{ title, description, variant }` shape used elsewhere in\n * the host app. The host app can replace the impl via `setToastImpl()`.\n */\n\ntype Variant = 'default' | 'destructive' | 'success' | 'error' | 'info' | 'warning';\ntype ToastArg = string | { title?: string; description?: string; variant?: Variant };\ntype ToastOptions = { description?: string; [key: string]: unknown };\n\ntype ToastImpl = (arg: ToastArg, opts?: ToastOptions) => void;\n\nconst defaultImpl: ToastImpl = (arg, opts) => {\n const isObj = typeof arg === 'object' && arg !== null;\n const title = isObj ? arg.title : arg;\n const description = isObj ? arg.description : opts?.description;\n const variant: Variant = (isObj ? arg.variant : undefined) || 'default';\n const msg = [title, description].filter(Boolean).join(' — ');\n if (variant === 'destructive' || variant === 'error') console.error('[toast]', msg);\n else if (variant === 'warning') console.warn('[toast]', msg);\n else console.log('[toast]', msg);\n};\n\nlet _impl: ToastImpl = defaultImpl;\n\nexport function setToastImpl(fn: ToastImpl) {\n _impl = fn;\n}\n\ntype ToastApi = ((arg: ToastArg, opts?: ToastOptions) => void) & {\n success: (msg: string, opts?: ToastOptions) => void;\n error: (msg: string, opts?: ToastOptions) => void;\n info: (msg: string, opts?: ToastOptions) => void;\n warning: (msg: string, opts?: ToastOptions) => void;\n};\n\nconst base = ((arg: ToastArg, opts?: ToastOptions) => _impl(arg, opts)) as ToastApi;\nbase.success = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'success' }, opts);\nbase.error = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'destructive' }, opts);\nbase.info = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'info' }, opts);\nbase.warning = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: 'warning' }, opts);\n\nexport const toast: ToastApi = base;\n","/**\n * Shuffle Datastore Service\n * \n * Provides reusable functions for interacting with the Shuffle datastore API.\n * Uses the correct Shuffle cache API endpoints.\n */\n\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\nexport interface DatastoreItem {\n key: string;\n value: string;\n category: string;\n created?: number;\n edited?: number;\n public_authorization?: string;\n enrichments?: Array<{ type: string; value?: string; data?: string }>;\n}\n\nexport interface CategoryAutomation {\n id?: string;\n name: string;\n type?: 'workflow' | 'webhook' | 'ai_agent' | 'enrich' | 'send_message' | 'security_rules';\n trigger?: 'on_create' | 'on_edit' | 'on_delete';\n workflow_id?: string;\n webhook_url?: string;\n enabled: boolean;\n description?: string;\n options?: { key: string; value: string }[];\n}\n\nexport interface CategoryConfig {\n id: string;\n org_id: string;\n category: string;\n automations: CategoryAutomation[] | null;\n settings: {\n timeout: number;\n public: boolean;\n };\n}\n\nexport interface DatastoreResponse {\n success: boolean;\n data?: DatastoreItem[];\n categoryConfig?: CategoryConfig;\n cursor?: string;\n totalAmount?: number;\n error?: string;\n diagnostics?: DatastoreDiagnostics;\n}\n\nexport interface DatastoreDiagnostics {\n operation: string;\n category?: string;\n orgId?: string | null;\n url?: string;\n cursor?: string;\n status?: number;\n statusText?: string;\n contentType?: string | null;\n responseShape?: 'array' | 'keys' | 'data' | 'unknown';\n itemCount?: number;\n totalAmount?: number | null;\n bodyPreview?: string;\n errorStage?: 'request' | 'response' | 'parse' | 'unknown';\n timestamp: string;\n}\n\n/**\n * Runtime-injected active org ID. AuthContext sets this synchronously when\n * /api/v1/getinfo resolves, so callers don't need to wait for the\n * `shuffle_user_info` localStorage write to land. Falls back to localStorage\n * for cases where the service is imported before AuthContext mounts.\n */\nlet _runtimeOrgId: string | null = null;\n\nexport const setRuntimeOrgId = (orgId: string | null) => {\n _runtimeOrgId = orgId || null;\n};\n\n/**\n * Get current org ID. Prefers the runtime value set by AuthContext, then\n * falls back to localStorage so legacy callers keep working.\n */\nconst getOrgId = (): string | null => {\n if (_runtimeOrgId) return _runtimeOrgId;\n try {\n const userInfo = localStorage.getItem('shuffle_user_info');\n if (userInfo) {\n const parsed = JSON.parse(userInfo);\n return parsed.active_org?.id || null;\n }\n } catch {\n // Ignore parsing errors\n }\n return null;\n};\n\nconst normalizeDatastoreKey = (key: string): string => {\n if (!key?.includes('::')) return key;\n const parts = key.split('::').filter(Boolean);\n return parts.length > 0 ? parts[parts.length - 1] : key;\n};\n\nconst truncateResponsePreview = (value: string | null | undefined, maxLength = 280): string | undefined => {\n if (!value) return undefined;\n const normalized = value.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > maxLength ? `${normalized.slice(0, maxLength)}…` : normalized;\n};\n\n/**\n * Serialize a datastore value to a string for the API.\n * Validates JSON-shaped strings (parse+restringify) so we always send valid JSON.\n */\nconst serializeDatastoreValue = (value: unknown): string => {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.stringify(JSON.parse(trimmed));\n } catch {\n return value;\n }\n }\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\n\n/**\n * Set a single item in the datastore\n */\nexport const setDatastoreItem = async (\n key: string,\n value: string | object,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n // Use the v2 datastore endpoint as a single-item array. This is the same\n // endpoint the bulk writer uses; set_cache has been retired for incident\n // updates because it stringifies the payload differently and caused\n // double-encoded JSON to land in the datastore.\n const payload = [{\n key: rawKey,\n value: serializeDatastoreValue(value),\n category,\n // Incident category is governed by automation/security rules that would\n // otherwise reject programmatic edits — bypass them for our own writes.\n ...(category === 'shuffle-security_incidents' ? { ignore_security_rules: true } : {}),\n }];\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Org-Id': orgId,\n ...getAuthHeader(),\n };\n\n const response = await fetch(getApiUrl('/api/v2/datastore'), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n return { success: false, error: `Failed to set datastore item: ${response.statusText}` };\n }\n\n return { success: true };\n};\n\n/**\n * Set multiple items in the datastore (bulk create) using v2 API\n */\nexport const setDatastoreItems = async (\n items: { key: string; value: string | object }[],\n category: string\n): Promise<DatastoreResponse> => {\n const orgId = getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n // Use v2 API for bulk operations - send as array\n const payload = items.map(item => ({\n key: item.key,\n value: serializeDatastoreValue(item.value),\n category,\n ...(category === 'shuffle-security_incidents' ? { ignore_security_rules: true } : {}),\n }));\n\n const response = await fetch(getApiUrl('/api/v2/datastore'), {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'Org-Id': orgId,\n ...getAuthHeader(),\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const fallbackResults = await Promise.all(items.map(item =>\n setDatastoreItem(item.key, item.value, category)\n ));\n const failedWrites = fallbackResults.filter(result => !result.success);\n if (failedWrites.length > 0) {\n return {\n success: false,\n error: failedWrites[0]?.error || `Failed to set datastore items: ${response.statusText}`,\n };\n }\n return { success: true };\n }\n\n return { success: true };\n};\n\n/**\n * Get a single item from the datastore\n */\nexport const getDatastoreItem = async (\n key: string,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse & { item?: DatastoreItem }> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n const payload: Record<string, string> = {\n key: rawKey,\n org_id: orgId,\n };\n \n if (category) {\n payload.category = category;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n };\n if (overrideOrgId) {\n headers['Org-Id'] = overrideOrgId;\n }\n\n const response = await fetch(getApiUrl(`/api/v1/orgs/${orgId}/get_cache`), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n // 404 means key doesn't exist - not an error, just empty\n if (response.status === 404) {\n return { success: true, item: undefined };\n }\n return { success: false, error: `Failed to get datastore item: ${response.statusText}` };\n }\n\n const data = await response.json();\n \n // API returns success: false if key not found\n if (data.success === false && !data.value) {\n return { success: true, item: undefined };\n }\n \n return { success: true, item: data };\n};\n\n/**\n * Get a single item from the datastore using public authorization (no login required)\n */\nexport const getDatastoreItemPublic = async (\n key: string,\n orgId: string,\n authorization: string,\n): Promise<DatastoreResponse & { item?: DatastoreItem }> => {\n const response = await fetch(\n getApiUrl(`/api/v1/orgs/${orgId}/cache/${key}?authorization=${authorization}`),\n { method: 'GET' },\n );\n\n if (!response.ok) {\n if (response.status === 404) {\n return { success: true, item: undefined };\n }\n return { success: false, error: `Failed to get public datastore item: ${response.statusText}` };\n }\n\n const data = await response.json();\n if (data.success === false && !data.value) {\n return { success: true, item: undefined };\n }\n return { success: true, item: data };\n};\n\n/**\n * Try to extract valid datastore items from a response body string,\n * even if the HTTP status was non-2xx (some backend servers return 400 with valid data).\n */\nconst tryExtractItemsFromBody = (rawBody: string): { items: DatastoreItem[]; categoryConfig?: CategoryConfig; cursor?: string; totalAmount?: number; shape: DatastoreDiagnostics['responseShape'] } | null => {\n try {\n const data = rawBody ? JSON.parse(rawBody) : null;\n if (!data || typeof data !== 'object') return null;\n\n const items = Array.isArray(data) ? data : data.keys || data.data || [];\n if (!Array.isArray(items) || items.length === 0) return null;\n\n // Basic validation: at least one item should have a key\n if (!items.some((i: any) => i && typeof i === 'object' && typeof i.key === 'string')) return null;\n\n const shape: DatastoreDiagnostics['responseShape'] = Array.isArray(data)\n ? 'array'\n : Array.isArray(data?.keys) ? 'keys'\n : Array.isArray(data?.data) ? 'data'\n : 'unknown';\n\n return {\n items,\n categoryConfig: data.category_config,\n cursor: data.cursor,\n totalAmount: data.total_amount,\n shape,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Get all items in a category with optional cursor-based pagination\n */\nexport const getDatastoreByCategory = async (\n category: string,\n cursor?: string,\n limit?: number\n): Promise<DatastoreResponse> => {\n const orgId = getOrgId();\n if (!orgId) {\n return {\n success: false,\n error: 'No organization ID found',\n diagnostics: {\n operation: 'list',\n category,\n orgId: null,\n cursor,\n errorStage: 'request',\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n // Default page size is 100. Incidents specifically cap at 50 because their\n // payloads are far larger than other categories — pagination via cursor\n // handles the rest.\n const effectiveLimit = limit ?? (category === DATASTORE_CATEGORIES.INCIDENTS ? 50 : 100);\n let url = `/api/v1/orgs/${orgId}/list_cache?category=${encodeURIComponent(category)}&top=${effectiveLimit}`;\n if (cursor) {\n url += `&cursor=${encodeURIComponent(cursor)}`;\n }\n\n const requestUrl = getApiUrl(url);\n const baseDiagnostics: DatastoreDiagnostics = {\n operation: 'list',\n category,\n orgId,\n url: requestUrl,\n cursor,\n timestamp: new Date().toISOString(),\n };\n\n let response: Response;\n\n try {\n response = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n } catch (error) {\n // Network error — retry once\n try {\n response = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n } catch (retryError) {\n return {\n success: false,\n error: retryError instanceof Error ? retryError.message : 'Failed to request datastore items',\n diagnostics: {\n ...baseDiagnostics,\n errorStage: 'request',\n },\n };\n }\n }\n\n const contentType = response.headers.get('content-type');\n const rawBody = await response.text();\n\n if (!response.ok) {\n // Some backend servers return 400 but still include valid data in the body.\n // Try to extract items before treating as a hard failure.\n const extracted = tryExtractItemsFromBody(rawBody);\n if (extracted && extracted.items.length > 0) {\n console.warn(`[Datastore] ${response.status} response for category=${category} but body contained ${extracted.items.length} valid items — treating as success`);\n return {\n success: true,\n data: extracted.items,\n categoryConfig: extracted.categoryConfig,\n cursor: extracted.cursor,\n totalAmount: extracted.totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n responseShape: extracted.shape,\n itemCount: extracted.items.length,\n totalAmount: extracted.totalAmount ?? null,\n },\n };\n }\n\n // No valid data in body — retry once for transient server errors\n if (response.status >= 400 && response.status < 500) {\n try {\n const retryResponse = await fetch(\n requestUrl,\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n }\n );\n const retryBody = await retryResponse.text();\n const retryExtracted = tryExtractItemsFromBody(retryBody);\n if (retryResponse.ok || (retryExtracted && retryExtracted.items.length > 0)) {\n const items = retryExtracted?.items || [];\n console.warn(`[Datastore] Retry succeeded for category=${category} (status=${retryResponse.status}, items=${items.length})`);\n return {\n success: true,\n data: items,\n categoryConfig: retryExtracted?.categoryConfig,\n cursor: retryExtracted?.cursor,\n totalAmount: retryExtracted?.totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: retryResponse.status,\n statusText: retryResponse.statusText,\n contentType: retryResponse.headers.get('content-type'),\n responseShape: retryExtracted?.shape || 'unknown',\n itemCount: items.length,\n totalAmount: retryExtracted?.totalAmount ?? null,\n },\n };\n }\n } catch { /* retry failed, fall through to error */ }\n }\n\n return {\n success: false,\n error: `Failed to get datastore items: ${response.status} ${response.statusText}`.trim(),\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n bodyPreview: truncateResponsePreview(rawBody),\n errorStage: 'response',\n },\n };\n }\n\n try {\n const data = rawBody ? JSON.parse(rawBody) : {};\n const responseShape: DatastoreDiagnostics['responseShape'] = Array.isArray(data)\n ? 'array'\n : Array.isArray(data?.keys)\n ? 'keys'\n : Array.isArray(data?.data)\n ? 'data'\n : 'unknown';\n const items = Array.isArray(data) ? data : data.keys || data.data || [];\n const totalAmount = data.total_amount ?? data.total ?? data.amount;\n\n return {\n success: true,\n data: items,\n categoryConfig: data.category_config,\n cursor: data.cursor,\n totalAmount,\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n responseShape,\n itemCount: Array.isArray(items) ? items.length : 0,\n totalAmount: totalAmount ?? null,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? `Failed to parse datastore response: ${error.message}` : 'Failed to parse datastore response',\n diagnostics: {\n ...baseDiagnostics,\n status: response.status,\n statusText: response.statusText,\n contentType,\n bodyPreview: truncateResponsePreview(rawBody),\n errorStage: 'parse',\n },\n };\n }\n};\n\n/**\n * Delete a single item from the datastore\n */\nexport const deleteDatastoreItem = async (\n key: string,\n category: string,\n overrideOrgId?: string\n): Promise<DatastoreResponse> => {\n const orgId = overrideOrgId || getOrgId();\n if (!orgId) {\n return { success: false, error: 'No organization ID found' };\n }\n\n const rawKey = normalizeDatastoreKey(key);\n const payload: Record<string, string> = {\n key: rawKey,\n org_id: orgId,\n };\n \n if (category) {\n payload.category = category;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n };\n if (overrideOrgId) {\n headers['Org-Id'] = overrideOrgId;\n }\n\n const response = await fetch(getApiUrl(`/api/v1/orgs/${orgId}/delete_cache`), {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n return { success: false, error: `Failed to delete datastore item: ${response.statusText}` };\n }\n\n return { success: true };\n};\n\n/**\n * Delete multiple items from the datastore (bulk delete)\n */\nexport const deleteDatastoreItems = async (\n keys: string[],\n category: string\n): Promise<{ success: boolean; deleted: number; failed: string[]; error?: string }> => {\n const orgId = getOrgId();\n if (!orgId) {\n return { success: false, deleted: 0, failed: keys, error: 'No organization ID found' };\n }\n\n const results = await Promise.allSettled(\n keys.map(key => deleteDatastoreItem(key, category))\n );\n\n const failed: string[] = [];\n let deleted = 0;\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled' && result.value.success) {\n deleted++;\n } else {\n failed.push(keys[index]);\n }\n });\n\n return {\n success: failed.length === 0,\n deleted,\n failed,\n };\n};\n\n// Category constants for consistency\nexport const DATASTORE_CATEGORIES = {\n INCIDENTS: 'shuffle-security_incidents',\n ASSETS: 'shuffle-security_assets',\n TEMPLATES: 'shuffle-security_templates',\n CONFIGURATION: 'shuffle-security_configuration',\n IOCS: 'shuffle-security_ioc-config',\n CUSTOM_FIELDS: 'shuffle-security_custom-fields',\n THREAT_FEEDS: 'shuffle-security_threat-feeds',\n INFRASTRUCTURE: 'shuffle-security_infrastructure',\n USERS: 'shuffle-security_users',\n REPORTS: 'shuffle-security_reports',\n // Legacy - for migration purposes\n LEGACY_ALERTS: 'shuffle-security_alerts',\n LEGACY_CASES: 'shuffle-security_cases',\n} as const;\n","import { useState, useCallback, useEffect } from 'react';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport type { AppAuthState, AuthStatus, ApiAuthEntry } from '@/Shuffle-MCPs/AppAuthConfig';\nimport { refreshAllIntegrationStatus } from '@/Shuffle-MCPs/IntegrationStatus';\n\n// Helper to process auth data and invalidate entries older than 30 days\nconst processAuthData = (authData: ApiAuthEntry[]): ApiAuthEntry[] => {\n const thirtyDaysAgoMs = Date.now() - (30 * 24 * 60 * 60 * 1000);\n \n return authData.map(entry => {\n if (entry.validation?.valid === true && entry.validation?.last_valid) {\n const lastValidMs = entry.validation.last_valid > 1e12 \n ? entry.validation.last_valid \n : entry.validation.last_valid * 1000;\n \n if (lastValidMs < thirtyDaysAgoMs) {\n return {\n ...entry,\n validation: {\n ...entry.validation,\n valid: false,\n error: 'Validation expired (older than 30 days)',\n },\n };\n }\n }\n return entry;\n });\n};\n\n// Human-readable error descriptions for HTTP status codes\nconst getStatusDescription = (status: number | string): string => {\n const statusDescriptions: Record<number, string> = {\n 400: 'Bad Request – The request was malformed or missing required parameters',\n 401: 'Unauthorized – Invalid or expired API key/credentials',\n 403: 'Forbidden – Access denied. Check your permissions',\n 404: 'Not Found – The API endpoint or resource doesn\\'t exist',\n 429: 'Too Many Requests – Rate limit exceeded. Try again later',\n 500: 'Internal Server Error – Something went wrong on the server',\n 502: 'Bad Gateway – The server received an invalid response',\n 503: 'Service Unavailable – The service is temporarily down',\n };\n const num = Number(status);\n if (statusDescriptions[num]) return statusDescriptions[num];\n if (num >= 400 && num < 500) return 'Client Error – Check your request parameters';\n if (num >= 500 && num < 600) return 'Server Error – The remote service may be unavailable';\n return '';\n};\n\nconst parseResultData = (data: any) => {\n const rawData = data.result || data.raw_response;\n if (!rawData) return null;\n try {\n return typeof rawData === 'string' ? JSON.parse(rawData) : rawData;\n } catch {\n return null;\n }\n};\n\nexport function useAppAuth() {\n const [authStates, setAuthStates] = useState<Record<string, AppAuthState>>({});\n const [authenticatedApps, setAuthenticatedApps] = useState<ApiAuthEntry[]>([]);\n const [loading, setLoading] = useState(true);\n\n // Load authenticated apps on mount\n const fetchAuthenticatedApps = useCallback(async () => {\n \n try {\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers: { ...getAuthHeader() },\n });\n if (response.ok) {\n const result = await response.json();\n const authData = result.data || result;\n if (Array.isArray(authData)) {\n setAuthenticatedApps(processAuthData(authData));\n }\n }\n } catch (error) {\n console.error('Failed to fetch auth data:', error);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchAuthenticatedApps();\n }, [fetchAuthenticatedApps]);\n\n const handleAuthChange = useCallback((systemId: string, credentials: Record<string, string>) => {\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n systemId,\n status: 'pending' as AuthStatus,\n credentials,\n },\n }));\n }, []);\n\n const handleTestConnection = useCallback(async (systemId: string, authenticationId?: string) => {\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n status: 'testing' as AuthStatus,\n credentials: prev[systemId]?.credentials || {},\n },\n }));\n\n try {\n const requestBody: Record<string, string | boolean> = {\n action: 'test_api',\n app: systemId,\n skip_workflow: true,\n };\n \n if (authenticationId) {\n requestBody.authentication_id = authenticationId;\n }\n\n const response = await fetch(getApiUrl('/api/v1/apps/categories/run'), {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n 'Accept-Encoding': 'identity',\n },\n body: JSON.stringify(requestBody),\n });\n\n const result = await response.json();\n \n let isValid = false;\n let errorMessage = 'Failed to connect. Please check your credentials.';\n let successMessage = '';\n let warningMessage = '';\n let errorCode: number | undefined;\n let workflowId = result.workflow_id || '';\n let executionId = result.execution_id || '';\n\n const validActions = ['done', 'app_validation'];\n if (response.ok && validActions.includes(result.action) && result.success === true) {\n try {\n const resultData = parseResultData(result);\n \n const hasErrorInBody = resultData && (\n resultData.error !== undefined || \n resultData.ok === false\n );\n \n if (hasErrorInBody) {\n const errorDetail = resultData.error || resultData.reason || 'unknown error';\n isValid = true;\n successMessage = `Connection likely working, but API returned: ${typeof errorDetail === 'string' ? errorDetail : JSON.stringify(errorDetail)}`;\n warningMessage = 'The API responded but included an error field.';\n } else if (resultData && resultData.status) {\n const parsedStatus = resultData.status;\n const statusLower = String(parsedStatus).toLowerCase();\n const statusNum = Number(parsedStatus);\n\n const isErrorStatus = (statusNum >= 400 && statusNum < 600) ||\n statusLower === 'error' || statusLower === 'failed' ||\n statusLower === 'unauthorized' || statusLower === 'forbidden';\n \n if (statusNum === 401 || statusNum === 403 || statusLower === 'unauthorized' || statusLower === 'forbidden') {\n errorCode = statusNum || 401;\n }\n \n const isGoodStatus = !isErrorStatus && (\n statusLower === 'ok' || statusLower === 'success' || statusLower === 'healthy' ||\n statusLower === 'connected' || statusLower === '200' || statusNum === 200\n );\n \n if (isErrorStatus) {\n const statusDesc = getStatusDescription(parsedStatus);\n const reason = resultData.reason ? ` • ${resultData.reason}` : '';\n errorMessage = statusDesc ? `${statusDesc}${reason}` : `Connection failed • Status: ${parsedStatus}${reason}`;\n } else if (isGoodStatus) {\n isValid = true;\n successMessage = `Connection verified • Status: ${parsedStatus}`;\n } else {\n const statusDesc = getStatusDescription(parsedStatus);\n errorMessage = statusDesc || `Connection failed • Unexpected status: ${parsedStatus}`;\n }\n } else if (resultData?.success !== undefined) {\n if (resultData.success === true) {\n isValid = true;\n successMessage = 'Connection verified';\n } else {\n errorMessage = resultData.reason || 'Connection failed';\n }\n }\n } catch {\n errorMessage = 'Connection failed – Unable to parse response.';\n }\n } else if (result.status !== undefined) {\n const statusDesc = getStatusDescription(result.status);\n errorMessage = statusDesc || `Connection failed • Status: ${result.status}`;\n const sn = Number(result.status);\n if (sn === 401 || sn === 403) errorCode = sn;\n }\n\n // Refresh auth list & notify all IntegrationStatus instances\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n credentials: prev[systemId]?.credentials || {},\n status: isValid ? 'connected' : 'error',\n errorMessage: isValid ? undefined : errorMessage,\n successMessage: isValid ? (successMessage || 'Connection verified') : undefined,\n warningMessage: isValid ? warningMessage : undefined,\n workflowId: isValid ? undefined : workflowId,\n executionId: isValid ? undefined : executionId,\n errorCode: isValid ? undefined : errorCode,\n },\n }));\n } catch (error) {\n await new Promise(resolve => setTimeout(resolve, 3000));\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n\n setAuthStates((prev) => ({\n ...prev,\n [systemId]: {\n ...prev[systemId],\n systemId,\n credentials: prev[systemId]?.credentials || {},\n status: 'error',\n errorMessage: error instanceof Error ? error.message : 'Connection test failed.',\n },\n }));\n }\n }, [fetchAuthenticatedApps]);\n\n const handleSaveAuth = useCallback(async (appId: string, credentials: Record<string, string>, appName?: string): Promise<boolean> => {\n const fields = Object.entries(credentials)\n .filter(([key, value]) => key?.trim() && value?.trim())\n .map(([key, value]) => ({ key, value }));\n\n const payload = {\n label: `Auth for ${(appName || appId).replace(/_/g, ' ')}`,\n app: {\n name: appName || appId,\n id: appId,\n app_version: '1.0.0',\n },\n fields,\n active: true,\n };\n\n try {\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n method: 'PUT',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (response.ok) {\n await fetchAuthenticatedApps();\n refreshAllIntegrationStatus();\n return true;\n }\n return false;\n } catch (error) {\n console.error('Failed to save authentication:', error);\n return false;\n }\n }, [fetchAuthenticatedApps]);\n\n return {\n authStates,\n authenticatedApps,\n loading,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth: fetchAuthenticatedApps,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport {\n Plus as AddIcon\n} from 'lucide-react';\nimport {\n Box,\n Typography,\n Tooltip,\n IconButton,\n Avatar,\n CircularProgress,\n} from '@mui/material';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport { fetchAuthenticatedApps } from '@/Shuffle-MCPs/authenticatedApps';\nimport { fetchAppsViaApiConfig as fetchApps } from '@/Shuffle-MCPs/appsCache';\nimport { getDatastoreItem } from '@/Shuffle-MCPs/datastore';\n\n// Onboarding datastore (must stay in sync with OnboardingPage)\nconst ONBOARDING_CONFIG_CATEGORY = 'shuffle-security_onboarding';\nconst SELECTED_TOOLS_KEY = 'selected_tools';\nimport { deduplicateAuthApps, backfillAppImages, type AuthAppEntry } from '@/Shuffle-MCPs/auth-utils';\nimport { useAppDetailOptional } from '@/Shuffle-MCPs/AppDetailContext';\nimport { SIEM_PATTERNS, CASES_PATTERNS, EDR_PATTERNS, EMAIL_APP_PATTERNS } from '@/Shuffle-MCPs/ingestionDetection';\n\ninterface Integration {\n id: string;\n name: string;\n icon: string;\n category: string;\n hasValidAuth: boolean;\n authInstances: { label: string; isValidated: boolean }[];\n isActiveOnly?: boolean;\n}\n\ninterface IntegrationStatusProps {\n collapsed: boolean;\n /** When provided, only show integrations whose name is in this list */\n filterApps?: string[];\n /** When provided, the Add button calls this instead of navigating to /onboarding */\n onAddClick?: () => void;\n /** Icon size override (default: 26) */\n iconSize?: number;\n /** When provided, hovering an icon shows a cross-out button that calls this with the app name */\n onDisable?: (name: string) => void;\n /** Set of app names that are currently disabled */\n disabledApps?: Set<string>;\n /** Show all integrations without truncation */\n showAll?: boolean;\n /** Hide the Add Integration button */\n hideAddButton?: boolean;\n /** Hide the \"Integrations\" section header */\n hideHeader?: boolean;\n /** When set, apps matching this category are sorted to the top */\n priorityCategory?: string;\n /** Extra apps to merge in (e.g. apps selected in onboarding but not yet activated). Merged by name (case-insensitive) — not duplicated if already present. */\n extraApps?: { id: string; name: string; icon?: string }[];\n}\n\nconst PRIORITY_CATEGORY_PATTERNS: Record<string, string[]> = {\n siem: SIEM_PATTERNS,\n case_management: CASES_PATTERNS,\n edr: EDR_PATTERNS,\n email: EMAIL_APP_PATTERNS,\n};\n\nfunction matchesPriorityCategory(appName: string, categoryId: string): boolean {\n const patterns = PRIORITY_CATEGORY_PATTERNS[categoryId];\n if (!patterns) return false;\n const lower = appName.toLowerCase();\n return patterns.some(p => lower.includes(p));\n}\n\n/** Fire this event from anywhere to make all IntegrationStatus instances re-fetch. */\nexport const refreshAllIntegrationStatus = () => {\n window.dispatchEvent(new CustomEvent('integrations-changed'));\n};\n\nexport const IntegrationStatus = ({ collapsed, filterApps, onAddClick, iconSize = 26, onDisable, disabledApps, showAll, hideAddButton, hideHeader, priorityCategory, extraApps }: IntegrationStatusProps) => {\n const [allIntegrations, setAllIntegrations] = useState<Integration[]>([]);\n const [onboardingApps, setOnboardingApps] = useState<{ id: string; name: string; icon?: string }[]>([]);\n const [loading, setLoading] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [failedImages, setFailedImages] = useState<Set<string>>(new Set());\n const [hoveredId, setHoveredId] = useState<string | null>(null);\n const appDetail = useAppDetailOptional();\n\n // Merge in any extra (pending/selected) apps not already present.\n // Combines explicit `extraApps` prop (live in-memory selections from the\n // onboarding wizard) with apps persisted in the shuffle-security_onboarding\n // datastore so every IntegrationStatus instance — regardless of where it is\n // mounted — shows the same set of enabled / pending apps.\n const mergedIntegrations = (() => {\n const pending = [...(extraApps || []), ...onboardingApps];\n if (pending.length === 0) return allIntegrations;\n const existing = new Set(allIntegrations.map(i => i.name.toLowerCase()));\n const seenExtra = new Set<string>();\n const extras: Integration[] = [];\n for (const e of pending) {\n const key = (e.name || '').toLowerCase();\n if (!key || existing.has(key) || seenExtra.has(key)) continue;\n seenExtra.add(key);\n extras.push({\n id: e.id || e.name,\n name: e.name,\n icon: e.icon || '',\n category: 'Integration',\n hasValidAuth: false,\n authInstances: [],\n isActiveOnly: true,\n });\n }\n return [...allIntegrations, ...extras];\n })();\n\n // Apply filter if provided (case-insensitive name match)\n const integrations = filterApps\n ? mergedIntegrations.filter(i => filterApps.some(f => f.toLowerCase() === i.name.toLowerCase()))\n : mergedIntegrations;\n\n const defaultLimit = showAll ? integrations.length : (collapsed ? 3 : 7);\n const displayLimit = showAll ? integrations.length : (expanded ? integrations.length : defaultLimit);\n const hasMore = !showAll && integrations.length > defaultLimit;\n\n // Fetch enabled integrations from API\n const fetchIntegrations = useCallback(async () => {\n setLoading(true);\n try {\n // Use the coalesced shared fetcher so we share a single in-flight\n // request with other consumers (e.g. the incident header source-app\n // logo). Without this, every detail-page navigation triggered 3+\n // identical /apps/authentication requests.\n const authData = (await fetchAuthenticatedApps().catch(() => [])) as unknown as AuthAppEntry[];\n\n let dedupedIntegrations: Integration[] = [];\n const authNameSet = new Set<string>();\n\n if (Array.isArray(authData) && authData.length > 0) {\n const dedupedApps = deduplicateAuthApps(authData);\n await backfillAppImages(dedupedApps);\n\n dedupedIntegrations = dedupedApps\n .map(({ app, instances, hasValidAuth, bestImage }) => {\n authNameSet.add(app.name.toLowerCase());\n return {\n id: app.id,\n name: app.name,\n icon: bestImage || app.large_image || '',\n category: app.categories?.[0] || 'Integration',\n hasValidAuth,\n authInstances: instances,\n isActiveOnly: false,\n };\n });\n }\n\n if (dedupedIntegrations.length < 10) {\n try {\n const appsData = await fetchApps();\n if (Array.isArray(appsData)) {\n const activatedApps = appsData.filter((app: any) => app.activated);\n const slotsRemaining = 10 - dedupedIntegrations.length;\n let added = 0;\n for (const app of activatedApps) {\n if (added >= slotsRemaining) break;\n if (!authNameSet.has((app.name || '').toLowerCase())) {\n authNameSet.add((app.name || '').toLowerCase());\n dedupedIntegrations.push({\n id: app.id || app.name,\n name: app.name,\n icon: app.large_image || '',\n category: app.categories?.[0] || 'Integration',\n hasValidAuth: false,\n authInstances: [],\n isActiveOnly: true,\n });\n added++;\n }\n }\n }\n } catch (_) {\n // Non-critical, ignore\n }\n }\n\n dedupedIntegrations.sort((a, b) => {\n // Priority category apps first\n if (priorityCategory) {\n const aMatch = matchesPriorityCategory(a.name, priorityCategory);\n const bMatch = matchesPriorityCategory(b.name, priorityCategory);\n if (aMatch && !bMatch) return -1;\n if (!aMatch && bMatch) return 1;\n }\n if (a.hasValidAuth && !b.hasValidAuth) return -1;\n if (!a.hasValidAuth && b.hasValidAuth) return 1;\n if (!a.isActiveOnly && b.isActiveOnly) return -1;\n if (a.isActiveOnly && !b.isActiveOnly) return 1;\n return a.name.localeCompare(b.name);\n });\n \n setAllIntegrations(dedupedIntegrations);\n } catch (error) {\n console.error('Failed to fetch integrations:', error);\n } finally {\n setLoading(false);\n }\n }, [priorityCategory]);\n\n // Load apps selected in the onboarding wizard (persisted to datastore).\n // This keeps every IntegrationStatus instance in sync with /onboarding/sources\n // without each parent having to plumb extraApps down manually.\n const fetchOnboardingApps = useCallback(async () => {\n try {\n const resp = await getDatastoreItem(SELECTED_TOOLS_KEY, ONBOARDING_CONFIG_CATEGORY);\n if (!resp?.success || !resp.item?.value) {\n setOnboardingApps([]);\n return;\n }\n const raw = typeof resp.item.value === 'string' ? JSON.parse(resp.item.value) : resp.item.value;\n if (!Array.isArray(raw)) {\n setOnboardingApps([]);\n return;\n }\n setOnboardingApps(\n raw\n .map((a: any) => ({\n id: a?.objectID || a?.id || a?.name,\n name: a?.name,\n icon: a?.image_url || a?.large_image || '',\n }))\n .filter((a: any) => a.name)\n );\n } catch (_) {\n setOnboardingApps([]);\n }\n }, []);\n\n // Fetch on mount\n useEffect(() => {\n fetchIntegrations();\n fetchOnboardingApps();\n }, [fetchIntegrations, fetchOnboardingApps]);\n\n // Re-fetch whenever any integration auth changes globally\n useEffect(() => {\n const handler = () => {\n fetchIntegrations();\n fetchOnboardingApps();\n };\n window.addEventListener('integrations-changed', handler);\n return () => window.removeEventListener('integrations-changed', handler);\n }, [fetchIntegrations, fetchOnboardingApps]);\n\n const getStatusColor = (integration: Integration) => {\n if (integration.isActiveOnly) return 'hsl(var(--destructive))';\n return integration.hasValidAuth ? 'hsl(var(--severity-low))' : 'hsl(var(--severity-medium))';\n };\n\n // Icon-only view for both collapsed and expanded states\n const sz = iconSize;\n return (\n <Box sx={{ px: collapsed ? 0 : 1, py: 1 }}>\n {/* Header - only show when expanded */}\n {!collapsed && !hideHeader && (\n <Typography \n sx={{ \n color: 'hsl(var(--muted-foreground))', \n fontSize: '0.7rem', \n fontWeight: 600, \n textTransform: 'uppercase', \n letterSpacing: '0.05em',\n px: 1.5,\n mb: 1,\n }}\n >\n Integrations\n </Typography>\n )}\n \n {/* Icon grid */}\n <Box sx={{ \n display: 'flex', \n flexWrap: 'wrap',\n gap: 0.5,\n justifyContent: collapsed ? 'center' : 'flex-start',\n px: collapsed ? 0 : 1,\n maxHeight: expanded ? 'none' : 80,\n overflow: 'hidden',\n }}>\n {loading ? (\n <CircularProgress size={20} sx={{ color: 'hsl(var(--muted-foreground))' }} />\n ) : (\n <>\n {integrations.slice(0, displayLimit).map((integration) => {\n const isDisabled = disabledApps?.has(integration.name) ?? false;\n const isHovered = hoveredId === integration.id;\n return (\n <Tooltip \n key={integration.id} \n title={onDisable && isHovered ? '' : (\n <Box sx={{ textAlign: 'left', minWidth: 160, maxWidth: 320, p: 0.5 }}>\n <Typography sx={{ fontWeight: 600, fontSize: '0.85rem', color: 'hsl(var(--foreground))' }}>\n {integration.name}\n {isDisabled && <Typography component=\"span\" sx={{ ml: 1, fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))' }}>(disabled)</Typography>}\n </Typography>\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mb: 1, textTransform: 'capitalize' }}>\n {integration.category}\n </Typography>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>\n {integration.authInstances.map((instance, idx) => (\n <Box key={idx} sx={{ display: 'flex', alignItems: 'center', gap: 0.75, minWidth: 0 }}>\n <Box \n sx={{ \n width: 7, \n height: 7, \n borderRadius: '50%', \n backgroundColor: instance.isValidated \n ? 'hsl(var(--severity-low))' \n : 'hsl(var(--severity-medium))',\n flexShrink: 0,\n }} \n />\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--foreground))', opacity: 0.9, flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {instance.label}\n </Typography>\n <Typography sx={{ fontSize: '0.65rem', color: instance.isValidated ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n {instance.isValidated ? 'Valid' : 'Pending'}\n </Typography>\n </Box>\n ))}\n </Box>\n </Box>\n )}\n placement=\"bottom\"\n arrow\n >\n <Box\n onMouseEnter={() => onDisable && setHoveredId(integration.id)}\n onMouseLeave={() => onDisable && setHoveredId(null)}\n sx={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: onDisable ? 'default' : 'pointer',\n textDecoration: 'none',\n opacity: isDisabled ? 0.35 : 1,\n transition: 'opacity 0.15s ease',\n '&:hover': onDisable ? {} : {\n transform: 'scale(1.1)',\n transition: 'transform 0.15s ease',\n },\n }}\n >\n {/* Icon — rendered as link only when not in disable mode */}\n <Box\n onClick={!onDisable && appDetail ? () => appDetail.openApp(integration.name) : undefined}\n sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', textDecoration: 'none', cursor: !onDisable && appDetail ? 'pointer' : 'default' }}\n >\n {integration.icon && !failedImages.has(integration.id) ? (\n <Box\n component=\"img\"\n src={integration.icon}\n alt={integration.name}\n sx={{\n width: sz,\n height: sz,\n borderRadius: '50%',\n objectFit: 'contain',\n backgroundColor: 'hsl(var(--muted))',\n p: 0.25,\n filter: isDisabled ? 'grayscale(1)' : 'none',\n transition: 'filter 0.15s ease',\n }}\n onError={() => {\n setFailedImages(prev => new Set(prev).add(integration.id));\n }}\n />\n ) : (\n <Avatar\n sx={{\n width: sz,\n height: sz,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: sz * 0.4 + 'px',\n color: 'hsl(var(--foreground))',\n filter: isDisabled ? 'grayscale(1)' : 'none',\n }}\n >\n {integration.name.charAt(0).toUpperCase()}\n </Avatar>\n )}\n </Box>\n\n {/* Status dot */}\n {!isDisabled && (\n <Box\n sx={{\n position: 'absolute',\n bottom: -1,\n right: -1,\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: getStatusColor(integration),\n border: '1.5px solid hsl(var(--card))',\n pointerEvents: 'none',\n }}\n />\n )}\n\n {/* Hover cross-out overlay */}\n {onDisable && isHovered && (\n <Box\n onClick={() => onDisable(integration.name)}\n sx={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: isDisabled\n ? 'hsla(var(--severity-low) / 0.25)'\n : 'hsla(var(--destructive) / 0.75)',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease',\n }}\n >\n {isDisabled ? (\n /* Re-enable: checkmark */\n <svg width={sz * 0.45} height={sz * 0.45} viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M2 6l3 3 5-5\" stroke=\"hsl(var(--severity-low))\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n ) : (\n /* Disable: X */\n <svg width={sz * 0.45} height={sz * 0.45} viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M2 2l8 8M10 2l-8 8\" stroke=\"white\" strokeWidth=\"1.8\" strokeLinecap=\"round\"/>\n </svg>\n )}\n </Box>\n )}\n </Box>\n </Tooltip>\n );\n })}\n \n {hasMore && !expanded && (\n <Tooltip title={`Show all ${integrations.length} integrations`} placement=\"bottom\">\n <Avatar\n onClick={() => setExpanded(true)}\n sx={{\n width: 26,\n height: 26,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: '0.65rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n },\n }}\n >\n +{integrations.length - defaultLimit}\n </Avatar>\n </Tooltip>\n )}\n \n {expanded && hasMore && (\n <Tooltip title=\"Show less\" placement=\"bottom\">\n <Avatar\n onClick={() => setExpanded(false)}\n sx={{\n width: 26,\n height: 26,\n backgroundColor: 'hsl(var(--muted))',\n fontSize: '0.65rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n },\n }}\n >\n −\n </Avatar>\n </Tooltip>\n )}\n \n {/* Add button */}\n {!hideAddButton && (\n <Tooltip title=\"Add Integration\" placement=\"bottom\">\n {onAddClick ? (\n <IconButton\n size=\"small\"\n onClick={onAddClick}\n sx={{ \n width: 26,\n height: 26,\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n borderRadius: '50%',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n borderStyle: 'solid',\n },\n }}\n >\n <AddIcon size={14} />\n </IconButton>\n ) : (\n <IconButton\n size=\"small\"\n component={RouterLink}\n to=\"/onboarding\"\n sx={{ \n width: 26,\n height: 26,\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n borderRadius: '50%',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n borderStyle: 'solid',\n },\n }}\n >\n <AddIcon size={14} />\n </IconButton>\n )}\n </Tooltip>\n )}\n </>\n )}\n </Box>\n </Box>\n );\n};\n","/**\n * Shared, request-coalescing fetcher for `/api/v1/apps/authentication`.\n *\n * Multiple components on a single page (sidebar `IntegrationStatus`, the\n * incident header source-app logo, the Forward dialog, the Automations\n * dialog, etc.) all need the authenticated-apps list. Without coordination\n * they each fired their own HTTP request on mount, producing 3+ identical\n * requests on every incident detail load.\n *\n * This helper:\n * 1. Coalesces concurrent in-flight calls into a single Promise so\n * simultaneous mounts only trigger one network round-trip.\n * 2. Caches the resolved JSON for a short TTL so a follow-up mount within\n * that window can read the result synchronously instead of refetching.\n * 3. Exposes an `invalidateAuthenticatedAppsCache()` so code paths that\n * mutate authentications (delete, reauth, etc.) can force a refresh.\n *\n * The cache key includes the optional `Org-Id` header value so cross-org\n * lookups stay isolated from the active org's data.\n */\n\nimport { getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\nexport interface AuthenticatedAppRaw {\n id?: string;\n active?: boolean;\n label?: string;\n app?: {\n name?: string;\n id?: string;\n large_image?: string;\n small_image?: string;\n categories?: string[];\n [key: string]: unknown;\n };\n validation?: { valid?: boolean; [key: string]: unknown };\n fields?: Array<{ key: string; value: string }>;\n [key: string]: unknown;\n}\n\ninterface CacheEntry {\n promise?: Promise<AuthenticatedAppRaw[]>;\n data?: AuthenticatedAppRaw[];\n fetchedAt?: number;\n}\n\nconst TTL_MS = 30_000;\nconst cache = new Map<string, CacheEntry>();\n\nconst cacheKey = (crossOrgId?: string | null): string => crossOrgId || '';\n\nconst doFetch = async (crossOrgId?: string | null): Promise<AuthenticatedAppRaw[]> => {\n // getAuthHeader() now scopes to the active org by default; pass crossOrgId\n // explicitly to override when reading from a different tenant.\n const headers: Record<string, string> = {\n ...getAuthHeader(crossOrgId ?? undefined),\n };\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers,\n });\n if (!response.ok) return [];\n const result = await response.json();\n const data = result?.data || result;\n return Array.isArray(data) ? data : [];\n};\n\n/**\n * Get the raw authenticated-apps list. Returns the cached value if it is\n * still within the TTL; otherwise fires (or joins) a single network request.\n */\nexport const fetchAuthenticatedApps = (crossOrgId?: string | null): Promise<AuthenticatedAppRaw[]> => {\n const key = cacheKey(crossOrgId);\n const entry = cache.get(key) || {};\n\n // Fresh cache hit — return it without touching the network.\n if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {\n return Promise.resolve(entry.data);\n }\n // In-flight request — join it instead of firing a duplicate.\n if (entry.promise) return entry.promise;\n\n const promise = doFetch(crossOrgId)\n .then((data) => {\n cache.set(key, { data, fetchedAt: Date.now() });\n return data;\n })\n .catch((err) => {\n // On failure, drop the in-flight promise so the next caller can retry.\n cache.delete(key);\n throw err;\n });\n\n cache.set(key, { ...entry, promise });\n return promise;\n};\n\n/**\n * Invalidate the cached entry for one (or all) cross-org keys. Call after\n * mutating authentications (delete, create, reauth) so the next read fires\n * a fresh request.\n */\nexport const invalidateAuthenticatedAppsCache = (crossOrgId?: string | null) => {\n if (crossOrgId === undefined) {\n cache.clear();\n return;\n }\n cache.delete(cacheKey(crossOrgId));\n};\n","/**\n * Auth-app dedup + image backfill utilities.\n * Inlined into the Shuffle-MCPs library so it has no host-app dependency.\n * (Mirror copy of the helpers in src/lib/utils.ts — keep in sync.)\n */\n\nexport interface AuthAppEntry {\n app: {\n id: string;\n name: string;\n large_image?: string;\n categories?: string[];\n };\n active?: boolean;\n validation?: {\n valid: boolean;\n error?: string;\n };\n label?: string;\n id?: string;\n}\n\nexport interface DeduplicatedApp {\n app: AuthAppEntry['app'];\n hasValidAuth: boolean;\n bestImage: string;\n instances: { label: string; isValidated: boolean }[];\n}\n\nexport function deduplicateAuthApps(apps: AuthAppEntry[]): DeduplicatedApp[] {\n const appMap = new Map<string, DeduplicatedApp>();\n\n apps.forEach(auth => {\n if (!auth.active && !auth.validation?.valid) return;\n const normalizedName = auth.app.name.toLowerCase().trim().replace(/[\\s_\\-]+/g, '_');\n const existing = appMap.get(normalizedName);\n const isValidated = auth.validation?.valid === true;\n const entryImage = auth.app.large_image || '';\n const instance = {\n label: auth.label || auth.id || 'Default',\n isValidated,\n };\n\n if (!existing) {\n appMap.set(normalizedName, {\n app: auth.app,\n hasValidAuth: isValidated,\n bestImage: entryImage,\n instances: [instance],\n });\n } else {\n existing.instances.push(instance);\n if (isValidated) existing.hasValidAuth = true;\n if (!existing.bestImage && entryImage) existing.bestImage = entryImage;\n if (isValidated && !existing.app.large_image && entryImage) {\n existing.app = { ...existing.app, large_image: entryImage };\n }\n }\n });\n\n return Array.from(appMap.values());\n}\n\nconst _imageCache = new Map<string, string>();\nconst _pendingLookups = new Map<string, Promise<string | null>>();\nconst _normalize = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\nexport function seedImageCache(appName: string, imageUrl: string) {\n if (appName && imageUrl) _imageCache.set(_normalize(appName), imageUrl);\n}\n\nexport async function backfillAppImages(dedupedApps: DeduplicatedApp[]): Promise<DeduplicatedApp[]> {\n for (const d of dedupedApps) {\n const norm = _normalize(d.app.name);\n const existingImg = d.bestImage || d.app.large_image;\n if (existingImg) {\n _imageCache.set(norm, existingImg);\n } else if (_imageCache.has(norm)) {\n d.bestImage = _imageCache.get(norm)!;\n d.app = { ...d.app, large_image: d.bestImage };\n }\n }\n\n let missing = dedupedApps.filter(d => !d.bestImage && !d.app.large_image);\n if (missing.length === 0) return dedupedApps;\n\n // 1) Fallback to the user's /api/v1/apps list (already cached, no rate\n // limits). This must run BEFORE Algolia so we keep working when the\n // public Algolia index is rate-limited (429).\n try {\n const { fetchAppsViaApiConfig } = await import('./appsCache');\n const apps = await fetchAppsViaApiConfig().catch(() => []);\n if (Array.isArray(apps) && apps.length > 0) {\n const byName = new Map<string, string>();\n for (const a of apps) {\n const url = a?.large_image || a?.image_url;\n if (!url) continue;\n const n = _normalize(a?.name || '');\n if (n && !byName.has(n)) byName.set(n, url);\n }\n for (const entry of missing) {\n const url = byName.get(_normalize(entry.app.name));\n if (url) {\n entry.bestImage = url;\n entry.app = { ...entry.app, large_image: url };\n _imageCache.set(_normalize(entry.app.name), url);\n }\n }\n missing = dedupedApps.filter(d => !d.bestImage && !d.app.large_image);\n }\n } catch {\n // ignore\n }\n\n if (missing.length === 0) return dedupedApps;\n\n // 2) Last resort: public Algolia catalog. May 429 — handled silently.\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n\n await Promise.all(missing.map(async (entry) => {\n const norm = _normalize(entry.app.name);\n if (!_pendingLookups.has(norm)) {\n _pendingLookups.set(norm, (async () => {\n try {\n const result = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: entry.app.name, hitsPerPage: 3 },\n });\n const match = (result.hits as any[]).find(\n h => _normalize(h.name || '') === norm\n );\n const url = match?.image_url || null;\n if (url) _imageCache.set(norm, url);\n return url;\n } catch {\n return null;\n } finally {\n _pendingLookups.delete(norm);\n }\n })());\n }\n const url = await _pendingLookups.get(norm);\n if (url) {\n entry.bestImage = url;\n entry.app = { ...entry.app, large_image: url };\n }\n }));\n } catch {\n // ignore\n }\n\n return dedupedApps;\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react';\n\ninterface AppDetailContextType {\n openApp: (appName: string) => void;\n closeApp: () => void;\n currentAppName: string | null;\n isOpen: boolean;\n}\n\nconst AppDetailContext = createContext<AppDetailContextType | undefined>(undefined);\n\nexport const AppDetailProvider = ({ children }: { children: ReactNode }) => {\n const [currentAppName, setCurrentAppName] = useState<string | null>(null);\n\n const openApp = useCallback((appName: string) => {\n setCurrentAppName(appName);\n }, []);\n\n const closeApp = useCallback(() => {\n setCurrentAppName(null);\n }, []);\n\n return (\n <AppDetailContext.Provider value={{ openApp, closeApp, currentAppName, isOpen: currentAppName !== null }}>\n {children}\n </AppDetailContext.Provider>\n );\n};\n\nexport const useAppDetail = () => {\n const context = useContext(AppDetailContext);\n if (!context) {\n throw new Error('useAppDetail must be used within an AppDetailProvider');\n }\n return context;\n};\n\n/** Safe variant: returns null if no provider is mounted. Useful for components used both inside and outside the dashboard. */\nexport const useAppDetailOptional = () => {\n return useContext(AppDetailContext) ?? null;\n};\n","/**\n * Shared app category detection utilities.\n * Used by onboarding (AutomationConfig) and incident automations (CategoryAutomationsDialog).\n */\n\nimport { AuthAppEntry, deduplicateAuthApps } from '@/Shuffle-MCPs/auth-utils';\n\n// ============================================================================\n// Category patterns\n// ============================================================================\nexport const EMAIL_APP_PATTERNS = ['gmail', 'outlook', 'email', 'microsoft_graph', 'office365', 'exchange', 'imap', 'smtp'];\nexport const CASES_PATTERNS = ['jira', 'servicenow', 'zendesk', 'freshdesk', 'pagerduty', 'opsgenie', 'ticket', 'itsm', 'salesforce', 'thehive', 'cortex'];\nexport const EDR_PATTERNS = ['crowdstrike', 'sentinelone', 'carbon black', 'defender', 'cylance', 'sophos', 'trellix', 'vmware', 'tanium', 'falcon', 'edr'];\nexport const SIEM_PATTERNS = ['splunk', 'elastic', 'qradar', 'sentinel', 'chronicle', 'logrhythm', 'sumo logic', 'graylog', 'wazuh', 'siem', 'arcsight'];\nexport const THREAT_INTEL_PATTERNS = ['virustotal', 'shodan', 'alienvault', 'otx', 'threatcrowd', 'urlscan', 'hybrid-analysis', 'abuseipdb', 'greynoise', 'urlhaus', 'malwarebazaar', 'threatfox', 'misp', 'opencti', 'recorded future', 'mandiant', 'crowdstrike intel', 'intel471', 'flashpoint', 'domaintools'];\nexport const COMMUNICATION_PATTERNS_NAMES = ['slack', 'teams', 'discord', 'mattermost', 'telegram', 'webhook'];\nexport const VULN_SCANNER_PATTERNS = ['qualys', 'tenable', 'nessus', 'rapid7', 'nexpose', 'snyk', 'sonarqube', 'trivy', 'grype', 'anchore', 'dependabot', 'aws_inspector', 'azure_defender', 'gcp_scc', 'scout', 'prowler', 'checkov', 'wiz', 'orca', 'lacework', 'prisma'];\n\n// ============================================================================\n// Detection helpers\n// ============================================================================\nexport const isEmailApp = (appName: string): boolean =>\n EMAIL_APP_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isThreatIntelApp = (appName: string): boolean =>\n THREAT_INTEL_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isVulnScannerApp = (appName: string): boolean =>\n VULN_SCANNER_PATTERNS.some(pattern => appName.toLowerCase().includes(pattern));\n\nexport const isIngestionApp = (appName: string): boolean => {\n const name = appName.toLowerCase();\n return isEmailApp(appName) ||\n CASES_PATTERNS.some(p => name.includes(p)) ||\n EDR_PATTERNS.some(p => name.includes(p)) ||\n SIEM_PATTERNS.some(p => name.includes(p));\n};\n\nexport type IngestionCategory = 'email' | 'cases' | 'edr' | 'siem' | 'other';\n\nexport const normalizeAppName = (name: string): string =>\n name.toLowerCase().trim().replace(/[\\s_\\-]+/g, '_');\n\nexport const getIngestionCategory = (appName: string, appCategories?: string[]): IngestionCategory | null => {\n const name = appName.toLowerCase();\n const categories = (appCategories || []).map(c => c.toLowerCase());\n \n if (isEmailApp(name)) return 'email';\n if (CASES_PATTERNS.some(p => name.includes(p)) || categories.includes('cases') || categories.includes('itsm')) return 'cases';\n if (EDR_PATTERNS.some(p => name.includes(p)) || categories.includes('edr') || categories.includes('endpoint')) return 'edr';\n if (SIEM_PATTERNS.some(p => name.includes(p)) || categories.includes('siem')) return 'siem';\n \n return null;\n};\n\n// ============================================================================\n// Workflow-based ingestion detection\n// ============================================================================\n\n/** Name of the workflow that powers automatic ingestion */\nexport const INGEST_TICKETS_WORKFLOW_NAME = 'Ingest Tickets';\n\n/** Name of the workflow that powers forward tickets */\nexport const FORWARD_TICKETS_WORKFLOW_NAME = 'Forward Tickets';\n\n/**\n * Extract normalized app names from a workflow's actions.\n * Returns a Set of normalized app names found in the workflow.\n */\nexport function extractWorkflowAppNames(workflow: any): Set<string> {\n const names = new Set<string>();\n if (!workflow?.actions || !Array.isArray(workflow.actions)) return names;\n\n for (const action of workflow.actions) {\n if (action.app_name) {\n names.add(normalizeAppName(action.app_name));\n }\n if (action.app_id) {\n names.add(normalizeAppName(action.app_id));\n }\n // Handle Singul-type actions with nested app_name in parameters\n if (action.parameters) {\n for (const param of action.parameters) {\n if (param.name === 'app_name' && param.value) {\n names.add(normalizeAppName(param.value));\n }\n }\n }\n }\n return names;\n}\n\n/**\n * Find the 'Ingest Tickets' workflow from a list of workflows.\n * Returns the workflow object or null.\n */\nexport function findIngestTicketsWorkflow(workflows: any[]): any | null {\n return workflows.find(w => w.name === INGEST_TICKETS_WORKFLOW_NAME) || null;\n}\n\n/**\n * Check if a workflow's schedule/trigger is stopped.\n * Returns true if all triggers are stopped or the workflow has no triggers.\n */\nexport function isWorkflowScheduleStopped(workflow: any): boolean {\n if (!workflow) return true;\n const triggers = workflow.triggers;\n if (!Array.isArray(triggers) || triggers.length === 0) return true;\n // If every trigger is explicitly stopped, the workflow is effectively disabled\n return triggers.every(\n (t: any) => (t.status || '').toLowerCase() === 'stopped'\n );\n}\n\n/**\n * Find the 'Forward Tickets' workflow from a list of workflows.\n * Returns the workflow object or null.\n */\nexport function findForwardTicketsWorkflow(workflows: any[]): any | null {\n return workflows.find(w => w.name === FORWARD_TICKETS_WORKFLOW_NAME) || null;\n}\n\n// ============================================================================\n// Validated ingestion app extraction from raw API data\n// ============================================================================\nexport interface ValidatedIngestionApp {\n id: string;\n name: string;\n image?: string;\n validated: boolean;\n enabled: boolean;\n category: IngestionCategory;\n}\n\n/**\n * Extract validated apps from the raw /api/v1/apps/authentication response.\n * Returns deduplicated apps that have valid authentication.\n *\n * Enablement is determined by whether the app appears in the\n * 'Ingest Tickets' workflow's actions (workflows are the source of truth).\n *\n * @param authApiResponse - Raw response from /api/v1/apps/authentication\n * @param workflowAppNames - Set of normalized app names from the Ingest Tickets workflow actions\n */\nexport function extractValidatedIngestionApps(\n authApiResponse: any[],\n workflowAppNames?: Set<string>,\n): ValidatedIngestionApp[] {\n const dedupedApps = deduplicateAuthApps(\n authApiResponse.filter(auth => auth.active || auth.validation?.valid)\n );\n\n const enabledNames = workflowAppNames || new Set<string>();\n\n const apps: ValidatedIngestionApp[] = [];\n\n for (const { app, bestImage, hasValidAuth } of dedupedApps) {\n const category = getIngestionCategory(app.name, app.categories) || 'other';\n const enabled = enabledNames.has(normalizeAppName(app.name));\n\n apps.push({\n id: app.id,\n name: app.name,\n image: bestImage || app.large_image,\n validated: hasValidAuth,\n enabled,\n category,\n });\n }\n\n // Sort: Enabled+Validated > Enabled+Unvalidated > Disabled+Validated > Disabled+Unvalidated, then alphabetically\n apps.sort((a, b) => {\n const aScore = (a.enabled ? 2 : 0) + (a.validated ? 1 : 0);\n const bScore = (b.enabled ? 2 : 0) + (b.validated ? 1 : 0);\n if (aScore !== bScore) return bScore - aScore;\n return a.name.localeCompare(b.name);\n });\n\n return apps;\n}\n","/**\n * AppTitleHeader — Standalone title/header card for an app.\n *\n * Shows avatar (with valid-auth border), name, Verified/Pending chip,\n * categories, and either an \"Activate/Deactivate\" or \"+ Add\" action.\n *\n * Pure presentational component — pass in already-resolved props.\n */\n\nimport { Box, Typography, Avatar, Chip, Button } from '@mui/material';\nimport {\n CheckCircle2 as CheckCircleIcon,\n AlertCircle as ErrorOutlineIcon\n} from 'lucide-react';\nimport { motion } from 'framer-motion';\n\nexport interface AppTitleHeaderProps {\n /** Display name of the app (will be capitalized via CSS). */\n name: string;\n /** Image URL for the app icon. */\n image?: string;\n /** Whether at least one valid authentication exists. */\n hasValidAuth?: boolean;\n /** Whether at least one auth entry exists (valid or not). */\n hasAnyAuth?: boolean;\n /** Whether the host is authenticated — controls Verified/Pending chip + Activate button visibility. */\n isAuthenticated?: boolean;\n /** App categories to display as chips. */\n categories?: string[];\n /** Activation state — `null` hides the Activate button. */\n isActivated?: boolean | null;\n /** Whether activation toggle is in-flight. */\n activateLoading?: boolean;\n /** Called when user clicks Activate/Deactivate. */\n onActivateToggle?: () => void;\n /** When provided, replaces the Activate button with \"+ Add\". */\n onAdd?: () => void;\n}\n\nexport default function AppTitleHeader({\n name,\n image,\n hasValidAuth = false,\n hasAnyAuth = false,\n isAuthenticated = true,\n categories,\n isActivated = null,\n activateLoading = false,\n onActivateToggle,\n onAdd,\n}: AppTitleHeaderProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n mb: 3,\n p: 2.5,\n borderRadius: 3,\n background: 'linear-gradient(135deg, hsl(var(--foreground) / 0.03) 0%, hsl(var(--foreground) / 0.01) 100%)',\n border: '1px solid hsl(var(--border))',\n }}\n >\n <Avatar\n src={image}\n alt={name}\n sx={{\n width: 56,\n height: 56,\n borderRadius: '14px',\n backgroundColor: 'hsl(var(--muted))',\n border: '2px solid',\n borderColor: hasValidAuth\n ? 'hsl(var(--severity-low))'\n : hasAnyAuth\n ? 'hsl(142 76% 36% / 0.3)'\n : 'hsl(var(--border))',\n p: 0.5,\n '& img': { objectFit: 'contain', borderRadius: '10px' },\n }}\n >\n <Typography sx={{ fontSize: '1.2rem', fontWeight: 700 }}>{name.charAt(0).toUpperCase()}</Typography>\n </Avatar>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', textTransform: 'capitalize' }}>\n {name}\n </Typography>\n {isAuthenticated && hasValidAuth && (\n <Chip\n icon={<CheckCircleIcon size={14} />}\n label=\"Verified\"\n size=\"small\"\n sx={{ height: 22, backgroundColor: 'hsla(142, 76%, 36%, 0.15)', color: 'hsl(var(--severity-low))', fontWeight: 600, fontSize: '0.7rem', '& .MuiChip-icon': { color: 'hsl(var(--severity-low))' } }}\n />\n )}\n {isAuthenticated && !hasValidAuth && hasAnyAuth && (\n <Chip\n icon={<ErrorOutlineIcon size={14} />}\n label=\"Pending\"\n size=\"small\"\n sx={{ height: 22, backgroundColor: 'hsla(38, 92%, 50%, 0.15)', color: 'hsl(var(--severity-medium))', fontWeight: 600, fontSize: '0.7rem', '& .MuiChip-icon': { color: 'hsl(var(--severity-medium))' } }}\n />\n )}\n </Box>\n\n {categories && categories.length > 0 && (\n <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>\n {categories.slice(0, 3).map(cat => (\n <Chip\n key={cat}\n label={cat}\n size=\"small\"\n sx={{ height: 18, fontSize: '0.6rem', fontWeight: 500, backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))', textTransform: 'capitalize' }}\n />\n ))}\n </Box>\n )}\n </Box>\n\n {onAdd && (\n <Button\n onClick={onAdd}\n variant=\"contained\"\n size=\"small\"\n sx={{\n textTransform: 'none', fontWeight: 600, fontSize: '0.72rem', borderRadius: 2, px: 1.5, py: 0.5, minHeight: 0, flexShrink: 0,\n bgcolor: 'hsl(var(--primary))', '&:hover': { bgcolor: 'hsl(var(--primary) / 0.85)' },\n }}\n >\n + Add\n </Button>\n )}\n\n {!onAdd && isAuthenticated && isActivated !== null && onActivateToggle && (\n <Button\n onClick={onActivateToggle}\n disabled={activateLoading}\n variant={isActivated ? 'outlined' : 'contained'}\n size=\"small\"\n sx={{\n textTransform: 'none', fontWeight: 600, fontSize: '0.72rem', borderRadius: 2, px: 1.5, py: 0.5, minHeight: 0, flexShrink: 0,\n ...(isActivated\n ? { color: 'hsl(var(--muted-foreground))', borderColor: 'hsl(var(--border))', '&:hover': { borderColor: 'hsl(var(--destructive))', color: 'hsl(var(--destructive))', bgcolor: 'hsla(var(--destructive) / 0.08)' } }\n : { bgcolor: 'hsl(var(--primary))', '&:hover': { bgcolor: 'hsl(var(--primary) / 0.85)' } }),\n }}\n >\n {activateLoading ? '…' : isActivated ? 'Deactivate' : 'Activate'}\n </Button>\n )}\n </Box>\n </motion.div>\n );\n}\n","/**\n * AppAuthSection — Standalone Authentication block for an app.\n *\n * Wraps the heading/description + AppAuthCard. Pass in the resolved\n * algoliaApp and auth state so this remains presentational.\n */\n\nimport { Box, Typography } from '@mui/material';\nimport { motion } from 'framer-motion';\nimport { AppAuthCard } from '@/Shuffle-MCPs/AppAuthConfig';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\n\nexport interface AppAuthSectionProps {\n /** Display name (used in copy when no auth exists). */\n displayName: string;\n /** Algolia app object — required to render the AuthCard. */\n algoliaApp: AlgoliaSearchApp | null;\n /** Resolved app id (Algolia objectID). When missing the card is hidden. */\n resolvedAlgoliaId: string | null;\n /** Auth state object from useAppAuth. */\n authState: any;\n /** Whether the card is expanded. */\n expanded: boolean;\n onToggle: () => void;\n /** Number of matching auth entries — drives the subtitle copy. */\n authCount: number;\n /** Whether the host is authenticated (no Cloud session = hide form). */\n isAuthenticated?: boolean;\n /** Auth entries already filtered to this app. */\n matchingEntries: any[];\n onAuthChange: any;\n onTestConnection: (appId: string, authId?: string) => any;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n onRefreshAuth: () => void;\n}\n\nexport default function AppAuthSection({\n displayName,\n algoliaApp,\n resolvedAlgoliaId,\n authState,\n expanded,\n onToggle,\n authCount,\n isAuthenticated = true,\n matchingEntries,\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n onRefreshAuth,\n}: AppAuthSectionProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.1 }}>\n <Box sx={{ mb: 3 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem', mb: 0.5 }}>\n Authentication\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))', mb: 1.5 }}>\n {isAuthenticated\n ? authCount > 0\n ? `${authCount} configuration${authCount > 1 ? 's' : ''} found`\n : 'No authentication configured yet'\n : `Connect your ${displayName} account`}\n </Typography>\n {isAuthenticated && algoliaApp && resolvedAlgoliaId && (\n <AppAuthCard\n app={algoliaApp}\n authState={authState}\n isExpanded={expanded}\n onToggle={onToggle}\n onAuthChange={onAuthChange}\n onTestConnection={onTestConnection}\n onSaveAuth={onSaveAuth}\n apiAuthEntries={matchingEntries}\n onRefreshAuth={onRefreshAuth}\n />\n )}\n </Box>\n </motion.div>\n );\n}\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport {\n CheckCircle2 as CheckCircleIcon,\n X as CloseIcon,\n Trash2 as DeleteOutlineIcon,\n Pencil as EditIcon,\n ChevronDown as ExpandMoreIcon,\n Lock as LockIcon,\n BookOpen as MenuBookIcon\n} from 'lucide-react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport {\n Box,\n Typography,\n TextField,\n Button,\n Card,\n CardContent,\n Collapse,\n Alert,\n CircularProgress,\n Chip,\n IconButton,\n Link,\n Divider,\n FormControl,\n Select,\n MenuItem,\n Checkbox,\n ListItemText,\n OutlinedInput,\n Tooltip,\n Dialog,\n DialogTitle,\n DialogContent,\n} from '@mui/material';\nimport { motion } from 'framer-motion';\nimport type { AlgoliaSearchApp } from '@/Shuffle-MCPs';\nimport { AppFallbackIcon } from '@/Shuffle-MCPs/AppFallbackIcon';\nimport { API_CONFIG, getApiUrl, getAuthHeader, isDevEnvironment, isCloudDomain } from '@/Shuffle-MCPs/api';\nimport { getIngestionCategory } from '@/Shuffle-MCPs/ingestionDetection';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nexport type AuthStatus = 'pending' | 'testing' | 'connected' | 'error';\n\nexport interface AppAuthState {\n systemId: string;\n status: AuthStatus;\n credentials: Record<string, string>;\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number; // HTTP status code for credential errors (401, 403, etc.)\n}\n\n// Helper to check if auth type is OAuth2 (includes oauth2-app variant)\nconst isOAuth2Type = (type: string | undefined): boolean => {\n if (!type) return false;\n const lowerType = type.toLowerCase();\n return lowerType === 'oauth2' || lowerType === 'oauth2-app';\n};\n\n// Helper to check if auth type indicates no authentication required\n// Returns true for explicit \"no auth\" types OR apps with no parameters/OAuth config\nconst isNoAuthRequired = (auth: AppAuthentication | undefined): boolean => {\n if (!auth) return false; // No auth object loaded yet = unknown\n const type = auth.type?.toLowerCase() || '';\n // Explicit \"no auth\" types\n if (type === 'none' || type === 'no_auth' || type === 'no authentication' || type === 'no_key') return true;\n // Check if there's nothing to configure (not OAuth, no parameters)\n const isOAuth = type === 'oauth2' || type === 'oauth2-app';\n const hasParameters = auth.parameters && auth.parameters.length > 0;\n const hasOAuthConfig = auth.client_id || auth.client_secret || auth.token_uri;\n // If no OAuth and no parameters, auth is not required\n if (!isOAuth && !hasParameters && !hasOAuthConfig) return true;\n return false;\n};\n\n// URL validation helper\nconst isValidUrl = (value: string): boolean => {\n if (!value) return false;\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n};\n\ninterface AuthParameter {\n description: string;\n example: string;\n id: string;\n name: string;\n required: boolean;\n schema: {\n type: string;\n };\n}\n\ninterface AppAuthentication {\n type: string;\n description?: string;\n redirect_uri?: string;\n token_uri?: string;\n refresh_uri?: string;\n authorization_url?: string;\n // Common alternative field names for the authorization endpoint\n auth_uri?: string;\n authorize_url?: string;\n scope?: string[];\n client_id?: string;\n client_secret?: string;\n parameters?: AuthParameter[];\n}\n\n// API authentication entry (from /api/v1/apps/authentication)\nexport interface ApiAuthEntry {\n id?: string;\n label?: string;\n app: {\n id: string;\n name: string;\n large_image?: string;\n };\n active?: boolean;\n created?: number;\n edited?: number;\n validation?: {\n valid: boolean;\n error?: string;\n last_valid?: number;\n };\n}\n\ninterface DecodedApp {\n name: string;\n description: string;\n authentication: AppAuthentication;\n large_image?: string;\n}\n\ninterface AppAuthConfigProps {\n apps: AlgoliaSearchApp[];\n authStates: Record<string, AppAuthState>;\n authenticatedApps?: ApiAuthEntry[];\n onAuthChange: (appId: string, credentials: Record<string, string>) => void;\n onTestConnection: (appId: string, authenticationId?: string) => void;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n onSelectAuth?: (appId: string, authId: string) => void;\n onRefreshAuth?: () => Promise<void> | void;\n}\n\nexport interface AppAuthCardProps {\n app: AlgoliaSearchApp;\n authState: AppAuthState;\n isExpanded: boolean;\n onToggle: () => void;\n onAuthChange: (appId: string, credentials: Record<string, string>) => void;\n onTestConnection: (appId: string, authenticationId?: string) => void;\n onSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n apiAuthEntries: ApiAuthEntry[];\n onSelectAuth?: (appId: string, authId: string) => void;\n /** Called to refresh auth entries (e.g. after OAuth popup closes) */\n onRefreshAuth?: () => Promise<void> | void;\n /** When true, do NOT auto-fill URL fields with the param.example value. */\n disableUrlPrefill?: boolean;\n /** Hide the entire card header row (app icon, name, description, chips, docs, expand). Body stays expanded. */\n hideHeader?: boolean;\n /** Hide the \"Configured / Not configured\" and \"Tested / Not tested\" chips. */\n hideStatusChips?: boolean;\n /** Hide the documentation (book icon) link. */\n hideDocsLink?: boolean;\n}\n\nconst containerVariants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: { staggerChildren: 0.1 },\n },\n};\n\nconst itemVariants = {\n hidden: { opacity: 0, y: 20 },\n visible: { opacity: 1, y: 0, transition: { duration: 0.4 } },\n};\n\nconst ADD_NEW_AUTH = '__add_new__';\n\nexport const AppAuthCard = ({\n app,\n authState,\n isExpanded,\n onToggle,\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n apiAuthEntries,\n onSelectAuth,\n onRefreshAuth,\n disableUrlPrefill,\n hideHeader,\n hideStatusChips,\n hideDocsLink,\n}: AppAuthCardProps) => {\n // Helper to get best default auth: prioritize validated, otherwise last entry\n const getBestDefaultAuth = (entries: ApiAuthEntry[]): string => {\n if (entries.length === 0) return ADD_NEW_AUTH;\n \n // First, find a validated entry\n const validatedEntry = entries.find(e => e.validation?.valid === true);\n if (validatedEntry) {\n return validatedEntry.id || validatedEntry.label || '0';\n }\n \n // Otherwise, use the last entry (assuming API returns in chronological order)\n const lastEntry = entries[entries.length - 1];\n return lastEntry.id || lastEntry.label || '0';\n };\n\n // Track selected auth from dropdown\n const [selectedAuthId, setSelectedAuthId] = useState<string>(() => {\n return getBestDefaultAuth(apiAuthEntries);\n });\n\n // Track if user has made an explicit selection (to prevent auto-override on refresh)\n const [userHasSelected, setUserHasSelected] = useState(false);\n \n // Track test status PER authentication ID for this session\n // This ensures switching between auths shows each one's test result correctly\n type TestStatusValue = 'untested' | 'testing' | 'success' | 'pending_validation' | 'error';\n const [testStatusPerAuth, setTestStatusPerAuth] = useState<Record<string, TestStatusValue>>({});\n \n // Track test messages per auth (error message, success message, warning message)\n const [testMessagesPerAuth, setTestMessagesPerAuth] = useState<Record<string, {\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number;\n }>>({});\n \n // Track which auth ID is currently being tested (to avoid updating wrong auth on switch)\n const [testingAuthId, setTestingAuthId] = useState<string | null>(null);\n \n // Delete auth state\n const [deleteConfirmAuthId, setDeleteConfirmAuthId] = useState<string | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const handleDeleteAuth = async (authId: string) => {\n setDeleting(true);\n try {\n const response = await fetch(getApiUrl(`/api/v1/apps/authentication/${authId}`), {\n method: 'DELETE',\n credentials: 'include',\n headers: { ...getAuthHeader() },\n });\n if (response.ok) {\n // If we deleted the selected auth, reset selection\n if (selectedAuthId === authId) {\n setSelectedAuthId(ADD_NEW_AUTH);\n setUserHasSelected(false);\n }\n if (onRefreshAuth) await onRefreshAuth();\n }\n } catch (err) {\n console.error('Failed to delete auth:', err);\n } finally {\n setDeleting(false);\n setDeleteConfirmAuthId(null);\n }\n };\n\n const localTestStatus = testStatusPerAuth[selectedAuthId] || 'untested';\n \n // Track if the selected auth was already validated BEFORE we started testing\n // This is used to determine if we should trust the 200 response as source of truth\n const [wasPreValidatedPerAuth, setWasPreValidatedPerAuth] = useState<Record<string, boolean>>({});\n\n // Track previous entry count to detect new auths added (e.g. from OAuth popup)\n const prevEntryCountRef = useRef(apiAuthEntries.length);\n // Guard to prevent multiple auto-tests firing\n const autoTestFiredRef = useRef<string | null>(null);\n\n // Update selection when apiAuthEntries changes\n useEffect(() => {\n if (apiAuthEntries.length > 0) {\n // If a new entry was added (count increased), auto-select the newest one\n if (apiAuthEntries.length > prevEntryCountRef.current) {\n const sorted = [...apiAuthEntries].sort((a, b) => {\n const aTime = a.created || a.edited || 0;\n const bTime = b.created || b.edited || 0;\n return bTime - aTime;\n });\n const newestId = sorted[0]?.id || sorted[0]?.label || '0';\n setSelectedAuthId(newestId);\n \n // Auto-test the new auth if not already validated and not already auto-tested\n const newestEntry = sorted[0];\n const alreadyValid = newestEntry?.validation?.valid === true;\n if (!alreadyValid && newestId !== autoTestFiredRef.current) {\n autoTestFiredRef.current = newestId;\n // Small delay to let state settle before firing test\n setTimeout(() => {\n toast({\n title: 'Auto-testing new authentication',\n description: `Verifying connection for ${app.name.replace(/_/g, ' ')}...`,\n });\n setTestingAuthId(newestId);\n onTestConnection(app.objectID, newestId);\n }, 500);\n }\n } else if (!userHasSelected) {\n setSelectedAuthId(getBestDefaultAuth(apiAuthEntries));\n }\n }\n prevEntryCountRef.current = apiAuthEntries.length;\n }, [apiAuthEntries, userHasSelected]);\n \n // Track pre-validation state when auth selection changes (for first-time tests)\n useEffect(() => {\n // Only set pre-validated state if we haven't tracked this auth yet\n if (wasPreValidatedPerAuth[selectedAuthId] === undefined) {\n const currentAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === selectedAuthId\n );\n setWasPreValidatedPerAuth(prev => ({\n ...prev,\n [selectedAuthId]: currentAuth?.validation?.valid === true\n }));\n }\n }, [selectedAuthId, apiAuthEntries]);\n \n // Get the currently selected auth entry (needed for validation check)\n const selectedAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === selectedAuthId\n );\n \n // Helper to update test status for a specific auth\n const setTestStatusForAuth = (authId: string, status: TestStatusValue) => {\n setTestStatusPerAuth(prev => ({ ...prev, [authId]: status }));\n };\n \n // Helper to update test messages for a specific auth\n const setTestMessagesForAuth = (authId: string, messages: {\n errorMessage?: string;\n successMessage?: string;\n warningMessage?: string;\n workflowId?: string;\n executionId?: string;\n errorCode?: number;\n }) => {\n setTestMessagesPerAuth(prev => ({ ...prev, [authId]: messages }));\n };\n \n // Get test messages for current auth\n const localTestMessages = testMessagesPerAuth[selectedAuthId] || {};\n const wasPreValidated = wasPreValidatedPerAuth[selectedAuthId] || false;\n \n // Sync test status with authState when test completes, checking backend validation status\n // IMPORTANT: Only update the auth that was being tested, not the currently selected auth\n useEffect(() => {\n // Only process if we have a testingAuthId (a test was initiated)\n if (!testingAuthId) return;\n \n if (authState.status === 'testing') {\n setTestStatusForAuth(testingAuthId, 'testing');\n // Clear previous messages when starting a new test\n setTestMessagesForAuth(testingAuthId, {});\n } else if (authState.status === 'connected') {\n // Get the auth entry that was being tested\n const testedAuth = apiAuthEntries.find(\n auth => (auth.id || auth.label || '') === testingAuthId\n );\n const wasTestedAuthPreValidated = wasPreValidatedPerAuth[testingAuthId] || false;\n \n // If auth was already validated before testing, trust the 200 response\n // (Re-tests don't always update the backend validation status)\n if (wasTestedAuthPreValidated) {\n setTestStatusForAuth(testingAuthId, 'success');\n } else {\n // For newly tested auths, check if backend has validated\n const isBackendValidated = testedAuth?.validation?.valid === true;\n setTestStatusForAuth(testingAuthId, isBackendValidated ? 'success' : 'pending_validation');\n }\n // Store the success/warning messages for this auth\n setTestMessagesForAuth(testingAuthId, {\n successMessage: authState.successMessage,\n warningMessage: authState.warningMessage,\n });\n // Clear testingAuthId after processing completed status\n setTestingAuthId(null);\n } else if (authState.status === 'error') {\n setTestStatusForAuth(testingAuthId, 'error');\n // Store the error details for this auth\n setTestMessagesForAuth(testingAuthId, {\n errorMessage: authState.errorMessage,\n workflowId: authState.workflowId,\n executionId: authState.executionId,\n errorCode: authState.errorCode,\n });\n // Clear testingAuthId after processing completed status\n setTestingAuthId(null);\n }\n }, [authState.status, authState.errorMessage, authState.successMessage, authState.warningMessage, testingAuthId, apiAuthEntries, wasPreValidatedPerAuth]);\n \n // Track credential errors (401/403) to show warning but don't auto-switch\n // User can manually switch back to other auths or add new one\n const isCredentialError = localTestMessages.errorCode === 401 || localTestMessages.errorCode === 403;\n\n const showAddNewForm = selectedAuthId === ADD_NEW_AUTH;\n\n // Compute configured/tested status for the SELECTED auth entry only (not any auth)\n const isConfigured = selectedAuth?.active === true;\n const isTested = selectedAuth?.validation?.valid === true;\n \n // Get last validation timestamp (prefer selected auth, fallback to any validated entry)\n const getLastValidTimestamp = (): number | undefined => {\n if (selectedAuth?.validation?.last_valid) return selectedAuth.validation.last_valid;\n const validEntry = apiAuthEntries.find(a => a.validation?.valid === true && a.validation?.last_valid);\n return validEntry?.validation?.last_valid;\n };\n \n const formatLastValidDate = (): string => {\n const timestamp = getLastValidTimestamp();\n if (!timestamp) return 'Unknown';\n // Detect if timestamp is in seconds or milliseconds\n // If > 10^12, it's likely milliseconds; otherwise seconds\n const ms = timestamp > 1e12 ? timestamp : timestamp * 1000;\n const date = new Date(ms);\n return date.toLocaleDateString(undefined, { \n year: 'numeric', \n month: 'short', \n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n // Local credentials state for the form\n const [localCredentials, setLocalCredentials] = useState<Record<string, string>>(authState.credentials || {});\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n\n // App config fetching for dynamic fields\n const [loading, setLoading] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveSuccess, setSaveSuccess] = useState<boolean | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [appConfig, setAppConfig] = useState<DecodedApp | null>(null);\n\n // Refresh auth entries every time the card is expanded\n useEffect(() => {\n if (isExpanded && onRefreshAuth) {\n onRefreshAuth();\n }\n }, [isExpanded]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n const fetchAppConfig = async () => {\n if (!isExpanded || appConfig) return;\n \n setLoading(true);\n setError(null);\n \n try {\n const response = await fetch(getApiUrl(`/api/v1/apps/${app.objectID}/config`), {\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n },\n });\n \n if (!response.ok) {\n throw new Error('Failed to fetch app configuration');\n }\n \n const data = await response.json();\n \n if (data.success && data.app) {\n const decodedAppString = atob(data.app);\n const decodedApp = JSON.parse(decodedAppString) as DecodedApp;\n setAppConfig(decodedApp);\n } else {\n throw new Error('Invalid response format');\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load configuration');\n } finally {\n setLoading(false);\n }\n };\n \n fetchAppConfig();\n }, [isExpanded, app.objectID, appConfig]);\n\n const auth = appConfig?.authentication;\n const isOAuth2 = isOAuth2Type(auth?.type);\n\n const [selectedScopes, setSelectedScopes] = useState<string[]>([]);\n\n // Update scopes when auth loads\n useEffect(() => {\n if (auth?.scope) {\n setSelectedScopes(auth.scope);\n }\n }, [auth?.scope]);\n \n // Auto-populate URL fields with example values when auth config loads\n useEffect(() => {\n if (disableUrlPrefill) return;\n if (!auth?.parameters || auth.parameters.length === 0) return;\n \n const urlDefaults: Record<string, string> = {};\n auth.parameters.forEach((param, index) => {\n const fieldKey = param.id || param.name || `param_${index}`;\n const nameOrId = (param.name || param.id || '').toLowerCase();\n \n // Check if this is a URL field and has an example that looks like a URL\n const isUrlField = nameOrId.includes('url') || nameOrId.includes('endpoint') || nameOrId.includes('host');\n const hasUrlExample = param.example && (\n param.example.startsWith('http://') || \n param.example.startsWith('https://')\n );\n \n // Only pre-fill if field is empty and has a URL example\n if (isUrlField && hasUrlExample && !localCredentials[fieldKey]) {\n urlDefaults[fieldKey] = param.example;\n }\n });\n \n // Update credentials with URL defaults if any\n if (Object.keys(urlDefaults).length > 0) {\n setLocalCredentials(prev => ({ ...urlDefaults, ...prev }));\n }\n }, [auth?.parameters, disableUrlPrefill]);\n\n // Sync externally-driven URL/endpoint changes (e.g. provider preset\n // selectors) into the local form state so the field reflects the choice.\n useEffect(() => {\n const incoming = authState.credentials || {};\n setLocalCredentials((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const [k, v] of Object.entries(incoming)) {\n const lk = k.toLowerCase();\n const isUrlish = lk.includes('url') || lk.includes('endpoint') || lk.includes('host');\n if (isUrlish && typeof v === 'string' && v !== prev[k]) {\n next[k] = v;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [authState.credentials]);\n\n const [docsOpen, setDocsOpen] = useState(false);\n const [docsContent, setDocsContent] = useState<string>('');\n const [docsLoading, setDocsLoading] = useState(false);\n const [editingLabel, setEditingLabel] = useState(false);\n const [editLabelValue, setEditLabelValue] = useState('');\n const [savingLabel, setSavingLabel] = useState(false);\n\n const handleRenameAuth = async () => {\n if (!selectedAuth || !editLabelValue.trim()) return;\n setSavingLabel(true);\n try {\n // Build the auth body with all fields but replaced label\n // Fill any sensitive fields with placeholder\n const placeholder = 'Secret. Replaced during app execution!';\n const authBody: Record<string, any> = {\n ...selectedAuth,\n label: editLabelValue.trim(),\n };\n // Ensure fields array values are placeholders\n if (authBody.fields) {\n const newFields: Record<string, any> = {};\n for (const [key, val] of Object.entries(authBody.fields)) {\n newFields[key] = typeof val === 'string' ? placeholder : val;\n }\n authBody.fields = newFields;\n }\n\n const response = await fetch(getApiUrl('/api/v1/apps/authentication'), {\n method: 'PUT',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...getAuthHeader(),\n },\n body: JSON.stringify(authBody),\n });\n\n if (response.ok) {\n setEditingLabel(false);\n if (onRefreshAuth) await onRefreshAuth();\n toast({ title: 'Label updated', description: `Renamed to \"${editLabelValue.trim()}\"` });\n } else {\n toast({ title: 'Failed to rename', description: 'Could not update the authentication label', variant: 'destructive' });\n }\n } catch (err) {\n toast({ title: 'Error', description: 'Failed to rename authentication', variant: 'destructive' });\n } finally {\n setSavingLabel(false);\n }\n };\n\n const fetchDocs = async () => {\n setDocsLoading(true);\n try {\n const encodedName = encodeURIComponent(app.name);\n const response = await fetch(getApiUrl(`/api/v1/docs/${encodedName}?location=openapi`), {\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n },\n });\n if (response.ok) {\n const data = await response.json();\n setDocsContent(data.reason || data.data || data.content || 'No documentation available.');\n } else {\n setDocsContent('Failed to load documentation.');\n }\n } catch (error) {\n setDocsContent('Error loading documentation.');\n } finally {\n setDocsLoading(false);\n }\n };\n\n const handleOpenDocs = () => {\n setDocsOpen(true);\n fetchDocs();\n };\n\n // Render OAuth2 fields - only for OAuth2 apps\n const renderOAuth2Fields = () => {\n if (!auth || !isOAuth2) return null;\n\n const availableScopes = auth.scope || [];\n\n const hasManualCredentials = !!localCredentials['client_id']?.trim() && !!localCredentials['client_secret']?.trim();\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n {/* Quick Connect Button — always shown for OAuth2 apps. The popup target\n * (https://shuffler.io/appauth) handles the redirect server-side regardless\n * of which host opened it, so there is no reason to gate this on hostname.\n * Previously this was gated on isDevEnvironment() || isCloudDomain(), which\n * meant any consumer of the lib outside the hardcoded ['security.shuffler.io',\n * 'shutdown.no'] / Lovable preview list never saw a Quick Connect button at all. */}\n {true && (\n <>\n <Collapse in={!hasManualCredentials}>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n <Button\n variant=\"outlined\"\n fullWidth\n startIcon={\n app.image_url ? (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 24, height: 24, borderRadius: 1, objectFit: 'contain' }}\n />\n ) : <LockIcon />\n }\n onClick={() => {\n const authUrl = `https://shuffler.io/appauth?app_id=${app.objectID}&source=shuffle`;\n const popup = window.open(authUrl, '_blank', 'width=600,height=700');\n if (!onRefreshAuth) return;\n const baselineCount = (apiAuthEntries || []).length;\n const startedAt = Date.now();\n const MAX_MS = 5 * 60 * 1000; // 5 minutes\n let stopped = false;\n const stop = () => {\n if (stopped) return;\n stopped = true;\n clearInterval(authPollTimer);\n clearInterval(closePollTimer);\n };\n const tick = async () => {\n try { await onRefreshAuth(); } catch {}\n if ((apiAuthEntries || []).length > baselineCount) stop();\n if (Date.now() - startedAt > MAX_MS) stop();\n };\n // Fire immediately, then every 2s regardless of popup state\n tick();\n const authPollTimer = setInterval(tick, 2000);\n const closePollTimer = setInterval(() => {\n // popup may be null if blocked; in that case rely on auth poll + timeout\n if (popup && popup.closed) {\n // One last refresh after window closes\n tick();\n // Keep polling briefly in case backend writes the auth a moment later\n setTimeout(() => { tick(); stop(); }, 4000);\n }\n }, 500);\n }}\n sx={{\n py: 1.5,\n borderColor: 'hsl(var(--primary) / 0.4)',\n color: 'hsl(var(--foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '1rem',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n }}\n >\n Quick Connect with {app.name.replace(/_/g, ' ')}\n </Button>\n\n {/* OR Divider */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>\n <Divider sx={{ flex: 1, borderColor: 'hsl(var(--border))' }} />\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.875rem' }}>OR configure manually</Typography>\n <Divider sx={{ flex: 1, borderColor: 'hsl(var(--border))' }} />\n </Box>\n </Box>\n </Collapse>\n {hasManualCredentials && (\n <Button\n variant=\"text\"\n size=\"small\"\n onClick={() => {\n setLocalCredentials({});\n onAuthChange(app.objectID, {});\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'none',\n fontSize: '0.8rem',\n alignSelf: 'flex-start',\n p: 0,\n minWidth: 0,\n '&:hover': { color: 'hsl(var(--foreground))', backgroundColor: 'transparent' },\n }}\n >\n ← Use Quick Connect instead\n </Button>\n )}\n </>\n )}\n\n {/* Manual OAuth2 Fields */}\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))' }}>\n Redirect URL: <Typography component=\"span\" sx={{ color: 'hsl(var(--primary))', fontWeight: 600 }}>\n {auth.redirect_uri || 'https://shuffler.io/set_authentication'}\n </Typography>\n </Typography>\n\n <TextField\n label=\"Client ID\"\n placeholder=\"Enter your Client ID\"\n value={localCredentials['client_id'] || ''}\n onChange={(e) => handleCredentialChange('client_id', e.target.value)}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n />\n\n <TextField\n label=\"Client Secret\"\n type=\"password\"\n placeholder=\"Enter your Client Secret\"\n value={localCredentials['client_secret'] || ''}\n onChange={(e) => handleCredentialChange('client_secret', e.target.value)}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n />\n\n {/* Scopes */}\n {availableScopes.length > 0 && (\n <FormControl fullWidth size=\"small\">\n <Select\n multiple\n value={selectedScopes}\n onChange={(e) => {\n const value = e.target.value as string[];\n setSelectedScopes(value);\n handleCredentialChange('scopes', value.join(' '));\n }}\n input={<OutlinedInput />}\n renderValue={(selected) => selected.length === 0 ? 'Select Scopes' : `${selected.length} scope(s) selected`}\n displayEmpty\n sx={{\n backgroundColor: 'action.hover',\n borderRadius: 2,\n color: 'text.primary',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'divider' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'text.disabled' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'primary.main' },\n '& .MuiSvgIcon-root': { color: 'text.secondary' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n maxHeight: 300,\n },\n },\n },\n }}\n >\n {availableScopes.map((scope) => (\n <MenuItem key={scope} value={scope} sx={{ color: 'hsl(var(--foreground))' }}>\n <Checkbox \n checked={selectedScopes.indexOf(scope) > -1}\n sx={{ color: 'hsl(var(--muted-foreground))', '&.Mui-checked': { color: 'hsl(var(--primary))' } }}\n />\n <ListItemText primary={scope} sx={{ '& .MuiTypography-root': { color: 'hsl(var(--foreground))' } }} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n )}\n </Box>\n </Box>\n );\n };\n\n // Render parameter fields - for non-OAuth2 apps with parameters\n const renderParameterFields = () => {\n if (isOAuth2) return null;\n if (!auth?.parameters || auth.parameters.length === 0) return null;\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n {auth.parameters.map((param, index) => {\n // Use param.id if available, otherwise fallback to name or index\n const fieldKey = param.id || param.name || `param_${index}`;\n return (\n <TextField\n key={fieldKey}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {param.name}\n {param.required && (\n <Typography component=\"span\" sx={{ color: 'hsl(var(--destructive))', fontSize: '0.8rem' }}>*</Typography>\n )}\n </Box>\n }\n type={param.name.toLowerCase().includes('password') || param.name.toLowerCase().includes('secret') || param.name.toLowerCase().includes('key') ? 'password' : 'text'}\n placeholder={param.example || `Enter ${param.name}`}\n value={localCredentials[fieldKey] || ''}\n onChange={(e) => handleCredentialChange(fieldKey, e.target.value)}\n error={!!fieldErrors[fieldKey]}\n helperText={fieldErrors[fieldKey] || param.description}\n fullWidth\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: 2,\n '& fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n '& .MuiInputLabel-root': { color: 'hsl(var(--muted-foreground))' },\n '& .MuiFormHelperText-root': { color: fieldErrors[fieldKey] ? 'hsl(var(--destructive))' : 'hsl(var(--muted-foreground))' },\n }}\n />\n );\n })}\n </Box>\n );\n };\n\n // No longer rendering fallback API key field - apps without parameters don't need auth config\n\n // Validate a single field\n const validateField = (key: string, value: string): string | null => {\n const lowerKey = key.toLowerCase();\n if (lowerKey.includes('url') || lowerKey === 'url') {\n if (!value) return 'URL is required';\n if (!isValidUrl(value)) return 'Please enter a valid URL (e.g., https://example.com)';\n }\n return null;\n };\n\n // Check if all required fields are valid for saving\n const isFormValid = (): boolean => {\n // Check for any field errors\n if (Object.values(fieldErrors).some(err => err)) return false;\n \n // Validate all current credentials\n for (const [key, value] of Object.entries(localCredentials)) {\n const error = validateField(key, value);\n if (error) return false;\n }\n \n // Check required parameters are filled\n if (auth?.parameters && auth.parameters.length > 0) {\n for (let i = 0; i < auth.parameters.length; i++) {\n const param = auth.parameters[i];\n const fieldKey = param.id || param.name || `param_${i}`;\n if (param.required && !localCredentials[fieldKey]?.trim()) return false;\n }\n // At least one parameter must have a value\n const hasAnyValue = auth.parameters.some((param, index) => {\n const fieldKey = param.id || param.name || `param_${index}`;\n return localCredentials[fieldKey]?.trim();\n });\n if (!hasAnyValue) return false;\n }\n // Apps without parameters don't need validation - they work without auth\n \n return true;\n };\n\n const handleSave = async () => {\n setSaving(true);\n setSaveSuccess(null);\n const success = await onSaveAuth(app.objectID, localCredentials);\n setSaving(false);\n setSaveSuccess(success);\n if (success) {\n setUserHasSelected(false); // Allow auto-selection to pick up new auth\n setLocalCredentials({}); // Clear form after success\n setFieldErrors({}); // Clear errors\n }\n };\n\n // Helper to update local credentials and notify parent\n const handleCredentialChange = (key: string, value: string) => {\n // Ignore empty keys\n if (!key || key.trim() === '') return;\n \n const updated = { ...localCredentials, [key]: value };\n setLocalCredentials(updated);\n onAuthChange(app.objectID, updated);\n \n // Validate the field\n const error = validateField(key, value);\n setFieldErrors(prev => ({\n ...prev,\n [key]: error || '',\n }));\n };\n\n return (\n <motion.div variants={itemVariants} style={{ width: '100%', maxWidth: '100%' }}>\n <Card\n sx={{\n background: 'transparent',\n border: '1px solid',\n borderColor: isTested\n ? 'hsl(var(--severity-low) / 0.5)'\n : authState.status === 'error'\n ? 'hsl(var(--destructive) / 0.3)'\n : 'hsl(var(--border))',\n borderRadius: 3,\n boxShadow: 'none',\n overflow: 'hidden',\n transition: 'all 0.3s ease',\n width: '100%',\n maxWidth: '100%',\n }}\n >\n {!hideHeader && (\n <CardContent\n onClick={onToggle}\n sx={{\n display: 'flex',\n flexDirection: { xs: 'column', sm: 'row' },\n alignItems: { xs: 'flex-start', sm: 'center' },\n gap: { xs: 1.5, sm: 2 },\n cursor: 'pointer',\n p: { xs: 2, sm: 3 },\n '&:last-child': { pb: { xs: 2, sm: 3 } },\n '&:hover': { backgroundColor: 'hsl(var(--muted) / 0.35)' },\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flex: 1, minWidth: 0 }}>\n <Box\n sx={{\n width: { xs: 40, sm: 48 },\n height: { xs: 40, sm: 48 },\n borderRadius: 2,\n backgroundColor: 'hsl(var(--muted) / 0.5)',\n p: 1,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <AppFallbackIcon\n name={app.name}\n imageUrl={app.image_url}\n size={32}\n style={{ borderRadius: 6 }}\n />\n </Box>\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Typography \n sx={{ \n color: 'hsl(var(--foreground))', \n fontWeight: 600, \n fontSize: { xs: '0.9rem', sm: '1rem' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {app.name.replace(/_/g, ' ')}\n </Typography>\n {app.description && (\n <Typography \n variant=\"caption\" \n sx={{ \n color: 'hsl(var(--muted-foreground))',\n display: { xs: 'none', md: 'block' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n }}\n >\n {app.description}\n </Typography>\n )}\n </Box>\n </Box>\n <Box sx={{ \n display: 'flex', \n alignItems: 'center', \n gap: { xs: 1, sm: 1.5 }, \n flexWrap: 'wrap',\n width: { xs: '100%', sm: 'auto' },\n justifyContent: { xs: 'flex-start', sm: 'flex-end' },\n }}>\n {/* Auth status chip - show \"Auth not required\" for no-auth apps */}\n {!hideStatusChips && (isNoAuthRequired(auth) ? (\n <Chip\n label=\"Auth not required\"\n size=\"small\"\n sx={{\n backgroundColor: 'hsl(var(--severity-info) / 0.15)',\n color: 'hsl(var(--severity-info))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n }}\n />\n ) : (\n <>\n {/* Configured status chip */}\n <Chip\n label={isConfigured ? 'Configured' : 'Not configured'}\n size=\"small\"\n sx={{\n backgroundColor: isConfigured ? 'hsl(var(--severity-medium) / 0.15)' : 'hsl(var(--destructive) / 0.15)',\n color: isConfigured ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n }}\n />\n {/* Tested status chip */}\n <Tooltip \n title={isTested ? `Last validated: ${formatLastValidDate()}` : ''} \n arrow\n disableHoverListener={!isTested}\n >\n <Chip\n label={isTested ? 'Tested' : 'Not tested'}\n size=\"small\"\n sx={{\n backgroundColor: isTested ? 'hsl(var(--severity-low) / 0.15)' : 'hsl(var(--muted) / 0.8)',\n color: isTested ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))',\n fontWeight: 500,\n fontSize: { xs: '0.6rem', sm: '0.65rem' },\n height: { xs: 22, sm: 24 },\n cursor: isTested ? 'help' : 'default',\n }}\n />\n </Tooltip>\n </>\n ))}\n {!hideDocsLink && (\n <Tooltip title=\"View documentation\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n handleOpenDocs();\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { \n color: 'hsl(var(--severity-info))',\n backgroundColor: 'hsl(var(--severity-info) / 0.1)',\n },\n }}\n >\n <MenuBookIcon size={16} />\n </IconButton>\n </Tooltip>\n )}\n <IconButton\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n transform: isExpanded ? 'rotate(180deg)' : 'none',\n transition: 'transform 0.3s ease',\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n </Box>\n </CardContent>\n )}\n\n <Collapse in={isExpanded}>\n <Box\n sx={{\n px: { xs: 2, sm: 3 },\n pb: { xs: 2, sm: 3 },\n pt: 2,\n borderTop: '1px solid hsl(var(--border))',\n }}\n >\n {/* Auth Selection Dropdown - always at top */}\n {apiAuthEntries.length > 0 && (\n <Box sx={{ mb: 3 }}>\n <Typography variant=\"body2\" sx={{ color: 'hsl(var(--muted-foreground))', mb: 1 }}>\n Select authentication\n </Typography>\n <FormControl fullWidth size=\"small\">\n <Select\n value={selectedAuthId}\n onChange={(e) => {\n const value = e.target.value as string;\n setSelectedAuthId(value);\n // Track that user has made an explicit selection\n setUserHasSelected(true);\n if (value !== ADD_NEW_AUTH && onSelectAuth) {\n onSelectAuth(app.objectID, value);\n }\n }}\n sx={{\n backgroundColor: 'hsl(var(--background))',\n borderRadius: 2,\n color: 'hsl(var(--foreground))',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border) / 0.8)' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n '& .MuiSvgIcon-root': { color: 'hsl(var(--muted-foreground))' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n maxWidth: 480,\n '& .MuiMenuItem-root': { maxWidth: '100%' },\n },\n },\n },\n }}\n >\n {/* Sort by created date - most recent first */}\n {[...apiAuthEntries]\n .sort((a, b) => {\n const aTime = a.created || a.edited || 0;\n const bTime = b.created || b.edited || 0;\n return bTime - aTime; // Descending (newest first)\n })\n .map((authEntry, index) => {\n const isLatest = index === 0 && apiAuthEntries.length > 1;\n const entryId = authEntry.id || authEntry.label || index.toString();\n const entryLabel = authEntry.label || `Auth ${index + 1}`;\n const isActive = authEntry.active === true;\n const isValid = authEntry.validation?.valid === true;\n \n // Format timestamp for tooltips\n const formatTimestamp = (ts?: number): string => {\n if (!ts) return 'Unknown';\n const date = ts > 1e12 ? new Date(ts) : new Date(ts * 1000);\n return date.toLocaleString();\n };\n \n const configuredDate = authEntry.created || authEntry.edited;\n const lastValidDate = authEntry.validation?.last_valid;\n \n return (\n <MenuItem key={entryId} value={entryId} sx={{ color: 'hsl(var(--foreground))', py: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, width: '100%', minWidth: 0 }}>\n <Box sx={{ display: 'flex', gap: 0.5, flexShrink: 0 }}>\n <Tooltip \n title={isActive ? `Created: ${formatTimestamp(configuredDate)}` : 'Not configured'}\n arrow\n placement=\"top\"\n >\n <Chip\n label={isActive ? 'Configured' : 'Not configured'}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n backgroundColor: isActive ? 'hsl(var(--severity-medium) / 0.15)' : 'hsl(var(--destructive) / 0.15)',\n color: isActive ? 'hsl(var(--severity-medium))' : 'hsl(var(--destructive))',\n }}\n />\n </Tooltip>\n <Tooltip \n title={lastValidDate ? `Last valid: ${formatTimestamp(lastValidDate)}` : 'Never validated'}\n arrow\n placement=\"top\"\n >\n <Chip\n label={isValid ? 'Tested' : 'Not tested'}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n backgroundColor: isValid ? 'hsl(var(--severity-low) / 0.15)' : 'hsl(var(--muted) / 0.8)',\n color: isValid ? 'hsl(var(--severity-low))' : 'hsl(var(--muted-foreground))',\n }}\n />\n </Tooltip>\n {isLatest && (\n <Chip\n label=\"Latest\"\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--infra-email) / 0.15)',\n color: 'hsl(var(--infra-email))',\n }}\n />\n )}\n </Box>\n <Typography sx={{ \n flex: 1, \n overflow: 'hidden', \n textOverflow: 'ellipsis', \n whiteSpace: 'nowrap',\n minWidth: 0,\n }}>\n {entryLabel}\n </Typography>\n {/* Delete button for non-validated entries */}\n {!isValid && (\n <Tooltip title=\"Delete authentication\" arrow placement=\"top\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n setDeleteConfirmAuthId(entryId);\n }}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n p: 0.5,\n ml: 0.5,\n flexShrink: 0,\n '&:hover': {\n color: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n <DeleteOutlineIcon size={16} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </MenuItem>\n );\n })}\n <Divider sx={{ borderColor: 'hsl(var(--border))', my: 1 }} />\n <MenuItem value={ADD_NEW_AUTH} sx={{ color: 'hsl(var(--primary))', fontWeight: 600 }}>\n + Add new authentication\n </MenuItem>\n </Select>\n </FormControl>\n\n {/* Delete confirmation dialog */}\n <Dialog\n open={!!deleteConfirmAuthId}\n onClose={() => setDeleteConfirmAuthId(null)}\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 3,\n minWidth: 360,\n },\n },\n }}\n >\n <DialogTitle sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, pb: 1 }}>\n Delete Authentication\n </DialogTitle>\n <DialogContent>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', mb: 3 }}>\n Are you sure you want to delete this authentication? This action cannot be undone.\n </Typography>\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={() => setDeleteConfirmAuthId(null)}\n disabled={deleting}\n sx={{\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'none',\n '&:hover': {\n borderColor: 'hsl(var(--border) / 0.8)',\n backgroundColor: 'hsl(var(--muted) / 0.5)',\n },\n }}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={() => {\n if (deleteConfirmAuthId) handleDeleteAuth(deleteConfirmAuthId);\n }}\n disabled={deleting}\n sx={{\n backgroundColor: 'hsl(var(--destructive))',\n color: 'hsl(var(--destructive-foreground))',\n textTransform: 'none',\n fontWeight: 600,\n '&:hover': { backgroundColor: 'hsl(var(--destructive) / 0.9)' },\n '&.Mui-disabled': {\n backgroundColor: 'hsl(var(--destructive) / 0.3)',\n color: 'hsl(var(--destructive-foreground) / 0.5)',\n },\n }}\n >\n {deleting ? 'Deleting...' : 'Delete'}\n </Button>\n </Box>\n </DialogContent>\n </Dialog>\n\n {/* Show selected auth info if not adding new */}\n {!showAddNewForm && selectedAuth && (\n <Box sx={{ \n mt: 2, \n p: 0,\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: 3,\n border: '1px solid hsl(var(--border))',\n overflow: 'hidden',\n }}>\n {/* Active authentication header */}\n <Box sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: { xs: 2, sm: 2.5 },\n py: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background-surface))',\n }}>\n <Box sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: localTestStatus === 'success' \n ? 'hsl(var(--severity-low))' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium))'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive))'\n : 'hsl(var(--muted-foreground))',\n boxShadow: localTestStatus === 'success' \n ? '0 0 8px hsl(var(--severity-low) / 0.6)'\n : localTestStatus === 'pending_validation'\n ? '0 0 8px hsl(var(--severity-medium) / 0.6)'\n : localTestStatus === 'error'\n ? '0 0 8px hsl(var(--destructive) / 0.6)'\n : '0 0 8px hsl(var(--muted-foreground) / 0.4)',\n }} />\n <Typography sx={{ \n color: 'hsl(var(--muted-foreground))', \n fontSize: '0.75rem',\n fontWeight: 500,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}>\n {localTestStatus === 'success' \n ? 'Verified Authentication' \n : localTestStatus === 'pending_validation'\n ? 'Awaiting Backend Validation'\n : localTestStatus === 'error'\n ? 'Test Failed'\n : 'Pending Verification'}\n </Typography>\n </Box>\n\n {/* Main content area — always stacked vertically for drawer contexts */}\n <Box sx={{ \n display: 'flex', \n flexDirection: 'column',\n alignItems: 'stretch', \n gap: 2,\n p: { xs: 2, sm: 2.5 },\n }}>\n {/* Auth name with icon */}\n <Box sx={{ \n display: 'flex', \n alignItems: 'center', \n gap: 1.5, \n minWidth: 0,\n flex: 1,\n }}>\n <Box sx={{\n width: 36,\n height: 36,\n borderRadius: 2,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: localTestStatus === 'success' \n ? 'hsl(var(--severity-low) / 0.1)' \n : localTestStatus === 'error'\n ? 'hsl(var(--destructive) / 0.1)'\n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium) / 0.1)'\n : isTested\n ? 'hsl(var(--severity-low) / 0.1)'\n : isConfigured\n ? 'hsl(var(--severity-medium) / 0.1)' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground) / 0.1)',\n border: `1px solid ${\n localTestStatus === 'success' \n ? 'hsl(var(--severity-low) / 0.2)' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium) / 0.2)'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive) / 0.2)'\n : isTested\n ? 'hsl(var(--severity-low) / 0.2)'\n : isConfigured\n ? 'hsl(var(--severity-medium) / 0.2)' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground) / 0.2)'\n }`,\n flexShrink: 0,\n }}>\n <CheckCircleIcon size={20} />\n </Box>\n <Box sx={{ minWidth: 0, flex: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {editingLabel ? (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }} onClick={e => e.stopPropagation()}>\n <TextField\n value={editLabelValue}\n onChange={e => setEditLabelValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') handleRenameAuth();\n if (e.key === 'Escape') setEditingLabel(false);\n }}\n size=\"small\"\n autoFocus\n sx={{\n '& .MuiOutlinedInput-root': {\n height: 28,\n fontSize: '0.85rem',\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiOutlinedInput-input': { py: 0.25, px: 1 },\n }}\n />\n <Button\n size=\"small\"\n variant=\"contained\"\n onClick={handleRenameAuth}\n disabled={savingLabel || !editLabelValue.trim()}\n sx={{\n minWidth: 0,\n px: 1.5,\n py: 0.25,\n fontSize: '0.7rem',\n textTransform: 'none',\n bgcolor: 'hsl(var(--primary))',\n '&:hover': { bgcolor: 'hsl(var(--primary) / 0.9)' },\n }}\n >\n {savingLabel ? <CircularProgress size={12} sx={{ color: 'inherit' }} /> : 'Save'}\n </Button>\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => setEditingLabel(false)}\n sx={{\n minWidth: 0,\n px: 1,\n py: 0.25,\n fontSize: '0.7rem',\n textTransform: 'none',\n color: 'hsl(var(--muted-foreground))',\n }}\n >\n Cancel\n </Button>\n </Box>\n ) : (\n <>\n <Typography sx={{ \n color: 'hsl(var(--foreground))', \n fontWeight: 600, \n fontSize: { xs: '0.9rem', sm: '0.95rem' },\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n lineHeight: 1.3,\n }}>\n {selectedAuth.label || 'Selected authentication'}\n </Typography>\n <Tooltip title=\"Rename authentication\" arrow>\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n setEditLabelValue(selectedAuth.label || '');\n setEditingLabel(true);\n }}\n sx={{\n p: 0.3,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--primary))' },\n }}\n >\n <EditIcon size={14} />\n </IconButton>\n </Tooltip>\n </>\n )}\n </Box>\n <Typography sx={{ \n color: localTestStatus === 'success' \n ? 'hsl(var(--severity-low))' \n : localTestStatus === 'pending_validation'\n ? 'hsl(var(--severity-medium))'\n : localTestStatus === 'error'\n ? 'hsl(var(--destructive))'\n : isTested\n ? 'hsl(var(--severity-low))'\n : isConfigured\n ? 'hsl(var(--severity-medium))' // Yellow for configured but not tested\n : 'hsl(var(--muted-foreground))', \n fontSize: '0.75rem',\n mt: 0.25,\n fontWeight: (localTestStatus !== 'untested' || isTested || isConfigured) ? 500 : 400,\n }}>\n {localTestStatus === 'success' \n ? '✓ Connection verified' \n : localTestStatus === 'pending_validation'\n ? '⏳ Test passed, awaiting backend validation'\n : localTestStatus === 'error'\n ? '✗ Test failed'\n : localTestStatus === 'testing'\n ? 'Testing...'\n : 'Not tested in this session'}\n </Typography>\n </Box>\n </Box>\n\n {/* Test Connection button */}\n <Button\n variant={authState.status === 'testing' ? 'contained' : 'outlined'}\n size=\"medium\"\n onClick={(e) => {\n e.stopPropagation();\n // Track which auth is being tested so results go to the right auth\n setTestingAuthId(selectedAuthId);\n onTestConnection(app.objectID, selectedAuthId !== ADD_NEW_AUTH ? selectedAuthId : undefined);\n }}\n disabled={authState.status === 'testing'}\n startIcon={\n authState.status === 'testing' \n ? <CircularProgress size={16} sx={{ color: 'inherit' }} />\n : <CheckCircleIcon size={18} />\n }\n sx={{\n borderColor: authState.status === 'testing' ? 'transparent' : 'hsl(var(--primary) / 0.5)',\n color: authState.status === 'testing' ? 'hsl(var(--foreground))' : 'hsl(var(--primary))',\n background: authState.status === 'testing' \n ? 'linear-gradient(90deg, hsl(var(--primary) / 0.3) 0%, hsl(var(--primary) / 0.5) 50%, hsl(var(--primary) / 0.3) 100%)'\n : 'transparent',\n backgroundSize: authState.status === 'testing' ? '200% 100%' : 'auto',\n animation: authState.status === 'testing' ? 'shimmer 1.5s infinite linear' : 'none',\n fontWeight: 600,\n textTransform: 'none',\n px: 3,\n py: 1,\n borderRadius: 2,\n flexShrink: 0,\n minWidth: 160,\n width: '100%',\n transition: 'all 0.3s ease',\n '@keyframes shimmer': {\n '0%': { backgroundPosition: '200% 0' },\n '100%': { backgroundPosition: '-200% 0' },\n },\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: authState.status === 'testing' ? undefined : 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n color: authState.status === 'testing' ? 'hsl(var(--foreground))' : 'hsl(var(--muted-foreground))',\n borderColor: authState.status === 'testing' ? 'transparent' : 'hsl(var(--border))',\n },\n }}\n >\n {authState.status === 'testing' ? 'Testing Connection...' : 'Test Connection'}\n </Button>\n </Box>\n\n {/* Status messages - only show for current test session */}\n {localTestStatus === 'error' && localTestMessages.errorMessage && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--destructive))' },\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, width: '100%' }}>\n <Typography sx={{ fontSize: '0.875rem', flex: 1 }}>\n {localTestMessages.errorMessage}\n </Typography>\n {localTestMessages.workflowId && localTestMessages.executionId && (\n <Button\n variant=\"outlined\"\n size=\"small\"\n href={`https://shuffler.io/workflows/${localTestMessages.workflowId}?execution_id=${localTestMessages.executionId}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n borderColor: 'hsl(var(--destructive) / 0.5)',\n color: 'hsl(var(--destructive))',\n textTransform: 'none',\n fontSize: '0.75rem',\n py: 0.5,\n px: 1.5,\n flexShrink: 0,\n '&:hover': {\n borderColor: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n View Execution\n </Button>\n )}\n </Box>\n </Alert>\n </Box>\n )}\n {localTestStatus === 'success' && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity={localTestMessages.warningMessage ? \"warning\" : \"success\"}\n sx={{\n backgroundColor: localTestMessages.warningMessage \n ? 'hsl(var(--severity-medium) / 0.1)' \n : 'hsl(var(--severity-low) / 0.1)',\n color: localTestMessages.warningMessage ? 'hsl(var(--severity-medium))' : 'hsl(var(--severity-low))',\n border: localTestMessages.warningMessage \n ? '1px solid hsl(var(--severity-medium) / 0.2)' \n : '1px solid hsl(var(--severity-low) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { \n color: localTestMessages.warningMessage ? 'hsl(var(--severity-medium))' : 'hsl(var(--severity-low))' \n },\n }}\n >\n {localTestMessages.warningMessage ? (\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n {localTestMessages.successMessage || 'Connection probably working'}\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9 }}>\n {localTestMessages.warningMessage}\n </Typography>\n </Box>\n ) : (\n localTestMessages.successMessage || 'Connection verified successfully'\n )}\n </Alert>\n </Box>\n )}\n {localTestStatus === 'pending_validation' && (\n <Box sx={{ \n px: { xs: 2, sm: 2.5 }, \n pb: { xs: 2, sm: 2.5 },\n }}>\n <Alert\n severity=\"warning\"\n sx={{\n backgroundColor: 'hsl(var(--severity-medium) / 0.1)',\n color: 'hsl(var(--severity-medium))',\n border: '1px solid hsl(var(--severity-medium) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-medium))' },\n }}\n >\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n Test passed (Status 200), but not marked as validated\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9, mb: 1 }}>\n The API returned success, but Shuffle hasn't confirmed the validation yet. This could mean credentials are correct but the app needs additional setup.\n </Typography>\n <Link \n href={`${API_CONFIG.baseUrl}/admin?tab=app_auth`}\n target=\"_blank\"\n sx={{ \n color: 'hsl(var(--severity-medium))', \n fontWeight: 500,\n fontSize: '0.85rem',\n textDecoration: 'underline',\n '&:hover': { opacity: 0.8 }\n }}\n >\n Check status in Admin → App Authentication\n </Link>\n </Box>\n </Alert>\n </Box>\n )}\n </Box>\n )}\n </Box>\n )}\n\n {/* Show form when no auths exist or \"Add new\" is selected */}\n {(apiAuthEntries.length === 0 || showAddNewForm) && (\n <Box sx={{ \n p: 3, \n backgroundColor: 'hsl(var(--background) / 0.4)', \n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n }}>\n {/* Show credential error notice if switched due to 401/403 */}\n {isCredentialError && (\n <Alert\n severity=\"warning\"\n sx={{\n backgroundColor: 'hsl(var(--severity-medium) / 0.1)',\n color: 'hsl(var(--severity-medium))',\n border: '1px solid hsl(var(--severity-medium) / 0.2)',\n borderRadius: 2,\n mb: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-medium))' },\n }}\n >\n <Typography sx={{ fontSize: '0.875rem' }}>\n {localTestMessages.errorCode === 401 \n ? 'Previous credentials were invalid or expired. Please enter new credentials.'\n : 'Access was denied with the previous credentials. Please re-authenticate with valid permissions.'}\n </Typography>\n </Alert>\n )}\n <Typography variant=\"subtitle2\" sx={{ color: 'hsl(var(--primary))', fontWeight: 600, mb: 2 }}>\n {apiAuthEntries.length === 0 ? 'Configure Authentication' : 'Add New Authentication'}\n </Typography>\n \n {loading ? (\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', py: 4 }}>\n <CircularProgress size={32} sx={{ color: 'hsl(var(--primary))' }} />\n <Typography sx={{ ml: 2, color: 'hsl(var(--muted-foreground))' }}>\n Loading configuration...\n </Typography>\n </Box>\n ) : error ? (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n {error}\n </Alert>\n ) : isNoAuthRequired(auth) ? (\n <Alert\n severity=\"info\"\n sx={{\n backgroundColor: 'hsl(var(--severity-info) / 0.1)',\n color: 'hsl(var(--severity-info))',\n border: '1px solid hsl(var(--severity-info) / 0.2)',\n borderRadius: 2,\n '& .MuiAlert-icon': { color: 'hsl(var(--severity-info))' },\n }}\n >\n <Box>\n <Typography sx={{ fontWeight: 600, mb: 0.5 }}>\n No authentication required\n </Typography>\n <Typography sx={{ fontSize: '0.85rem', opacity: 0.9 }}>\n This app works without credentials. You can use it directly.\n </Typography>\n </Box>\n </Alert>\n ) : (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n {/* Render dynamic fields based on auth type */}\n {renderOAuth2Fields()}\n {renderParameterFields()}\n\n {authState.status === 'error' && authState.errorMessage && (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, width: '100%' }}>\n <Typography sx={{ fontSize: '0.875rem', flex: 1 }}>\n {authState.errorMessage}\n </Typography>\n {authState.workflowId && authState.executionId && (\n <Button\n variant=\"outlined\"\n size=\"small\"\n href={`https://shuffler.io/workflows/${authState.workflowId}?execution_id=${authState.executionId}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={{\n borderColor: 'hsl(var(--destructive) / 0.5)',\n color: 'hsl(var(--destructive))',\n textTransform: 'none',\n fontSize: '0.75rem',\n py: 0.5,\n px: 1.5,\n flexShrink: 0,\n '&:hover': {\n borderColor: 'hsl(var(--destructive))',\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n },\n }}\n >\n View Execution\n </Button>\n )}\n </Box>\n </Alert>\n )}\n\n {/* Success message removed per user request */}\n\n {saveSuccess === false && (\n <Alert\n severity=\"error\"\n sx={{\n backgroundColor: 'hsl(var(--destructive) / 0.1)',\n color: 'hsl(var(--destructive))',\n border: '1px solid hsl(var(--destructive) / 0.3)',\n borderRadius: 2,\n }}\n >\n Failed to save authentication. Please try again.\n </Alert>\n )}\n\n {/* Save button for non-OAuth2 apps */}\n {!isOAuth2 && (\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', pt: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"medium\"\n onClick={(e) => {\n e.stopPropagation();\n handleSave();\n }}\n disabled={saving || !isFormValid()}\n sx={{\n borderColor: isFormValid() ? 'hsl(var(--primary) / 0.5)' : 'hsl(var(--border))',\n color: isFormValid() ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '0.9rem',\n px: 3,\n py: 1,\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n },\n }}\n >\n {saving ? 'Saving...' : 'Save Authentication'}\n </Button>\n </Box>\n )}\n\n {/* Save & Authenticate button for OAuth2 apps with manual credentials */}\n {isOAuth2 && (() => {\n const hasClientId = !!localCredentials['client_id']?.trim();\n const hasClientSecret = !!localCredentials['client_secret']?.trim();\n const hasScopes = selectedScopes.length > 0;\n const hasAuthUrl = !!auth?.authorization_url;\n const allFilled = hasClientId && hasClientSecret && (!auth?.scope?.length || hasScopes);\n\n // Build the direct OAuth2 authorization URL with state\n const buildOAuth2Url = (): string | null => {\n if (!localCredentials['client_id']?.trim()) return null;\n \n // Resolve authorization URL from multiple possible fields,\n // or derive from token_uri (common pattern: /token → /authorize)\n const authorizationUrl = auth?.authorization_url \n || auth?.auth_uri \n || auth?.authorize_url\n || (auth?.token_uri ? auth.token_uri.replace(/\\/token\\b.*$/, '/authorize') : null);\n \n if (!authorizationUrl) return null;\n \n const redirectUri = auth?.redirect_uri || 'https://shuffler.io/set_authentication';\n const scopes = selectedScopes.join(' ');\n const clientId = localCredentials['client_id'].trim();\n const clientSecret = localCredentials['client_secret']?.trim() || '';\n\n // Build state parameter matching Shuffle's expected format\n const stateParams = new URLSearchParams({\n workflow_id: '',\n reference_action_id: app.objectID,\n app_name: app.name,\n app_id: app.objectID,\n app_version: app.app_version || '1.0.0',\n authentication_url: auth?.token_uri || '',\n scope: scopes,\n client_id: clientId,\n client_secret: clientSecret,\n org_id: 'undefined',\n oauth_url: auth?.token_uri?.replace(/\\/token.*$/, '') || '',\n refresh_uri: auth?.refresh_uri || auth?.token_uri || '',\n });\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n prompt: 'login',\n scope: scopes,\n state: stateParams.toString(),\n access_type: 'offline',\n });\n\n return `${authorizationUrl}?${params.toString()}`;\n };\n\n return (\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', pt: 1.5 }}>\n <Button\n variant=\"outlined\"\n size=\"medium\"\n startIcon={\n app.image_url ? (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 20, height: 20, borderRadius: 0.5, objectFit: 'contain' }}\n />\n ) : (\n <LockIcon size={18} />\n )\n }\n onClick={(e) => {\n e.stopPropagation();\n // Open OAuth2 popup directly — no save step needed\n // The OAuth redirect callback handles credential storage\n const directUrl = buildOAuth2Url();\n const popupUrl = directUrl || `https://shuffler.io/appauth?app_id=${app.objectID}&source=shuffle`;\n const popup = window.open(popupUrl, '_blank', 'width=600,height=700');\n if (popup && onRefreshAuth) {\n const authPollTimer = setInterval(() => {\n onRefreshAuth();\n }, 3000);\n const closePollTimer = setInterval(() => {\n if (popup.closed) {\n clearInterval(closePollTimer);\n clearInterval(authPollTimer);\n onRefreshAuth();\n }\n }, 500);\n }\n }}\n disabled={!allFilled}\n sx={{\n borderColor: allFilled ? 'hsl(var(--primary) / 0.5)' : 'hsl(var(--border))',\n color: allFilled ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n fontWeight: 600,\n textTransform: 'none',\n fontSize: '0.9rem',\n px: 3,\n py: 1,\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n borderColor: 'hsl(var(--primary))',\n backgroundColor: 'hsl(var(--primary) / 0.08)',\n },\n '&.Mui-disabled': {\n borderColor: 'hsl(var(--border))',\n color: 'hsl(var(--muted-foreground))',\n },\n }}\n >\n Authenticate\n </Button>\n </Box>\n );\n })()}\n </Box>\n )}\n </Box>\n )}\n </Box>\n </Collapse>\n </Card>\n\n {/* Documentation Modal */}\n <Dialog\n open={docsOpen}\n onClose={() => setDocsOpen(false)}\n maxWidth=\"md\"\n fullWidth\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'background.paper',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 3,\n maxHeight: '80vh',\n },\n },\n }}\n >\n <DialogTitle\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n borderBottom: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>\n {app.image_url && (\n <Box\n component=\"img\"\n src={app.image_url}\n alt={app.name}\n sx={{ width: 32, height: 32, borderRadius: 1, objectFit: 'contain' }}\n />\n )}\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n {app.name.replace(/_/g, ' ')} Documentation\n </Typography>\n </Box>\n <IconButton onClick={() => setDocsOpen(false)} sx={{ color: 'hsl(var(--muted-foreground))' }}>\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n <DialogContent sx={{ pt: 3 }}>\n {docsLoading ? (\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', py: 6 }}>\n <CircularProgress size={32} sx={{ color: 'hsl(var(--primary))' }} />\n <Typography sx={{ ml: 2, color: 'hsl(var(--muted-foreground))' }}>\n Loading documentation...\n </Typography>\n </Box>\n ) : (\n <Box\n sx={{\n color: 'hsl(var(--foreground))',\n '& h1, & h2, & h3, & h4': { color: 'hsl(var(--foreground))', mt: 3, mb: 2 },\n '& p': { mb: 2, lineHeight: 1.7 },\n '& code': {\n backgroundColor: 'hsl(var(--muted))',\n px: 1,\n py: 0.5,\n borderRadius: 1,\n fontSize: '0.875rem',\n },\n '& pre': {\n backgroundColor: 'hsl(var(--background))',\n p: 2,\n borderRadius: 2,\n overflow: 'auto',\n },\n '& a': { color: 'hsl(var(--primary))' },\n '& ul, & ol': { pl: 3, mb: 2 },\n '& li': { mb: 1 },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{docsContent}</ReactMarkdown>\n </Box>\n )}\n </DialogContent>\n </Dialog>\n </motion.div>\n );\n};\n\nexport const AppAuthConfig = ({\n apps,\n authStates,\n authenticatedApps = [],\n onAuthChange,\n onTestConnection,\n onSaveAuth,\n onSelectAuth,\n onRefreshAuth,\n}: AppAuthConfigProps) => {\n // Helper to find ALL API auth entries for an app\n const getApiAuthEntries = (app: AlgoliaSearchApp): ApiAuthEntry[] => {\n const normalize = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n return authenticatedApps\n .filter(auth => normalize(auth.app?.name || '') === normalize(app.name))\n .map(auth => ({\n ...auth,\n app: {\n ...auth.app,\n large_image: auth.app?.large_image || app.image_url,\n },\n }));\n };\n\n // Helper to check if app is configured (has any auth entry)\n const isAppConfigured = (app: AlgoliaSearchApp): boolean => {\n const entries = getApiAuthEntries(app);\n return entries.some(e => e.active === true);\n };\n\n // Helper to check if app is validated (data is already pre-processed to invalidate old entries)\n const isAppValidated = (app: AlgoliaSearchApp): boolean => {\n const entries = getApiAuthEntries(app);\n return entries.some(e => e.validation?.valid === true);\n };\n\n // Keep initial sort order stable - only sort once when authenticatedApps is loaded\n const initialSortRef = useRef<AlgoliaSearchApp[] | null>(null);\n const authAppsLoadedRef = useRef<boolean>(false);\n \n // Reset sort ref when authenticatedApps first loads with data\n if (!authAppsLoadedRef.current && authenticatedApps.length > 0) {\n authAppsLoadedRef.current = true;\n initialSortRef.current = null; // Force re-sort\n }\n \n if (initialSortRef.current === null && apps.length > 0 && authenticatedApps.length > 0) {\n // Sort priority: \n // 1. Category-matched apps (email, siem, edr, cases) first\n // 2. Within each group: Not Configured > Not Tested > Tested\n const getPriority = (app: AlgoliaSearchApp): number => {\n const isSourceCategory = getIngestionCategory(app.name, app.categories) !== null;\n const configured = isAppConfigured(app);\n const validated = isAppValidated(app);\n \n // Category apps get priority 0-2, non-category apps get 3-5\n const base = isSourceCategory ? 0 : 3;\n if (!configured) return base; // Not Configured - top of group\n if (!validated) return base + 1; // Configured but Not Tested - middle\n return base + 2; // Tested - bottom of group\n };\n \n initialSortRef.current = [...apps].sort((a, b) => {\n return getPriority(a) - getPriority(b);\n });\n }\n\n // Use the stable initial sort, or fall back to apps if not yet initialized\n const sortedApps = initialSortRef.current || apps;\n\n // Find first non-validated app for auto-expand (prefer not configured, then not tested)\n const firstNotConfigured = sortedApps.find(app => !isAppConfigured(app));\n const firstNotValidated = sortedApps.find(app => !isAppValidated(app));\n // If every app is already validated, start with all cards collapsed — the\n // user has nothing left to do here, so do not auto-open one for them.\n const defaultExpanded = firstNotConfigured?.objectID || firstNotValidated?.objectID || false;\n\n const [expanded, setExpanded] = useState<string | false>(defaultExpanded);\n\n if (apps.length === 0) {\n return (\n <Alert\n severity=\"info\"\n sx={{\n backgroundColor: 'hsl(var(--primary) / 0.1)',\n color: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary) / 0.3)',\n borderRadius: 2,\n }}\n >\n No integrations selected. Go back and select at least one integration.\n </Alert>\n );\n }\n\n // Count validated vs total\n const validatedCount = sortedApps.filter(app => isAppValidated(app)).length;\n const totalCount = sortedApps.length;\n\n return (\n <Box sx={{ width: '100%', maxWidth: '100%', overflow: 'hidden' }}>\n <Typography\n variant=\"h5\"\n sx={{\n color: 'hsl(var(--foreground))',\n fontWeight: 700,\n mb: 1,\n fontSize: { xs: '1.25rem', sm: '1.5rem' },\n }}\n >\n Configure Authentication\n </Typography>\n <Typography\n variant=\"body1\"\n sx={{ mb: 2, color: 'hsl(var(--muted-foreground))', fontSize: { xs: '0.875rem', sm: '1rem' } }}\n >\n Set up credentials for each integration. Apps with orange borders need configuration.\n </Typography>\n <Chip\n label={`${validatedCount}/${totalCount} validated`}\n size=\"small\"\n sx={{\n mb: 3,\n background: validatedCount === totalCount \n ? 'hsl(var(--severity-low) / 0.15)' \n : 'hsl(var(--severity-medium) / 0.15)',\n color: validatedCount === totalCount ? 'hsl(var(--severity-low))' : 'hsl(var(--severity-medium))',\n fontWeight: 600,\n }}\n />\n\n <motion.div variants={containerVariants} initial=\"hidden\" animate=\"visible\">\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%', maxWidth: '100%' }}>\n {sortedApps.map((app) => {\n const authState = authStates[app.objectID] || { systemId: app.objectID, status: 'pending' as const, credentials: {} };\n const isExpanded = expanded === app.objectID;\n const apiAuthEntries = getApiAuthEntries(app);\n\n return (\n <AppAuthCard\n key={app.objectID}\n app={app}\n authState={authState}\n isExpanded={isExpanded}\n onToggle={() => setExpanded(isExpanded ? false : app.objectID)}\n onAuthChange={onAuthChange}\n onTestConnection={onTestConnection}\n onSaveAuth={onSaveAuth}\n apiAuthEntries={apiAuthEntries}\n onSelectAuth={onSelectAuth}\n onRefreshAuth={onRefreshAuth}\n />\n );\n })}\n </Box>\n </motion.div>\n </Box>\n );\n};\n","/**\n * AppFallbackIcon — lightweight, list-friendly app icon with graceful fallback.\n *\n * Resolution order:\n * 1. The provided `imageUrl` (if any). If it loads, we use it.\n * 2. If it 404s OR is empty, look up the app by name in the Algolia\n * `appsearch` index (module-level cache so 100 list items only fire\n * one search per unique name).\n * 3. If Algolia has no match, render a colored letter avatar derived\n * from the app name.\n *\n * Designed to drop into <ShuffleMCP />'s grid items where the previous\n * code only rendered an <img> when `image_url` was non-empty (causing\n * blank tiles for private/custom apps without uploaded icons).\n */\n\nimport { useEffect, useRef, useState, CSSProperties } from 'react';\n\nconst norm = (s: string) => s.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\n// ---------------------------------------------------------------------------\n// Persistent app-icon URL cache (localStorage)\n// ---------------------------------------------------------------------------\n// We resolve image_url -> name once (via Algolia) and persist the mapping so\n// reloads do not have to round-trip the network just to render an app icon.\n// Cache is namespaced + versioned so we can invalidate it cleanly later.\nconst STORAGE_KEY = 'shuffle:app-icon-cache:v1';\nconst STORAGE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\ninterface PersistedEntry { url: string; ts: number; }\ntype PersistedMap = Record<string, PersistedEntry>;\n\nconst readPersisted = (): PersistedMap => {\n if (typeof window === 'undefined') return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n return (parsed && typeof parsed === 'object') ? parsed : {};\n } catch {\n return {};\n }\n};\n\nconst writePersisted = (key: string, url: string) => {\n if (typeof window === 'undefined' || !url) return;\n try {\n const map = readPersisted();\n map[key] = { url, ts: Date.now() };\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(map));\n } catch {\n /* quota / privacy mode — fail silently */\n }\n};\n\nconst readPersistedFresh = (key: string): string | null => {\n const entry = readPersisted()[key];\n if (!entry) return null;\n if (Date.now() - entry.ts > STORAGE_TTL_MS) return null;\n return entry.url || null;\n};\n\n// Module-level memo so every grid item shares the same in-flight cache.\nconst lookupCache = new Map<string, Promise<string>>();\n\nconst lookupImageByName = (name: string): Promise<string> => {\n const key = norm(name);\n if (!key) return Promise.resolve('');\n const hit = lookupCache.get(key);\n if (hit) return hit;\n\n // localStorage hit -> resolve synchronously without hitting Algolia.\n const persisted = readPersistedFresh(key);\n if (persisted) {\n const p = Promise.resolve(persisted);\n lookupCache.set(key, p);\n return p;\n }\n\n const promise = (async () => {\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const res = await client.search({\n requests: [{ indexName: 'appsearch', query: name.replace(/_/g, ' '), hitsPerPage: 5 }],\n });\n const hits = ((res as any)?.results?.[0]?.hits || []) as any[];\n const match = hits.find((h) => h.name && norm(h.name) === key) || hits[0];\n const url = (match?.image_url as string) || '';\n if (url) writePersisted(key, url);\n return url;\n } catch {\n return '';\n }\n })();\n\n lookupCache.set(key, promise);\n return promise;\n};\n\n/** Eagerly persist a known-good app image URL (e.g. when /api/v1/apps already\n * returned image_url). Lets later renders skip the Algolia round-trip. */\nexport const rememberAppImage = (name: string, url: string) => {\n if (!name || !url) return;\n writePersisted(norm(name), url);\n};\n\n// Stable, accessible color from a string (HSL hue 0-360).\nconst colorFromName = (name: string): string => {\n let h = 0;\n for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0;\n return `hsl(${h % 360}, 55%, 45%)`;\n};\n\ninterface AppFallbackIconProps {\n name: string;\n imageUrl?: string;\n size?: number;\n style?: CSSProperties;\n className?: string;\n alt?: string;\n}\n\nexport const AppFallbackIcon = ({\n name,\n imageUrl,\n size = 28,\n style,\n className,\n alt,\n}: AppFallbackIconProps) => {\n // Initial src: prop > persisted-localStorage hit > empty (will lookup).\n const [src, setSrc] = useState<string>(() => imageUrl || readPersistedFresh(norm(name || '')) || '');\n const [errored, setErrored] = useState(false);\n const lookedUpRef = useRef(false);\n\n // Remember a working caller-provided URL so future reloads skip the network.\n useEffect(() => {\n if (imageUrl && name) writePersisted(norm(name), imageUrl);\n }, [imageUrl, name]);\n\n // Reset when props change\n useEffect(() => {\n setSrc(imageUrl || readPersistedFresh(norm(name || '')) || '');\n setErrored(false);\n lookedUpRef.current = false;\n }, [imageUrl, name]);\n\n // Trigger lookup when we have no imageUrl OR after the provided one errored.\n useEffect(() => {\n if (lookedUpRef.current) return;\n if (src) return;\n if (!name) return;\n lookedUpRef.current = true;\n lookupImageByName(name).then((found) => {\n if (found) {\n setSrc(found);\n setErrored(false);\n }\n });\n }, [src, name]);\n\n const baseStyle: CSSProperties = {\n width: size,\n height: size,\n borderRadius: 6,\n flexShrink: 0,\n objectFit: 'contain',\n ...style,\n };\n\n if (src && !errored) {\n return (\n <img\n src={src}\n alt={alt || name}\n className={className}\n style={baseStyle}\n onError={() => {\n // Fall through to letter avatar; the lookup effect will also\n // try once if we have not already looked up.\n setErrored(true);\n setSrc('');\n }}\n />\n );\n }\n\n // Letter avatar fallback\n const display = (name || '?').trim();\n const letter = (display.replace(/[^a-z0-9]/i, '').charAt(0) || '?').toUpperCase();\n return (\n <div\n className={className}\n style={{\n ...baseStyle,\n background: colorFromName(display || '?'),\n color: '#fff',\n fontSize: Math.round(size * 0.5),\n fontWeight: 600,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n textTransform: 'uppercase',\n letterSpacing: 0,\n }}\n aria-label={alt || display}\n >\n {letter}\n </div>\n );\n};\n\nexport default AppFallbackIcon;\n","/**\n * TryMcpSection — Standalone \"Try MCP\" block.\n *\n * Wraps the heading + AppMcpChat. Pass in the resolved app props.\n */\n\nimport { Box, Typography } from '@mui/material';\nimport { motion } from 'framer-motion';\nimport AppMcpChat from '@/Shuffle-MCPs/AppMcpChat';\n\nexport interface TryMcpSectionProps {\n appName: string;\n /** Image URL used as the chat avatar. */\n appIcon?: string;\n /** Resolved app id (Algolia objectID or Shuffle id). */\n appId: string;\n /** App categories — used to pick suggested actions. */\n categories?: string[];\n}\n\nexport default function TryMcpSection({ appName, appIcon, appId, categories }: TryMcpSectionProps) {\n return (\n <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: 0.15 }}>\n <Box sx={{ mt: 5, mb: 3 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem', mb: 1.5 }}>\n Try MCP\n </Typography>\n <AppMcpChat\n appName={appName}\n appIcon={appIcon}\n appId={appId}\n categories={categories}\n />\n </Box>\n </motion.div>\n );\n}\n","import { useState, useRef, useMemo } from 'react';\nimport {\n CheckCircle as CheckCircleOutlineIcon,\n AlertCircle as ErrorOutlineIcon,\n Play as PlayArrowRoundedIcon,\n RotateCcw as RestartAltIcon\n} from 'lucide-react';\nimport {\n Box,\n Typography,\n Avatar,\n CircularProgress,\n Chip,\n InputBase,\n} from '@mui/material';\nimport AgentIcon from '@/Shuffle-MCPs/AgentIcon';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport {\n THREAT_INTEL_PATTERNS,\n EMAIL_APP_PATTERNS,\n EDR_PATTERNS,\n SIEM_PATTERNS,\n CASES_PATTERNS,\n COMMUNICATION_PATTERNS_NAMES,\n} from '@/Shuffle-MCPs/ingestionDetection';\n\ninterface AppMcpChatProps {\n appName: string;\n appIcon?: string;\n appId?: string;\n categories?: string[];\n}\n\ntype RunState = 'idle' | 'running' | 'done';\n\n/** Category-based suggestion prompts — natural, actionable questions.\n * Keys are lowercase fragments that we match against app category strings. */\nconst CATEGORY_SUGGESTIONS: Record<string, string[]> = {\n 'threat': [\n 'Is 1.2.3.4 a known bad actor?',\n 'Check if this domain is malicious',\n 'Look up threat indicators for a hash',\n ],\n 'siem': [\n 'Show me the latest critical alerts',\n 'Any unusual login attempts today?',\n 'Summarize recent security events',\n ],\n 'email': [\n 'Did I get a message from my team yesterday?',\n 'Find emails with attachments from last week',\n 'Check for any phishing reports',\n ],\n 'communication': [\n 'Did I get a message from my team yesterday?',\n 'Send a status update to the channel',\n 'Check for unread notifications',\n ],\n 'edr': [\n 'Is this endpoint compromised?',\n 'Show recent detections on workstations',\n 'Isolate a suspicious host',\n ],\n 'endpoint': [\n 'Is this endpoint compromised?',\n 'Show recent detections on workstations',\n 'Isolate a suspicious host',\n ],\n 'cloud': [\n 'List my running instances',\n 'Any public S3 buckets detected?',\n 'Check IAM policy changes today',\n ],\n 'ticket': [\n 'What tickets are assigned to me?',\n 'Create a new incident ticket',\n 'Show open high-priority issues',\n ],\n 'itsm': [\n 'What tickets are assigned to me?',\n 'Create a new incident ticket',\n 'Show open high-priority issues',\n ],\n 'case': [\n 'What cases are assigned to me?',\n 'Create a new incident case',\n 'Show open high-priority cases',\n ],\n 'vulnerab': [\n 'Any new critical CVEs this week?',\n 'Check vulnerability status for this asset',\n 'Show unpatched systems',\n ],\n 'network': [\n 'Any unusual outbound connections?',\n 'Check firewall rule changes',\n 'Show top talkers in the last hour',\n ],\n 'identity': [\n 'Show recent failed login attempts',\n 'Is this user account locked out?',\n 'List users with admin privileges',\n ],\n 'intel': [\n 'Is 1.2.3.4 a known bad actor?',\n 'Check if this domain is malicious',\n 'Look up threat indicators for a hash',\n ],\n};\n\nconst DEFAULT_SUGGESTIONS = [\n 'What can you do?',\n 'Show me recent activity',\n 'Run a quick check',\n];\n\n/** Infer category keys from the app name using known patterns */\nfunction inferCategoryKeysFromName(appName: string): string[] {\n const name = appName.toLowerCase();\n const keys: string[] = [];\n if (THREAT_INTEL_PATTERNS.some(p => name.includes(p))) keys.push('threat', 'intel');\n if (EMAIL_APP_PATTERNS.some(p => name.includes(p))) keys.push('email');\n if (EDR_PATTERNS.some(p => name.includes(p))) keys.push('edr', 'endpoint');\n if (SIEM_PATTERNS.some(p => name.includes(p))) keys.push('siem');\n if (CASES_PATTERNS.some(p => name.includes(p))) keys.push('ticket', 'case');\n if (COMMUNICATION_PATTERNS_NAMES.some(p => name.includes(p))) keys.push('communication');\n return keys;\n}\n\nfunction getSuggestions(appName: string, categories?: string[]): string[] {\n const matched: string[] = [];\n\n // 1. Match from explicit categories\n if (categories && categories.length > 0) {\n for (const cat of categories) {\n const normalized = cat.toLowerCase();\n for (const [key, prompts] of Object.entries(CATEGORY_SUGGESTIONS)) {\n if (normalized.includes(key) || key.includes(normalized)) {\n matched.push(...prompts);\n }\n }\n }\n }\n\n // 2. Fallback: infer from the app name itself\n if (matched.length === 0) {\n const inferred = inferCategoryKeysFromName(appName);\n for (const inferredKey of inferred) {\n const prompts = CATEGORY_SUGGESTIONS[inferredKey];\n if (prompts) matched.push(...prompts);\n }\n }\n\n if (matched.length === 0) return DEFAULT_SUGGESTIONS;\n\n const unique = [...new Set(matched)];\n return unique.slice(0, 4);\n}\n\n/** Pick a short display label from categories, or infer from app name */\nfunction getPrimaryCategory(appName: string, categories?: string[]): string | null {\n if (categories && categories.length > 0) {\n const skip = ['other', 'general', 'integration'];\n const filtered = categories.filter(c => !skip.includes(c.toLowerCase()));\n if (filtered.length > 0) return filtered[0];\n return categories[0];\n }\n // Infer from name\n const name = appName.toLowerCase();\n if (THREAT_INTEL_PATTERNS.some(p => name.includes(p))) return 'Threat Intel';\n if (EMAIL_APP_PATTERNS.some(p => name.includes(p))) return 'Email';\n if (EDR_PATTERNS.some(p => name.includes(p))) return 'EDR';\n if (SIEM_PATTERNS.some(p => name.includes(p))) return 'SIEM';\n if (CASES_PATTERNS.some(p => name.includes(p))) return 'Ticketing';\n if (COMMUNICATION_PATTERNS_NAMES.some(p => name.includes(p))) return 'Communication';\n return null;\n}\n\nconst AppMcpChat = ({ appName, appIcon, appId, categories }: AppMcpChatProps) => {\n const [input, setInput] = useState('');\n const [runState, setRunState] = useState<RunState>('idle');\n const [query, setQuery] = useState('');\n const [result, setResult] = useState('');\n const [isError, setIsError] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const suggestions = useMemo(() => getSuggestions(appName, categories), [appName, categories]);\n const primaryCategory = useMemo(() => getPrimaryCategory(appName, categories), [appName, categories]);\n const MIN_INPUT_LENGTH = 6;\n const runAction = async () => {\n const trimmed = input.trim();\n if (trimmed.length < MIN_INPUT_LENGTH || runState === 'running') return;\n\n setQuery(trimmed);\n setInput('');\n setRunState('running');\n setResult('');\n setIsError(false);\n\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(appName)}/mcp`),\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n ...getAuthHeader(),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: crypto.randomUUID(),\n method: 'tools/call',\n params: {\n tool_name: appName,\n tool_id: appId || appName,\n input: { text: trimmed },\n },\n }),\n }\n );\n\n // Read raw text first to handle non-JSON responses safely\n const rawText = await response.text();\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n setIsError(true);\n setResult(`Error ${response.status}: ${rawText || response.statusText}`);\n } else if (!contentType?.includes('application/json')) {\n // Got HTML or other non-JSON back\n if (rawText.trim().startsWith('<!') || rawText.includes('<html')) {\n setIsError(true);\n setResult(`Received an unexpected HTML response (status ${response.status}). This may indicate an auth redirect or server issue.`);\n } else {\n setResult(rawText);\n }\n } else {\n const data = JSON.parse(rawText);\n let content = '';\n\n if (typeof data === 'string') {\n content = data;\n } else if (data?.result) {\n // Extract message if result is an object with a message field\n if (typeof data.result === 'object' && data.result !== null) {\n if (data.result.message) {\n content = data.result.message;\n }\n // Append remaining fields as context if there's more than just message\n const rest = { ...data.result };\n delete rest.message;\n if (Object.keys(rest).length > 0) {\n const extra = JSON.stringify(rest, null, 2);\n content = content\n ? `${content}\\n\\n\\`\\`\\`json\\n${extra}\\n\\`\\`\\``\n : `\\`\\`\\`json\\n${extra}\\n\\`\\`\\``;\n }\n } else {\n content = String(data.result);\n }\n } else if (data?.response) {\n content = typeof data.response === 'string' ? data.response : JSON.stringify(data.response, null, 2);\n } else if (data?.message) {\n content = data.message;\n } else {\n content = `\\`\\`\\`json\\n${JSON.stringify(data, null, 2)}\\n\\`\\`\\``;\n }\n\n if (content) {\n setResult(content);\n } else {\n setResult('No output returned.');\n }\n }\n } catch (err) {\n setIsError(true);\n setResult(`Could not connect. ${err instanceof Error ? err.message : 'Unknown error'}`);\n } finally {\n setRunState('done');\n }\n };\n\n const reset = () => {\n setRunState('idle');\n setQuery('');\n setResult('');\n setIsError(false);\n setInput('');\n setTimeout(() => inputRef.current?.focus(), 50);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n runAction();\n }\n };\n\n const displayName = appName.replace(/_/g, ' ');\n\n return (\n <Box\n sx={{\n borderRadius: 3,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background))',\n overflow: 'hidden',\n }}\n >\n <AnimatePresence mode=\"wait\">\n {/* ── IDLE ── */}\n {runState === 'idle' && (\n <motion.div\n key=\"idle\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n >\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2.5 }}>\n {/* Label */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box\n sx={{\n width: 28,\n height: 28,\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsl(var(--primary) / 0.1)',\n border: '1px solid hsl(var(--primary) / 0.2)',\n flexShrink: 0,\n }}\n >\n {appIcon ? (\n <Avatar\n src={appIcon}\n sx={{ width: 18, height: 18, '& img': { objectFit: 'contain' } }}\n />\n ) : (\n <AgentIcon size={16} />\n )}\n </Box>\n <Typography sx={{ fontSize: '0.8rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n Try it out\n </Typography>\n {primaryCategory && (\n <Chip\n label={primaryCategory}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 600,\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'capitalize',\n }}\n />\n )}\n <Chip\n label=\"MCP\"\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.6rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n letterSpacing: '0.06em',\n ml: 'auto',\n }}\n />\n </Box>\n\n {/* Command input */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--card))',\n px: 1.5,\n py: 0.75,\n transition: 'border-color 0.15s ease, box-shadow 0.15s ease',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary) / 0.5)',\n boxShadow: '0 0 0 3px hsl(var(--primary) / 0.08)',\n },\n }}\n >\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--primary))', fontWeight: 600, userSelect: 'none', fontFamily: \"'JetBrains Mono', monospace\" }}>\n ›\n </Typography>\n <InputBase\n inputRef={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={`Ask ${displayName} something…`}\n fullWidth\n sx={{\n fontSize: '0.82rem',\n color: 'hsl(var(--foreground))',\n '& input::placeholder': {\n color: 'hsl(var(--muted-foreground))',\n opacity: 0.7,\n },\n }}\n />\n <Box\n component=\"button\"\n onClick={runAction}\n disabled={input.trim().length < MIN_INPUT_LENGTH}\n title={input.trim().length < MIN_INPUT_LENGTH ? `Enter at least ${MIN_INPUT_LENGTH} characters` : undefined}\n sx={{\n all: 'unset',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 30,\n height: 30,\n borderRadius: '8px',\n flexShrink: 0,\n cursor: input.trim().length >= MIN_INPUT_LENGTH ? 'pointer' : 'not-allowed',\n backgroundColor: input.trim().length >= MIN_INPUT_LENGTH ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: input.trim().length >= MIN_INPUT_LENGTH ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n transition: 'all 0.15s ease',\n '&:hover': input.trim().length >= MIN_INPUT_LENGTH ? {\n filter: 'brightness(1.1)',\n } : {},\n }}\n >\n <PlayArrowRoundedIcon size={18} />\n </Box>\n </Box>\n\n {/* Quick actions */}\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75 }}>\n {suggestions.map((s) => (\n <Chip\n key={s}\n label={s}\n size=\"small\"\n onClick={() => {\n setInput(s);\n inputRef.current?.focus();\n }}\n sx={{\n height: 26,\n fontSize: '0.7rem',\n fontWeight: 500,\n cursor: 'pointer',\n backgroundColor: 'transparent',\n color: 'hsl(var(--muted-foreground))',\n border: '1px dashed hsl(var(--border))',\n transition: 'all 0.15s ease',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n borderStyle: 'solid',\n borderColor: 'hsl(var(--primary) / 0.3)',\n },\n }}\n />\n ))}\n </Box>\n </Box>\n </motion.div>\n )}\n\n {/* ── RUNNING ── */}\n {runState === 'running' && (\n <motion.div\n key=\"running\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n >\n <Box sx={{ p: 3, display: 'flex', alignItems: 'center', gap: 2 }}>\n <CircularProgress size={20} thickness={5} sx={{ color: 'hsl(var(--primary))' }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n Executing…\n </Typography>\n <Typography\n sx={{\n fontSize: '0.72rem',\n color: 'hsl(var(--muted-foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontFamily: \"'JetBrains Mono', monospace\",\n }}\n >\n › {query}\n </Typography>\n </Box>\n </Box>\n </motion.div>\n )}\n\n {/* ── DONE ── */}\n {runState === 'done' && (\n <motion.div\n key=\"done\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n >\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2 }}>\n {/* Status bar */}\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {isError ? (\n <ErrorOutlineIcon size={18} color={'hsl(0 70% 55%)'} />\n ) : (\n <CheckCircleOutlineIcon size={18} color={'hsl(145 60% 45%)'} />\n )}\n <Typography sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {isError ? 'Failed' : 'Completed'}\n </Typography>\n </Box>\n <Chip\n icon={<RestartAltIcon size={14} />}\n label=\"Run again\"\n size=\"small\"\n onClick={reset}\n sx={{\n height: 26,\n fontSize: '0.7rem',\n fontWeight: 500,\n cursor: 'pointer',\n backgroundColor: 'transparent',\n color: 'hsl(var(--muted-foreground))',\n border: '1px solid hsl(var(--border))',\n transition: 'all 0.15s ease',\n '&:hover': {\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n },\n }}\n />\n </Box>\n\n {/* Query echo */}\n <Typography\n sx={{\n fontSize: '0.72rem',\n color: 'hsl(var(--muted-foreground))',\n fontFamily: \"'JetBrains Mono', monospace\",\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n › {query}\n </Typography>\n\n {/* Output */}\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n backgroundColor: 'hsl(var(--card))',\n border: '1px solid',\n borderColor: isError ? 'hsl(0 60% 50% / 0.25)' : 'hsl(var(--border))',\n maxHeight: 340,\n overflowY: 'auto',\n '&::-webkit-scrollbar': { width: 4 },\n '&::-webkit-scrollbar-track': { background: 'transparent' },\n '&::-webkit-scrollbar-thumb': {\n background: 'hsl(var(--border))',\n borderRadius: 2,\n },\n '& p': {\n fontSize: '0.8rem',\n lineHeight: 1.65,\n color: 'hsl(var(--foreground))',\n m: 0,\n '&:not(:last-child)': { mb: 1 },\n },\n '& pre': {\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1,\n p: 1.5,\n overflow: 'auto',\n fontSize: '0.72rem',\n fontFamily: \"'JetBrains Mono', monospace\",\n my: 1,\n },\n '& code': {\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n backgroundColor: 'hsl(var(--muted))',\n px: 0.5,\n borderRadius: 0.5,\n },\n '& pre code': { backgroundColor: 'transparent', p: 0 },\n '& ul, & ol': {\n pl: 2,\n fontSize: '0.8rem',\n color: 'hsl(var(--foreground))',\n },\n '& a': {\n color: 'hsl(var(--primary))',\n textDecoration: 'underline',\n },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {result}\n </ReactMarkdown>\n </Box>\n </Box>\n </motion.div>\n )}\n </AnimatePresence>\n </Box>\n );\n};\n\nexport default AppMcpChat;\n","import singulAgentIcon from '@/assets/singul-agent-icon.png';\n\ninterface AgentIconProps {\n size?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Renders the Singul agent icon — use this everywhere instead of 🤖.\n */\nconst AgentIcon = ({ size = 16, className, style }: AgentIconProps) => (\n <img\n src={singulAgentIcon}\n alt=\"AI Agent\"\n width={size}\n height={size}\n className={className}\n style={{ borderRadius: '3px', objectFit: 'contain', ...style }}\n />\n);\n\nexport default AgentIcon;\n","/**\n * SingulActionsPreview — Standalone \"Try individual actions\" block.\n *\n * Renders the action picker (grouped by category), curl/python toggle,\n * editable snippet, Play button (calls Shuffle Tools `execute_python` or\n * the http app `curl` action) and a response area that streams in.\n *\n * Self-contained — pass in the app name + categories. Optionally pass\n * `activeOrgId` so multi-org curl previews include the right Org-Id header.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport {\n Box,\n Typography,\n Chip,\n Button,\n Autocomplete,\n TextField,\n IconButton,\n Tooltip,\n Avatar,\n} from '@mui/material';\nimport {\n Code2,\n Terminal,\n Check as CheckIcon,\n Copy as ContentCopyIcon,\n Lock as LockIcon,\n Play as PlayArrowIcon\n} from 'lucide-react';\nimport { API_CONFIG, getApiUrl, getAuthHeader, getTrackedOrgId } from '@/Shuffle-MCPs/api';\nimport JsonView from 'react18-json-view';\nimport 'react18-json-view/src/style.css';\nimport 'react18-json-view/src/dark.css';\n\n/** Recursively parse JSON-looking strings into objects/arrays so JsonView can collapse them. */\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n } catch { /* ignore */ }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\ninterface SingulAction {\n name: string;\n label: string;\n category: string;\n fields: { name: string; value: string }[];\n}\n\n/** Default starter fields per canonical action (lowercased snake_case key). */\nconst ACTION_DEFAULT_FIELDS: Record<string, { name: string; value: string }[]> = {\n list_messages: [{ name: 'channel', value: '#general' }, { name: 'limit', value: '10' }],\n send_message: [{ name: 'channel', value: '#general' }, { name: 'message', value: 'Hello from Shuffle' }],\n get_message: [{ name: 'message_id', value: '' }],\n search_messages: [{ name: 'query', value: 'incident' }],\n list_attachments: [{ name: 'message_id', value: '' }],\n get_attachment: [{ name: 'attachment_id', value: '' }],\n get_contact: [{ name: 'email', value: 'user@example.com' }],\n\n search: [{ name: 'query', value: 'event.type:login' }, { name: 'time_range', value: '24h' }],\n list_alerts: [{ name: 'severity', value: 'high' }],\n close_alert: [{ name: 'alert_id', value: '' }],\n get_alert: [{ name: 'alert_id', value: '' }],\n create_detection: [{ name: 'name', value: 'My detection' }, { name: 'query', value: 'event.type:login AND result:failure' }],\n add_to_lookup_list: [{ name: 'list_name', value: 'blocked_ips' }, { name: 'value', value: '1.2.3.4' }],\n isolate_endpoint: [{ name: 'host_id', value: '' }],\n\n block_hash: [{ name: 'hash', value: 'd41d8cd98f00b204e9800998ecf8427e' }],\n search_hosts: [{ name: 'query', value: 'hostname:laptop-*' }],\n isolate_host: [{ name: 'host_id', value: '' }],\n unisolate_host: [{ name: 'host_id', value: '' }],\n trigger_host_scan: [{ name: 'host_id', value: '' }],\n\n list_tickets: [{ name: 'status', value: 'open' }],\n get_ticket: [{ name: 'ticket_id', value: '' }],\n create_ticket: [{ name: 'title', value: 'New incident' }, { name: 'description', value: '' }, { name: 'priority', value: 'medium' }],\n close_ticket: [{ name: 'ticket_id', value: '' }],\n add_comment: [{ name: 'ticket_id', value: '' }, { name: 'comment', value: 'Investigation update' }],\n update_ticket: [{ name: 'ticket_id', value: '' }, { name: 'status', value: 'in_progress' }],\n search_tickets: [{ name: 'query', value: 'status:open' }],\n\n list_assets: [{ name: 'limit', value: '50' }],\n get_asset: [{ name: 'asset_id', value: '' }],\n search_assets: [{ name: 'query', value: 'os:windows' }],\n search_users: [{ name: 'query', value: 'department:finance' }],\n search_endpoints: [{ name: 'query', value: 'os:windows' }],\n search_vulnerabilities: [{ name: 'severity', value: 'critical' }],\n\n get_ioc: [{ name: 'value', value: '1.2.3.4' }],\n search_ioc: [{ name: 'query', value: 'malicious.com' }],\n create_ioc: [{ name: 'type', value: 'ipv4' }, { name: 'value', value: '1.2.3.4' }],\n update_ioc: [{ name: 'ioc_id', value: '' }, { name: 'value', value: '1.2.3.4' }],\n delete_ioc: [{ name: 'ioc_id', value: '' }],\n\n reset_password: [{ name: 'user_id', value: '' }],\n enable_user: [{ name: 'user_id', value: '' }],\n disable_user: [{ name: 'user_id', value: '' }],\n get_identity: [{ name: 'user_id', value: '' }],\n search_identity: [{ name: 'query', value: 'department:finance' }],\n get_kms_key: [{ name: 'key_id', value: '' }],\n\n get_rules: [],\n allow_ip: [{ name: 'ip', value: '1.2.3.4' }],\n block_ip: [{ name: 'ip', value: '1.2.3.4' }],\n\n answer_question: [{ name: 'question', value: 'What is this alert about?' }],\n run_action: [{ name: 'app', value: 'jira' }, { name: 'action', value: 'create_ticket' }],\n run_llm: [{ name: 'prompt', value: 'Summarize this incident' }, { name: 'model', value: 'gpt-4o-mini' }],\n\n update_info: [{ name: 'key', value: '' }, { name: 'value', value: '' }],\n get_info: [{ name: 'key', value: '' }],\n get_status: [],\n get_version: [],\n get_health: [],\n get_config: [{ name: 'key', value: '' }],\n get_configs: [],\n get_configs_by_type: [{ name: 'type', value: '' }],\n get_configs_by_name: [{ name: 'name', value: '' }],\n run_script: [{ name: 'script', value: 'whoami' }],\n};\n\n/** Default categories + their action labels (canonical order). */\nconst ACTION_CATEGORIES: { name: string; action_labels: string[] }[] = [\n { name: 'Communication', action_labels: ['List Messages', 'Send Message', 'Get Message', 'Search messages', 'List Attachments', 'Get Attachment', 'Get Contact'] },\n { name: 'SIEM', action_labels: ['Search', 'List Alerts', 'Close Alert', 'Get Alert', 'Create detection', 'Add to lookup list', 'Isolate endpoint'] },\n { name: 'Eradication', action_labels: ['List Alerts', 'Close Alert', 'Get Alert', 'Create detection', 'Block hash', 'Search Hosts', 'Isolate host', 'Unisolate host', 'Trigger host scan'] },\n { name: 'Cases', action_labels: ['List tickets', 'Get ticket', 'Create ticket', 'Close ticket', 'Add comment', 'Update ticket', 'Search tickets'] },\n { name: 'Assets', action_labels: ['List Assets', 'Get Asset', 'Search Assets', 'Search Users', 'Search endpoints', 'Search vulnerabilities'] },\n { name: 'Intel', action_labels: ['Get IOC', 'Search IOC', 'Create IOC', 'Update IOC', 'Delete IOC'] },\n { name: 'IAM', action_labels: ['Reset Password', 'Enable user', 'Disable user', 'Get Identity', 'Get Asset', 'Search Identity', 'Get KMS Key'] },\n { name: 'Network', action_labels: ['Get Rules', 'Allow IP', 'Block IP'] },\n { name: 'AI', action_labels: ['Answer Question', 'Run Action', 'Run LLM'] },\n { name: 'Internal', action_labels: ['Answer Question', 'Run Action', 'Run LLM'] },\n { name: 'Other', action_labels: ['Update Info', 'Get Info', 'Get Status', 'Get Version', 'Get Health', 'Get Config', 'Get Configs', 'Get Configs by type', 'Get Configs by name', 'Run script'] },\n];\n\nconst labelToName = (label: string) =>\n label.trim().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '');\n\n/** Flat list of ALL actions across every category, preserving order. */\nconst ALL_ACTIONS: SingulAction[] = ACTION_CATEGORIES.flatMap((cat) =>\n cat.action_labels.map((label) => {\n const name = labelToName(label);\n return {\n name,\n label,\n category: cat.name,\n fields: ACTION_DEFAULT_FIELDS[name] ?? [],\n };\n }),\n);\n\n/** Pick the best matching default category for an app, given its raw categories. */\nfunction pickDefaultCategory(categories?: string[]): string {\n if (!categories || categories.length === 0) return 'Other';\n const known = ACTION_CATEGORIES.map((c) => c.name.toLowerCase());\n for (const cat of categories) {\n const n = cat.toLowerCase();\n const direct = known.find((k) => k === n);\n if (direct) return ACTION_CATEGORIES.find((c) => c.name.toLowerCase() === direct)!.name;\n const partial = known.find((k) => n.includes(k) || k.includes(n));\n if (partial) return ACTION_CATEGORIES.find((c) => c.name.toLowerCase() === partial)!.name;\n }\n return 'Other';\n}\n\nfunction buildSingulCurl(\n appName: string,\n action: SingulAction | null,\n opts?: { apiKey?: string | null; orgId?: string | null; baseUrl?: string },\n): string {\n const act = action?.name || '{action}';\n const body = {\n app: appName || '<appname>',\n action: act,\n fields: action?.fields.length ? action.fields : [{ name: 'field1', value: 'value1' }],\n };\n const token = opts?.apiKey || 'YOUR_TOKEN';\n const orgLine = opts?.orgId ? `\\n -H \"Org-Id: ${opts.orgId}\" \\\\` : '';\n const base = (opts?.baseUrl || '').replace(/\\/+$/, '');\n return `curl -X POST ${base}/api/v1/singul \\\\\n -H \"Authorization: Bearer ${token}\" \\\\${orgLine}\n -d '${JSON.stringify(body, null, 2)}'`;\n}\n\nfunction buildSingulPython(\n appName: string,\n action: SingulAction | null,\n opts?: { apiKey?: string | null; baseUrl?: string },\n): string {\n const act = action?.name || 'send_message';\n const app = appName || '<appname>';\n const fields = action?.fields.length ? action.fields : [];\n const fieldsStr = JSON.stringify(fields);\n const token = opts?.apiKey || 'APIKEY';\n const base = (opts?.baseUrl || '').replace(/\\/+$/, '');\n return `from shufflepy import Singul\n\nsingul = Singul(\n \"${token}\",\n url=\"${base}\",\n)\n\nresponse = singul.run(\"${app}\", action=\"${act}\", fields=${fieldsStr})\n\nprint(response)`;\n}\n\ntype SnippetLang = 'curl' | 'python';\n\n/** HTML-escape user content before injecting into a highlighted <pre>. */\nconst escapeHtml = (s: string) =>\n s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\n/** Single-pass tokenizer-based highlighter. We MUST NOT run successive regex\n * passes over already-highlighted HTML, because the inline `style=\"color:hsl(...)\"`\n * attributes contain words/numbers that later passes would happily re-match\n * (e.g. `hsl` matches `\\w+(?=\\()`, digits inside `280` match `\\d+`). */\nfunction highlightSnippet(code: string, lang: SnippetLang): string {\n const COL = {\n string: 'hsl(140 60% 65%)',\n keyword: 'hsl(280 70% 75%)',\n func: 'hsl(45 90% 65%)',\n number: 'hsl(20 90% 65%)',\n flag: 'hsl(200 80% 70%)',\n builtin: 'hsl(0 70% 70%)',\n comment: 'hsl(var(--muted-foreground))',\n };\n const PY_KEYWORDS = new Set([\n 'import', 'from', 'as', 'def', 'return', 'if', 'else', 'elif', 'for',\n 'while', 'in', 'None', 'True', 'False', 'print', 'class', 'with', 'try', 'except',\n ]);\n const wrap = (color: string, text: string) =>\n `<span style=\"color:${color}\">${escapeHtml(text)}</span>`;\n\n const out: string[] = [];\n let i = 0;\n const n = code.length;\n while (i < n) {\n const ch = code[i];\n // Strings\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n let j = i + 1;\n while (j < n && code[j] !== quote) {\n if (code[j] === '\\\\' && j + 1 < n) j += 2;\n else j++;\n }\n j = Math.min(j + 1, n);\n out.push(wrap(COL.string, code.slice(i, j)));\n i = j;\n continue;\n }\n // Python comments\n if (lang === 'python' && ch === '#') {\n let j = i;\n while (j < n && code[j] !== '\\n') j++;\n out.push(wrap(COL.comment, code.slice(i, j)));\n i = j;\n continue;\n }\n // Curl flags ( -X / --header ), only at start of token\n if (lang === 'curl' && ch === '-' && (i === 0 || /\\s/.test(code[i - 1]))) {\n let j = i + 1;\n if (code[j] === '-') j++;\n while (j < n && /[\\w-]/.test(code[j])) j++;\n out.push(wrap(COL.flag, code.slice(i, j)));\n i = j;\n continue;\n }\n // Numbers\n if (/\\d/.test(ch)) {\n let j = i;\n while (j < n && /[\\d.]/.test(code[j])) j++;\n out.push(wrap(COL.number, code.slice(i, j)));\n i = j;\n continue;\n }\n // Identifiers / keywords / function calls\n if (/[A-Za-z_]/.test(ch)) {\n let j = i;\n while (j < n && /[\\w]/.test(code[j])) j++;\n const word = code.slice(i, j);\n if (lang === 'python' && PY_KEYWORDS.has(word)) {\n out.push(wrap(COL.keyword, word));\n } else if (lang === 'curl' && word === 'curl') {\n out.push(wrap(COL.builtin, word));\n } else if (code[j] === '(') {\n out.push(wrap(COL.func, word));\n } else {\n out.push(escapeHtml(word));\n }\n i = j;\n continue;\n }\n // Plain char (operators, whitespace, punctuation)\n out.push(escapeHtml(ch));\n i++;\n }\n return out.join('');\n}\n\n\n\nconst SingulActionsPreview = ({\n appName,\n appIcon,\n categories,\n activeOrgId,\n onAuthenticate,\n}: {\n appName: string;\n appIcon?: string;\n categories?: string[];\n activeOrgId?: string | null;\n /** Optional click handler invoked when the user presses the\n * \"Authenticate {App}\" button surfaced after an\n * `action: \"app_authentication\"` response. */\n onAuthenticate?: (appName: string) => void;\n}) => {\n const defaultCategory = useMemo(() => pickDefaultCategory(categories), [categories]);\n const actions = ALL_ACTIONS;\n // Sort so that the app's default category appears first, rest follow original order.\n const sortedActions = useMemo(() => {\n const inCat = actions.filter((a) => a.category === defaultCategory);\n const rest = actions.filter((a) => a.category !== defaultCategory);\n return [...inCat, ...rest];\n }, [actions, defaultCategory]);\n const isDisabled = false;\n const [selected, setSelected] = useState<SingulAction | null>(null);\n const [lang, setLang] = useState<SnippetLang>('curl');\n const [snippet, setSnippet] = useState<string>('');\n\n const curlOpts = useMemo(() => {\n const apiKey = API_CONFIG.apiKey;\n const trackedOrg = getTrackedOrgId();\n const orgId = trackedOrg && activeOrgId && trackedOrg !== activeOrgId ? trackedOrg : null;\n const baseUrl = API_CONFIG.baseUrl;\n return { apiKey, orgId, baseUrl };\n }, [activeOrgId]);\n\n const buildSnippet = useCallback(\n (action: SingulAction | null, l: SnippetLang) =>\n l === 'python' ? buildSingulPython(appName, action, curlOpts) : buildSingulCurl(appName, action, curlOpts),\n [appName, curlOpts],\n );\n\n useEffect(() => {\n const initial = sortedActions[0] || null;\n setSelected(initial);\n setSnippet(buildSnippet(initial, lang));\n }, [appName, sortedActions, curlOpts, lang, buildSnippet]);\n\n const handleSelect = (action: SingulAction | null) => {\n setSelected(action);\n setSnippet(buildSnippet(action, lang));\n };\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(snippet);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n toast.error('Copy failed');\n }\n };\n\n const [playLoading, setPlayLoading] = useState(false);\n const [playResult, setPlayResult] = useState<string | null>(null);\n const responseRef = useRef<HTMLDivElement | null>(null);\n const [copied, setCopied] = useState(false);\n\n const scrollToResponse = () => {\n requestAnimationFrame(() => {\n responseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n });\n };\n\n const handlePlay = async () => {\n if (!snippet || playLoading) return;\n setPlayLoading(true);\n setPlayResult('');\n scrollToResponse();\n try {\n const body = lang === 'python'\n ? {\n name: 'execute_python',\n app_id: '3e2bdf9d5069fe3f4746c29d68785a6a',\n environment: 'Cloud',\n parameters: [{ name: 'code', value: snippet, schema: { type: 'string' } }],\n app_name: 'Shuffle Tools',\n app_version: '1.2.0',\n }\n : {\n name: 'curl',\n app_id: 'ebfe7d5c80000676588f86731db0a555',\n environment: 'Cloud',\n parameters: [{ name: 'statement', value: snippet, schema: { type: 'string' } }],\n app_name: 'http',\n app_version: '1.4.0',\n };\n const path = lang === 'python' ? '/api/v1/apps/3e2bdf9d5069fe3f4746c29d68785a6a/run?delete=true' : '/api/v1/apps/http/run?delete=true';\n const res = await fetch(getApiUrl(path), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...getAuthHeader() },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n let output = data?.result;\n if (typeof output === 'string') {\n try { output = JSON.stringify(JSON.parse(output), null, 2); } catch {}\n } else if (output != null) {\n output = JSON.stringify(output, null, 2);\n } else {\n output = JSON.stringify(data, null, 2);\n }\n setPlayResult(output);\n const parsed = (() => { try { return JSON.parse(data?.result || '{}'); } catch { return null; } })();\n if (parsed?.success === false) {\n toast.error(parsed.reason || 'Run failed');\n } else {\n toast.success(`Ran ${selected?.name || lang}`);\n }\n } catch (err: any) {\n const msg = err?.message || 'Run failed';\n setPlayResult(msg);\n toast.error(msg);\n } finally {\n setPlayLoading(false);\n scrollToResponse();\n }\n };\n\n const lineCount = useMemo(() => Math.max(snippet.split('\\n').length, 1), [snippet]);\n\n return (\n <Box sx={{ mt: 5, mb: 3, opacity: isDisabled ? 0.55 : 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.5 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 600, fontSize: '0.95rem' }}>\n Try individual actions\n </Typography>\n <Chip\n label=\"Preview\"\n size=\"small\"\n sx={{ height: 18, fontSize: '0.6rem', fontWeight: 500, backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' }}\n />\n </Box>\n\n <Box\n sx={{\n position: 'relative',\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n background: 'linear-gradient(180deg, hsl(var(--muted) / 0.35) 0%, hsl(var(--background) / 0.6) 100%)',\n pointerEvents: isDisabled ? 'none' : 'auto',\n overflow: 'hidden',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n inset: -1,\n borderRadius: 2,\n padding: '1px',\n background: 'linear-gradient(135deg, hsl(var(--primary) / 0.35), transparent 40%, hsl(var(--primary) / 0.15))',\n WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',\n WebkitMaskComposite: 'xor',\n maskComposite: 'exclude',\n pointerEvents: 'none',\n },\n }}\n >\n {isDisabled ? (\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', fontStyle: 'italic', textAlign: 'center', py: 1 }}>\n No category detected for this app\n </Typography>\n ) : (\n <>\n <Box sx={{ display: 'flex', gap: 1, mb: 1.5, alignItems: 'center' }}>\n <Autocomplete\n size=\"small\"\n disableClearable\n options={sortedActions}\n value={selected ?? sortedActions[0]}\n onChange={(_, v) => v && handleSelect(v as SingulAction)}\n groupBy={(o: SingulAction) => o.category}\n getOptionLabel={(o: SingulAction | null) => o?.label ?? ''}\n isOptionEqualToValue={(a, b) => a?.name === b?.name && a?.category === b?.category}\n renderOption={(props, option) => (\n <li {...props} key={`${option.category}-${option.name}`}>\n <Box sx={{ display: 'flex', flexDirection: 'column' }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--foreground))' }}>{option.label}</Typography>\n <Typography sx={{ fontFamily: \"'JetBrains Mono', monospace\", fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))' }}>\n {option.name}\n </Typography>\n </Box>\n </li>\n )}\n sx={{\n flex: 1,\n '& .MuiOutlinedInput-root': {\n backgroundColor: 'hsl(var(--card))',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.75rem',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--primary))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n slotProps={{\n paper: {\n sx: {\n backgroundColor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n border: '1px solid hsl(var(--border))',\n '& .MuiAutocomplete-groupLabel': {\n backgroundColor: 'hsl(var(--muted) / 0.6)',\n color: 'hsl(var(--muted-foreground))',\n fontSize: '0.65rem',\n fontWeight: 600,\n textTransform: 'uppercase',\n letterSpacing: 0.6,\n lineHeight: '24px',\n },\n },\n },\n }}\n renderInput={(params) => (\n <TextField {...params} placeholder=\"Select action\" />\n )}\n />\n </Box>\n\n {/* Code card */}\n <Box\n sx={{\n position: 'relative',\n borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--background))',\n overflow: 'hidden',\n boxShadow: '0 8px 24px -12px hsl(var(--primary) / 0.25)',\n }}\n >\n {/* Header bar — matches ApiCallViewer */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 2,\n py: 1,\n borderBottom: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--card))',\n }}\n >\n <Code2 size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />\n <Typography\n sx={{\n fontSize: '0.7rem',\n fontWeight: 600,\n color: 'hsl(var(--muted-foreground))',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Action\n </Typography>\n {selected && (\n <Chip\n label={selected.name}\n size=\"small\"\n sx={{\n height: 18,\n fontSize: '0.6rem',\n fontWeight: 700,\n fontFamily: \"'JetBrains Mono', monospace\",\n bgcolor: 'hsla(var(--severity-medium) / 0.15)',\n color: 'hsl(var(--severity-medium))',\n '& .MuiChip-label': { px: 0.75 },\n }}\n />\n )}\n <Box sx={{ flex: 1 }} />\n {/* Language toggle (cURL / Python) */}\n <Box sx={{ display: 'flex', gap: 0.5 }}>\n {(['curl', 'python'] as SnippetLang[]).map((m) => (\n <Chip\n key={m}\n label={m === 'curl' ? 'cURL' : 'Python'}\n icon={m === 'curl' ? <Terminal size={12} /> : <Code2 size={12} />}\n size=\"small\"\n onClick={() => setLang(m)}\n sx={{\n height: 22,\n fontSize: '0.6rem',\n fontWeight: 600,\n cursor: 'pointer',\n bgcolor: lang === m ? 'hsl(var(--primary) / 0.12)' : 'transparent',\n color: lang === m ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n border: lang === m ? '1px solid hsl(var(--primary) / 0.3)' : '1px solid transparent',\n '& .MuiChip-icon': {\n color: lang === m ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n },\n '&:hover': {\n bgcolor: lang === m ? 'hsl(var(--primary) / 0.15)' : 'hsl(var(--muted))',\n },\n }}\n />\n ))}\n </Box>\n <Tooltip title={copied ? 'Copied!' : 'Copy'} arrow>\n <IconButton size=\"small\" onClick={handleCopy} sx={{ color: 'hsl(var(--muted-foreground))' }}>\n {copied ? <CheckIcon size={14} /> : <ContentCopyIcon size={14} />}\n </IconButton>\n </Tooltip>\n <Button\n size=\"small\"\n onClick={handlePlay}\n disabled={playLoading}\n startIcon={!playLoading && <PlayArrowIcon size={14} />}\n sx={{\n height: 26,\n minWidth: 0,\n px: 1.5,\n fontSize: '0.65rem',\n fontWeight: 600,\n textTransform: 'none',\n color: 'hsl(var(--primary-foreground))',\n backgroundColor: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary))',\n boxShadow: '0 0 12px -2px hsl(var(--primary) / 0.6)',\n '& .MuiButton-startIcon': { mr: 0.5 },\n '&:hover': { backgroundColor: 'hsl(var(--primary) / 0.9)', boxShadow: '0 0 16px -2px hsl(var(--primary) / 0.7)' },\n '&.Mui-disabled': { color: 'hsl(var(--primary-foreground) / 0.7)', backgroundColor: 'hsl(var(--primary) / 0.45)', boxShadow: 'none', borderColor: 'hsl(var(--primary) / 0.45)' },\n }}\n >\n {playLoading ? 'Running…' : 'Play'}\n </Button>\n </Box>\n\n {/* Editor area with line numbers */}\n <Box sx={{ display: 'flex', minHeight: 270 }}>\n <Box\n aria-hidden\n sx={{\n userSelect: 'none',\n py: 1.5,\n pl: 1.25,\n pr: 1,\n textAlign: 'right',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n color: 'hsl(var(--muted-foreground) / 0.6)',\n borderRight: '1px solid hsl(var(--border))',\n backgroundColor: 'hsl(var(--muted) / 0.25)',\n minWidth: 36,\n }}\n >\n {Array.from({ length: lineCount }, (_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </Box>\n <Box sx={{ flex: 1, position: 'relative', minHeight: 270 }}>\n <Box\n aria-hidden\n sx={{\n position: 'absolute',\n inset: 0,\n m: 0,\n p: 1.5,\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n pointerEvents: 'none',\n overflow: 'hidden',\n }}\n dangerouslySetInnerHTML={{ __html: highlightSnippet(snippet, lang) + '\\n' }}\n />\n <Box\n component=\"textarea\"\n value={snippet}\n onChange={(e: any) => setSnippet(e.target.value)}\n spellCheck={false}\n sx={{\n position: 'relative',\n width: '100%',\n height: '100%',\n minHeight: 270,\n resize: 'vertical',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.72rem',\n lineHeight: 1.5,\n color: 'transparent',\n WebkitTextFillColor: 'transparent',\n backgroundColor: 'transparent',\n border: 'none',\n p: 1.5,\n m: 0,\n outline: 'none',\n caretColor: 'hsl(var(--primary))',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n overflow: 'auto',\n '&::selection': { color: 'inherit', backgroundColor: 'hsl(var(--primary) / 0.3)' },\n }}\n />\n </Box>\n </Box>\n </Box>\n </>\n )}\n\n {(playLoading || playResult !== null) && (() => {\n const parsedResult = (() => {\n if (!playResult) return null;\n try {\n const p = JSON.parse(playResult);\n return typeof p === 'object' && p !== null ? p : null;\n } catch { return null; }\n })();\n const needsAuth = !!parsedResult && (\n parsedResult.action === 'app_authentication' ||\n parsedResult.app_authentication === true\n );\n const pretty = appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const handleAuthClick = () => {\n if (onAuthenticate) {\n onAuthenticate(appName);\n return;\n }\n if (typeof document === 'undefined') return;\n const target = document.getElementById('app-auth-section');\n if (target) {\n target.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n return (\n <Box ref={responseRef} sx={{ mt: 1.5 }}>\n {needsAuth && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n mb: 1,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}\n >\n <LockIcon size={22} color={'hsl(var(--severity-medium))'} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {typeof parsedResult?.reason === 'string' && parsedResult.reason\n ? parsedResult.reason\n : `Connect your ${pretty} account so this action can run, then try again.`}\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={appIcon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n onClick={handleAuthClick}\n sx={{ height: 36, textTransform: 'none', fontWeight: 600, flexShrink: 0 }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n )}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mb: 0.5 }}>\n <Box sx={{ width: 6, height: 6, borderRadius: '50%', backgroundColor: needsAuth ? 'hsl(var(--severity-medium))' : 'hsl(140 60% 55%)' }} />\n <Typography sx={{ fontFamily: \"'JetBrains Mono', monospace\", fontSize: '0.65rem', color: 'hsl(var(--muted-foreground))', letterSpacing: 0.4 }}>\n response\n </Typography>\n </Box>\n {parsedResult ? (\n <Box\n sx={{\n p: 1.5,\n maxHeight: 320,\n overflow: 'auto',\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n fontFamily: \"'JetBrains Mono', ui-monospace, monospace\",\n '& .json-view': {\n fontSize: '0.72rem !important',\n fontFamily: 'inherit !important',\n bgcolor: 'transparent !important',\n },\n }}\n >\n <JsonView\n src={deepParseJsonStrings(parsedResult)}\n dark\n collapsed={2}\n collapseStringMode=\"word\"\n collapseStringsAfterLength={120}\n enableClipboard\n displaySize\n />\n </Box>\n ) : (\n <Box\n component=\"pre\"\n sx={{\n p: 1.5,\n maxHeight: 240,\n overflow: 'auto',\n fontFamily: \"'JetBrains Mono', monospace\",\n fontSize: '0.7rem',\n lineHeight: 1.5,\n color: 'hsl(var(--foreground))',\n backgroundColor: 'hsl(var(--background))',\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n m: 0,\n }}\n >\n {playLoading && !playResult ? 'Running…' : playResult}\n </Box>\n )}\n </Box>\n );\n })()}\n </Box>\n </Box>\n );\n};\n\nexport default SingulActionsPreview;\n","import * as React from \"react\";\nimport { motion, LayoutGroup } from \"framer-motion\";\n// Local tiny classnames helper to avoid pulling clsx/tailwind-merge into\n// the library bundle (they aren't declared as peer deps).\nconst cn = (...inputs: Array<string | false | null | undefined>) =>\n inputs.filter(Boolean).join(\" \");\n\n/**\n * SegmentedControl\n *\n * iOS-style pill with a smoothly sliding active background (shared layoutId).\n * Items can be tabs (`type: 'tab'`, default) OR action buttons\n * (`type: 'action'`) — actions just fire onClick and never become \"active\".\n * A vertical divider can be inserted with `{ type: 'divider' }`.\n *\n * Use this anywhere we need filter tabs (All • Public • Private) or a\n * mixed pill like Start • Simple • Detailed | Reload Schedule.\n */\n\nexport type SegmentedItem<V extends string = string> =\n | {\n type?: \"tab\";\n value: V;\n label: React.ReactNode;\n count?: number;\n title?: string;\n disabled?: boolean;\n dataTour?: string;\n }\n | {\n type: \"action\";\n /** Stable key, required since `value` is absent. */\n key: string;\n label: React.ReactNode;\n title?: string;\n disabled?: boolean;\n onClick: () => void;\n dataTour?: string;\n }\n | {\n type: \"divider\";\n key?: string;\n };\n\n// Back-compat alias.\nexport type SegmentedOption<V extends string = string> = SegmentedItem<V>;\n\nexport interface SegmentedControlProps<V extends string = string> {\n options: SegmentedItem<V>[];\n value: V;\n onChange: (value: V) => void;\n size?: \"sm\" | \"md\";\n /**\n * Visual style:\n * - \"outline\" (default): transparent track + hairline border, filled active pill.\n * - \"filled\": subtly filled track + no border, filled active pill (iOS-style).\n */\n variant?: \"outline\" | \"filled\";\n className?: string;\n ariaLabel?: string;\n /** Unique id so multiple segmented controls on a page do not share their pill. */\n layoutId?: string;\n}\n\nconst sizeClasses = {\n sm: {\n container: \"p-0.5 text-[11px]\",\n item: \"px-2.5 py-1 gap-1.5\",\n count: \"min-w-[16px] h-[16px] px-1 text-[10px]\",\n divider: \"h-4 mx-0.5\",\n },\n md: {\n container: \"p-1 text-xs\",\n item: \"px-3 py-1.5 gap-1.5\",\n count: \"min-w-[18px] h-[18px] px-1.5 text-[10px]\",\n divider: \"h-5 mx-1\",\n },\n};\n\nlet uid = 0;\nfunction useUniqueId(prefix: string) {\n const ref = React.useRef<string>();\n if (!ref.current) {\n uid += 1;\n ref.current = `${prefix}-${uid}`;\n }\n return ref.current;\n}\n\nexport function SegmentedControl<V extends string = string>({\n options,\n value,\n onChange,\n size = \"md\",\n variant = \"outline\",\n className,\n ariaLabel,\n layoutId,\n}: SegmentedControlProps<V>) {\n const autoId = useUniqueId(\"segmented\");\n const groupId = layoutId ?? autoId;\n const s = sizeClasses[size];\n\n return (\n <LayoutGroup id={groupId}>\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={cn(\n \"inline-flex items-center gap-0.5 rounded-full\",\n variant === \"outline\"\n ? \"border border-border bg-transparent\"\n : \"border border-transparent bg-muted/40\",\n s.container,\n className,\n )}\n >\n {options.map((opt, i) => {\n if (opt.type === \"divider\") {\n return (\n <span\n key={opt.key ?? `divider-${i}`}\n aria-hidden\n className={cn(\"w-px bg-border self-center\", s.divider)}\n />\n );\n }\n\n const isAction = opt.type === \"action\";\n const active = !isAction && opt.value === value;\n const key = isAction ? opt.key : opt.value;\n\n return (\n <button\n key={key}\n type=\"button\"\n data-tour={opt.dataTour}\n role={isAction ? \"button\" : \"tab\"}\n aria-selected={isAction ? undefined : active}\n title={opt.title}\n disabled={opt.disabled}\n onClick={() => {\n if (opt.disabled) return;\n if (isAction) opt.onClick();\n else onChange(opt.value);\n }}\n className={cn(\n \"relative inline-flex items-center rounded-full font-medium\",\n \"transition-colors duration-300\",\n \"focus:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n s.item,\n active\n ? \"text-foreground\"\n : \"text-muted-foreground hover:text-foreground\",\n opt.disabled && \"opacity-50 cursor-not-allowed\",\n )}\n >\n {active && (\n <motion.span\n layoutId={`${groupId}-pill`}\n className=\"absolute inset-0 rounded-full bg-muted border border-border\"\n initial={false}\n transition={{\n type: \"spring\",\n stiffness: 260,\n damping: 30,\n }}\n />\n )}\n <span className=\"relative z-10 inline-flex items-center gap-1.5\">\n {opt.label}\n </span>\n {!isAction && typeof opt.count === \"number\" && (\n <span\n className={cn(\n \"relative z-10 inline-flex items-center justify-center rounded-md font-semibold tabular-nums border border-border/60\",\n s.count,\n active\n ? \"bg-transparent text-foreground\"\n : \"bg-transparent text-muted-foreground\",\n )}\n >\n {opt.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n </LayoutGroup>\n );\n}\n\nexport default SegmentedControl;\n","/**\n * AppSearchDrawer — Reusable drawer for searching apps.\n * Selecting an app opens the AppDetailDrawer for full configuration.\n */\n\nimport { useState, useEffect } from 'react';\nimport {\n X as CloseIcon\n} from 'lucide-react';\nimport { Box, Typography, IconButton, Drawer, Avatar, Tooltip } from '@mui/material';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { ShuffleMCP, AppDetailDrawer } from '@/Shuffle-MCPs';\nimport type { AppSelectedEvent } from '@/Shuffle-MCPs';\nimport { API_CONFIG } from '@/Shuffle-MCPs/api';\nimport { ShufflePipelinesBanner } from '@/Shuffle-MCPs/ShufflePipelinesBanner';\n\n\n// Singul styles — compact dark theme\nconst singulStyles = {\n container: { width: '100%' },\n inputWrapper: {\n backgroundColor: 'hsl(var(--background-elevated))',\n borderRadius: '12px',\n border: '1px solid hsl(var(--border))',\n },\n input: {\n backgroundColor: 'transparent',\n color: 'hsl(var(--foreground))',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 16px',\n fontSize: '14px',\n },\n searchIcon: { color: 'hsl(var(--muted-foreground))' },\n spinner: {\n borderColor: 'hsl(var(--border))',\n borderTopColor: 'hsl(var(--primary))',\n },\n resultsContainer: { marginTop: '12px', gap: '10px' },\n dropdownItem: {\n backgroundColor: 'hsl(var(--input))',\n border: '1px solid hsl(var(--border))',\n borderRadius: '12px',\n padding: '14px',\n color: 'hsl(var(--foreground))',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n },\n dropdownItemHover: {\n borderColor: 'hsl(var(--primary) / 0.5)',\n backgroundColor: 'hsl(var(--accent) / 0.08)',\n },\n selectedItem: {\n backgroundColor: 'hsl(var(--primary) / 0.1)',\n borderColor: 'hsl(var(--primary))',\n },\n appIcon: {\n width: '36px',\n height: '36px',\n borderRadius: '8px',\n backgroundColor: 'hsl(var(--muted))',\n objectFit: 'contain' as const,\n padding: '4px',\n },\n appName: { fontSize: '13px', fontWeight: 600, color: 'hsl(var(--foreground))' },\n appDescription: {\n fontSize: '11px',\n color: 'hsl(var(--muted-foreground))',\n lineHeight: 1.4,\n },\n appCategory: {\n marginTop: '6px',\n padding: '2px 8px',\n backgroundColor: 'hsl(var(--muted))',\n color: 'hsl(var(--muted-foreground))',\n fontSize: '10px',\n fontWeight: 600,\n textTransform: 'uppercase' as const,\n borderRadius: '4px',\n display: 'inline-block',\n width: 'fit-content',\n },\n checkbox: { border: '2px solid hsl(var(--border))' },\n checkboxChecked: { backgroundColor: 'hsl(var(--primary))', borderColor: 'hsl(var(--primary))' },\n emptyState: {\n padding: '24px',\n color: 'hsl(var(--muted-foreground))',\n textAlign: 'center' as const,\n fontSize: '13px',\n backgroundColor: 'hsl(var(--muted))',\n borderRadius: '12px',\n border: '1px solid hsl(var(--border))',\n gridColumn: '1 / -1',\n },\n};\n\ninterface ConnectionPathApp {\n name: string;\n icon: string;\n hasValidAuth?: boolean;\n isActiveOnly?: boolean;\n}\n\ninterface AppSearchDrawerProps {\n open: boolean;\n onClose: () => void;\n initialQuery?: string;\n title?: string;\n subtitle?: string;\n anchor?: 'left' | 'right';\n width?: number;\n /** Show the Shuffle Pipelines banner above search results */\n showPipelinesBanner?: boolean;\n /** If provided, selecting an app calls this instead of opening AppDetailDrawer */\n onQuickSelect?: (app: { name: string; icon: string; categories: string[]; id: string | null }) => void;\n /** If provided, called before default behavior. Return true to prevent opening detail drawer. */\n onSelectOverride?: (app: { name: string; icon: string; categories: string[] }) => boolean;\n /** Called when the detail drawer closes, with the app name that was being configured */\n onDetailClose?: (appName: string) => void;\n /** When set, replaces Activate with \"+ Add\" in the detail drawer */\n onAddToCanvas?: (appInfo: { name: string; icon: string; algoliaId: string | null }) => void;\n /** When set, apps matching this category are sorted to the top in user's apps */\n priorityCategory?: string;\n /** Apps currently in the connection path diagram — shown first in the drawer */\n connectionPathApps?: ConnectionPathApp[];\n /** Apps to pin at the top of the ShuffleMCP search results (deduped by name). */\n pinnedApps?: Array<{ name: string; image_url: string; categories?: string[]; objectID?: string }>;\n /** Highlight (pulsing ring) the matching app card after `highlightDelayMs` */\n highlightAppName?: string;\n /** Delay before the highlight kicks in (default 5000ms) */\n highlightDelayMs?: number;\n /** Enable multi-select: clicking apps toggles them in/out of the selection,\n * drawer stays open, and the picker shows checkboxes + a primary-bordered\n * highlight on already-chosen rows. */\n multiSelect?: boolean;\n /** Currently chosen apps (used to highlight rows in multi-select mode).\n * Match is by objectID first, then by normalized name. */\n selectedApps?: Array<{ name: string; id?: string | null; icon?: string }>;\n /** Fires whenever the selection changes in multi-select mode. */\n onSelectionChange?: (apps: Array<{ name: string; id: string | null; icon: string; categories: string[] }>) => void;\n}\n\n\nexport default function AppSearchDrawer({\n open,\n onClose,\n initialQuery = '',\n title = 'Add Integration',\n subtitle = 'Search and configure a tool',\n anchor = 'right',\n width = 560,\n showPipelinesBanner = false,\n onQuickSelect,\n onSelectOverride,\n onDetailClose,\n onAddToCanvas,\n priorityCategory,\n connectionPathApps,\n pinnedApps,\n highlightAppName,\n highlightDelayMs = 5000,\n multiSelect = false,\n selectedApps,\n onSelectionChange,\n}: AppSearchDrawerProps) {\n const [detailAppName, setDetailAppName] = useState<string | null>(null);\n const [detailAppId, setDetailAppId] = useState<string | null>(null);\n const [highlightActive, setHighlightActive] = useState(false);\n\n // Activate highlight only after the delay, so users get a chance to find\n // the app on their own before we draw attention to it.\n useEffect(() => {\n setHighlightActive(false);\n if (!open || !highlightAppName) return;\n const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);\n return () => clearTimeout(t);\n }, [open, highlightAppName, highlightDelayMs]);\n\n const handleClose = () => {\n setDetailAppName(null);\n setDetailAppId(null);\n onClose();\n };\n\n // Project caller-supplied selection to the AlgoliaSearchApp shape that\n // ShuffleMCP's `selectedApps` prop expects. Only `objectID` and `name` are\n // used for matching; the rest are placeholders.\n const projectedSelectedApps = (selectedApps || []).map((a) => ({\n objectID: a.id || `name:${(a.name || '').toLowerCase().replace(/[\\s-]+/g, '_')}`,\n name: a.name,\n image_url: a.icon || '',\n description: '',\n categories: [],\n creator: '',\n app_version: '1.0.0',\n time_edited: 0,\n generated: false,\n invalid: false,\n priority: 0,\n actions: 0,\n tags: [],\n accessible_by: [],\n action_labels: [],\n triggers: [],\n verified: true,\n })) as any[];\n\n const handleAppSelected = (detail: AppSelectedEvent) => {\n const algoliaId = (detail.app as any).objectID || null;\n const appInfo = {\n name: detail.app.name,\n icon: detail.app.image_url || '',\n categories: detail.app.categories || [],\n id: algoliaId,\n };\n\n // Multi-select mode: toggle in/out of the chosen list, keep the drawer open.\n if (multiSelect && onSelectionChange) {\n const norm = (s: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const current = selectedApps || [];\n const targetSlug = norm(appInfo.name);\n const exists = current.some(\n (a) => (a.id && a.id === appInfo.id) || norm(a.name) === targetSlug,\n );\n const next = exists\n ? current.filter(\n (a) => !((a.id && a.id === appInfo.id) || norm(a.name) === targetSlug),\n ).map((a) => ({\n name: a.name,\n id: a.id ?? null,\n icon: a.icon || '',\n categories: [] as string[],\n }))\n : [\n ...current.map((a) => ({\n name: a.name,\n id: a.id ?? null,\n icon: a.icon || '',\n categories: [] as string[],\n })),\n appInfo,\n ];\n onSelectionChange(next);\n return;\n }\n\n if (onQuickSelect) {\n onQuickSelect(appInfo);\n onClose();\n return;\n }\n if (onSelectOverride?.(appInfo)) {\n return;\n }\n setDetailAppName(detail.app.name);\n setDetailAppId(algoliaId);\n };\n\n\n return (\n <>\n <Drawer\n anchor={anchor}\n open={open && detailAppName === null}\n onClose={handleClose}\n sx={{\n zIndex: 9999,\n '& .MuiDrawer-paper': {\n width,\n maxWidth: '100vw',\n height: '100vh',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: anchor === 'right' ? '1px solid hsl(var(--border))' : 'none',\n borderRight: anchor === 'left' ? '1px solid hsl(var(--border))' : 'none',\n },\n }}\n >\n {/* Header */}\n <Box\n sx={{\n px: 3,\n py: 2,\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n }}\n >\n <Box sx={{ flex: 1 }}>\n <Typography sx={{ color: 'hsl(var(--foreground))', fontWeight: 700, fontSize: '1rem', lineHeight: 1.2 }}>\n {title}\n </Typography>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.75rem' }}>\n {subtitle}\n </Typography>\n </Box>\n <IconButton\n size=\"small\"\n onClick={handleClose}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--foreground))' } }}\n >\n <CloseIcon size={16} />\n </IconButton>\n </Box>\n\n {/* Search body */}\n <Box sx={{ flex: 1, boxSizing: 'border-box', overflow: 'hidden', p: 3, minHeight: 0, display: 'flex', flexDirection: 'column' }}>\n \n\n {/* Connection path apps — shown first */}\n {connectionPathApps && connectionPathApps.length > 0 && (\n <Box sx={{ mb: 2.5 }}>\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.7rem', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em', mb: 1 }}>\n In this usecase\n </Typography>\n <Box sx={{ display: 'flex', gap: 1.5, flexWrap: 'wrap' }}>\n {connectionPathApps.map((app) => (\n <Tooltip key={app.name} title={app.name.replace(/_/g, ' ')} arrow placement=\"bottom\">\n <Box\n onClick={() => handleAppSelected({ app: { name: app.name, image_url: app.icon, categories: [] } } as any)}\n sx={{\n position: 'relative',\n cursor: 'pointer',\n transition: 'transform 0.15s ease',\n '&:hover': { transform: 'scale(1.1)' },\n }}\n >\n <Avatar\n src={app.icon}\n alt={app.name}\n sx={{ width: 32, height: 32, borderRadius: '8px', backgroundColor: 'hsl(var(--muted))' }}\n variant=\"rounded\"\n />\n <Box\n sx={{\n position: 'absolute',\n bottom: -2,\n right: -2,\n width: 9,\n height: 9,\n borderRadius: '50%',\n backgroundColor: app.hasValidAuth ? 'hsl(var(--severity-low))' : app.isActiveOnly ? 'hsl(var(--destructive))' : 'hsl(var(--severity-medium))',\n border: '1.5px solid hsl(var(--card))',\n }}\n />\n </Box>\n </Tooltip>\n ))}\n </Box>\n </Box>\n )}\n\n <Box\n sx={{\n flex: 1,\n minHeight: 0,\n overflow: 'hidden',\n '& .singul-container, & .singul-search-bar-container': {\n height: '100%',\n minHeight: 0,\n },\n '& .singul-search-bar-container': {\n display: 'flex',\n flexDirection: 'column',\n },\n '& .singul-results-container': {\n flex: 1,\n minHeight: 0,\n maxHeight: 'none',\n overflowY: 'auto',\n },\n '& .singul-results-grid': {\n gridAutoRows: '75px',\n gap: '12px',\n },\n '& .singul-results-grid .singul-dropdown-item': {\n minHeight: 75,\n maxHeight: 75,\n height: 75,\n padding: '14px 16px',\n alignItems: 'center',\n overflow: 'hidden',\n },\n '& .singul-results-grid .singul-app-info': {\n alignItems: 'center',\n gap: '12px',\n },\n '& .singul-results-grid .singul-app-icon': {\n width: 40,\n height: 40,\n borderRadius: 8,\n padding: 4,\n },\n ...(highlightActive && highlightAppName ? {\n [`& .singul-dropdown-item[data-app-name=\"${highlightAppName}\"]`]: {\n borderColor: 'hsl(var(--primary)) !important',\n boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 18px 2px hsl(var(--primary) / 0.55)',\n animation: 'shuffleHighlightPulse 1.6s ease-in-out infinite',\n },\n '@keyframes shuffleHighlightPulse': {\n '0%, 100%': { boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 12px 1px hsl(var(--primary) / 0.4)' },\n '50%': { boxShadow: '0 0 0 2px hsl(var(--primary)), 0 0 24px 4px hsl(var(--primary) / 0.75)' },\n },\n } : {}),\n }}\n >\n <AnimatePresence mode=\"wait\">\n <motion.div\n key=\"search\"\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: -20 }}\n transition={{ duration: 0.2 }}\n style={{ height: '100%', minHeight: 0 }}\n >\n <ShuffleMCP\n apiKey={API_CONFIG.apiKey || undefined}\n apiBaseUrl={API_CONFIG.baseUrl}\n placeholder={initialQuery ? `Search ${initialQuery} integrations...` : 'Search integrations...'}\n layout=\"grid\"\n gridColumns={2}\n inline={true}\n initialFilterQuery={initialQuery}\n hitsPerPage={12}\n showDescription={false}\n showCategories={true}\n showCheckbox={multiSelect}\n multiSelect={multiSelect}\n selectedApps={multiSelect ? projectedSelectedApps : undefined}\n preventDefault={true}\n onAppSelected={handleAppSelected}\n onSelectionChange={multiSelect && onSelectionChange ? (apps) => {\n onSelectionChange(\n apps.map((a: any) => ({\n name: a.name,\n id: (a.objectID && !String(a.objectID).startsWith('name:') && !String(a.objectID).startsWith('pinned-')) ? a.objectID : null,\n icon: a.image_url || '',\n categories: a.categories || [],\n }))\n );\n } : undefined}\n pinnedApps={pinnedApps?.map(p => ({\n name: p.name,\n image_url: p.image_url,\n categories: p.categories || [],\n objectID: p.objectID || `pinned-${p.name}`,\n description: '',\n creator: '',\n app_version: '1.0.0',\n time_edited: 0,\n generated: false,\n invalid: false,\n priority: 0,\n actions: 0,\n tags: [],\n accessible_by: [],\n action_labels: [],\n triggers: [],\n verified: true,\n }))}\n customStyles={singulStyles}\n />\n </motion.div>\n </AnimatePresence>\n </Box>\n </Box>\n </Drawer>\n\n {/* App detail drawer — opens when an app is selected from search */}\n <AppDetailDrawer\n open={open && detailAppName !== null}\n onClose={() => {\n const name = detailAppName;\n setDetailAppName(null);\n setDetailAppId(null);\n if (name) onDetailClose?.(name);\n }}\n appName={detailAppName}\n appId={detailAppId}\n anchor={anchor}\n width={width}\n onRefresh={onClose}\n onAddToCanvas={onAddToCanvas}\n />\n </>\n );\n}\n","import { Box, Typography, Chip } from '@mui/material';\nimport shuffleIcon from '@/assets/shuffle-icon.png';\n\nexport function ShufflePipelinesBanner() {\n return (\n <Box\n component=\"a\"\n href=\"/detection\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n p: 2,\n mb: 2,\n borderRadius: 2.5,\n background: 'linear-gradient(135deg, hsla(25, 100%, 50%, 0.08) 0%, hsla(25, 100%, 50%, 0.03) 100%)',\n border: '1px solid hsla(25, 100%, 50%, 0.2)',\n textDecoration: 'none',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n '&:hover': {\n border: '1px solid hsla(25, 100%, 50%, 0.4)',\n background: 'linear-gradient(135deg, hsla(25, 100%, 50%, 0.12) 0%, hsla(25, 100%, 50%, 0.05) 100%)',\n },\n }}\n >\n <Box\n component=\"img\"\n src={shuffleIcon}\n alt=\"Shuffle\"\n sx={{ width: 36, height: 36, borderRadius: '10px', flexShrink: 0 }}\n />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontWeight: 700, fontSize: '0.85rem', color: 'hsl(var(--foreground))', lineHeight: 1.3 }}>\n Shuffle Pipelines\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', lineHeight: 1.4 }}>\n Do not have a SIEM? Shuffle can ingest, parse, and correlate your logs and events directly — no external SIEM required.\n </Typography>\n </Box>\n <Chip\n label=\"Built-in\"\n size=\"small\"\n sx={{\n height: 22,\n fontSize: '0.65rem',\n fontWeight: 700,\n backgroundColor: 'hsl(var(--primary) / 0.15)',\n color: 'hsl(var(--primary))',\n border: '1px solid hsl(var(--primary) / 0.3)',\n flexShrink: 0,\n }}\n />\n </Box>\n );\n}\n\nexport default ShufflePipelinesBanner;\n","/**\n * AgentUI — Standalone \"start + debug agents\" surface.\n *\n * TypeScript port and modernization of the legacy Shuffle Core\n * `AgentUI.jsx`. One component, two modes:\n *\n * 1. **Starter** — large hero prompt (\"What do you want to do?\")\n * with attached MCP/app chips. Submits to `/api/v1/agent`.\n * 2. **Debugger** — compact header + decision timeline driven by\n * `/api/v1/streams/results`, with question/continuation forms\n * and per-decision raw-JSON inspection.\n *\n * Mode switches automatically when an execution is started or when\n * `?execution_id=...&authorization=...` is present in the URL.\n *\n * Self-contained: uses {@link AppSearchDrawer} for app picking,\n * {@link runAgent} for the JSON-RPC call, and the library's\n * {@link toast} facade for notifications.\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Plus as AddIcon,\n Paperclip as AttachFileIcon,\n CheckCircle2 as CheckCircleIcon,\n Check as CheckIcon,\n X as CloseIcon,\n AlertCircle as ErrorIcon,\n TimerOff as HourglassDisabledIcon,\n Lock as LockIcon,\n ExternalLink as OpenInNewIcon,\n Pause as PauseIcon,\n Play as PlayArrowRoundedIcon,\n RefreshCw as RefreshIcon,\n RotateCcw as RestartAltIcon,\n Clock as ScheduleIcon,\n Send as SendIcon,\n CircleStop as StopCircleIcon,\n ThumbsDown as ThumbDownIcon,\n ThumbsUp as ThumbUpIcon,\n AlertTriangle as WarningIcon\n} from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Avatar,\n AvatarGroup,\n Box,\n Button,\n // ButtonGroup removed (replaced by chip tabs)\n Chip,\n CircularProgress,\n IconButton,\n InputBase,\n MenuItem,\n Popover,\n Select,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkBreaks from 'remark-breaks';\n\n// Normalize agent answer text so react-markdown renders it correctly:\n// - Decode literal escape sequences (\"\\n\", \"\\t\", \"\\r\") that come back\n// double-encoded in some JSON payloads.\n// - Strip surrounding quotes if the value is itself a JSON-encoded string.\n// - Trim leading/trailing whitespace.\nconst normalizeMarkdown = (raw: unknown): string => {\n if (raw == null) return '';\n let s = typeof raw === 'string' ? raw : (() => {\n try { return JSON.stringify(raw, null, 2); } catch { return String(raw); }\n })();\n // If the whole thing is a JSON-encoded string, decode it once.\n if (s.length > 1 && s.startsWith('\"') && s.endsWith('\"')) {\n try { s = JSON.parse(s); } catch { /* keep as-is */ }\n }\n // Convert literal \"\\n\" / \"\\t\" / \"\\r\" sequences into real characters.\n s = s.replace(/\\\\r\\\\n/g, '\\n').replace(/\\\\n/g, '\\n').replace(/\\\\t/g, '\\t').replace(/\\\\\"/g, '\"');\n return s.trim();\n};\nimport JsonView from 'react18-json-view';\nimport 'react18-json-view/src/style.css';\nimport 'react18-json-view/src/dark.css';\n\n/** Recursively parse JSON-looking strings into objects/arrays so JsonView can collapse them. */\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n } catch { /* ignore */ }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\n\nimport { SegmentedControl } from './SegmentedControl';\nimport AgentIcon from '@/Shuffle-MCPs/AgentIcon';\nimport AppSearchDrawer from '@/Shuffle-MCPs/AppSearchDrawer';\nimport AppDetailDrawer from '@/Shuffle-MCPs/AppDetailDrawer';\nimport { getApiUrl, getAuthHeader, API_CONFIG } from '@/Shuffle-MCPs/api';\nimport { fetchApps } from '@/Shuffle-MCPs/appsCache';\nimport { resolveApps } from '@/Shuffle-MCPs/resolveApp';\nimport { toast } from '@/Shuffle-MCPs/toast';\nimport { runAgent } from '@/Shuffle-MCPs/agentRun';\nimport { parseScheduleHint } from '@/Shuffle-MCPs/scheduleHint';\nimport AgentRunDiagnosisBanner from '@/Shuffle-MCPs/AgentRunDiagnosisBanner';\n\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport interface AgentUIApp {\n /** App slug, e.g. \"http\", \"shuffle_tools\", \"gmail\". */\n name: string;\n /** Algolia objectID / Shuffle app id (preferred). */\n id?: string;\n /** Optional preview icon URL. */\n icon?: string;\n}\n\nexport interface AgentUIProps {\n /** Controlled list of apps. When provided, overrides defaultApps and disables auto-load. */\n apps?: AgentUIApp[];\n /** Initial chip set under the prompt. Used only when `apps` is not provided. */\n defaultApps?: AgentUIApp[];\n /**\n * When true (default) and neither `apps` nor `defaultApps` is provided, fetch the\n * caller's authenticated apps via `/api/v1/apps/authentication` (requires an API\n * token to be set on `API_CONFIG`).\n */\n autoLoadApps?: boolean;\n /** Hero title above the prompt. */\n title?: string;\n /** Optional subtitle/description shown under the title. */\n subtitle?: React.ReactNode;\n /** Placeholder shown in the empty prompt. */\n placeholder?: string;\n /** Pre-fill the prompt with this text. */\n defaultInput?: string;\n /** Submit immediately on mount when `defaultInput` is provided. */\n autoSubmit?: boolean;\n /** Hide the centered hero icon (compact mode). */\n hideHeroIcon?: boolean;\n /** Replace the default AgentIcon with a custom node (e.g. brand logo). */\n heroIcon?: React.ReactNode;\n /** Pixel size of the hero icon container. Default 84. */\n heroIconSize?: number;\n /** Maximum width of the centered card. */\n maxWidth?: number;\n /** Compact mode: hides the hero icon, shrinks padding. */\n compact?: boolean;\n /** Hide the \"Select Apps / MCPs\" chip row entirely. */\n hideAppPicker?: boolean;\n /** Hide the paperclip image-attachment button. */\n hideAttach?: boolean;\n /** Disable the \"Start\" tab in the run switcher (e.g. when viewing a fixed execution). */\n disableStartTab?: boolean;\n /** Label on the \"Select Apps / MCPs\" chip. */\n appPickerLabel?: string;\n /** Title on the AppSearchDrawer. */\n appPickerTitle?: string;\n /** Subtitle on the AppSearchDrawer. */\n appPickerSubtitle?: string;\n /** Tooltip on the submit button. Default: \"⌘+Enter to send\". */\n submitTooltip?: string;\n /** Custom icon for the submit button. */\n submitIcon?: React.ReactNode;\n /**\n * When provided, the submit button + Cmd/Ctrl+Enter call this instead of\n * running the agent. Used for \"edit existing scheduled workflow\" mode where\n * the same starter UI is reused for editing the prompt + apps.\n */\n submitOverride?: (info: { input: string; apps: Array<{ name: string; id?: string; icon?: string }> }) => void | Promise<void>;\n /** When set, renders the submit control as a wider labelled button instead of the icon-only send button. */\n submitLabel?: string;\n /** Force-disable the schedule (clock) button. Optional tooltip override. */\n disableSchedule?: boolean;\n disableScheduleTooltip?: string;\n /** Placeholder for the post-finish continuation field. */\n continuationPlaceholder?: string;\n /** Read `?execution_id` & `?authorization` from window URL on mount. */\n readUrlParams?: boolean;\n /**\n * Optional explicit execution to attach to on mount. Overrides URL params\n * and skips the starter — useful when embedding to monitor a known run.\n */\n executionId?: string;\n /** Authorization token paired with `executionId`. */\n authorization?: string;\n /**\n * Pre-loaded execution payload. When provided, AgentUI skips the starter\n * and renders Simple/Detailed views immediately — no `/streams/results`\n * fetch, no `authorization` token required. Useful for embedding inside\n * a list/drawer that already has the execution data in hand. If the run\n * is still EXECUTING and an `authorization` is also present, polling\n * continues normally.\n */\n initialExecution?: {\n execution_id?: string;\n authorization?: string;\n status?: string;\n started_at?: number | string;\n completed_at?: number | string;\n results?: any[];\n workflow?: { id?: string; name?: string };\n [k: string]: any;\n };\n /** Called whenever a run finishes (success or failure). */\n onRun?: (info: { input: string; success: boolean; executionId?: string; error?: string }) => void;\n /** Called whenever the active top-level view changes (start / simple / detailed). */\n onViewChange?: (view: 'start' | 'simple' | 'detailed') => void;\n /**\n * Called when the user saves a recurring schedule (cron expression) for the\n * current prompt. When omitted, a toast is shown indicating scheduling is\n * not wired up in this embed.\n */\n onSchedule?: (info: {\n cron: string;\n input: string;\n apps?: Array<{ name: string; id?: string; icon?: string }>;\n onStep?: (event: { id: 'name' | 'workflow' | 'schedule'; state: 'active' | 'done' | 'error'; detail?: string }) => void;\n }) => void | Promise<void>;\n /**\n * Optional Shuffle API key. When provided, all `/api/v1/*` calls made by\n * this component (agent run, polling, app autoload, icon fallback) use it\n * via `Authorization: Bearer <apiKey>`. When omitted, falls back to the\n * shared `API_CONFIG` (browser session / `localStorage.shuffle_api_key`).\n */\n apiKey?: string;\n /**\n * Optional Shuffle backend base URL (e.g. `https://shuffler.io`). When\n * omitted, falls back to the shared `API_CONFIG.baseUrl`. Useful when\n * embedding `AgentUI` inside another app that targets a different region.\n */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header on every call. */\n orgId?: string;\n /** Optional className forwarded to the root container. */\n className?: string;\n /** Style overrides merged into the root container sx. */\n sx?: SxProps<Theme>;\n /** Style overrides for the inner content card (the column under the run-switcher). */\n contentSx?: SxProps<Theme>;\n}\n\ninterface ExecutionData {\n execution_id?: string;\n authorization?: string;\n status?: string;\n started_at?: number;\n completed_at?: number;\n results?: any[];\n workflow?: { id?: string; name?: string };\n [k: string]: any;\n}\n\ninterface AgentDecision {\n action?: string;\n category?: string;\n reason?: string;\n fields?: Array<{ key?: string; value?: string }>;\n details?: any;\n run_details?: {\n id?: string;\n status?: string;\n started_at?: number;\n completed_at?: number;\n raw_response?: string;\n };\n [k: string]: any;\n}\n\ninterface TimelineItem {\n label?: string;\n type: 'agent' | 'decision' | 'processing';\n category?: string;\n status?: string;\n start_time?: number;\n end_time?: number;\n details?: any;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nconst validateJson = (raw: unknown): { valid: boolean; result: any } => {\n if (raw == null) return { valid: false, result: null };\n if (typeof raw === 'object') return { valid: true, result: raw };\n if (typeof raw !== 'string') return { valid: false, result: raw };\n try {\n return { valid: true, result: JSON.parse(raw) };\n } catch {\n return { valid: false, result: raw };\n }\n};\n\n/**\n * Detect whether a single decision came back asking for app authentication.\n * Returns the app name (and optional id from `details.tool` when prefixed\n * \"app:<id>:<name>\") so the caller can render an inline \"Authenticate X\"\n * banner. Returns null when the decision did not request auth.\n */\nconst extractAuthRequest = (decision: any): { appName: string; appId: string | null } | null => {\n if (!decision || typeof decision !== 'object') return null;\n const raw = decision?.run_details?.raw_response;\n let parsed: any = null;\n if (typeof raw === 'string') {\n try { parsed = JSON.parse(raw); } catch { parsed = null; }\n } else if (raw && typeof raw === 'object') {\n parsed = raw;\n }\n const needsAuth = parsed && (parsed.action === 'app_authentication' || parsed.app_authentication === true);\n if (!needsAuth) return null;\n let appName: string | undefined = parsed.app || parsed.app_name || parsed.appname;\n let appId: string | null = null;\n if (!appName && typeof decision?.tool === 'string') {\n const t = decision.tool;\n if (t.startsWith('app:')) {\n const parts = t.split(':');\n appId = parts[1] || null;\n appName = parts[2] || t;\n } else {\n appName = t;\n }\n }\n if (!appName) {\n const f = (decision?.fields || []).find((x: any) => x?.key === 'app' || x?.key === 'app_name');\n if (f?.value) appName = f.value;\n }\n if (!appName) return null;\n return { appName, appId };\n};\n\nconst STATUS_COLORS = {\n finished: 'hsl(142, 71%, 45%)',\n warning: 'hsl(38, 92%, 50%)',\n error: 'hsl(0, 72%, 55%)',\n running: 'hsl(var(--primary))',\n};\n\nconst buildToolName = (apps: AgentUIApp[]): string => {\n if (!apps.length) return 'API';\n return apps\n .map((a) => {\n const slug = a.name.toLowerCase().replace(/\\s+/g, '_').replace(/-/g, '_');\n return a.id ? `app:${a.id}:${slug}` : slug;\n })\n .join(',');\n};\n\n// ── Inner: timeline item ──────────────────────────────────────────────────────\n\nconst StatusIcon: React.FC<{ status?: string }> = ({ status }) => {\n const s = (status || '').toUpperCase();\n let node: React.ReactNode;\n let label: string;\n if (s === 'RUNNING' || s === 'EXECUTING' || s === '') {\n node = <CircularProgress size={18} sx={{ color: STATUS_COLORS.running }} />;\n label = 'Running';\n } else if (s === 'WAITING') {\n node = <PauseIcon size={20} />;\n label = 'Waiting for input';\n } else if (s === 'FINISHED' || s === 'SUCCESS') {\n node = <CheckCircleIcon size={20} />;\n label = 'Finished successfully';\n } else if (s === 'ABORTED' || s === 'FAILURE') {\n node = <ErrorIcon size={20} />;\n label = s === 'ABORTED' ? 'Aborted' : 'Failed';\n } else if (s === 'IGNORED' || s === 'IGNORE') {\n node = <WarningIcon size={20} />;\n label = 'Ignored — skipped after run finished';\n } else {\n node = <HourglassDisabledIcon size={20} color={'hsl(var(--muted-foreground))'} />;\n label = 'Pending';\n }\n return (\n <Tooltip title={label} arrow>\n <Box sx={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>\n {node}\n </Box>\n </Tooltip>\n );\n};\n\n\n\ninterface TimelineRowProps {\n item: TimelineItem;\n index: number;\n open: boolean;\n onToggle: () => void;\n appsById: Record<string, AgentUIApp>;\n totalDuration: number;\n originalStartTime: number;\n maxWidth: number;\n questionAnswers: Record<string, { index: number; value: string }>;\n setQuestionAnswers: React.Dispatch<React.SetStateAction<Record<string, { index: number; value: string }>>>;\n onSubmitQuestions: (decisionId: string, answers: Record<string, any>, isContinuation?: boolean) => void;\n onRerunAgent: () => void;\n onRerunDecision: (decision: any) => void;\n agentRequestLoading: boolean;\n getFormUrl?: (decisionId: string) => string | null;\n runFinished?: boolean;\n onAuthenticateApp?: (appName: string, appId?: string | null) => void;\n isAppAuthenticated?: (appName: string) => boolean;\n /** When true, briefly draw attention to this row + its output. Used after\n * a \"jump to evidence\" click from the diagnosis banner. */\n highlight?: boolean;\n}\n\nconst TimelineRow: React.FC<TimelineRowProps> = ({\n item, index, open, onToggle, appsById, totalDuration, originalStartTime,\n maxWidth, questionAnswers, setQuestionAnswers, onSubmitQuestions,\n onRerunAgent, onRerunDecision, agentRequestLoading, getFormUrl, runFinished,\n onAuthenticateApp, isAppAuthenticated, highlight = false,\n}) => {\n const [submitAttempted, setSubmitAttempted] = useState(false);\n const validate = validateJson(item.details);\n const itemStart = item.start_time || 0;\n const itemEnd = item.end_time || itemStart;\n const hasTiming = itemStart > 0 && itemEnd >= itemStart;\n const dur = hasTiming ? Math.max(0, itemEnd - itemStart) : 0;\n const offset = totalDuration > 0 && hasTiming ? ((itemStart - originalStartTime) / totalDuration) * maxWidth : 0;\n const width = totalDuration > 0 && hasTiming ? Math.max(4, (dur / totalDuration) * maxWidth) : 0;\n\n // Adapt label based on action/category\n let displayType = item.type as string;\n let displayLabel = item.label?.replace(/_/g, ' ') || '';\n const details = item.details as AgentDecision | undefined;\n const isProcessing = item.category === 'processing';\n if (isProcessing) {\n displayType = 'processing';\n } else if (details?.reason) {\n displayLabel = details.reason;\n }\n if (!isProcessing) {\n if (details?.action === 'finish' || item.category === 'finish' || details?.action === 'finalise') {\n displayType = 'finalise';\n } else if (item.category === 'ask' || details?.action === 'ask') {\n displayType = 'question';\n } else if (details?.action === 'add_tool') {\n displayType = 'add tool';\n }\n }\n\n // Resolve app icon for the tool used. `details.tool` may be a name or an ID.\n // Skip finalise/question/finish actions — they use the agent's \"core\" tool.\n // Also skip generic transport tools (api/http/webhook/shuffle_tools/singul/\n // core) that don't represent a specific integration — otherwise we end up\n // showing whichever app happened to be cached under that generic key\n // (e.g. Gmail for tool=\"api\"), which is misleading.\n let toolApp: AgentUIApp | undefined;\n const GENERIC_TOOLS = new Set(['api', 'http', 'https', 'webhook', 'singul', 'core', 'shuffle_tools', 'shuffle-tools']);\n const skipToolIcon =\n item.category === 'finalise' || item.category === 'finish' || item.category === 'ask' ||\n details?.action === 'finalise' || details?.action === 'finish' || details?.action === 'ask';\n if (!skipToolIcon && details?.tool && typeof details.tool === 'string') {\n const raw = details.tool;\n let tn = raw.toLowerCase().replace(/[\\s-]+/g, '_');\n if (tn.startsWith('app:')) tn = tn.split(':')[2] || tn;\n if (!GENERIC_TOOLS.has(tn)) {\n const candidate = appsById[raw] || appsById[tn];\n // Only trust the lookup when the resolved app's id or normalized name\n // actually matches the tool slug — `appsById` is a shared map keyed by\n // multiple aliases, so a stale/aliased entry can otherwise return an\n // unrelated app (the original symptom: tool=\"api\" → Gmail icon).\n if (candidate) {\n const candidateSlugs = new Set<string>();\n if (candidate.id) candidateSlugs.add(String(candidate.id).toLowerCase());\n if (candidate.name) candidateSlugs.add(candidate.name.toLowerCase().replace(/[\\s-]+/g, '_'));\n if (candidateSlugs.has(tn) || candidateSlugs.has(raw.toLowerCase())) {\n toolApp = candidate;\n }\n }\n }\n }\n\n // Question fields. A field counts as \"answered\" when either the upstream\n // payload already carries an `answer` value on the field itself, or the\n // user has typed an answer locally in `questionAnswers`.\n const questions: { question: string; index: number; preAnswer?: string }[] = [];\n if (item.category === 'ask' || details?.action === 'ask') {\n for (const f of details?.fields || []) {\n if (f.key === 'question' && f.value) {\n const preAnswer = typeof (f as any).answer === 'string' ? (f as any).answer.trim() : '';\n questions.push({ question: f.value, index: questions.length + 1, preAnswer: preAnswer || undefined });\n }\n }\n }\n const questionsAnswered = questions.every(\n (q) => q.preAnswer || questionAnswers[q.question]?.value\n );\n const unansweredQuestions = questions.filter(\n (q) => !q.preAnswer && !questionAnswers[q.question]?.value\n );\n\n // If the run as a whole has finished, treat any still-RUNNING/WAITING rows\n // (typically an unanswered ASK that the agent moved past) as ignored so we\n // don't keep highlighting them with the orange \"running\" bar.\n const effectiveStatus =\n runFinished && (item.status === 'RUNNING' || item.status === 'WAITING')\n ? 'IGNORED'\n : item.status;\n const barColor = isProcessing ? 'hsl(var(--muted-foreground) / 0.45)' :\n effectiveStatus === 'IGNORED' ? STATUS_COLORS.warning :\n effectiveStatus === 'FINISHED' ? STATUS_COLORS.finished :\n effectiveStatus === 'FAILURE' || effectiveStatus === 'ABORTED' ? STATUS_COLORS.error :\n STATUS_COLORS.running;\n\n return (\n <Box\n data-timeline-index={index}\n sx={{\n borderTop: index === 0 ? 'none' : '1px solid hsl(var(--border))',\n bgcolor: highlight\n ? 'hsla(var(--severity-medium) / 0.12)'\n : open\n ? 'hsl(var(--muted) / 0.3)'\n : 'transparent',\n transition: 'background 0.6s ease, box-shadow 0.6s ease',\n scrollMarginTop: 96,\n position: 'relative',\n boxShadow: highlight ? 'inset 0 0 0 2px hsla(var(--severity-medium) / 0.55)' : 'none',\n }}\n >\n <Box\n onClick={isProcessing ? undefined : onToggle}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: 2,\n py: 1.25,\n cursor: isProcessing ? 'default' : 'pointer',\n '&:hover': isProcessing ? {} : { bgcolor: 'hsl(var(--muted) / 0.4)' },\n }}\n >\n <Box sx={{ width: 24, display: 'flex', justifyContent: 'center' }}>\n {isProcessing ? (\n <Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: 'hsl(var(--muted-foreground) / 0.5)' }} />\n ) : (\n <StatusIcon status={effectiveStatus} />\n )}\n </Box>\n <Box sx={{ width: 24, display: 'flex', justifyContent: 'center' }}>\n {isProcessing ? (\n <Box sx={{ width: 22 }} />\n ) : toolApp?.icon ? (\n <Tooltip title={(toolApp.name || '').replace(/_/g, ' ')} arrow>\n <Avatar src={toolApp.icon} sx={{ width: 22, height: 22, bgcolor: 'transparent' }} variant=\"rounded\" />\n </Tooltip>\n ) : item.category === 'finalise' || details?.action === 'finish' ? (\n <Tooltip title=\"Final answer\" arrow>\n <CheckIcon size={18} />\n </Tooltip>\n ) : (\n <Box sx={{ width: 22 }} />\n )}\n </Box>\n\n <Chip\n label={displayType}\n size=\"small\"\n sx={{\n height: 22,\n bgcolor: isProcessing ? 'transparent' : 'hsl(var(--muted))',\n color: isProcessing ? 'hsl(var(--muted-foreground))' : 'hsl(var(--foreground))',\n border: isProcessing ? '1px dashed hsl(var(--border))' : 'none',\n fontSize: '0.7rem',\n fontWeight: 500,\n textTransform: 'capitalize',\n minWidth: 80,\n fontStyle: isProcessing ? 'italic' : 'normal',\n }}\n />\n <Box sx={{\n flex: 1,\n minWidth: 0,\n fontSize: '0.85rem',\n color: 'hsl(var(--foreground))',\n maxHeight: 60,\n overflow: 'hidden',\n '& p': { margin: 0 },\n '& pre, & code': { fontSize: '0.78rem' },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline', textUnderlineOffset: '2px' },\n '& a:hover': { opacity: 0.85 },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(displayLabel)}</Markdown>\n </Box>\n <Tooltip title={hasTiming ? `Duration: ${dur.toFixed(2)}s · ${new Date(itemStart * 1000).toLocaleString()}` : 'No timing data'}>\n <Box sx={{ width: maxWidth, position: 'relative', height: 10, flexShrink: 0 }}>\n {dur > 0 && (\n <Box sx={{\n position: 'absolute',\n left: Math.max(0, offset),\n width,\n height: 8,\n top: 1,\n bgcolor: barColor,\n borderRadius: 1,\n transition: 'all 0.2s ease',\n }} />\n )}\n </Box>\n </Tooltip>\n <Box sx={{ width: 60, fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', textAlign: 'right' }}>\n {dur > 0 ? `${dur.toFixed(2)}s` : ''}\n </Box>\n {/* Per-row actions: Approve/Deny, Rerun */}\n <Box\n sx={{ display: 'flex', alignItems: 'center', gap: 0.25, ml: 1, minWidth: 96, justifyContent: 'flex-end' }}\n onClick={(e) => {\n // Only swallow the click when it actually lands on a button —\n // otherwise the empty area inside this row-actions box would\n // block the parent's expand/collapse toggle.\n if ((e.target as HTMLElement).closest('button, a')) e.stopPropagation();\n }}\n >\n {item.type === 'decision'\n && details?.run_details?.status === 'WAITING'\n && (item.category === 'ask' || details?.action === 'ask')\n && questions.length === 0 && (\n <>\n <Tooltip title=\"Approve this step\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={() => {\n if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: 'true' });\n }}\n sx={{ color: STATUS_COLORS.finished }}\n >\n <ThumbUpIcon size={16} />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip title=\"Deny this step\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={() => {\n if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: 'false' });\n }}\n sx={{ color: STATUS_COLORS.error }}\n >\n <ThumbDownIcon size={16} />\n </IconButton>\n </span>\n </Tooltip>\n </>\n )}\n {item.type === 'agent' && null}\n {item.type === 'decision' && (() => {\n const action = details?.action;\n const cat = item.category;\n const isApiAction =\n action !== 'ask' && cat !== 'ask' &&\n action !== 'finish' && action !== 'finalise' && cat !== 'finish' && cat !== 'finalise' &&\n cat !== 'processing' &&\n action !== 'add_tool';\n if (!isApiAction) return null;\n return (\n <Tooltip title=\"Rerun from this decision (clears all decisions after it)\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading || !details?.run_details?.id}\n onClick={() => details && onRerunDecision(details)}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <RestartAltIcon size={16} />\n </IconButton>\n </span>\n </Tooltip>\n );\n })()}\n {item.type === 'decision' && (details?.run_details as any)?.debug_url && (\n <Tooltip title=\"Open debug URL\">\n <span>\n <IconButton\n size=\"small\"\n onClick={() => window.open((details!.run_details as any).debug_url, '_blank', 'noopener,noreferrer')}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon size={16} />\n </IconButton>\n </span>\n </Tooltip>\n )}\n </Box>\n </Box>\n\n {/* Question form (for ASK decisions) */}\n {questions.length > 0 && !runFinished && (item.status === 'RUNNING' || item.status === 'WAITING') && (\n <Box sx={{ px: 4, pb: 2 }}>\n {(() => {\n const trySubmit = () => {\n if (agentRequestLoading) return;\n if (!questionsAnswered) {\n setSubmitAttempted(true);\n return;\n }\n if (details?.run_details?.id) {\n onSubmitQuestions(details.run_details.id, questionAnswers);\n }\n };\n return (\n <>\n {questions.map((q, qi) => {\n const value = questionAnswers[q.question]?.value || '';\n const isMissing = submitAttempted && !value;\n return (\n <Box key={qi} sx={{ mt: 2 }}>\n <Box sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', mb: 1 }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n <TextField\n fullWidth\n multiline\n minRows={2}\n placeholder=\"Your answer here…\"\n value={value}\n error={isMissing}\n helperText={isMissing ? 'Please answer this question' : undefined}\n onChange={(e) => {\n const v = e.target.value;\n setQuestionAnswers((prev) => ({\n ...prev,\n [q.question]: { index: qi, value: v },\n }));\n }}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n trySubmit();\n }\n }}\n size=\"small\"\n sx={{\n '& .MuiOutlinedInput-root': { bgcolor: 'hsl(var(--card))' },\n }}\n />\n </Box>\n );\n })}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 2 }}>\n <Tooltip title={!questionsAnswered ? 'Please answer all questions first' : ''} placement=\"top\" arrow>\n <span>\n <Button\n variant=\"contained\"\n size=\"small\"\n disabled={agentRequestLoading || !questionsAnswered}\n onClick={trySubmit}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'hsl(var(--primary-foreground))' }} /> : undefined}\n >\n {agentRequestLoading ? 'Submitting…' : 'Submit'}\n </Button>\n </span>\n </Tooltip>\n {details?.run_details?.id && getFormUrl && getFormUrl(details.run_details.id) && (\n <Tooltip title=\"Answer in the Form UI\" placement=\"right\">\n <IconButton\n size=\"small\"\n onClick={() => {\n const url = getFormUrl(details.run_details!.id!);\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n }}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon size={18} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </>\n );\n })()}\n </Box>\n )}\n\n {/* Unanswered questions (read-only) when the run finished without an answer */}\n {open && runFinished && unansweredQuestions.length > 0 && (\n <Box sx={{ px: 4, pb: 2 }}>\n <Typography sx={{ fontSize: '0.7rem', textTransform: 'uppercase', letterSpacing: 0.5, color: 'hsl(var(--muted-foreground))', mb: 1 }}>\n {unansweredQuestions.length === 1 ? 'Question (unanswered)' : 'Questions (unanswered)'}\n </Typography>\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n display: 'flex', flexDirection: 'column', gap: 1.5,\n }}>\n {unansweredQuestions.map((q, qi) => (\n <Box key={qi} sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', '& p': { my: 0.5 } }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n ))}\n </Box>\n </Box>\n )}\n\n {/* App authentication required banner — surfaces whenever the upstream\n tool returned `action: \"app_authentication\"`. Always visible\n (regardless of expand state) so users do not have to click into\n a failed step to discover that auth is missing. */}\n {(() => {\n const req = extractAuthRequest(details);\n if (!req) return null;\n if (isAppAuthenticated?.(req.appName)) return null;\n const pretty = req.appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const slug = req.appName.toLowerCase().replace(/[\\s-]+/g, '_');\n const appId = req.appId || appsById[req.appName]?.id || appsById[slug]?.id || null;\n const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : '') || '';\n return (\n <Box sx={{ px: 4, pb: 2 }}>\n <Box sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}>\n <LockIcon size={22} color={'hsl(var(--severity-medium))'} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n Connect your {pretty} account so the agent can complete this step, then rerun the decision.\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={icon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n disabled={!onAuthenticateApp}\n onClick={(e) => {\n e.stopPropagation();\n onAuthenticateApp?.(req.appName, appId);\n }}\n sx={{\n height: 36, textTransform: 'none', fontWeight: 600,\n }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n </Box>\n );\n })()}\n\n {/* Raw JSON */}\n {open && (\n <Box sx={{ px: 4, pb: 2 }}>\n <Box\n sx={{\n p: 2,\n borderRadius: 1.5,\n border: highlight\n ? '1px solid hsl(var(--severity-medium))'\n : '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n boxShadow: highlight\n ? '0 0 0 3px hsla(var(--severity-medium) / 0.25)'\n : 'none',\n transition: 'border-color 0.6s ease, box-shadow 0.6s ease',\n overflow: 'auto',\n maxHeight: 400,\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n '& .json-view': {\n fontSize: '0.72rem !important',\n fontFamily: 'inherit !important',\n bgcolor: 'transparent !important',\n },\n }}\n >\n {validate.valid && validate.result && typeof validate.result === 'object' ? (\n <JsonView\n src={deepParseJsonStrings(validate.result)}\n dark\n collapsed={2}\n collapseStringMode=\"word\"\n collapseStringsAfterLength={120}\n enableClipboard\n displaySize\n />\n ) : (\n <Box component=\"pre\" sx={{ m: 0, fontSize: '0.72rem', color: 'hsl(var(--foreground))' }}>\n <code>{String(item.details ?? '')}</code>\n </Box>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n};\n\n// ── Main component ────────────────────────────────────────────────────────────\n\n\nconst AgentUI: React.FC<AgentUIProps> = ({\n apps,\n defaultApps,\n autoLoadApps = true,\n title = 'What do you want to do?',\n subtitle,\n placeholder = 'Describe a task, e.g. \"Get my emails for today and summarise them\"',\n defaultInput = '',\n autoSubmit = false,\n hideHeroIcon = false,\n heroIcon,\n heroIconSize = 84,\n maxWidth = 900,\n compact = false,\n hideAppPicker = false,\n hideAttach = false,\n disableStartTab = false,\n appPickerLabel = 'Select Apps / MCPs',\n appPickerTitle = 'Select Apps / MCPs',\n appPickerSubtitle = 'Pick the tools the agent is allowed to use for this run',\n submitTooltip = '⌘+Enter to send',\n submitIcon,\n submitOverride,\n submitLabel,\n disableSchedule,\n disableScheduleTooltip,\n continuationPlaceholder = 'Add more details to continue this task…',\n readUrlParams = true,\n executionId,\n authorization,\n initialExecution,\n onRun,\n onViewChange,\n onSchedule,\n apiKey,\n apiBaseUrl,\n orgId,\n className,\n sx,\n contentSx,\n}) => {\n // Per-instance API target. Props win over the shared API_CONFIG so the\n // component can be embedded against a different Shuffle backend without\n // mutating global state.\n const resolveUrl = useCallback(\n (path: string) => (apiBaseUrl ? `${apiBaseUrl.replace(/\\/+$/, '')}${path}` : getApiUrl(path)),\n [apiBaseUrl],\n );\n const resolveHeaders = useCallback((): Record<string, string> => {\n const h: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : { ...getAuthHeader() };\n if (orgId) h['Org-Id'] = orgId;\n return h;\n }, [apiKey, orgId]);\n const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;\n const navigate = useNavigate();\n const [actionInput, setActionInput] = useState(defaultInput);\n const BUILTIN_DEFAULT_APPS: AgentUIApp[] = [\n { name: 'http' },\n { name: 'shuffle_tools' },\n ];\n const [chosenApps, setChosenApps] = useState<AgentUIApp[]>(apps ?? defaultApps ?? BUILTIN_DEFAULT_APPS);\n // Apps the caller has authenticated — used to resolve icons by name and as\n // suggestions in the picker. NOT auto-selected as `chosenApps`.\n const [availableApps, setAvailableApps] = useState<AgentUIApp[]>([]);\n // Apps actually allowed for the current execution, derived from the agent's\n // `allowed_actions` field (format: \"app:<id>:<name>\"). Falls back to\n // `chosenApps` when the field is missing (legacy runs).\n const [executionApps, setExecutionApps] = useState<AgentUIApp[]>([]);\n // Icons resolved on-demand for tools referenced in the timeline that are\n // NOT in chosenApps/executionApps. Resolution order:\n // 1) /api/v1/apps cache — match by id, then by lowercase+underscore name\n // 2) Algolia — match by objectID, then by name\n const [resolvedToolApps, setResolvedToolApps] = useState<Record<string, AgentUIApp>>({});\n const [appSearchOpen, setAppSearchOpen] = useState(false);\n const [authDrawerApp, setAuthDrawerApp] = useState<{ name: string; id?: string | null } | null>(null);\n const [agentRequestLoading, setAgentRequestLoading] = useState(false);\n const [execution, setExecution] = useState<ExecutionData | null>(null);\n const [agentData, setAgentData] = useState<{ decisions?: AgentDecision[]; original_input?: string; status?: string; started_at?: number; completed_at?: number; [k: string]: any }>({});\n const [agentActionResult, setAgentActionResult] = useState<any>(null);\n const [showStarter, setShowStarter] = useState(true);\n const [scheduleAnchor, setScheduleAnchor] = useState<HTMLElement | null>(null);\n const [scheduleCron, setScheduleCron] = useState('0 * * * *');\n const [scheduleSaving, setScheduleSaving] = useState(false);\n const [scheduleSteps, setScheduleSteps] = useState<Array<{ id: 'name' | 'workflow' | 'schedule'; state: 'pending' | 'active' | 'done' | 'error'; detail?: string }>>([\n { id: 'name', state: 'pending' },\n { id: 'workflow', state: 'pending' },\n { id: 'schedule', state: 'pending' },\n ]);\n // Structured recurrence controls (Google-Calendar style). These compile\n // down to a 5-field cron expression in `scheduleCron`. The advanced cron\n // text field at the bottom of the popover lets power users override.\n type SchedFreq = 'minutes' | 'hours' | 'days' | 'weeks' | 'months';\n const [schedFreq, setSchedFreq] = useState<SchedFreq>('hours');\n const [schedInterval, setSchedInterval] = useState<number>(1);\n const [schedHour, setSchedHour] = useState<number>(9);\n const [schedMinute, setSchedMinute] = useState<number>(0);\n // Cron day-of-week: 0=Sun .. 6=Sat\n const [schedWeekdays, setSchedWeekdays] = useState<Set<number>>(() => new Set([1]));\n const [schedDayOfMonth, setSchedDayOfMonth] = useState<number>(1);\n const [schedAdvancedOpen, setSchedAdvancedOpen] = useState<boolean>(false);\n // When the user clicks a preset chip or types a custom cron, we mark the\n // structured controls \"dirty\" so the auto-compile effect doesn't clobber\n // it on the same render.\n const cronManualOverrideRef = useRef<boolean>(false);\n const [openIndexes, setOpenIndexes] = useState<Set<number>>(new Set());\n // Briefly pulses a row + its output box after the diagnosis banner's\n // \"Where this was found\" jump. Cleared on a timer.\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n const [questionAnswers, setQuestionAnswers] = useState<Record<string, { index: number; value: string }>>({});\n const [simpleSubmitAttempted, setSimpleSubmitAttempted] = useState(false);\n const [continuationText, setContinuationText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [searchParams, setSearchParams] = useSearchParams();\n const initialViewParam = searchParams.get('agentView');\n const [viewMode, setViewMode] = useState<'simple' | 'detailed'>(\n initialViewParam === 'detailed' ? 'detailed' : 'simple'\n );\n const [attachedImages, setAttachedImages] = useState<{ dataUrl: string; name: string }[]>([]);\n const [nowTick, setNowTick] = useState(() => Math.floor(Date.now() / 1000));\n // Local fallback start timestamp captured the moment we first see an\n // execution_id, so the \"Agent is working… Xs\" counter starts ticking\n // immediately — even before the backend echoes `started_at` back to us.\n const [localRunStart, setLocalRunStart] = useState<number | null>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n // Tracks the execution_id we currently want to display. Used to discard\n // stale poll responses from a previous run after the user has started a\n // new one (otherwise an in-flight fetch can repaint the old execution).\n const activeExecutionIdRef = useRef<string | null>(null);\n // AbortController for the in-flight POST /api/v1/agent request, plus a\n // generation counter so a slow request that resolves AFTER the user clicks\n // \"Cancel and go to Start\" cannot repaint the UI or swap tabs back.\n const runAbortRef = useRef<AbortController | null>(null);\n const runGenerationRef = useRef(0);\n // Sticky flag set when the user manually clicks the \"Start\" tab while a run\n // is loaded. Prevents downstream effects (URL sync, initialExecution attach,\n // etc.) from flipping back to Simple/Detailed when a poll response lands.\n // Cleared the moment the user actually submits a new run.\n const userPickedStartRef = useRef(false);\n // Mirror of state used inside async callbacks (e.g. submitInput) so we can\n // snapshot prior values for rollback without making the callback re-render\n // on every state change.\n const stateRef = useRef({\n execution: null as ExecutionData | null,\n agentData: {} as any,\n agentActionResult: null as any,\n openIndexes: new Set<number>(),\n questionAnswers: {} as Record<string, { index: number; value: string }>,\n continuationText: '',\n localRunStart: null as number | null,\n showStarter: true,\n });\n\n // Mirror state into stateRef on every render so async callbacks can read the\n // current values without taking them as dependencies.\n stateRef.current.execution = execution;\n stateRef.current.agentData = agentData;\n stateRef.current.agentActionResult = agentActionResult;\n stateRef.current.openIndexes = openIndexes;\n stateRef.current.questionAnswers = questionAnswers;\n stateRef.current.continuationText = continuationText;\n stateRef.current.localRunStart = localRunStart;\n stateRef.current.showStarter = showStarter;\n\n // Reset / capture the local run start. Seed as soon as the user submits\n // (so the counter ticks from t=0 even before /agent returns), and keep it\n // pinned until the run is cleared. Without this, the \"0s/1s\" counter\n // freezes because the backend's `started_at` keeps catching up to `now`\n // on every poll.\n useEffect(() => {\n if (execution?.execution_id || agentRequestLoading) {\n setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1000));\n } else {\n setLocalRunStart(null);\n }\n }, [execution?.execution_id, agentRequestLoading]);\n\n // Tick every second while anything run-related is in flight. Deps are\n // intentionally minimal so the interval is NOT torn down and recreated on\n // every poll response — that was making the \"Xs\" counter look frozen at 1s.\n useEffect(() => {\n const status = (execution?.status || agentData?.status || '').toUpperCase();\n const TERMINAL = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'];\n if (TERMINAL.includes(status)) return;\n const id = setInterval(() => setNowTick(Math.floor(Date.now() / 1000)), 1000);\n return () => clearInterval(id);\n }, [execution?.status, agentData?.status]);\n\n\n const readImageAsDataUrl = (file: File): Promise<{ dataUrl: string; name: string } | null> =>\n new Promise((resolve) => {\n if (!file.type.startsWith('image/')) {\n resolve(null);\n return;\n }\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result;\n resolve(typeof result === 'string' ? { dataUrl: result, name: file.name || 'Pasted image' } : null);\n };\n reader.onerror = () => resolve(null);\n reader.readAsDataURL(file);\n });\n\n const handleImagesSelected = async (files: FileList | File[] | null) => {\n if (!files) return;\n const arr = Array.from(files);\n const nonImages = arr.some((f) => !f.type.startsWith('image/'));\n if (nonImages) setError('Only image files can be attached.');\n const results = await Promise.all(arr.map(readImageAsDataUrl));\n const valid = results.filter((r): r is { dataUrl: string; name: string } => r !== null);\n if (valid.length > 0) {\n setAttachedImages((prev) => [...prev, ...valid]);\n setError(null);\n }\n };\n\n const appsById = useMemo(() => {\n const m: Record<string, AgentUIApp> = {};\n const add = (a: AgentUIApp) => {\n if (!a?.name) return;\n const slug = a.name.toLowerCase().replace(/[\\s-]+/g, '_');\n if (!m[slug] || (!m[slug].icon && a.icon)) m[slug] = a;\n if (a.id) {\n if (!m[a.id] || (!m[a.id].icon && a.icon)) m[a.id] = a;\n }\n };\n for (const a of chosenApps) add(a);\n for (const a of executionApps) add(a);\n for (const [k, v] of Object.entries(resolvedToolApps)) {\n if (!m[k] || (!m[k].icon && v.icon)) m[k] = v;\n add(v);\n }\n return m;\n }, [chosenApps, executionApps, resolvedToolApps]);\n\n // Predicate used by the auth banners — an app is considered authenticated\n // when it appears in the caller's `availableApps` list (which is populated\n // from /api/v1/apps/authentication and only includes valid entries).\n const isAppAuthenticated = useCallback((appName: string) => {\n if (!appName) return false;\n const norm = (s: string) => s.toLowerCase().replace(/[\\s-]+/g, '_');\n const target = norm(appName);\n return availableApps.some((a) => norm(a.name || '') === target);\n }, [availableApps]);\n\n // Unique apps (across all decisions) that returned `app_authentication`\n // and are not yet authenticated. Powers the Simple-view banners.\n const pendingAuthApps = useMemo(() => {\n const decisions: any[] = (agentData?.decisions as any[]) || [];\n const seen = new Set<string>();\n const out: { appName: string; appId: string | null; icon: string }[] = [];\n for (const d of decisions) {\n const req = extractAuthRequest(d);\n if (!req) continue;\n const slug = req.appName.toLowerCase().replace(/[\\s-]+/g, '_');\n if (seen.has(slug)) continue;\n if (isAppAuthenticated(req.appName)) continue;\n seen.add(slug);\n const appId = req.appId || appsById[req.appName]?.id || appsById[slug]?.id || null;\n const icon = appsById[req.appName]?.icon || appsById[slug]?.icon || (appId ? appsById[appId]?.icon : '') || '';\n out.push({ appName: req.appName, appId, icon });\n }\n return out;\n }, [agentData, appsById, isAppAuthenticated]);\n\n // Sync controlled `apps` prop into local state.\n useEffect(() => {\n if (apps) setChosenApps(apps);\n }, [apps]);\n\n // Resolve icons for tools referenced in the timeline that aren't already\n // covered by chosenApps/executionApps. Lookup order:\n // 1) /api/v1/apps cache — by id, then by lowercase+underscore name\n // 2) Algolia — by objectID, then by name\n useEffect(() => {\n const decisions = (agentData as any)?.decisions || [];\n if (!Array.isArray(decisions) || decisions.length === 0) return;\n\n const norm = (s: string) => s.toLowerCase().replace(/[\\s-]+/g, '_');\n // Collect unique tool tokens (raw + slug variant) that we haven't resolved.\n const wanted: { raw: string; slug: string }[] = [];\n const seen = new Set<string>();\n const consider = (raw: string) => {\n if (!raw || typeof raw !== 'string') return;\n let slug = norm(raw);\n if (slug.startsWith('app:')) slug = slug.split(':')[2] || slug;\n if (appsById[raw]?.icon || appsById[slug]?.icon) return;\n if (resolvedToolApps[raw]?.icon || resolvedToolApps[slug]?.icon) return;\n const key = `${raw}|${slug}`;\n if (seen.has(key)) return;\n seen.add(key);\n wanted.push({ raw, slug });\n };\n for (const dec of decisions) {\n const action = dec?.action || dec?.details?.action;\n const category = dec?.category || dec?.details?.category;\n // Tool tokens — skip terminal/ask steps.\n if (action !== 'finish' && action !== 'finalise' && action !== 'ask' &&\n category !== 'finish' && category !== 'finalise' && category !== 'ask') {\n const tool = dec?.details?.tool ?? dec?.tool;\n if (tool && tool !== 'singul' && tool !== 'core') consider(tool);\n }\n // App auth requests — banner needs the icon too.\n const req = extractAuthRequest(dec);\n if (req?.appName) consider(req.appName);\n }\n if (wanted.length === 0) return;\n\n let cancelled = false;\n (async () => {\n // Single general-purpose resolver — checks authenticated apps,\n // /api/v1/apps and Algolia in order so we get an icon even when the\n // app isn't activated yet.\n const tokens = Array.from(new Set(wanted.flatMap((w) => [w.raw, w.slug])));\n const resolved = await resolveApps(tokens);\n if (cancelled) return;\n\n const found: Record<string, AgentUIApp> = {};\n for (const { raw, slug } of wanted) {\n const r = resolved[raw] || resolved[slug];\n if (!r) continue;\n const app: AgentUIApp = { id: r.id, name: r.name || slug, icon: r.image || '' };\n found[raw] = app;\n found[slug] = app;\n }\n\n if (Object.keys(found).length === 0) return;\n setResolvedToolApps((prev) => ({ ...prev, ...found }));\n })();\n\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify((agentData as any)?.decisions?.map((d: any) => [d?.details?.tool || d?.tool, extractAuthRequest(d)?.appName]) || []), appsById]);\n\n // Sideload missing app icons via Algolia (same source as the picker), so\n // built-in/default chips like \"http\" and \"shuffle_tools\" show their logo\n // even when the caller didn't pass one in.\n useEffect(() => {\n const missing = chosenApps.filter((a) => !a.icon && a.name);\n if (missing.length === 0) return;\n let cancelled = false;\n const norm = (n: string) => n.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\n (async () => {\n // Pass 1 — try Algolia (public, works without an API key).\n const resolved: Record<string, string> = {};\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n await Promise.all(missing.map(async (a) => {\n const known = availableApps.find((x) => norm(x.name) === norm(a.name));\n if (known?.icon) { resolved[a.name] = known.icon; return; }\n try {\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: a.name.replace(/_/g, ' '), hitsPerPage: 3 },\n });\n const match = (res.hits as any[]).find((h) => norm(h.name || '') === norm(a.name))\n || (res.hits as any[])[0];\n if (match?.image_url) resolved[a.name] = match.image_url;\n } catch { /* fall through to /api/v1/apps */ }\n }));\n } catch { /* fall through to /api/v1/apps */ }\n\n // Pass 2 — for anything Algolia didn't resolve, fall back to /api/v1/apps\n // so built-in chips (http, shuffle_tools) still get their logo even when\n // Algolia is blocked or offline.\n const stillMissing = missing.filter((a) => !resolved[a.name]);\n if (stillMissing.length > 0) {\n try {\n const baseUrl = apiBaseUrl ? apiBaseUrl.replace(/\\/+$/, '') : API_CONFIG.baseUrl;\n const apps = await fetchApps({\n baseUrl,\n apiKey: apiKey || API_CONFIG.apiKey,\n orgId: orgId || null,\n });\n if (Array.isArray(apps)) {\n for (const a of stillMissing) {\n const m = apps.find((x: any) => norm(x.name || '') === norm(a.name));\n const img = m?.large_image || m?.image_url || m?.image;\n if (img) resolved[a.name] = img;\n }\n }\n } catch { /* chips will just show initials */ }\n }\n\n if (cancelled) return;\n setChosenApps((prev) => prev.map((a) => {\n if (a.icon) return a;\n const icon = resolved[a.name];\n return icon ? { ...a, icon } : a;\n }));\n })();\n return () => { cancelled = true; };\n }, [chosenApps, availableApps, resolveUrl, resolveHeaders]);\n\n // Auto-load the caller's authenticated apps when nothing was passed in\n // and an API token is configured. Skipped when controlled or `defaultApps`\n // were provided explicitly.\n useEffect(() => {\n if (!autoLoadApps) return;\n if (apps || defaultApps) return;\n if (!hasApiKey) return;\n let cancelled = false;\n (async () => {\n try {\n const resp = await fetch(resolveUrl('/api/v1/apps/authentication'), {\n credentials: 'include',\n headers: { ...resolveHeaders() },\n });\n if (!resp.ok) return;\n const result = await resp.json();\n const list = Array.isArray(result) ? result : (result?.data || []);\n const seen = new Set<string>();\n const loaded: AgentUIApp[] = [];\n for (const entry of list) {\n const app = entry?.app || entry;\n const name: string | undefined = app?.name;\n if (!name) continue;\n const valid = entry?.active || entry?.validation?.valid || entry?.hasValidAuth;\n if (valid === false) continue;\n const key = name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n loaded.push({\n name,\n id: app?.id || entry?.id,\n icon: app?.large_image || app?.image_url || app?.image || entry?.bestImage || '',\n });\n }\n if (!cancelled && loaded.length) setAvailableApps(loaded);\n } catch {\n // silent — caller can still pick apps manually\n }\n })();\n return () => { cancelled = true; };\n }, [autoLoadApps, apps, defaultApps, hasApiKey, resolveUrl, resolveHeaders]);\n\n\n // Derive the apps actually allowed for the current execution from the\n // agent's `allowed_actions` field. Format: \"app:<id>:<name>\". Resolves\n // icons via `availableApps` (in-memory) first, then falls back to the\n // global `/api/v1/apps` cache by id (preferred) or name.\n useEffect(() => {\n const raw = (agentData as any)?.allowed_actions;\n if (!Array.isArray(raw) || raw.length === 0) {\n setExecutionApps([]);\n return;\n }\n const parsed: { id: string; name: string }[] = [];\n const seen = new Set<string>();\n for (const entry of raw) {\n if (typeof entry !== 'string') continue;\n const parts = entry.split(':');\n if (parts.length < 3 || parts[0] !== 'app') continue;\n const id = parts[1] || '';\n const name = parts.slice(2).join(':') || '';\n if (!name && !id) continue;\n const key = `${id}|${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n parsed.push({ id, name });\n }\n if (parsed.length === 0) {\n setExecutionApps([]);\n return;\n }\n\n // First pass: resolve from availableApps without any network call.\n const resolveFromAvailable = (id: string, name: string): AgentUIApp => {\n const byId = id ? availableApps.find((a) => a.id === id) : undefined;\n const byName = !byId && name\n ? availableApps.find((a) => (a.name || '').toLowerCase() === name.toLowerCase())\n : undefined;\n const hit = byId || byName;\n return { id: id || hit?.id, name: hit?.name || name, icon: hit?.icon };\n };\n const initial = parsed.map(({ id, name }) => resolveFromAvailable(id, name));\n setExecutionApps(initial);\n\n // Second pass: fill missing icons from the global apps cache (covers\n // apps that the user has not authenticated yet). Lookup order:\n // 1) /api/v1/apps — by id, then by lowercase+underscore name\n // 2) Algolia — by objectID, then by name\n if (initial.every((a) => !!a.icon)) return;\n let cancelled = false;\n const norm = (s: string) => (s || '').toLowerCase().replace(/[\\s-]+/g, '_');\n (async () => {\n let next = initial;\n // Pass A — /api/v1/apps cache.\n try {\n const all = await fetchApps({\n baseUrl: API_CONFIG.baseUrl,\n apiKey: apiKey || API_CONFIG.apiKey,\n orgId: orgId || null,\n });\n if (!cancelled && Array.isArray(all) && all.length > 0) {\n const byIdMap = new Map<string, any>();\n const byNameMap = new Map<string, any>();\n for (const a of all) {\n if (a?.id) byIdMap.set(String(a.id), a);\n if (a?.name) byNameMap.set(norm(String(a.name)), a);\n }\n next = next.map((a) => {\n if (a.icon) return a;\n const hit = (a.id && byIdMap.get(a.id)) || byNameMap.get(norm(a.name || ''));\n if (!hit) return a;\n return {\n id: a.id || hit.id,\n name: hit.name || a.name,\n icon: hit.large_image || hit.image_url || hit.image || a.icon,\n } as AgentUIApp;\n });\n }\n } catch { /* fall through to Algolia */ }\n\n // Pass B — Algolia (objectID, then name) for anything still missing.\n const stillMissing = next.filter((a) => !a.icon);\n if (stillMissing.length > 0) {\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const resolved: Record<string, { name: string; icon: string; id: string }> = {};\n await Promise.all(stillMissing.map(async (a) => {\n try {\n if (a.id) {\n try {\n const obj = await (client as any).getObject({ indexName: 'appsearch', objectID: a.id });\n if (obj?.image_url) {\n resolved[a.id || a.name] = { name: obj.name || a.name, icon: obj.image_url, id: obj.objectID || a.id };\n return;\n }\n } catch { /* not an objectID — fall through */ }\n }\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: (a.name || '').replace(/_/g, ' '), hitsPerPage: 3 },\n });\n const hits = (res.hits as any[]) || [];\n const match = hits.find((h) => norm(h.name || '') === norm(a.name || '')) || hits[0];\n if (match?.image_url) {\n resolved[a.id || a.name] = { name: match.name || a.name, icon: match.image_url, id: match.objectID || a.id || '' };\n }\n } catch { /* skip */ }\n }));\n if (Object.keys(resolved).length > 0) {\n next = next.map((a) => {\n if (a.icon) return a;\n const r = resolved[a.id || a.name];\n return r ? { id: r.id || a.id, name: r.name || a.name, icon: r.icon } : a;\n });\n }\n } catch { /* algolia unavailable */ }\n }\n\n if (!cancelled) setExecutionApps(next);\n })();\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify((agentData as any)?.allowed_actions || []), availableApps]);\n\n // ── Fetch execution result (poll-friendly) ──\n const getExecution = useCallback(async (executionId: string, authorization: string) => {\n if (!executionId || !authorization) return;\n try {\n const resp = await fetch(resolveUrl('/api/v1/streams/results'), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders() },\n body: JSON.stringify({ execution_id: executionId, authorization }),\n });\n // Discard stale responses: if the user has since started a different\n // run (or cleared this one), do not write old data back into state.\n // Discard stale responses: only accept when the ref still matches the\n // execution we fetched. (Submitting a new run briefly clears the ref;\n // any in-flight poll from the previous run must be dropped, not written\n // back into state — otherwise the UI snaps to the old execution.)\n if (activeExecutionIdRef.current !== executionId) return;\n if (!resp.ok) {\n setError(`Could not fetch execution (${resp.status}).`);\n return;\n }\n const json = await resp.json();\n if (activeExecutionIdRef.current !== executionId) return;\n if (json?.success === false) {\n setError(json.reason || 'Failed to load agent data.');\n return;\n }\n setExecution({ ...json, execution_id: executionId, authorization });\n\n // Find AI Agent result for the timeline\n let actionResult: any = null;\n if (Array.isArray(json?.results)) {\n actionResult =\n json.results.find((r: any) => r?.action?.app_name === 'AI Agent') || json.results[0];\n } else {\n actionResult = json;\n }\n setAgentActionResult(actionResult);\n const v = validateJson(actionResult?.result);\n if (v.valid) setAgentData({ ...v.result, started_at: json.started_at, completed_at: json.completed_at, status: json.status });\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Network error.');\n }\n }, []);\n\n // Attach to an explicit execution (props) or one passed via URL params.\n // Props take precedence over URL params.\n useEffect(() => {\n let eid: string | null = null;\n let auth: string | null = null;\n if (executionId && authorization) {\n eid = executionId;\n auth = authorization;\n } else if (readUrlParams) {\n const params = new URLSearchParams(window.location.search);\n eid = params.get('execution_id');\n auth = params.get('authorization');\n }\n if (eid && auth) {\n if (!userPickedStartRef.current) setShowStarter(false);\n activeExecutionIdRef.current = eid;\n setExecution({ execution_id: eid, authorization: auth, status: 'EXECUTING' });\n getExecution(eid, auth);\n }\n }, [readUrlParams, executionId, authorization, getExecution]);\n\n // Attach to a pre-loaded execution (e.g. embedded inside a list/drawer\n // that already has the run data). Skips the starter and seeds Simple/\n // Detailed views directly — no `/streams/results` fetch, no\n // `authorization` token required.\n useEffect(() => {\n if (!initialExecution || !initialExecution.execution_id) return;\n if (!userPickedStartRef.current) setShowStarter(false);\n activeExecutionIdRef.current = initialExecution.execution_id;\n setExecution(initialExecution as ExecutionData);\n let actionResult: any = null;\n if (Array.isArray(initialExecution.results)) {\n actionResult =\n initialExecution.results.find((r: any) => r?.action?.app_name === 'AI Agent') ||\n initialExecution.results[0];\n } else {\n actionResult = initialExecution;\n }\n setAgentActionResult(actionResult);\n const v = validateJson(actionResult?.result);\n if (v.valid) {\n setAgentData({\n ...v.result,\n started_at: initialExecution.started_at,\n completed_at: initialExecution.completed_at,\n status: initialExecution.status,\n });\n }\n setError(null);\n\n // Sideloaded executions from the listing endpoint sometimes ship a\n // placeholder result body like `{ success: false, reason: \"Result too\n // large to handle ...\", extra: \"replace\" }` instead of the real agent\n // output. Detect that and re-fetch the full payload directly from\n // /api/v1/streams/results so the timeline renders properly.\n const needsReplace = (() => {\n const r = v.valid ? v.result : null;\n if (!r || typeof r !== 'object') return false;\n if (r.success === false && typeof r.reason === 'string' && /too large/i.test(r.reason)) return true;\n if (r.extra === 'replace') return true;\n return false;\n })();\n if (needsReplace && initialExecution.authorization && initialExecution.execution_id) {\n getExecution(initialExecution.execution_id, initialExecution.authorization);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialExecution?.execution_id]);\n\n // Poll while running. Continue indefinitely until we see a terminal status\n // (FINISHED / FAILURE / ABORTED). We never give up on our own — long\n // executions just keep streaming results back.\n useEffect(() => {\n if (!execution?.execution_id || !execution?.authorization) return;\n const status = (execution.status || '').toUpperCase();\n const TERMINAL = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'];\n if (TERMINAL.includes(status)) return;\n const id = setInterval(() => {\n getExecution(execution.execution_id!, execution.authorization!);\n }, 3000);\n return () => clearInterval(id);\n }, [execution?.execution_id, execution?.authorization, execution?.status, getExecution]);\n\n // ── Submit input ──\n const submitInput = useCallback(async (text: string) => {\n if (!text.trim()) return;\n if (text.trim().length < 6) {\n setError('Please enter at least 6 characters before starting the agent.');\n toast({\n title: 'Input too short',\n description: 'The agent needs at least 6 characters to start.',\n variant: 'destructive',\n });\n return;\n }\n setError(null);\n setAgentRequestLoading(true);\n\n // Mint a generation id for THIS submit. If the user aborts before the\n // request resolves, abortAgent() will bump runGenerationRef so the stale\n // resolution below short-circuits instead of swapping tabs back.\n const myGeneration = ++runGenerationRef.current;\n // Cancel any previous in-flight controller, then install a fresh one so\n // abortAgent() can actually kill the underlying fetch.\n try { runAbortRef.current?.abort(); } catch { /* noop */ }\n const controller = new AbortController();\n runAbortRef.current = controller;\n\n // Snapshot prior run state so a failed network request does not leave\n // the user staring at an empty page with no way to retry. We only\n // commit the destructive reset once the new run has been accepted.\n const prevExecution = stateRef.current.execution;\n const prevAgentData = stateRef.current.agentData;\n const prevAgentActionResult = stateRef.current.agentActionResult;\n const prevOpenIndexes = stateRef.current.openIndexes;\n const prevQuestionAnswers = stateRef.current.questionAnswers;\n const prevContinuationText = stateRef.current.continuationText;\n const prevLocalRunStart = stateRef.current.localRunStart;\n const prevActiveExecutionId = activeExecutionIdRef.current;\n const prevShowStarter = stateRef.current.showStarter;\n const prevViewMode = viewMode;\n\n // Hard reset NOW — kill the previous run's poll loop, blank the\n // execution/timeline state, drop the previous execution_id +\n // agentView from the URL, and reset the view to simple. Otherwise\n // the previous run's poll keeps writing into state during the\n // in-flight request and the user sees the old \"Detailed\" tab flash\n // back in.\n activeExecutionIdRef.current = null;\n setExecution(null);\n setAgentData({ original_input: text.trim() });\n setAgentActionResult(null);\n setExecutionApps([]);\n setResolvedToolApps({});\n setHighlightedIndex(null);\n setOpenIndexes(new Set());\n setQuestionAnswers({});\n setContinuationText('');\n setSimpleSubmitAttempted(false);\n \n setError(null);\n setLocalRunStart(null);\n setViewMode('simple');\n setShowStarter(false);\n // The user is starting a new run — drop any sticky \"manual Start\" pin so\n // future polls/effects can populate Simple/Detailed normally.\n userPickedStartRef.current = false;\n if (readUrlParams && typeof window !== 'undefined') {\n try {\n const url = new URL(window.location.href);\n url.searchParams.delete('execution_id');\n url.searchParams.delete('authorization');\n url.searchParams.delete('agentView');\n window.history.replaceState({}, '', url.toString());\n } catch { /* noop */ }\n }\n\n const result = await runAgent({\n input: text.trim(),\n skipPolling: true,\n signal: controller.signal,\n ...(apiKey ? { apiKey } : {}),\n ...(apiBaseUrl ? { apiBaseUrl } : {}),\n ...(orgId ? { orgId } : {}),\n // Send a single comma-separated `tool_name` in the format\n // `app:<objectID>:<slug>,app:<objectID>:<slug>` so the backend resolves\n // the exact app versions instead of guessing by slug.\n ...(chosenApps.length > 0 ? { toolName: buildToolName(chosenApps) } : {}),\n ...(attachedImages.length > 0 ? { images: attachedImages.map((img) => {\n const m = /^data:([^;]+);base64,(.*)$/.exec(img.dataUrl);\n return m ? { mimeType: m[1], data: m[2], name: img.name } : { mimeType: 'image/png', data: img.dataUrl, name: img.name };\n }) } : {}),\n });\n\n // If the user aborted while we were waiting, drop this result on the floor.\n // Do NOT touch UI state — abortAgent() already reset us to the Start tab.\n if (myGeneration !== runGenerationRef.current || controller.signal.aborted) {\n // Best-effort: if the backend still managed to spawn an execution\n // before our fetch was aborted, ask it to abort that execution too.\n const raw: any = (result as any)?.rawData;\n const eid = raw?.execution_id;\n const auth = raw?.authorization;\n const wfId = raw?.workflow?.id;\n if (eid && wfId) {\n try {\n fetch(\n resolveUrl(`/api/v1/workflows/${wfId}/executions/${eid}/abort`),\n {\n method: 'GET',\n credentials: 'include',\n headers: { ...resolveHeaders(), ...(auth ? { Authorization: `Bearer ${auth}` } : {}) },\n },\n ).catch(() => { /* noop */ });\n } catch { /* noop */ }\n }\n return;\n }\n\n setAgentRequestLoading(false);\n\n if (!result.success) {\n // Restore the previous run so the user can try Rerun again.\n setError(result.error || 'Agent run failed.');\n activeExecutionIdRef.current = prevActiveExecutionId;\n setExecution(prevExecution);\n setAgentData(prevAgentData);\n setAgentActionResult(prevAgentActionResult);\n setOpenIndexes(prevOpenIndexes);\n setQuestionAnswers(prevQuestionAnswers);\n setContinuationText(prevContinuationText);\n setLocalRunStart(prevLocalRunStart);\n setShowStarter(prevShowStarter);\n setViewMode(prevViewMode);\n onRun?.({ input: text, success: false, error: result.error });\n return;\n }\n\n // Success — start the live timer for the new run. The destructive\n // reset already happened up-front, so all we need to do here is\n // seed the timer reference for elapsed-time rendering.\n const browserStart = Math.floor(Date.now() / 1000);\n setNowTick(browserStart);\n setLocalRunStart(browserStart);\n\n const raw = result.rawData as any;\n const eid = raw?.execution_id;\n const auth = raw?.authorization;\n if (eid && auth) {\n // Seed an EXECUTING stub so the poll effect starts immediately,\n // then kick off the first fetch. The poller continues until terminal.\n activeExecutionIdRef.current = eid;\n setExecution({ execution_id: eid, authorization: auth, status: 'EXECUTING' });\n // Reflect the new execution in the URL so the run is shareable/refreshable.\n if (readUrlParams && typeof window !== 'undefined') {\n try {\n const url = new URL(window.location.href);\n url.searchParams.set('execution_id', eid);\n url.searchParams.set('authorization', auth);\n window.history.replaceState({}, '', url.toString());\n } catch { /* noop */ }\n }\n getExecution(eid, auth);\n onRun?.({ input: text, success: true, executionId: eid });\n } else {\n // Direct response (no async execution): synthesize a single-step view\n setExecution({\n execution_id: eid || crypto.randomUUID(),\n authorization: auth,\n status: 'FINISHED',\n results: [{ action: { app_name: 'AI Agent' }, result: raw }],\n });\n const v = validateJson(raw);\n if (v.valid) {\n setAgentData({ ...v.result, status: 'FINISHED', original_input: text });\n } else {\n setAgentData({ original_input: text, status: 'FINISHED', message: result.content });\n }\n onRun?.({ input: text, success: true, executionId: eid });\n }\n }, [chosenApps, getExecution, onRun, attachedImages, readUrlParams, viewMode]);\n\n // Auto-submit on mount when caller provides a defaultInput + autoSubmit.\n const autoSubmittedRef = useRef(false);\n useEffect(() => {\n if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {\n autoSubmittedRef.current = true;\n submitInput(defaultInput);\n }\n }, [autoSubmit, defaultInput, executionId, submitInput]);\n\n // ── Submit answers / continuation ──\n const submitQuestions = useCallback(async (\n decisionId: string,\n answers: Record<string, any>,\n isContinuation?: boolean,\n ) => {\n if (!execution?.execution_id || !execution?.authorization) return;\n\n let newArgument: Record<string, string> = {};\n if (isContinuation) {\n newArgument = { ...answers };\n } else {\n for (const k in answers) {\n if (k === 'approve') {\n newArgument[k] = answers[k];\n break;\n }\n const a = answers[k];\n newArgument[`question_${a.index}`] = a.value;\n }\n }\n\n setAgentRequestLoading(true);\n const wfId = execution.workflow?.id || execution.execution_id;\n const params = new URLSearchParams({\n reference_execution: execution.execution_id,\n authorization: execution.authorization,\n answer: 'true',\n note: JSON.stringify(newArgument),\n agentic: 'true',\n decision_id: decisionId,\n });\n try {\n const resp = await fetch(resolveUrl(`/api/v1/workflows/${wfId}/run?${params.toString()}`), {\n method: 'GET',\n credentials: 'include',\n headers: { ...resolveHeaders() },\n });\n const json = await resp.json();\n if (json.success === false) {\n toast({ title: 'Failed to submit', description: json.reason || 'Try again later.', variant: 'destructive' });\n } else {\n // No success toast — the UI updates inline.\n setQuestionAnswers({});\n setContinuationText('');\n setTimeout(() => {\n getExecution(execution.execution_id!, execution.authorization!);\n }, 600);\n }\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n } finally {\n setAgentRequestLoading(false);\n }\n }, [execution, getExecution]);\n\n // ── Rerun the whole agent with the original input ──\n // Instead of silently re-submitting (which leaves the user staring at the\n // same screen wondering if anything happened), bounce them back to the\n // Start tab with the prompt + tools pre-filled so they can review and\n // hit Start themselves.\n const rerunAgent = useCallback(() => {\n const input =\n agentData?.original_input ||\n actionInput ||\n (() => {\n const msgs = (agentData as any)?.input?.messages || [];\n const m = msgs.find((m: any) => m?.role === 'user' && !String(m?.role).includes('USER CONTEXT'));\n return m?.content || '';\n })();\n if (input && typeof input === 'string') {\n setActionInput(input);\n }\n if (executionApps.length > 0) {\n setChosenApps(executionApps);\n }\n // When the Start tab is hidden (e.g. embedded in the execution drawer),\n // there is no Start view to bounce to — just resubmit immediately with\n // the previous prompt + tools.\n if (disableStartTab) {\n if (input && typeof input === 'string' && input.trim().length >= 6) {\n submitInput(input);\n }\n return;\n }\n setShowStarter(true);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n return next;\n }, { replace: true });\n }, [agentData, actionInput, executionApps, setSearchParams, disableStartTab, submitInput]);\n\n // ── Abort the currently running agent execution ──\n // If the agent has not produced an execution_id yet (i.e. the initial\n // /run request is still in flight or failed silently), we simply discard\n // the in-flight UI state and bounce the user back to the Start tab so\n // they can try again. Once an execution_id exists, we ask the backend to\n // abort the workflow execution; the existing poll loop will then pick up\n // the ABORTED status on its next tick.\n const abortAgent = useCallback(async () => {\n const execId = execution?.execution_id;\n const auth = execution?.authorization;\n const wfId = (execution as any)?.workflow?.id;\n\n // Bump the run-generation counter and abort any in-flight POST /agent\n // request immediately. This guarantees a slow initial request that\n // resolves AFTER the user clicks \"Cancel\" cannot repaint the UI or\n // swap tabs back to the run view.\n runGenerationRef.current += 1;\n try { runAbortRef.current?.abort(); } catch { /* noop */ }\n runAbortRef.current = null;\n\n // Helper: wipe local run state and return to the Start tab.\n const resetToStart = () => {\n activeExecutionIdRef.current = null;\n setExecution(null);\n setAgentData({});\n setAgentRequestLoading(false);\n setShowStarter(true);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n next.delete('execution_id');\n next.delete('authorization');\n return next;\n }, { replace: true });\n };\n\n // Agent never produced an execution — nothing to abort server-side.\n if (!execId || !wfId) {\n resetToStart();\n toast({ title: 'Run aborted', description: 'The agent had not started yet — reset to Start.' });\n return;\n }\n\n try {\n const resp = await fetch(\n resolveUrl(`/api/v1/workflows/${wfId}/executions/${execId}/abort`),\n {\n method: 'GET',\n credentials: 'include',\n headers: {\n ...resolveHeaders(),\n ...(auth ? { Authorization: `Bearer ${auth}` } : {}),\n },\n },\n );\n if (!resp.ok) {\n const txt = await resp.text().catch(() => '');\n toast({ title: 'Abort failed', description: txt || `HTTP ${resp.status}`, variant: 'destructive' });\n return;\n }\n toast({ title: 'Aborting run', description: 'The execution will be set to ABORTED shortly.' });\n // Nudge the poll loop to refresh sooner so the UI reflects the change.\n setTimeout(() => getExecution(execId, auth!), 500);\n setTimeout(() => getExecution(execId, auth!), 2500);\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n }\n }, [execution, resolveUrl, resolveHeaders, getExecution, setSearchParams]);\n\n\n // Build a popout URL to answer the agent's question in the standalone Form UI.\n // Mirrors the legacy AgentUI behavior so users can hand off to /forms/...\n const getFormUrl = useCallback((decisionId: string): string | null => {\n const wfId = (execution as any)?.workflow?.id;\n const auth = execution?.authorization;\n const execId = execution?.execution_id;\n const sourceNode = agentActionResult?.action?.id;\n if (!wfId || !auth || !execId || !sourceNode || !decisionId) return null;\n const backend = apiBaseUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n const params = new URLSearchParams({\n authorization: auth,\n reference_execution: execId,\n source_node: sourceNode,\n decision_id: decisionId,\n ...(backend ? { backend_url: backend } : {}),\n });\n return `/forms/${wfId}?${params.toString()}`;\n }, [execution, agentActionResult, apiBaseUrl]);\n\n // ── Rerun a single decision (clears decisions after it on the backend) ──\n const rerunDecision = useCallback(async (decision: any) => {\n if (!execution?.execution_id) {\n toast({ title: 'No execution loaded', description: 'Cannot rerun this decision.', variant: 'destructive' });\n return;\n }\n if (!agentActionResult?.action) {\n toast({ title: 'Missing action context', description: 'Could not locate the agent action node.', variant: 'destructive' });\n return;\n }\n const decisionId = decision?.run_details?.id;\n if (!decisionId) {\n toast({ title: 'Missing decision id', description: 'This decision cannot be rerun.', variant: 'destructive' });\n return;\n }\n const body: any = { ...agentActionResult.action };\n body.source_execution = execution.execution_id;\n body.source_workflow = execution.workflow?.id;\n setAgentRequestLoading(true);\n try {\n const resp = await fetch(resolveUrl(`/api/v1/apps/agent/run?rerun=true&decision_id=${encodeURIComponent(decisionId)}`), {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders() },\n body: JSON.stringify(body),\n });\n const json = await resp.json().catch(() => ({}));\n if (json?.success === false) {\n toast({ title: 'Rerun failed', description: json.reason || 'Try again later.', variant: 'destructive' });\n } else {\n toast({ title: 'Rerunning decision', description: 'The agent will continue from this step.' });\n setTimeout(() => getExecution(execution.execution_id!, execution.authorization!), 800);\n setTimeout(() => getExecution(execution.execution_id!, execution.authorization!), 5000);\n }\n } catch (err) {\n toast({ title: 'Network error', description: String(err), variant: 'destructive' });\n } finally {\n setAgentRequestLoading(false);\n }\n }, [execution, agentActionResult, getExecution]);\n\n // ── Build timeline ──\n const { timeline, originalStartTime, totalDuration, finishDecisionId, finishAnswer } = useMemo(() => {\n // Backend may return Unix milliseconds (UnixMillis) or seconds. Normalize to seconds.\n const toSec = (t: any): number => {\n const n = Number(t) || 0;\n // Preserve sub-second precision so durations < 1s render as e.g. \"0.8s\"\n // instead of being floored to 0.\n return n > 1e12 ? n / 1000 : n;\n };\n const overallStatus = (execution?.status || agentData?.status || '').toUpperCase();\n const runIsFinished = ['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(overallStatus);\n const runEndSec = toSec(agentData?.completed_at || execution?.completed_at);\n // When the whole run has ended, cap any unfinished decisions at the run's\n // end time (or the latest known timestamp) so they stop counting up.\n let fallbackEnd = Date.now() / 1000;\n if (runIsFinished) {\n let maxKnown = runEndSec || 0;\n for (const dec of agentData?.decisions || []) {\n const rd = dec.run_details || {};\n maxKnown = Math.max(maxKnown, toSec(rd.completed_at), toSec(rd.started_at));\n }\n fallbackEnd = maxKnown || fallbackEnd;\n }\n\n const items: TimelineItem[] = [\n {\n label: 'AI Agent',\n type: 'agent',\n category: 'agent',\n details: agentData,\n status: execution?.status || agentData?.status,\n start_time: toSec(agentData?.started_at || execution?.started_at),\n end_time: toSec(agentData?.completed_at || execution?.completed_at),\n },\n ];\n\n let finishId = '';\n let finishAns = '';\n for (const dec of agentData?.decisions || []) {\n const rd = dec.run_details || {};\n const decStartSec = toSec(rd.started_at);\n const decEndSec = toSec(rd.completed_at);\n // Only fall back to \"now\"/run-end when we actually know when the\n // decision started — otherwise the bar would stretch from epoch 0\n // to now and look like a full-width row.\n const startTime = decStartSec || 0;\n const endTime = decEndSec || (decStartSec ? fallbackEnd : 0);\n items.push({\n label: dec.action,\n type: 'decision',\n category: dec.category,\n status: rd.status,\n start_time: startTime,\n end_time: endTime,\n details: dec,\n });\n if (dec.action === 'finish' || dec.category === 'finish' || dec.details?.action === 'finalise' || dec.action === 'finalise') {\n finishId = rd.id || '';\n const reasonText = (dec.reason || '').trim();\n const fieldText = (Array.isArray(dec.fields) && dec.fields.length > 0 ? (dec.fields[0]?.value || '') : '').trim();\n // Prefer whichever has more substance. Sometimes the field value is a\n // short headline like \"Task Failed\" while the real explanation lives\n // in `reason` — surface that to the user instead of the headline.\n if (fieldText && reasonText && reasonText.length > fieldText.length * 1.5) {\n finishAns = reasonText;\n } else {\n finishAns = fieldText || reasonText;\n }\n }\n }\n\n // Sort: Agent row pinned to top, Finalise pinned to bottom, everything\n // else preserves insertion order (the index `i` from the decisions array).\n // Timestamps are intentionally NOT used — they're often missing or 0,\n // which would scatter rows unpredictably.\n const isFinalise = (it: TimelineItem) => {\n const det: any = it.details || {};\n const cat = (it.category || '').toLowerCase();\n const act = (det.action || '').toLowerCase();\n return cat === 'finish' || cat === 'finalise' || act === 'finish' || act === 'finalise';\n };\n const rank = (it: TimelineItem) => {\n if (it.type === 'agent') return 0;\n if (isFinalise(it)) return 2;\n return 1;\n };\n const sortItems = (arr: TimelineItem[]) => {\n const indexed = arr.map((it, i) => ({ it, i }));\n indexed.sort((a, b) => {\n const ra = rank(a.it);\n const rb = rank(b.it);\n if (ra !== rb) return ra - rb;\n return a.i - b.i;\n });\n arr.length = 0;\n arr.push(...indexed.map((x) => x.it));\n };\n sortItems(items);\n\n // Insert \"processing\" placeholder rows inline between consecutive decisions\n // when there is meaningful dead time (the agent is thinking / the LLM is\n // generating the next step). Walk the already-sorted items list and splice\n // the Thinking rows in-place so they stay between the two decisions whose\n // gap they represent. Do NOT re-sort afterwards — that would clump them.\n const withProcessing: TimelineItem[] = [];\n const agentItem = items.find((it) => it.type === 'agent');\n const runStart = agentItem?.start_time || 0;\n const runEnd = agentItem?.end_time || 0;\n let prevDecEnd = runStart;\n const pushThinking = (from: number, to: number) => {\n if (from > 0 && to > 0 && to - from >= 0.5) {\n withProcessing.push({\n label: '',\n type: 'decision',\n category: 'processing',\n status: 'FINISHED',\n start_time: from,\n end_time: to,\n details: undefined as any,\n });\n }\n };\n for (const it of items) {\n if (it.type === 'decision') {\n const decStart = it.start_time || 0;\n // Insert Thinking before this decision (works for first decision after\n // run start, gaps between decisions, and the gap before Finalise).\n pushThinking(prevDecEnd, decStart);\n withProcessing.push(it);\n prevDecEnd = it.end_time || decStart || prevDecEnd;\n } else {\n withProcessing.push(it);\n }\n }\n // Tail: if the last decision finished well before the run ended and there\n // was no Finalise, surface that trailing dead time too.\n if (runEnd > 0) pushThinking(prevDecEnd, runEnd);\n items.length = 0;\n items.push(...withProcessing);\n\n const start = items.reduce((acc, it) => Math.min(acc, it.start_time || acc), Infinity);\n const end = items.reduce((acc, it) => Math.max(acc, it.end_time || acc), 0);\n const startSafe = start === Infinity ? 0 : start;\n const total = Math.max(1, end - startSafe);\n return { timeline: items, originalStartTime: startSafe, totalDuration: total, finishDecisionId: finishId, finishAnswer: finishAns };\n }, [agentData, execution?.status, execution?.started_at, execution?.completed_at]);\n\n\n const toggleOpen = (i: number) =>\n setOpenIndexes((prev) => {\n const next = new Set(prev);\n if (next.has(i)) next.delete(i); else next.add(i);\n return next;\n });\n\n const handlePrimarySubmit = useCallback(() => {\n if (submitOverride) {\n submitOverride({ input: actionInput, apps: chosenApps });\n } else {\n submitInput(actionInput);\n }\n }, [submitOverride, actionInput, chosenApps, submitInput]);\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n handlePrimarySubmit();\n }\n };\n\n // restart() removed — Start tab now toggles via goToTab() while preserving the execution.\n\n\n // The three top-level \"tabs\": Start (the prompt form), Simple summary,\n // and Detailed timeline. They're all available once an execution exists,\n // so the user can flip back and forth without losing the run.\n type TabKey = 'start' | 'simple' | 'detailed';\n const activeTab: TabKey = showStarter ? 'start' : viewMode;\n const hasExecution = !!execution?.execution_id;\n const showRunSwitcher = hasExecution || agentRequestLoading;\n useEffect(() => {\n onViewChange?.(activeTab);\n }, [activeTab, onViewChange]);\n const goToTab = (t: TabKey) => {\n if (t === 'start') {\n // Seed the starter form with the current run's prompt + tools so the\n // user can tweak and resubmit instead of starting from a blank slate.\n const runInput =\n agentData?.original_input ||\n (() => {\n const msgs = (agentData as any)?.input?.messages || [];\n const m = msgs.find((m: any) => m?.role === 'user');\n return m?.content || '';\n })();\n if (runInput && typeof runInput === 'string') {\n setActionInput(runInput);\n }\n if (executionApps.length > 0) {\n setChosenApps(executionApps);\n }\n setShowStarter(true);\n // Pin: user manually chose Start. Stay here even when polls land or\n // initialExecution is re-attached, until they explicitly start a new run\n // or click Simple/Detailed themselves.\n userPickedStartRef.current = true;\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.delete('agentView');\n return next;\n }, { replace: true });\n } else {\n setShowStarter(false);\n userPickedStartRef.current = false;\n setViewMode(t);\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set('agentView', t);\n return next;\n }, { replace: true });\n }\n };\n\n // Schedule guardrails: do not allow scheduling when the run required a\n // continuation (the oneshot prompt did not work) or did not perform any\n // actual app/tool actions (nothing meaningful would run on a schedule).\n const { scheduleDisabledReasons } = useMemo(() => {\n const decisions: any[] = (agentData?.decisions as any[]) || [];\n const runStatus = String(execution?.status || agentData?.status || '').toUpperCase();\n const isNotFinished = runStatus !== '' && !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(runStatus);\n const NON_ACTION_CATS = new Set(['finish', 'finalise', 'ask', 'agent', 'processing']);\n const NON_ACTION_ACTIONS = new Set(['finish', 'finalise', 'ask']);\n const finishCount = decisions.filter(\n (d) => d?.action === 'finish' || d?.action === 'finalise' || d?.category === 'finish' || d?.category === 'finalise',\n ).length;\n const continuedAfterFinish = decisions.some((d) =>\n Array.isArray(d?.fields) && d.fields.some((f: any) => String(f?.key || '').toLowerCase() === 'continue' && f?.value),\n );\n const hadContinuation = finishCount > 1 || continuedAfterFinish;\n const actionCount = decisions.filter((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n if (NON_ACTION_CATS.has(cat)) return false;\n if (NON_ACTION_ACTIONS.has(act)) return false;\n return true;\n }).length;\n // A decision failed if its run_details.status is FAILURE/ABORTED, or the\n // parsed raw_response reports success: false. We deliberately ignore\n // ASK/FINISH categories — those are agent-internal control steps.\n const failedDecision = decisions.some((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n if (NON_ACTION_CATS.has(cat) || NON_ACTION_ACTIONS.has(act)) return false;\n const status = String(d?.run_details?.status || '').toUpperCase();\n if (status === 'FAILURE' || status === 'ABORTED') return true;\n const raw = d?.run_details?.raw_response;\n let parsed: any = null;\n if (typeof raw === 'string') {\n try { parsed = JSON.parse(raw); } catch { parsed = null; }\n } else if (raw && typeof raw === 'object') {\n parsed = raw;\n }\n if (parsed && parsed.success === false) return true;\n if (parsed && parsed.action === 'app_authentication') return true;\n return false;\n });\n // A question was answered if an ASK decision has an \"answer\" field, OR if\n // its run finished (the agent submits answers to advance ask runs from\n // WAITING to FINISHED). Either way the prompt cannot run unattended.\n const answeredQuestion = decisions.some((d) => {\n const cat = String(d?.category || '').toLowerCase();\n const act = String(d?.action || '').toLowerCase();\n const isAsk = cat === 'ask' || act === 'ask';\n if (!isAsk) return false;\n const hasAnswerField = Array.isArray(d?.fields)\n && d.fields.some((f: any) => String(f?.key || '').toLowerCase() === 'answer' && f?.value);\n const status = String(d?.run_details?.status || '').toUpperCase();\n return hasAnswerField || status === 'FINISHED';\n });\n const reasons: string[] = [];\n if (isNotFinished) {\n reasons.push('Wait for the agent to finish before scheduling.');\n } else if (showStarter) {\n // On the Start view, a finished + validated run is always considered\n // ready to schedule. Quality gates (continuations, missing actions,\n // failed steps, manual answers) are only surfaced in Simple/Detailed\n // views where the user is actively reviewing the run.\n } else {\n if (hadContinuation) {\n reasons.push('This run needed a follow-up message to continue, so the one-shot prompt did not succeed on its own. Refine the prompt until it finishes in one go before scheduling.');\n }\n if (actionCount === 0) {\n reasons.push('This run did not perform any app or tool actions, so a scheduled run would have nothing meaningful to do.');\n }\n if (failedDecision) {\n reasons.push('A decision in this run failed. Fix the failing step (for example, authenticate the app or correct the input) and rerun successfully before scheduling.');\n }\n if (answeredQuestion) {\n reasons.push('A question in this run was answered manually. Scheduled runs are unattended, so refine the prompt so the agent does not need to ask anything before scheduling.');\n }\n }\n return { scheduleDisabledReasons: reasons };\n }, [agentData, execution?.status, showStarter]);\n\n // Detect natural-language scheduling intent in the prompt (e.g. \"daily at 6 am\",\n // \"next monday at 2am\", \"every 15 minutes\"). Used to highlight the Schedule\n // button and pre-seed the cron picker.\n const scheduleHint = useMemo(() => parseScheduleHint(actionInput), [actionInput]);\n // Track which hint we last auto-applied so we never overwrite a manual pick.\n const lastAppliedHintRef = useRef<string | null>(null);\n useEffect(() => {\n if (!scheduleHint) return;\n if (scheduleAnchor) return; // never override while popover is open\n if (lastAppliedHintRef.current === scheduleHint.cron) return;\n setScheduleCron(scheduleHint.cron);\n lastAppliedHintRef.current = scheduleHint.cron;\n }, [scheduleHint, scheduleAnchor]);\n\n // Compile structured recurrence controls into a 5-field cron expression.\n // Skipped if the user has manually overridden via preset chip / advanced\n // cron text field — that override is cleared whenever they touch a\n // structured control again.\n useEffect(() => {\n if (cronManualOverrideRef.current) return;\n const m = Math.max(0, Math.min(59, schedMinute));\n const h = Math.max(0, Math.min(23, schedHour));\n const n = Math.max(1, Math.floor(schedInterval || 1));\n let cron = '';\n if (schedFreq === 'minutes') {\n cron = `*/${n} * * * *`;\n } else if (schedFreq === 'hours') {\n cron = `${m} */${n} * * *`;\n } else if (schedFreq === 'days') {\n cron = n === 1 ? `${m} ${h} * * *` : `${m} ${h} */${n} * *`;\n } else if (schedFreq === 'weeks') {\n // Cron has no native \"every N weeks\", so we use the weekday set and\n // surface a small note in the UI when interval > 1.\n const days = schedWeekdays.size > 0\n ? [...schedWeekdays].sort((a, b) => a - b).join(',')\n : '*';\n cron = `${m} ${h} * * ${days}`;\n } else if (schedFreq === 'months') {\n const dom = Math.max(1, Math.min(31, schedDayOfMonth));\n cron = n === 1 ? `${m} ${h} ${dom} * *` : `${m} ${h} ${dom} */${n} *`;\n }\n if (cron) setScheduleCron(cron);\n }, [schedFreq, schedInterval, schedHour, schedMinute, schedWeekdays, schedDayOfMonth]);\n\n const scheduleDisabledReason = scheduleDisabledReasons[0] || '';\n const scheduleDisabledTooltip: React.ReactNode = scheduleDisabledReasons.length > 1 ? (\n <Box>\n <Box sx={{ fontWeight: 600, mb: 0.5 }}>Cannot schedule for {scheduleDisabledReasons.length} reasons:</Box>\n <Box sx={{ m: 0 }}>\n {scheduleDisabledReasons.map((r, i) => (\n <Box key={i} sx={{ mb: 0.5, display: 'flex', gap: 0.75 }}>\n <Box component=\"span\" sx={{ fontWeight: 700, flexShrink: 0 }}>{i + 1}.</Box>\n <Box component=\"span\">{r}</Box>\n </Box>\n ))}\n </Box>\n </Box>\n ) : scheduleDisabledReasons.length === 1 ? `Cannot schedule: ${scheduleDisabledReasons[0]}` : '';\n\n // Rendered inline (not a nested component) so it isn't remounted on every\n // parent re-render — the live duration ticker would otherwise reset hover\n // state every second and swallow clicks.\n const tabBarRef = useRef<HTMLDivElement | null>(null);\n const tabBar = (\n <Box\n ref={tabBarRef}\n sx={{\n display: 'flex', alignItems: 'center',\n width: 'fit-content',\n alignSelf: 'center',\n position: 'sticky',\n top: 8,\n zIndex: 5,\n }}\n >\n <SegmentedControl\n layoutId=\"agentui-view-switcher\"\n ariaLabel=\"Agent view\"\n value={activeTab}\n onChange={(v) => goToTab(v as TabKey)}\n options={[\n { value: 'start', label: 'Start', disabled: disableStartTab },\n { value: 'simple', label: 'Simple', disabled: !hasExecution },\n { value: 'detailed', label: 'Detailed', disabled: !hasExecution },\n { type: 'divider', key: 'div' },\n {\n type: 'action',\n key: 'reload',\n label: <RefreshIcon size={14} />,\n title: 'Reload execution data',\n disabled: !hasExecution,\n onClick: () => {\n if (execution?.execution_id && execution?.authorization) {\n getExecution(execution.execution_id, execution.authorization);\n }\n },\n },\n {\n type: 'action',\n key: 'schedule',\n label: <ScheduleIcon size={14} />,\n title: scheduleDisabledReason\n ? `Cannot schedule: ${scheduleDisabledReason}`\n : 'Schedule this prompt to run repeatedly on a cron schedule',\n disabled: Boolean(scheduleDisabledReason),\n onClick: () => {\n if (!scheduleDisabledReason && tabBarRef.current) {\n setScheduleAnchor(tabBarRef.current);\n }\n },\n },\n ]}\n />\n </Box>\n );\n\n // Popover is rendered outside `tabBar` so it still mounts when the tab bar\n // is hidden (e.g. on the Start view where `showRunSwitcher` is false). The\n // schedule (clock) icon in the chat composer shares the same anchor state.\n const schedulePopover = (\n <Popover\n open={Boolean(scheduleAnchor)}\n anchorEl={scheduleAnchor}\n onClose={() => setScheduleAnchor(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{\n paper: {\n sx: {\n mt: 1,\n p: 2,\n width: 360,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n boxShadow: '0 8px 24px hsl(0 0% 0% / 0.35)',\n },\n },\n }}\n >\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, mb: 0.5 }}>\n Schedule recurring run\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', mb: 1.5 }}>\n Choose how often this prompt should run. The schedule keeps running until you remove it.\n </Typography>\n {scheduleHint && (\n <Box\n sx={{\n mb: 1.5,\n p: 1,\n borderRadius: 1.5,\n border: '1px solid hsl(var(--primary) / 0.4)',\n bgcolor: 'hsl(var(--primary) / 0.08)',\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <ScheduleIcon size={16} color={'hsl(var(--primary))'} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mb: 0.25 }}>\n Detected from your prompt\n </Box>\n <Box sx={{ fontSize: '0.78rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {scheduleHint.label}\n </Box>\n <Box sx={{ fontSize: '0.68rem', fontFamily: 'monospace', color: 'hsl(var(--muted-foreground))' }}>\n {scheduleHint.cron}\n </Box>\n </Box>\n {scheduleCron !== scheduleHint.cron && (\n <Button\n size=\"small\"\n onClick={() => { cronManualOverrideRef.current = true; setScheduleCron(scheduleHint.cron); }}\n sx={{\n height: 28,\n textTransform: 'none',\n fontSize: '0.7rem',\n color: 'hsl(var(--primary))',\n '&:hover': { bgcolor: 'hsl(var(--primary) / 0.12)' },\n }}\n >\n Use\n </Button>\n )}\n </Box>\n )}\n {/* Structured recurrence builder (Google Calendar style) */}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n Repeat every\n </Typography>\n <TextField\n size=\"small\"\n type=\"number\"\n value={schedInterval}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedInterval(Math.max(1, Number(e.target.value) || 1)); }}\n slotProps={{ htmlInput: { min: 1, max: 999, style: { padding: '6px 8px', width: 48, textAlign: 'center', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n <Select\n size=\"small\"\n value={schedFreq}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedFreq(e.target.value as SchedFreq); }}\n sx={{\n flex: 1,\n fontSize: '0.8rem',\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n '& .MuiSelect-icon': { color: 'hsl(var(--muted-foreground))' },\n '& .MuiSelect-select': { py: '6px' },\n }}\n MenuProps={{ slotProps: { paper: { sx: { bgcolor: 'hsl(var(--popover))', color: 'hsl(var(--foreground))', border: '1px solid hsl(var(--border))' } } } }}\n >\n <MenuItem value=\"minutes\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'minute' : 'minutes'}</MenuItem>\n <MenuItem value=\"hours\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'hour' : 'hours'}</MenuItem>\n <MenuItem value=\"days\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'day' : 'days'}</MenuItem>\n <MenuItem value=\"weeks\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'week' : 'weeks'}</MenuItem>\n <MenuItem value=\"months\" sx={{ fontSize: '0.8rem' }}>{schedInterval === 1 ? 'month' : 'months'}</MenuItem>\n </Select>\n </Box>\n\n {(schedFreq === 'days' || schedFreq === 'weeks' || schedFreq === 'months') && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n At\n </Typography>\n <TextField\n size=\"small\"\n type=\"time\"\n value={`${String(schedHour).padStart(2, '0')}:${String(schedMinute).padStart(2, '0')}`}\n onChange={(e) => {\n cronManualOverrideRef.current = false;\n const [hh, mm] = (e.target.value || '09:00').split(':').map(Number);\n setSchedHour(Number.isFinite(hh) ? hh : 9);\n setSchedMinute(Number.isFinite(mm) ? mm : 0);\n }}\n slotProps={{ htmlInput: { style: { padding: '6px 8px', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n </Box>\n )}\n\n {schedFreq === 'weeks' && (\n <Box sx={{ mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', mb: 0.75 }}>\n Repeat on\n </Typography>\n <Box sx={{ display: 'flex', gap: 0.5 }}>\n {(['S', 'M', 'T', 'W', 'T', 'F', 'S'] as const).map((label, i) => {\n const active = schedWeekdays.has(i);\n return (\n <Box\n key={i}\n role=\"button\"\n tabIndex={0}\n onClick={() => {\n cronManualOverrideRef.current = false;\n setSchedWeekdays((prev) => {\n const next = new Set(prev);\n if (next.has(i)) next.delete(i); else next.add(i);\n return next;\n });\n }}\n sx={{\n width: 30,\n height: 30,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: '0.75rem',\n fontWeight: 600,\n userSelect: 'none',\n bgcolor: active ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: active ? 'hsl(var(--primary-foreground))' : 'hsl(var(--foreground))',\n border: '1px solid',\n borderColor: active ? 'hsl(var(--primary))' : 'hsl(var(--border))',\n transition: 'background-color 120ms',\n '&:hover': { bgcolor: active ? 'hsl(var(--primary))' : 'hsl(var(--muted) / 0.7)' },\n }}\n >\n {label}\n </Box>\n );\n })}\n </Box>\n {schedInterval > 1 && (\n <Typography sx={{ fontSize: '0.68rem', color: 'hsl(var(--muted-foreground))', mt: 0.75 }}>\n Cron does not support every {schedInterval} weeks natively — this will run weekly on the selected days.\n </Typography>\n )}\n </Box>\n )}\n\n {schedFreq === 'months' && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.25 }}>\n <Typography sx={{ fontSize: '0.78rem', color: 'hsl(var(--muted-foreground))', flexShrink: 0 }}>\n On day\n </Typography>\n <TextField\n size=\"small\"\n type=\"number\"\n value={schedDayOfMonth}\n onChange={(e) => { cronManualOverrideRef.current = false; setSchedDayOfMonth(Math.max(1, Math.min(31, Number(e.target.value) || 1))); }}\n slotProps={{ htmlInput: { min: 1, max: 31, style: { padding: '6px 8px', width: 56, textAlign: 'center', fontSize: '0.8rem' } } }}\n sx={{\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n of the month\n </Typography>\n </Box>\n )}\n\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))', mt: 0.5, mb: 0.5 }}>\n Quick presets\n </Typography>\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, mb: 0.5 }}>\n {([\n ['Every 15 min', '*/15 * * * *'],\n ['Hourly', '0 * * * *'],\n ['Daily 9am', '0 9 * * *'],\n ['Weekdays 9am', '0 9 * * 1-5'],\n ['Weekly Mon', '0 9 * * 1'],\n ['Monthly 1st', '0 9 1 * *'],\n ] as const).map(([label, expr]) => (\n <Chip\n key={expr}\n label={label}\n size=\"small\"\n onClick={() => { cronManualOverrideRef.current = true; setScheduleCron(expr); }}\n sx={{\n fontSize: '0.7rem',\n bgcolor: scheduleCron === expr ? 'hsl(var(--primary) / 0.15)' : 'hsl(var(--muted))',\n color: scheduleCron === expr ? 'hsl(var(--primary))' : 'hsl(var(--foreground))',\n border: scheduleCron === expr ? '1px solid hsl(var(--primary))' : '1px solid transparent',\n '&:hover': { bgcolor: 'hsl(var(--muted) / 0.8)' },\n }}\n />\n ))}\n </Box>\n\n <Box sx={{ mt: 1.25 }}>\n <Box\n role=\"button\"\n tabIndex={0}\n onClick={() => setSchedAdvancedOpen((v) => !v)}\n sx={{\n fontSize: '0.7rem',\n color: 'hsl(var(--muted-foreground))',\n cursor: 'pointer',\n userSelect: 'none',\n '&:hover': { color: 'hsl(var(--foreground))' },\n }}\n >\n {schedAdvancedOpen ? '▾' : '▸'} Advanced — edit cron expression\n </Box>\n {schedAdvancedOpen && (\n <TextField\n size=\"small\"\n fullWidth\n value={scheduleCron}\n onChange={(e) => { cronManualOverrideRef.current = true; setScheduleCron(e.target.value); }}\n placeholder=\"0 9 * * 1-5\"\n slotProps={{ htmlInput: { style: { fontFamily: 'monospace', fontSize: '0.78rem', padding: '6px 8px' } } }}\n sx={{\n mt: 0.75,\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--muted))',\n color: 'hsl(var(--foreground))',\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--border))' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n }}\n />\n )}\n <Typography sx={{ fontSize: '0.68rem', fontFamily: 'monospace', color: 'hsl(var(--muted-foreground))', mt: 0.75 }}>\n cron: {scheduleCron || '—'}\n </Typography>\n </Box>\n {scheduleSaving && (\n <Box sx={{ mt: 2, display: 'flex', flexDirection: 'column', gap: 0.75, p: 1.25, borderRadius: 1, bgcolor: 'hsl(var(--muted))', border: '1px solid hsl(var(--border))' }}>\n {scheduleSteps.map((s) => {\n const label =\n s.id === 'name' ? 'Generating name & description'\n : s.id === 'workflow' ? 'Creating workflow'\n : 'Enabling schedule';\n const color =\n s.state === 'done' ? 'hsl(var(--primary))'\n : s.state === 'error' ? 'hsl(var(--destructive))'\n : s.state === 'active' ? 'hsl(var(--foreground))'\n : 'hsl(var(--muted-foreground))';\n return (\n <Box key={s.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.78rem', color }}>\n <Box sx={{ width: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n {s.state === 'active' && <CircularProgress size={12} sx={{ color: 'hsl(var(--primary))' }} />}\n {s.state === 'done' && <Box sx={{ fontSize: '0.85rem', lineHeight: 1, color: 'hsl(var(--primary))' }}>✓</Box>}\n {s.state === 'error' && <Box sx={{ fontSize: '0.85rem', lineHeight: 1, color: 'hsl(var(--destructive))' }}>!</Box>}\n {s.state === 'pending' && <Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: 'hsl(var(--muted-foreground))', opacity: 0.4 }} />}\n </Box>\n <Box component=\"span\" sx={{ fontFamily: 'inherit' }}>\n {label}\n {s.detail && s.state !== 'pending' && (\n <Box component=\"span\" sx={{ ml: 0.75, color: 'hsl(var(--muted-foreground))', fontFamily: 'monospace', fontSize: '0.72rem' }}>\n — {s.detail}\n </Box>\n )}\n </Box>\n </Box>\n );\n })}\n </Box>\n )}\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 1, mt: 2 }}>\n <Button\n size=\"small\"\n onClick={() => setScheduleAnchor(null)}\n disabled={scheduleSaving}\n sx={{ height: 36, color: 'hsl(var(--muted-foreground))', textTransform: 'none' }}\n >\n Cancel\n </Button>\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!scheduleCron.trim() || scheduleSaving}\n onClick={async () => {\n const cron = scheduleCron.trim();\n console.log('[AgentUI] Save schedule clicked', { cron, hasOnSchedule: typeof onSchedule === 'function', inputLen: actionInput?.length });\n if (!cron) return;\n setScheduleSteps([\n { id: 'name', state: 'pending' },\n { id: 'workflow', state: 'pending' },\n { id: 'schedule', state: 'pending' },\n ]);\n setScheduleSaving(true);\n try {\n if (onSchedule) {\n await onSchedule({\n cron,\n input: actionInput || '',\n apps: chosenApps.filter((a) => !!a?.name).map((a) => ({ name: a.name, id: a.id, icon: a.icon })),\n onStep: (ev) => {\n setScheduleSteps((prev) => prev.map((p) => p.id === ev.id ? { ...p, state: ev.state, detail: ev.detail } : p));\n },\n });\n toast({ title: 'Schedule saved', description: 'This prompt will now run on the selected schedule.' });\n setScheduleAnchor(null);\n } else {\n toast({ title: 'Scheduling not configured', description: 'No handler is wired up for scheduled runs in this view.', variant: 'destructive' });\n setScheduleAnchor(null);\n }\n } catch (err) {\n console.error('[AgentUI] Schedule failed', err);\n toast({ title: 'Failed to save schedule', description: err instanceof Error ? err.message : String(err), variant: 'destructive' });\n } finally {\n setScheduleSaving(false);\n }\n }}\n sx={{\n height: 36, textTransform: 'none',\n bgcolor: 'hsl(var(--primary))', color: 'hsl(var(--primary-foreground))',\n '&:hover': { bgcolor: 'hsl(var(--primary))', filter: 'brightness(1.1)' },\n }}\n >\n {scheduleSaving ? <CircularProgress size={14} sx={{ color: 'inherit' }} /> : 'Save schedule'}\n </Button>\n </Box>\n </Popover>\n );\n\n\n // ── Render ──\n return (\n <Box\n className={className}\n sx={[\n { width: '100%', display: 'flex', justifyContent: 'center', pb: 4 },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n >\n <Box\n sx={[\n { width: '100%', maxWidth, display: 'flex', flexDirection: 'column', gap: 3 },\n ...(Array.isArray(contentSx) ? contentSx : contentSx ? [contentSx] : []),\n ]}\n >\n {showRunSwitcher && tabBar}\n {schedulePopover}\n {showStarter ? (\n <Box\n component=\"form\"\n onSubmit={(e) => { e.preventDefault(); handlePrimarySubmit(); }}\n sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: compact ? 2 : 3, py: compact ? 2 : 4 }}\n >\n {!hideHeroIcon && !compact && (\n <Box sx={{\n width: heroIconSize, height: heroIconSize, borderRadius: 3,\n bgcolor: 'hsl(var(--card))',\n border: '1px solid hsl(var(--border))',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n boxShadow: '0 8px 24px rgba(0,0,0,0.25)',\n }}>\n {heroIcon ?? <AgentIcon size={Math.round(heroIconSize * 0.67)} />}\n </Box>\n )}\n <Typography component=\"h1\" sx={{\n fontSize: compact ? { xs: '1.25rem', md: '1.5rem' } : { xs: '1.75rem', md: '2.25rem' },\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n textAlign: 'center',\n letterSpacing: '-0.01em',\n }}>\n {title}\n </Typography>\n {subtitle && (\n <Typography sx={{\n fontSize: '0.95rem',\n color: 'hsl(var(--muted-foreground))',\n textAlign: 'center',\n mt: -1,\n maxWidth: 600,\n }}>\n {subtitle}\n </Typography>\n )}\n\n <Box sx={{\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n borderRadius: attachedImages.length > 0 ? 4 : '28px',\n border: '1.5px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n px: 3,\n py: 1.75,\n transition: 'border-color 0.15s ease, box-shadow 0.15s ease, border-radius 0.15s ease',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary))',\n boxShadow: '0 0 0 3px hsla(var(--primary) / 0.12)',\n },\n }}>\n {attachedImages.length > 0 && (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75 }}>\n {attachedImages.map((img, idx) => (\n <Box key={`${img.name}-${idx}`} sx={{\n display: 'inline-flex', alignItems: 'center', gap: 1,\n p: 0.5, pr: 1, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n maxWidth: '100%',\n }}>\n <Box component=\"img\" src={img.dataUrl} alt={img.name} sx={{ width: 32, height: 32, borderRadius: 1, objectFit: 'cover', flexShrink: 0 }} />\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--foreground))', maxWidth: 190, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {img.name}\n </Typography>\n <IconButton size=\"small\" onClick={() => setAttachedImages((prev) => prev.filter((_, i) => i !== idx))} sx={{ p: 0.25, color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--destructive))' } }} aria-label=\"Remove attached image\">\n <CloseIcon size={12} />\n </IconButton>\n </Box>\n ))}\n </Box>\n )}\n <Box sx={{ display: 'flex', alignItems: 'flex-end', gap: 1, width: '100%' }}>\n <InputBase\n inputRef={inputRef}\n autoFocus\n multiline\n minRows={1}\n maxRows={6}\n fullWidth\n value={actionInput}\n onChange={(e) => setActionInput(e.target.value)}\n placeholder={placeholder}\n onKeyDown={onKeyDown}\n onPaste={(e) => {\n const items = e.clipboardData?.items;\n if (!items) return;\n const files: File[] = [];\n for (const item of Array.from(items)) {\n if (item.kind === 'file' && item.type.startsWith('image/')) {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n handleImagesSelected(files);\n }\n }}\n disabled={agentRequestLoading}\n sx={{\n fontSize: '1rem',\n color: 'hsl(var(--foreground))',\n '& textarea::placeholder': { color: 'hsl(var(--muted-foreground))', opacity: 0.7 },\n }}\n />\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n style={{ display: 'none' }}\n onChange={(e) => {\n handleImagesSelected(e.target.files);\n if (e.target) e.target.value = '';\n }}\n />\n {(() => {\n const allowWithoutExecution = showStarter;\n const promptTooShort = showStarter && (actionInput || '').trim().length < 6;\n const canSchedule = (hasExecution || allowWithoutExecution) && !scheduleDisabledReason && !promptTooShort && !disableSchedule;\n const hintActive = Boolean(scheduleHint) && canSchedule;\n const tip: React.ReactNode = disableSchedule\n ? (disableScheduleTooltip || 'Scheduling is disabled while editing')\n : scheduleDisabledReason\n ? scheduleDisabledTooltip\n : promptTooShort\n ? 'Type at least 6 characters of prompt before scheduling.'\n : hintActive\n ? `Detected schedule: ${scheduleHint!.label}. Click to review and save.`\n : 'Schedule this prompt to run repeatedly on a cron schedule';\n return (\n <Tooltip title={tip} placement=\"top\" arrow>\n <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5 }}>\n <IconButton\n type=\"button\"\n onClick={(e) => { if (canSchedule) setScheduleAnchor(e.currentTarget); }}\n disabled={!canSchedule || agentRequestLoading}\n sx={{\n height: 36,\n minWidth: 36,\n px: hintActive ? 1.25 : 0,\n width: hintActive ? 'auto' : 36,\n borderRadius: hintActive ? 999 : '50%',\n gap: hintActive ? 0.75 : 0,\n color: hintActive ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n bgcolor: hintActive ? 'hsl(var(--primary) / 0.12)' : 'transparent',\n border: hintActive ? '1px solid hsl(var(--primary) / 0.5)' : '1px solid transparent',\n '&:hover': hintActive\n ? { bgcolor: 'hsl(var(--primary) / 0.2)', color: 'hsl(var(--primary))' }\n : { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n '&.Mui-disabled': { opacity: 0.4, color: 'hsl(var(--muted-foreground))' },\n transition: 'all 160ms ease',\n }}\n >\n <ScheduleIcon size={18} />\n {hintActive && (\n <Box\n component=\"span\"\n sx={{\n fontSize: '0.72rem',\n fontWeight: 600,\n lineHeight: 1,\n whiteSpace: 'nowrap',\n maxWidth: 180,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {scheduleHint!.label}\n </Box>\n )}\n </IconButton>\n </Box>\n </Tooltip>\n );\n })()}\n {!hideAttach && (\n <IconButton\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n disabled={agentRequestLoading}\n title={attachedImages.length > 0 ? `Add image (${attachedImages.length} attached)` : 'Attach image'}\n sx={{\n width: 36, height: 36,\n color: attachedImages.length > 0 ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',\n bgcolor: attachedImages.length > 0 ? 'hsla(var(--primary) / 0.1)' : 'transparent',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <AttachFileIcon size={18} />\n </IconButton>\n )}\n <Tooltip title={submitTooltip} placement=\"top\" arrow>\n <span>\n {submitLabel ? (\n <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>\n <Tooltip title=\"Try this prompt without saving\" placement=\"top\" arrow>\n <IconButton\n type=\"button\"\n onClick={() => submitInput(actionInput)}\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: 'transparent',\n border: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n '&:hover': { bgcolor: 'hsl(var(--muted))' },\n '&.Mui-disabled': { color: 'hsl(var(--muted-foreground))' },\n }}\n >\n <PlayArrowRoundedIcon />\n </IconButton>\n </Tooltip>\n <Button\n type=\"submit\"\n variant=\"contained\"\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'inherit' }} /> : null}\n sx={{\n height: 36,\n px: 2,\n textTransform: 'none',\n fontSize: '0.85rem',\n fontWeight: 600,\n boxShadow: 'none',\n bgcolor: 'hsl(var(--primary))',\n color: 'hsl(var(--primary-foreground))',\n '&:hover': { bgcolor: 'hsl(var(--primary))', filter: 'brightness(1.1)', boxShadow: 'none' },\n '&.Mui-disabled': { bgcolor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n {submitLabel}\n </Button>\n </Box>\n ) : (\n <IconButton\n type=\"submit\"\n disabled={actionInput.trim().length < 6 || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: actionInput.trim().length >= 3 ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: actionInput.trim().length >= 3 ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n '&:hover': actionInput.trim().length >= 3 ? { filter: 'brightness(1.1)', bgcolor: 'hsl(var(--primary))' } : {},\n '&.Mui-disabled': { bgcolor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' },\n }}\n >\n {agentRequestLoading ? <CircularProgress size={16} sx={{ color: 'inherit' }} /> : (submitIcon ?? <PlayArrowRoundedIcon />)}\n </IconButton>\n )}\n </span>\n </Tooltip>\n </Box>\n </Box>\n\n {!hideAppPicker && (\n <Box sx={{ display: 'flex', justifyContent: 'center' }}>\n <Box sx={{\n display: 'inline-flex', flexWrap: 'wrap', alignItems: 'center', gap: 0.5,\n p: 0.5,\n borderRadius: 999,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n maxWidth: '100%',\n }}>\n <Tooltip title={agentRequestLoading ? 'Locked while the agent is running' : ''}>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={() => { if (!agentRequestLoading) setAppSearchOpen(true); }}\n disabled={agentRequestLoading}\n sx={{\n all: 'unset', cursor: agentRequestLoading ? 'not-allowed' : 'pointer',\n display: 'inline-flex', alignItems: 'center', gap: 0.5,\n px: 1.5, py: 0.5,\n borderRadius: 999,\n fontSize: '0.8rem', fontWeight: 500,\n color: 'hsl(var(--muted-foreground))',\n bgcolor: 'transparent',\n opacity: agentRequestLoading ? 0.5 : 1,\n transition: 'color 0.12s ease, background-color 0.12s ease, opacity 0.12s ease',\n '&:hover': agentRequestLoading ? {} : { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted) / 0.5)' },\n }}\n >\n <AddIcon size={14} />\n {appPickerLabel}\n </Box>\n </Tooltip>\n {chosenApps.map((app, i) => {\n const slug = (app.name || '').toLowerCase().replace(/[\\s-]+/g, '_');\n const NO_AUTH = new Set(['http', 'shuffle_tools', 'shuffle-tools', 'tools', 'singul', 'core', 'webhook', 'email']);\n const needsAuth = !NO_AUTH.has(slug) && !isAppAuthenticated(app.name || '');\n return (\n <Tooltip\n key={`${app.name}-${i}`}\n title={needsAuth ? `${(app.name || '').replace(/_/g, ' ')} is not authenticated yet — click to set it up` : ''}\n arrow\n >\n <Box\n onClick={needsAuth && !agentRequestLoading ? () => setAuthDrawerApp({ name: app.name, id: app.id || null }) : undefined}\n sx={{\n display: 'inline-flex', alignItems: 'center', gap: 0.5,\n pl: 0.5, pr: 0.75, py: 0.25,\n borderRadius: 999,\n bgcolor: needsAuth ? 'hsl(var(--severity-medium) / 0.12)' : 'hsl(var(--muted) / 0.6)',\n border: needsAuth ? '1px solid hsl(var(--severity-medium) / 0.55)' : '1px solid transparent',\n fontSize: '0.8rem',\n color: 'hsl(var(--foreground))',\n cursor: needsAuth && !agentRequestLoading ? 'pointer' : 'default',\n transition: 'background-color 0.12s ease',\n '&:hover': needsAuth && !agentRequestLoading ? { bgcolor: 'hsl(var(--severity-medium) / 0.18)' } : {},\n }}\n >\n <Avatar\n src={app.icon || undefined}\n alt={app.name}\n variant=\"rounded\"\n sx={{ width: 18, height: 18, bgcolor: 'transparent' }}\n />\n <Typography sx={{ fontSize: '0.8rem', mx: 0.25, textTransform: 'capitalize' }}>\n {app.name.replace(/_/g, ' ')}\n </Typography>\n {needsAuth && (\n <WarningIcon size={14} color={'hsl(var(--severity-medium))'} style={{ marginRight: 2 }} />\n )}\n <IconButton\n size=\"small\"\n onClick={(e) => { e.stopPropagation(); setChosenApps((prev) => prev.filter((_, idx) => idx !== i)); }}\n disabled={agentRequestLoading}\n sx={{ p: 0.125, color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--destructive))' }, '&.Mui-disabled': { opacity: 0.4 } }}\n >\n <CloseIcon size={12} />\n </IconButton>\n </Box>\n </Tooltip>\n );\n })}\n </Box>\n </Box>\n )}\n\n {/* Pre-run auth advisory — non-blocking. Lists chosen apps that\n are not yet authenticated and offers a one-click CTA to open\n the app drawer to set them up. The agent can still run\n without these — Shuffle will request auth mid-run if needed. */}\n {!hideAppPicker && (() => {\n const NO_AUTH = new Set(['http', 'shuffle_tools', 'shuffle-tools', 'tools', 'singul', 'core', 'webhook', 'email']);\n const unauthed = chosenApps.filter((a) => {\n const slug = (a.name || '').toLowerCase().replace(/[\\s-]+/g, '_');\n return !NO_AUTH.has(slug) && !isAppAuthenticated(a.name || '');\n });\n if (unauthed.length === 0) return null;\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: -0.5 }}>\n <Box sx={{\n display: 'inline-flex', alignItems: 'center', gap: 1,\n px: 1.25, py: 0.5,\n borderRadius: 999,\n border: '1px solid hsl(var(--severity-medium) / 0.45)',\n bgcolor: 'hsl(var(--severity-medium) / 0.08)',\n fontSize: '0.75rem',\n color: 'hsl(var(--foreground))',\n maxWidth: '100%',\n }}>\n <WarningIcon size={14} color={'hsl(var(--severity-medium))'} />\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {unauthed.length === 1\n ? `${unauthed[0].name.replace(/_/g, ' ')} is not authenticated.`\n : `${unauthed.length} apps are not authenticated.`}\n </Typography>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={() => setAuthDrawerApp({ name: unauthed[0].name, id: unauthed[0].id || null })}\n sx={{\n all: 'unset', cursor: 'pointer',\n fontSize: '0.75rem', fontWeight: 600,\n color: 'hsl(var(--primary))',\n textTransform: 'capitalize',\n '&:hover': { textDecoration: 'underline' },\n }}\n >\n Set up {unauthed[0].name.replace(/_/g, ' ')} →\n </Box>\n </Box>\n </Box>\n );\n })()}\n\n\n {error && (\n <Box sx={{\n width: '100%', p: 1.5, borderRadius: 1.5,\n border: '1px solid hsl(var(--destructive) / 0.4)',\n bgcolor: 'hsl(var(--destructive) / 0.08)',\n color: 'hsl(var(--destructive))',\n fontSize: '0.85rem',\n }}>{error}</Box>\n )}\n </Box>\n ) : (\n <Box>\n {/* Status row */}\n <Box sx={{\n display: 'flex', alignItems: 'center', gap: 2,\n p: 2,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n mb: 2,\n }}>\n <AvatarGroup max={4} sx={{ '& .MuiAvatar-root': { width: 28, height: 28, borderColor: 'hsl(var(--border))', fontSize: '0.7rem' } }}>\n {(executionApps.length > 0 ? executionApps : chosenApps).map((app, i) => (\n <Tooltip key={i} title={(app.name || '').replace(/_/g, ' ')}>\n <Avatar\n src={app.icon || undefined}\n alt={app.name}\n variant=\"rounded\"\n onClick={() => navigate(`/apps/${encodeURIComponent((app.name || '').toLowerCase().replace(/\\s+/g, '_'))}`)}\n sx={{\n bgcolor: 'hsl(var(--muted))',\n cursor: 'pointer',\n transition: 'transform 0.15s ease, border-color 0.15s ease',\n '&:hover': { transform: 'scale(1.08)', borderColor: 'hsl(var(--primary)) !important' },\n }}\n />\n </Tooltip>\n ))}\n </AvatarGroup>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--foreground))', fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {agentData?.original_input || actionInput || 'Agent run'}\n </Typography>\n <Typography sx={{ fontSize: '0.7rem', color: 'hsl(var(--muted-foreground))' }}>\n Status: {execution?.status || agentData?.status || '—'} · {execution?.execution_id?.slice(0, 8) || ''}\n </Typography>\n </Box>\n {(() => {\n const topStatus = String(execution?.status || agentData?.status || '').toUpperCase();\n const topRunning = !!(execution?.execution_id || agentRequestLoading) && !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(topStatus);\n return topRunning ? (\n <Tooltip title={execution?.execution_id ? 'Abort this execution' : 'Cancel and return to Start'}>\n <span>\n <IconButton\n size=\"small\"\n onClick={abortAgent}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--destructive))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <StopCircleIcon size={18} />\n </IconButton>\n </span>\n </Tooltip>\n ) : null;\n })()}\n <Tooltip title=\"Rerun with the same prompt and tools\">\n <span>\n <IconButton\n size=\"small\"\n disabled={agentRequestLoading}\n onClick={rerunAgent}\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--primary))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <RestartAltIcon size={18} />\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n\n {error && (\n <Box sx={{\n p: 1.5, borderRadius: 1.5, mb: 2,\n border: '1px solid hsl(var(--destructive) / 0.4)',\n bgcolor: 'hsl(var(--destructive) / 0.08)',\n color: 'hsl(var(--destructive))',\n fontSize: '0.85rem',\n }}>{error}</Box>\n )}\n\n {/* Shared diagnosis banner — same component used by drawers and\n incident pages, so the user sees identical reasoning here. */}\n <AgentRunDiagnosisBanner\n run={execution?.results?.length ? execution : agentData}\n sx={{ px: 0, pb: 0, mb: 2 }}\n executionId={execution?.execution_id}\n onJumpToEvidence={(decisionIndex) => {\n // Locate the timeline row for the offending decision and\n // expand + scroll to it on the detailed view, regardless of\n // whether the user is currently on Simple or Detailed.\n const dec = (agentData?.decisions || [])[decisionIndex];\n let rowIndex = -1;\n if (dec) {\n rowIndex = timeline.findIndex((it) => it.details === dec);\n if (rowIndex < 0 && dec.run_details?.id) {\n rowIndex = timeline.findIndex(\n (it) => (it.details as any)?.run_details?.id === dec.run_details.id\n );\n }\n }\n // Fall back to the agent row (0) if we cannot resolve.\n const targetIndex = rowIndex >= 0 ? rowIndex : 0;\n setOpenIndexes((prev) => {\n const next = new Set(prev);\n next.add(targetIndex);\n return next;\n });\n goToTab('detailed');\n // Pulse the row + its output box so the user can see exactly\n // which step the diagnosis was pulled from. Auto-clears after\n // a couple seconds; re-clicking restarts the pulse.\n setHighlightedIndex(targetIndex);\n window.setTimeout(() => {\n setHighlightedIndex((curr) => (curr === targetIndex ? null : curr));\n }, 2800);\n // Wait for the detailed view to mount, then scroll the row\n // into view. requestAnimationFrame x2 ensures layout has\n // settled after the tab switch.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const el = document.querySelector(\n `[data-timeline-index=\"${targetIndex}\"]`\n ) as HTMLElement | null;\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n });\n });\n }}\n />\n\n {/* Simple summary view */}\n {viewMode === 'simple' && (\n <Box sx={{\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n p: 2.5,\n display: 'flex',\n flexDirection: 'column',\n gap: 1.5,\n }}>\n {(() => {\n const status = (execution?.status || agentData?.status || 'EXECUTING').toUpperCase();\n const decisionCount = (agentData?.decisions || []).length;\n const isRunning = !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(status);\n const rawStartedAt = agentData?.started_at || execution?.started_at || 0;\n // Normalize: backend may return Unix milliseconds (UnixMillis) or seconds.\n const startedAtSec = rawStartedAt > 1e12 ? Math.floor(rawStartedAt / 1000) : rawStartedAt;\n // Prefer our locally-captured start while the run is in\n // progress — the backend's `started_at` is sometimes\n // restamped on every poll, which made the counter look\n // frozen at \"1s\". Once finished, prefer the backend value\n // so the displayed total matches the recorded run.\n const effectiveStart = isRunning\n ? (localRunStart || startedAtSec || 0)\n : (startedAtSec || localRunStart || 0);\n let durationSec: number | null = null;\n if (isRunning && effectiveStart) {\n durationSec = Math.max(0, nowTick - effectiveStart);\n } else if (totalDuration && totalDuration > 0) {\n durationSec = totalDuration;\n }\n // Detect a pending ASK decision (agent waiting on a user answer)\n const pendingAsk = (agentData?.decisions || []).slice().reverse().find((d) => {\n const isAsk = d.category === 'ask' || d.action === 'ask';\n const st = (d.run_details?.status || '').toUpperCase();\n return isAsk && (st === 'RUNNING' || st === 'WAITING');\n });\n const pendingQuestions: { question: string; index: number }[] = [];\n if (pendingAsk) {\n for (const f of pendingAsk.fields || []) {\n if (f.key === 'question' && f.value) {\n pendingQuestions.push({ question: f.value, index: pendingQuestions.length + 1 });\n }\n }\n }\n const pendingAnswered = pendingQuestions.every((q) => questionAnswers[q.question]?.value);\n\n return (\n <>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {isRunning ? (\n <CircularProgress size={16} sx={{ color: 'hsl(var(--primary))' }} />\n ) : status === 'FINISHED' ? (\n <CheckCircleIcon size={18} color={'hsl(142 70% 45%)'} />\n ) : (\n <ErrorIcon size={18} color={'hsl(var(--destructive))'} />\n )}\n <Typography sx={{ fontSize: '0.9rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {isRunning ? 'Agent is working…' : status === 'FINISHED' ? 'Run finished' : `Run ${status.toLowerCase()}`}\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n {decisionCount} step{decisionCount === 1 ? '' : 's'}\n {durationSec != null ? ` · ${Math.round(durationSec)}s` : ''}\n </Typography>\n <Box sx={{ flexGrow: 1 }} />\n </Box>\n {pendingAuthApps.map(({ appName, appId, icon }) => {\n const pretty = appName.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n return (\n <Box\n key={`auth-${appName}`}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 1.5,\n border: '1px solid hsla(var(--severity-medium) / 0.3)',\n bgcolor: 'hsla(var(--severity-medium) / 0.08)',\n }}\n >\n <LockIcon size={22} color={'hsl(var(--severity-medium))'} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {pretty} requires authentication\n </Typography>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))' }}>\n Connect your {pretty} account so the agent can complete this step, then rerun.\n </Typography>\n </Box>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={\n <Avatar\n src={icon || undefined}\n alt=\"\"\n variant=\"rounded\"\n sx={{\n width: 18, height: 18, borderRadius: 0.5,\n bgcolor: 'hsl(var(--background) / 0.4)',\n color: 'hsl(var(--background))',\n fontSize: '0.7rem', fontWeight: 700,\n '& img': { objectFit: 'contain' },\n }}\n >\n {pretty.charAt(0)}\n </Avatar>\n }\n onClick={() => setAuthDrawerApp({ name: appName, id: appId })}\n sx={{\n height: 36, textTransform: 'none', fontWeight: 600,\n }}\n >\n Authenticate {pretty}\n </Button>\n </Box>\n );\n })}\n {finishAnswer ? (\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n fontSize: '0.9rem',\n color: 'hsl(var(--foreground))',\n '& > *:first-of-type': { mt: 0 },\n '& > *:last-child': { mb: 0 },\n '& p': { my: 1, lineHeight: 1.55 },\n '& h1, & h2, & h3, & h4': { mt: 2, mb: 1, fontWeight: 600, lineHeight: 1.3 },\n '& h1': { fontSize: '1.15rem' },\n '& h2': { fontSize: '1.05rem' },\n '& h3, & h4': { fontSize: '0.95rem' },\n '& ul': { my: 1, pl: 3, listStyleType: 'disc', listStylePosition: 'outside' },\n '& ol': { my: 1, pl: 3, listStyleType: 'decimal', listStylePosition: 'outside' },\n '& ul ul': { listStyleType: 'circle' },\n '& ul ul ul': { listStyleType: 'square' },\n '& li': { my: 0.25, display: 'list-item' },\n '& li::marker': { color: 'hsl(var(--muted-foreground))' },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': {\n px: 0.5, py: 0.125, borderRadius: 0.5,\n bgcolor: 'hsl(var(--muted))',\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n fontSize: '0.82em',\n },\n '& pre': {\n p: 1.5, my: 1, borderRadius: 1,\n bgcolor: 'hsl(var(--muted))',\n overflowX: 'auto',\n fontSize: '0.82rem',\n },\n '& pre code': { p: 0, bgcolor: 'transparent' },\n '& blockquote': {\n borderLeft: '3px solid hsl(var(--border))',\n pl: 1.5, my: 1, color: 'hsl(var(--muted-foreground))',\n },\n '& table': { borderCollapse: 'collapse', my: 1, fontSize: '0.85rem' },\n '& th, & td': { border: '1px solid hsl(var(--border))', px: 1, py: 0.5 },\n '& hr': { border: 0, borderTop: '1px solid hsl(var(--border))', my: 1.5 },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(finishAnswer)}</Markdown>\n </Box>\n ) : pendingAsk && pendingQuestions.length > 0 ? (\n (() => {\n const trySimpleSubmit = () => {\n if (agentRequestLoading) return;\n if (!pendingAnswered) {\n setSimpleSubmitAttempted(true);\n return;\n }\n if (pendingAsk.run_details?.id) {\n submitQuestions(pendingAsk.run_details.id, questionAnswers);\n }\n };\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n {pendingQuestions.map((q, qi) => {\n const value = questionAnswers[q.question]?.value || '';\n const isMissing = simpleSubmitAttempted && !value;\n return (\n <Box key={qi}>\n <Box sx={{ fontSize: '0.9rem', color: 'hsl(var(--foreground))', mb: 1, '& p': { my: 0.5 } }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(q.question)}</Markdown>\n </Box>\n <TextField\n fullWidth\n multiline\n minRows={2}\n placeholder=\"Your answer here…\"\n value={value}\n error={isMissing}\n helperText={isMissing ? 'Please answer this question' : undefined}\n onChange={(e) => {\n const v = e.target.value;\n setQuestionAnswers((prev) => ({\n ...prev,\n [q.question]: { index: qi, value: v },\n }));\n }}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n trySimpleSubmit();\n }\n }}\n size=\"small\"\n sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'hsl(var(--background))' } }}\n />\n </Box>\n );\n })}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Tooltip title={!pendingAnswered ? 'Please answer all questions first' : ''} placement=\"top\" arrow>\n <span>\n <Button\n variant=\"contained\"\n size=\"small\"\n disabled={agentRequestLoading || !pendingAnswered}\n onClick={trySimpleSubmit}\n startIcon={agentRequestLoading ? <CircularProgress size={14} sx={{ color: 'hsl(var(--primary-foreground))' }} /> : undefined}\n >\n {agentRequestLoading ? 'Submitting…' : 'Submit'}\n </Button>\n </span>\n </Tooltip>\n {pendingAsk.run_details?.id && getFormUrl(pendingAsk.run_details.id) && (\n <Tooltip title=\"Answer in the Form UI\" placement=\"right\">\n <IconButton\n size=\"small\"\n onClick={() => {\n const url = getFormUrl(pendingAsk.run_details!.id!);\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n }}\n sx={{ color: 'hsl(var(--muted-foreground))', '&:hover': { color: 'hsl(var(--primary))' } }}\n >\n <OpenInNewIcon size={18} />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </Box>\n );\n })()\n ) : isRunning ? (\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n Waiting for the agent to produce the first step.\n </Typography>\n ) : (\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n No final answer was returned. Open Detailed to inspect each step.\n </Typography>\n )}\n\n {!isRunning && (\n <Box>\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => setViewMode('detailed')}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none', px: 0 }}\n >\n View detailed timeline →\n </Button>\n </Box>\n )}\n </>\n );\n })()}\n </Box>\n )}\n\n {/* Detailed timeline view */}\n {viewMode === 'detailed' && (() => {\n const detailedStatus = (execution?.status || agentData?.status || 'EXECUTING').toUpperCase();\n const detailedIsRunning = !['FINISHED', 'FAILURE', 'ABORTED', 'CANCELLED', 'CANCELED'].includes(detailedStatus);\n const detailedRunFinished = !detailedIsRunning;\n \n return (\n <Box sx={{\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n overflow: 'hidden',\n }}>\n {timeline.length === 0 || (timeline.length === 1 && agentRequestLoading) ? (\n <Box sx={{ p: 4, textAlign: 'center', color: 'hsl(var(--muted-foreground))', fontSize: '0.85rem' }}>\n <CircularProgress size={20} sx={{ mb: 1 }} />\n <Typography sx={{ fontSize: '0.85rem' }}>Waiting for agent response…</Typography>\n </Box>\n ) : (\n <>\n {timeline.map((item, i) => (\n <TimelineRow\n key={i}\n item={item}\n index={i}\n open={openIndexes.has(i)}\n onToggle={() => toggleOpen(i)}\n appsById={appsById}\n totalDuration={totalDuration}\n originalStartTime={originalStartTime}\n maxWidth={210}\n questionAnswers={questionAnswers}\n setQuestionAnswers={setQuestionAnswers}\n onSubmitQuestions={submitQuestions}\n onRerunAgent={rerunAgent}\n onRerunDecision={rerunDecision}\n agentRequestLoading={agentRequestLoading}\n getFormUrl={getFormUrl}\n runFinished={detailedRunFinished}\n onAuthenticateApp={(name, id) => setAuthDrawerApp({ name, id })}\n isAppAuthenticated={isAppAuthenticated}\n highlight={highlightedIndex === i}\n />\n ))}\n {detailedRunFinished && (\n <Box sx={{\n borderTop: '1px solid hsl(var(--border))',\n p: 2.5,\n display: 'flex',\n flexDirection: 'column',\n gap: 1.5,\n bgcolor: 'hsl(var(--muted) / 0.2)',\n }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {detailedStatus === 'FINISHED' ? (\n <CheckCircleIcon size={18} color={'hsl(142 70% 45%)'} />\n ) : (\n <ErrorIcon size={18} color={'hsl(var(--destructive))'} />\n )}\n <Typography sx={{ fontSize: '0.9rem', fontWeight: 600, color: 'hsl(var(--foreground))' }}>\n {detailedStatus === 'FINISHED' ? 'Run finished' : `Run ${detailedStatus.toLowerCase()}`}\n </Typography>\n </Box>\n {finishAnswer && (\n <Box sx={{\n p: 2, borderRadius: 1.5,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--background))',\n fontSize: '0.9rem',\n color: 'hsl(var(--foreground))',\n '& > *:first-of-type': { mt: 0 },\n '& > *:last-child': { mb: 0 },\n '& p': { my: 1, lineHeight: 1.55 },\n '& a': { color: 'hsl(var(--primary))', textDecoration: 'underline' },\n '& code': {\n px: 0.5, py: 0.125, borderRadius: 0.5,\n bgcolor: 'hsl(var(--muted))',\n fontFamily: '\"JetBrains Mono\", ui-monospace, monospace',\n fontSize: '0.82em',\n },\n '& pre': {\n p: 1.5, my: 1, borderRadius: 1,\n bgcolor: 'hsl(var(--muted))',\n overflowX: 'auto',\n fontSize: '0.82rem',\n },\n '& pre code': { p: 0, bgcolor: 'transparent' },\n }}>\n <Markdown remarkPlugins={[remarkGfm, remarkBreaks]}>{normalizeMarkdown(finishAnswer)}</Markdown>\n </Box>\n )}\n </Box>\n )}\n </>\n )}\n </Box>\n );\n })()}\n\n {/* Continuation form (after a finish decision) */}\n {finishDecisionId && (\n <Box sx={{ mt: 3, display: 'flex', justifyContent: 'center' }}>\n <Box sx={{ width: '100%', maxWidth: 640 }}>\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', mb: 0.75, textAlign: 'center' }}>\n Continue this agent run with more details\n </Typography>\n <Box\n component=\"form\"\n onSubmit={(e) => {\n e.preventDefault();\n if (continuationText.trim()) {\n submitQuestions(finishDecisionId, { continue: continuationText }, true);\n }\n }}\n sx={{\n display: 'flex', alignItems: 'flex-end', gap: 1,\n p: 1.25, borderRadius: 999,\n border: '1.5px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n '&:focus-within': {\n borderColor: 'hsl(var(--primary))',\n boxShadow: '0 0 0 3px hsla(var(--primary) / 0.12)',\n },\n }}\n >\n <InputBase\n fullWidth\n multiline\n minRows={1}\n maxRows={4}\n placeholder={continuationPlaceholder}\n value={continuationText}\n onChange={(e) => setContinuationText(e.target.value)}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n if (continuationText.trim() && !agentRequestLoading) {\n submitQuestions(finishDecisionId, { continue: continuationText }, true);\n }\n }\n }}\n disabled={agentRequestLoading}\n sx={{ fontSize: '0.9rem', color: 'hsl(var(--foreground))', px: 2 }}\n />\n <IconButton\n type=\"submit\"\n disabled={!continuationText.trim() || agentRequestLoading}\n sx={{\n width: 36, height: 36,\n bgcolor: continuationText.trim() && !agentRequestLoading ? 'hsl(var(--primary))' : 'hsl(var(--muted))',\n color: continuationText.trim() && !agentRequestLoading ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',\n '&:hover': continuationText.trim() && !agentRequestLoading ? { filter: 'brightness(1.1)', bgcolor: 'hsl(var(--primary))' } : {},\n }}\n >\n {agentRequestLoading ? <CircularProgress size={16} sx={{ color: 'inherit' }} /> : <SendIcon size={18} />}\n </IconButton>\n </Box>\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n <AppSearchDrawer\n open={appSearchOpen}\n onClose={() => setAppSearchOpen(false)}\n title={appPickerTitle}\n subtitle={appPickerSubtitle}\n multiSelect\n selectedApps={chosenApps.map((a) => ({ name: a.name, id: a.id || null, icon: a.icon }))}\n onSelectionChange={(next) => {\n setChosenApps(\n next.map((app) => {\n const known = availableApps.find(\n (a) => a.name?.toLowerCase() === app.name?.toLowerCase(),\n );\n return {\n name: app.name,\n icon: app.icon || known?.icon,\n id: app.id || known?.id || undefined,\n };\n }),\n );\n }}\n />\n\n <AppDetailDrawer\n open={!!authDrawerApp}\n onClose={() => setAuthDrawerApp(null)}\n appName={authDrawerApp?.name || null}\n appId={authDrawerApp?.id || null}\n activeOrgId={orgId || null}\n />\n </Box>\n </Box>\n );\n};\n\nexport default AgentUI;\n","/**\n * resolveApp — General-purpose app resolver.\n *\n * Given an app id OR name, look it up across all three known sources and\n * return a unified `{ id, name, image }` triple. Used anywhere we need to\n * render an app chip/icon and only have a free-form identifier (decision\n * `tool`, auth-request `appName`, `app_authentication` payload, etc.).\n *\n * Resolution order (each pass merges in any newly-found fields, so we keep\n * going until id/name/image are all known or all sources are exhausted):\n * 1. /api/v1/apps/authentication — covers user-installed/active apps,\n * including private ones that may not be in the public catalog.\n * 2. /api/v1/apps — covers everything visible to the org (activated\n * and private uploads).\n * 3. Algolia `appsearch` — canonical objectID + public catalog metadata.\n *\n * Results are cached in-memory by normalized key so repeat lookups for the\n * same name/id are free.\n */\n\nimport { fetchAppsViaApiConfig } from './appsCache';\nimport { fetchAuthenticatedApps } from './authenticatedApps';\n\nexport interface ResolvedApp {\n /** Canonical id — Algolia objectID when known, otherwise Shuffle app id. */\n id: string;\n /** Display name (may be raw slug if no source had a friendly name). */\n name: string;\n /** Best available large image URL. Empty string if not found. */\n image: string;\n /** Categories from whichever source provided them. */\n categories?: string[];\n}\n\nconst norm = (s: string): string =>\n (s || '').toLowerCase().trim().replace(/[\\s\\-]+/g, '_');\n\nconst _cache = new Map<string, ResolvedApp>();\nconst _pending = new Map<string, Promise<ResolvedApp | null>>();\n\n/** Returns true when the resolved record is fully populated. */\nconst isComplete = (r: Partial<ResolvedApp>): boolean =>\n Boolean(r.id && r.name && r.image);\n\nconst merge = (\n base: Partial<ResolvedApp>,\n next: Partial<ResolvedApp>,\n): Partial<ResolvedApp> => ({\n id: base.id || next.id,\n name: base.name || next.name,\n image: base.image || next.image,\n categories: base.categories?.length ? base.categories : next.categories,\n});\n\n/**\n * Resolve an app from id-or-name across auth + apps + Algolia.\n * Returns `null` only if all three sources came back empty.\n */\nexport async function resolveApp(idOrName: string): Promise<ResolvedApp | null> {\n if (!idOrName || typeof idOrName !== 'string') return null;\n const slug = norm(idOrName);\n const rawKey = idOrName;\n\n const cached = _cache.get(slug) || _cache.get(rawKey);\n if (cached) return cached;\n\n const inflight = _pending.get(slug);\n if (inflight) return inflight;\n\n const work = (async (): Promise<ResolvedApp | null> => {\n let acc: Partial<ResolvedApp> = {};\n\n // --- Pass 1: authenticated apps -----------------------------------\n try {\n const auths = await fetchAuthenticatedApps();\n const hit = auths.find((a) => {\n const app = a?.app || {};\n return (\n (app.id && (app.id === rawKey || app.id === slug)) ||\n (app.name && norm(String(app.name)) === slug)\n );\n });\n if (hit?.app) {\n acc = merge(acc, {\n id: hit.app.id ? String(hit.app.id) : undefined,\n name: hit.app.name ? String(hit.app.name) : undefined,\n image: hit.app.large_image || hit.app.small_image || '',\n categories: hit.app.categories as string[] | undefined,\n });\n }\n } catch { /* ignore */ }\n\n // --- Pass 2: /api/v1/apps -----------------------------------------\n if (!isComplete(acc)) {\n try {\n const apps = await fetchAppsViaApiConfig();\n const hit = apps.find(\n (a: any) =>\n a?.id === rawKey ||\n a?.id === slug ||\n (a?.name && norm(String(a.name)) === slug),\n );\n if (hit) {\n acc = merge(acc, {\n id: hit.id ? String(hit.id) : undefined,\n name: hit.name ? String(hit.name) : undefined,\n image: hit.large_image || hit.image_url || hit.image || '',\n categories: hit.categories,\n });\n }\n } catch { /* ignore */ }\n }\n\n // --- Pass 3: Algolia ----------------------------------------------\n if (!isComplete(acc)) {\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch(\n 'JNSS5CFDZZ',\n '33e4e3564f4f060e96e0531957bed552',\n );\n // Prefer direct objectID lookup if the input looks like one.\n let match: any = null;\n try {\n const obj = await (client as any).getObject({\n indexName: 'appsearch',\n objectID: rawKey,\n });\n if (obj?.name || obj?.image_url) match = obj;\n } catch { /* not an objectID — fall through */ }\n if (!match) {\n const res = await client.searchSingleIndex({\n indexName: 'appsearch',\n searchParams: { query: slug.replace(/_/g, ' '), hitsPerPage: 5 },\n });\n const hits = (res.hits as any[]) || [];\n match = hits.find((h) => norm(h.name || '') === slug) || hits[0];\n }\n if (match) {\n acc = merge(acc, {\n // Algolia objectID is canonical — prefer it for `id` when we\n // didn't already get a real id from auth/apps.\n id: acc.id || match.objectID || match.id,\n name: match.name,\n image: match.image_url,\n categories: match.categories,\n });\n }\n } catch { /* algolia unavailable / rate-limited */ }\n }\n\n if (!acc.id && !acc.name && !acc.image) return null;\n\n const resolved: ResolvedApp = {\n id: acc.id || slug,\n name: acc.name || idOrName,\n image: acc.image || '',\n categories: acc.categories,\n };\n _cache.set(slug, resolved);\n _cache.set(rawKey, resolved);\n return resolved;\n })();\n\n _pending.set(slug, work);\n try {\n return await work;\n } finally {\n _pending.delete(slug);\n }\n}\n\n/** Resolve many at once — convenience wrapper. */\nexport async function resolveApps(\n idsOrNames: string[],\n): Promise<Record<string, ResolvedApp>> {\n const out: Record<string, ResolvedApp> = {};\n await Promise.all(\n idsOrNames.map(async (n) => {\n const r = await resolveApp(n);\n if (r) out[n] = r;\n }),\n );\n return out;\n}\n\n/** Seed the cache (e.g. from chosenApps that already carry an icon). */\nexport function seedResolvedApp(idOrName: string, app: Partial<ResolvedApp>) {\n if (!idOrName || !app) return;\n const slug = norm(idOrName);\n const existing = _cache.get(slug) || _cache.get(idOrName);\n const merged: ResolvedApp = {\n id: app.id || existing?.id || slug,\n name: app.name || existing?.name || idOrName,\n image: app.image || existing?.image || '',\n categories: app.categories || existing?.categories,\n };\n _cache.set(slug, merged);\n _cache.set(idOrName, merged);\n}\n\n/** Clear the resolver cache (e.g. on org change). */\nexport function invalidateResolvedApps() {\n _cache.clear();\n}\n","/**\n * Agent Run Service\n * Shared logic for calling the /api/v1/agent JSON-RPC endpoint\n * and parsing the response into a usable format.\n */\n\nimport { getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\n\n// ── Request types ──────────────────────────────────────────────────────────────\n\n/**\n * MCP-spec image content block.\n * @see https://modelcontextprotocol.io specification — Image Content\n */\nexport interface AgentImageInput {\n /** Raw base64 (no data URL prefix) */\n data: string;\n /** e.g. \"image/png\", \"image/jpeg\" */\n mimeType: string;\n /** Optional original filename — for UI/debugging only */\n name?: string;\n}\n\nexport interface AgentRunRequest {\n /** The user's prompt / instruction */\n input: string;\n /** Optional: target a single app */\n toolName?: string;\n toolId?: string;\n /** Optional: target multiple apps */\n toolNames?: string[];\n toolIds?: string[];\n /**\n * Optional: one or more attached images. Sent under\n * `params.input.images` as an array of `{ url, detail }` objects,\n * where `url` is a `data:<mime>;base64,<data>` URL.\n */\n images?: AgentImageInput[];\n /** @deprecated Use `images`. Single base64 data URL kept for back-compat. */\n image?: string;\n /**\n * If true, return the initial response immediately without polling for the\n * final execution result. The caller is then responsible for polling\n * `/api/v1/streams/results` itself (e.g. AgentUI's live timeline).\n */\n skipPolling?: boolean;\n /**\n * Optional per-call overrides so callers (e.g. embedded `AgentUI`) can\n * point at a different Shuffle backend without mutating the global\n * `API_CONFIG`. When omitted, falls back to `getApiUrl` / `getAuthHeader`.\n */\n apiKey?: string;\n apiBaseUrl?: string;\n orgId?: string;\n /** Optional AbortSignal so callers can cancel the in-flight request. */\n signal?: AbortSignal;\n}\n\n/** Build URL + headers honouring optional per-call overrides. */\nconst resolveTarget = (\n path: string,\n opts: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): { url: string; headers: Record<string, string> } => {\n const url = opts.apiBaseUrl\n ? `${opts.apiBaseUrl.replace(/\\/+$/, '')}${path}`\n : getApiUrl(path);\n const headers: Record<string, string> = opts.apiKey\n ? { Authorization: `Bearer ${opts.apiKey}` }\n : { ...getAuthHeader() };\n if (opts.orgId) headers['Org-Id'] = opts.orgId;\n return { url, headers };\n};\n\n/** Split a `data:<mime>;base64,<data>` URL into its mime + base64 parts. */\nconst parseDataUrl = (dataUrl: string): AgentImageInput | null => {\n const match = /^data:([^;]+);base64,(.*)$/.exec(dataUrl);\n if (!match) return null;\n return { mimeType: match[1], data: match[2] };\n};\n\n// ── Response types ─────────────────────────────────────────────────────────────\n\nexport interface AgentRunResponse {\n success: boolean;\n /** Parsed, human-readable output content */\n content: string;\n /** The raw parsed JSON (if response was JSON), for further inspection */\n rawData?: unknown;\n /** Error message if success is false */\n error?: string;\n /** HTTP status code of the response */\n status: number;\n}\n\n// ── Response parser ────────────────────────────────────────────────────────────\n\n/**\n * Parse a JSON-RPC agent response into human-readable content.\n * Extracts the most useful information from the nested response structure.\n */\nexport const parseAgentResponse = (data: unknown): string => {\n if (typeof data === 'string') return data;\n if (data == null) return 'No output returned.';\n\n const obj = data as Record<string, unknown>;\n\n // JSON-RPC result field\n if (obj.result !== undefined) {\n const result = obj.result;\n\n if (typeof result === 'string') return result || 'No output returned.';\n\n if (typeof result === 'object' && result !== null) {\n const r = result as Record<string, unknown>;\n const parts: string[] = [];\n\n // Extract message first (most useful field)\n if (r.message && typeof r.message === 'string') {\n parts.push(r.message);\n }\n\n // Append any remaining fields as structured JSON\n const rest = { ...r };\n delete rest.message;\n if (Object.keys(rest).length > 0) {\n parts.push(JSON.stringify(rest, null, 2));\n }\n\n return parts.join('\\n\\n') || 'No output returned.';\n }\n\n return String(result);\n }\n\n // Fallback: top-level message\n if (obj.message && typeof obj.message === 'string') return obj.message;\n\n // Fallback: dump entire response\n return JSON.stringify(data, null, 2);\n};\n\n// ── Execution poller ───────────────────────────────────────────────────────────\n\n/**\n * Poll /api/v1/streams/results for the real execution result.\n * Retries up to `maxAttempts` with `intervalMs` between each.\n */\nconst pollExecutionResult = async (\n executionId: string,\n {\n maxAttempts = 15,\n intervalMs = 2000,\n apiKey,\n apiBaseUrl,\n orgId,\n }: { maxAttempts?: number; intervalMs?: number; apiKey?: string; apiBaseUrl?: string; orgId?: string } = {}\n): Promise<AgentRunResponse> => {\n const { url, headers } = resolveTarget('/api/v1/streams/results', { apiKey, apiBaseUrl, orgId });\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const resp = await fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n execution_id: executionId,\n authorization: executionId,\n }),\n });\n\n if (!resp.ok) {\n // Non-retryable server error\n if (resp.status >= 400 && resp.status < 500) {\n return {\n success: false,\n content: '',\n error: `Error ${resp.status}: Could not fetch execution result.`,\n status: resp.status,\n };\n }\n // Server error — keep polling\n await delay(intervalMs);\n continue;\n }\n\n const rawText = await resp.text();\n if (!rawText || rawText === '{}' || rawText === 'null') {\n // Not ready yet\n await delay(intervalMs);\n continue;\n }\n\n const contentType = resp.headers.get('content-type');\n if (!contentType?.includes('application/json')) {\n return { success: true, content: rawText, status: resp.status };\n }\n\n const data = JSON.parse(rawText);\n\n // Check if execution is still running (no real result yet)\n if (data?.status === 'EXECUTING' || data?.status === 'WAITING') {\n await delay(intervalMs);\n continue;\n }\n\n const content = parseAgentResponse(data);\n return {\n success: true,\n content,\n rawData: data,\n status: resp.status,\n };\n } catch {\n await delay(intervalMs);\n }\n }\n\n return {\n success: false,\n content: '',\n error: `Timed out waiting for execution ${executionId} to complete.`,\n status: 0,\n };\n};\n\nconst delay = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// ── Main function ──────────────────────────────────────────────────────────────\n\n/**\n * Check if the initial response is an execution stub\n * (contains execution_id but no real result content).\n */\nconst isExecutionStub = (data: unknown): data is { execution_id: string } => {\n if (typeof data !== 'object' || data === null) return false;\n const obj = data as Record<string, unknown>;\n return (\n typeof obj.execution_id === 'string' &&\n obj.execution_id.length > 0 &&\n // It's a stub if there's no result/message — just metadata\n obj.result === undefined &&\n obj.message === undefined\n );\n};\n\n/**\n * Run the agent with the given input and optional tool targets.\n * Handles the full lifecycle: build payload → fetch → parse response.\n * If the response is an execution stub, polls for the real result.\n */\nexport const runAgent = async (request: AgentRunRequest): Promise<AgentRunResponse> => {\n const input: Record<string, unknown> = { text: request.input };\n\n // Collect images: prefer explicit `images` array, fall back to legacy `image` data URL.\n const images: AgentImageInput[] = [];\n if (request.images && request.images.length > 0) {\n images.push(...request.images);\n } else if (request.image && request.image.length > 0) {\n const parsed = parseDataUrl(request.image);\n if (parsed) images.push(parsed);\n }\n\n // Sent under `params.input.images` as an array of `{ url, detail }` objects\n // so the agent can accept multiple images. `url` is a data URL.\n if (images.length > 0) {\n input.images = images.map((img) => ({\n url: `data:${img.mimeType};base64,${img.data}`,\n detail: 'auto',\n }));\n }\n\n const params: Record<string, unknown> = { input };\n\n // Single tool target\n if (request.toolName) params.tool_name = request.toolName;\n if (request.toolId) params.tool_id = request.toolId;\n\n // Multiple tool targets\n if (request.toolNames && request.toolNames.length > 0) {\n params.tool_names = request.toolNames;\n }\n if (request.toolIds && request.toolIds.length > 0) {\n params.tool_ids = request.toolIds;\n }\n\n const payload = {\n jsonrpc: '2.0',\n id: crypto.randomUUID(),\n method: 'tools/call',\n params,\n };\n\n const { url: agentUrl, headers: agentHeaders } = resolveTarget('/api/v1/agent', {\n apiKey: request.apiKey,\n apiBaseUrl: request.apiBaseUrl,\n orgId: request.orgId,\n });\n\n try {\n const response = await fetch(agentUrl, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...agentHeaders,\n },\n body: JSON.stringify(payload),\n signal: request.signal,\n });\n\n const rawText = await response.text();\n const contentType = response.headers.get('content-type');\n\n // Non-OK status\n if (!response.ok) {\n return {\n success: false,\n content: '',\n error: `Error ${response.status}: ${rawText || response.statusText}`,\n status: response.status,\n };\n }\n\n // Non-JSON response (HTML redirect, plain text, etc.)\n if (!contentType?.includes('application/json')) {\n if (rawText.trim().startsWith('<!') || rawText.includes('<html')) {\n return {\n success: false,\n content: '',\n error: 'Received an unexpected HTML response. This may indicate an auth redirect or server issue.',\n status: response.status,\n };\n }\n // Plain text is still valid output\n return {\n success: true,\n content: rawText,\n status: response.status,\n };\n }\n\n // JSON response — parse and check for execution stub\n const data = JSON.parse(rawText);\n\n if (isExecutionStub(data)) {\n if (request.skipPolling) {\n // Hand control back to the caller (it will poll itself).\n return {\n success: true,\n content: '',\n rawData: data,\n status: response.status,\n };\n }\n console.log(`[AgentRun] Got execution stub, polling for result: ${data.execution_id}`);\n return pollExecutionResult(data.execution_id, {\n apiKey: request.apiKey,\n apiBaseUrl: request.apiBaseUrl,\n orgId: request.orgId,\n });\n }\n\n const content = parseAgentResponse(data);\n\n return {\n success: true,\n content,\n rawData: data,\n status: response.status,\n };\n } catch (err) {\n const aborted = err instanceof DOMException && err.name === 'AbortError';\n return {\n success: false,\n content: '',\n error: aborted\n ? 'Request aborted by user.'\n : `Network error — could not reach the agent. ${err instanceof Error ? err.message : ''}`,\n status: 0,\n ...(aborted ? { aborted: true } as any : {}),\n };\n }\n};\n","/**\n * scheduleHint — lightweight natural-language detector for scheduling intent\n * inside an agent prompt. Recognises phrases like:\n * \"schedule this\", \"at 6 am\", \"next monday at 2am\",\n * \"daily in the evening\", \"every 15 minutes\", \"weekdays at 9am\",\n * \"every monday\", \"weekly\", \"hourly\", \"tonight at 11pm\"\n *\n * Returns a structured hint that the UI uses to (1) highlight the Schedule\n * button and (2) preselect a cron expression in the schedule popover.\n *\n * NOTE: Intentionally simple — pure heuristics, no LLM. Good enough to surface\n * scheduling as a suggestion; the user always confirms in the popover.\n */\n\nexport interface ScheduleHint {\n /** Suggested cron expression (5-field, UTC-naive — matches existing chips). */\n cron: string;\n /** Human-readable label, e.g. \"Daily at 6:00 AM\" or \"Every Monday at 2:00 AM\". */\n label: string;\n /** Strength of the match — used to decide how loud the UI hint should be. */\n confidence: 'low' | 'medium' | 'high';\n /** The substring of the input that triggered the match (for highlighting). */\n matchedText: string;\n}\n\nconst DAY_NAMES: Record<string, number> = {\n sunday: 0, sun: 0,\n monday: 1, mon: 1,\n tuesday: 2, tue: 2, tues: 2,\n wednesday: 3, wed: 3,\n thursday: 4, thu: 4, thurs: 4,\n friday: 5, fri: 5,\n saturday: 6, sat: 6,\n};\n\nconst PART_OF_DAY: Record<string, number> = {\n morning: 9,\n noon: 12,\n afternoon: 14,\n evening: 18,\n night: 22,\n midnight: 0,\n};\n\nconst DAY_LABEL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n\nconst fmtTime = (h: number, m: number): string => {\n const ampm = h >= 12 ? 'PM' : 'AM';\n const h12 = ((h + 11) % 12) + 1;\n const mm = m.toString().padStart(2, '0');\n return `${h12}:${mm} ${ampm}`;\n};\n\nconst findTime = (text: string): { h: number; m: number; matched: string } | null => {\n // 6am, 6 am, 6:30am, 14:00, 2:30 pm\n const re = /\\b(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm|a\\.m\\.|p\\.m\\.)\\b|\\b(\\d{1,2}):(\\d{2})\\b(?!\\s*(?:am|pm))/i;\n const m = text.match(re);\n if (!m) return null;\n if (m[1]) {\n let h = parseInt(m[1], 10);\n const min = m[2] ? parseInt(m[2], 10) : 0;\n const meridiem = m[3].toLowerCase().replace(/\\./g, '');\n if (meridiem === 'pm' && h < 12) h += 12;\n if (meridiem === 'am' && h === 12) h = 0;\n if (h > 23 || min > 59) return null;\n return { h, m: min, matched: m[0] };\n }\n if (m[4]) {\n const h = parseInt(m[4], 10);\n const min = parseInt(m[5], 10);\n if (h > 23 || min > 59) return null;\n return { h, m: min, matched: m[0] };\n }\n return null;\n};\n\nconst findDay = (text: string): { day: number; matched: string } | null => {\n for (const [name, d] of Object.entries(DAY_NAMES)) {\n const re = new RegExp(`\\\\b${name}\\\\b`, 'i');\n const m = text.match(re);\n if (m) return { day: d, matched: m[0] };\n }\n return null;\n};\n\nconst findPartOfDay = (text: string): { h: number; matched: string } | null => {\n for (const [name, h] of Object.entries(PART_OF_DAY)) {\n const re = new RegExp(`\\\\b${name}\\\\b`, 'i');\n const m = text.match(re);\n if (m) return { h, matched: m[0] };\n }\n return null;\n};\n\nexport const parseScheduleHint = (input: string): ScheduleHint | null => {\n if (!input) return null;\n const text = input.toLowerCase();\n const hits: string[] = [];\n\n // ── 1. Recurrence keywords ──────────────────────────────────────────────\n const everyMin = text.match(/every\\s+(\\d+)\\s*(?:m|min|mins|minute|minutes)\\b/);\n if (everyMin) {\n const n = Math.max(1, Math.min(59, parseInt(everyMin[1], 10)));\n return {\n cron: `*/${n} * * * *`,\n label: `Every ${n} minute${n === 1 ? '' : 's'}`,\n confidence: 'high',\n matchedText: everyMin[0],\n };\n }\n const everyHr = text.match(/every\\s+(\\d+)\\s*(?:h|hr|hrs|hour|hours)\\b/);\n if (everyHr) {\n const n = Math.max(1, Math.min(23, parseInt(everyHr[1], 10)));\n return {\n cron: `0 */${n} * * *`,\n label: `Every ${n} hour${n === 1 ? '' : 's'}`,\n confidence: 'high',\n matchedText: everyHr[0],\n };\n }\n if (/\\bhourly\\b|\\bevery hour\\b/.test(text)) {\n return { cron: '0 * * * *', label: 'Hourly', confidence: 'high', matchedText: 'hourly' };\n }\n\n // ── 2. Time of day (explicit or part-of-day) ────────────────────────────\n const t = findTime(text);\n const part = !t ? findPartOfDay(text) : null;\n const hour = t ? t.h : part ? part.h : null;\n const minute = t ? t.m : 0;\n if (t) hits.push(t.matched);\n if (part) hits.push(part.matched);\n\n // ── 3. Day-of-week ──────────────────────────────────────────────────────\n const day = findDay(text);\n if (day) hits.push(day.matched);\n\n // ── 4. Frequency words ──────────────────────────────────────────────────\n const isDaily = /\\b(daily|every\\s+day|each\\s+day)\\b/.test(text);\n const isWeekly = /\\b(weekly|every\\s+week)\\b/.test(text);\n const isWeekdays = /\\b(weekday|weekdays|every\\s+weekday|workdays?|business\\s+days?)\\b/.test(text);\n const isMonthly = /\\b(monthly|every\\s+month)\\b/.test(text);\n const hasScheduleWord = /\\b(schedule|recurring|recur|repeat|automate|cron)\\b/.test(text);\n if (isDaily) hits.push('daily');\n if (isWeekly) hits.push('weekly');\n if (isWeekdays) hits.push('weekdays');\n if (isMonthly) hits.push('monthly');\n\n // Future word — \"next monday at 2am\" is treated as weekly Monday.\n if (/\\bnext\\b/.test(text)) hits.push('next');\n if (/\\btonight\\b/.test(text) && hour === null) {\n return { cron: '0 21 * * *', label: 'Daily at 9:00 PM (tonight)', confidence: 'medium', matchedText: 'tonight' };\n }\n if (/\\btomorrow\\b/.test(text) && hour !== null) {\n return {\n cron: `${minute} ${hour} * * *`,\n label: `Daily at ${fmtTime(hour, minute)}`,\n confidence: 'medium',\n matchedText: hits.join(' '),\n };\n }\n\n // ── 5. Build cron from collected pieces ─────────────────────────────────\n if (day && hour !== null) {\n return {\n cron: `${minute} ${hour} * * ${day.day}`,\n label: `Every ${DAY_LABEL[day.day]} at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isWeekdays && hour !== null) {\n return {\n cron: `${minute} ${hour} * * 1-5`,\n label: `Weekdays at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isMonthly && hour !== null) {\n return {\n cron: `${minute} ${hour} 1 * *`,\n label: `Monthly on the 1st at ${fmtTime(hour, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isWeekly) {\n const d = day ? day.day : 1;\n const h = hour ?? 9;\n return {\n cron: `${minute} ${h} * * ${d}`,\n label: `Every ${DAY_LABEL[d]} at ${fmtTime(h, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (isDaily || (hour !== null && (isDaily || part || hasScheduleWord || /\\bevery\\b/.test(text)))) {\n const h = hour ?? 9;\n return {\n cron: `${minute} ${h} * * *`,\n label: `Daily at ${fmtTime(h, minute)}`,\n confidence: 'high',\n matchedText: hits.join(' '),\n };\n }\n if (day) {\n return {\n cron: `0 9 * * ${day.day}`,\n label: `Every ${DAY_LABEL[day.day]} at 9:00 AM`,\n confidence: 'medium',\n matchedText: day.matched,\n };\n }\n if (hour !== null) {\n return {\n cron: `${minute} ${hour} * * *`,\n label: `Daily at ${fmtTime(hour, minute)}`,\n confidence: 'medium',\n matchedText: hits.join(' '),\n };\n }\n if (hasScheduleWord) {\n return {\n cron: '0 9 * * *',\n label: 'Schedule this prompt',\n confidence: 'low',\n matchedText: text.match(/\\b(schedule|recurring|recur|repeat|automate|cron)\\b/)?.[0] || 'schedule',\n };\n }\n return null;\n};\n","/**\n * AgentRunDiagnosisBanner — compact, dismissible \"nudge\" shown above an\n * agent run when it failed or its output looks suspicious.\n *\n * Designed to be unobtrusive: a single line with an icon, short message,\n * an optional jump-to-evidence affordance, and a dismiss (X) button that\n * permanently hides the banner for that exact execution.\n *\n * Returns `null` when the run has no failure / warning, or when the user\n * has already dismissed the banner for this execution id.\n */\n\nimport { Box, Button, IconButton, Tooltip, Typography } from '@mui/material';\nimport { AlertTriangle, ArrowUpRight, ExternalLink, HelpCircle, Settings2, X } from 'lucide-react';\nimport AgentDiagnosisCtas from './AgentDiagnosisCtas';\nimport { useEffect, useMemo, useState } from 'react';\nimport {\n diagnoseOutputWarning,\n extractDecisionIndex,\n getFailureInfo,\n hasOutputWarning,\n type DiagnosableRun,\n} from './agentDiagnosis';\n\ninterface Props {\n run: DiagnosableRun | null | undefined;\n /** Outer padding wrapper. Defaults to `{ px: 2.5, pb: 0.5 }`. */\n sx?: Record<string, unknown>;\n /** When provided, the banner becomes clickable and asks the host to jump\n * to the underlying decision (e.g. switch to the detailed timeline,\n * expand that row, scroll to it). */\n onJumpToEvidence?: (decisionIndex: number) => void;\n /** Stable id used to persist dismissals per-execution. Falls back to\n * `run.execution_id` if present. When neither is available, dismiss\n * still works for the current mount but is not persisted. */\n executionId?: string;\n}\n\nconst DISMISS_PREFIX = 'agent-diagnosis-dismissed::';\n\nconst readDismissed = (key: string | null): boolean => {\n if (!key || typeof window === 'undefined') return false;\n try {\n return window.localStorage.getItem(DISMISS_PREFIX + key) === '1';\n } catch {\n return false;\n }\n};\n\nconst writeDismissed = (key: string | null) => {\n if (!key || typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(DISMISS_PREFIX + key, '1');\n } catch {\n /* ignore */\n }\n};\n\nconst AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, executionId }: Props) => {\n const dismissKey = useMemo(() => {\n if (executionId) return executionId;\n const fromRun = (run as any)?.execution_id;\n return typeof fromRun === 'string' && fromRun ? fromRun : null;\n }, [executionId, run]);\n\n const [dismissed, setDismissed] = useState<boolean>(() => readDismissed(dismissKey));\n\n // Re-sync if the underlying execution changes.\n useEffect(() => {\n setDismissed(readDismissed(dismissKey));\n }, [dismissKey]);\n\n if (!run || dismissed) return null;\n\n const status = (run.status || '').toUpperCase();\n const isFailed = status === 'FAILED' || status === 'ABORTED';\n const failureInfo = isFailed ? getFailureInfo(run) : null;\n const outputWarning = !isFailed && hasOutputWarning(run);\n const diagnosis = outputWarning ? diagnoseOutputWarning(run) : null;\n\n if (!failureInfo && !diagnosis) return null;\n\n const isCritical = !!failureInfo;\n const tone = isCritical ? 'critical' : 'medium';\n const Icon = isCritical ? AlertTriangle : HelpCircle;\n\n const message = isCritical\n ? failureInfo!.reason\n : `${diagnosis!.title} — ${diagnosis!.remediation}`;\n\n const firstEvidence = diagnosis?.evidence?.[0] || null;\n const jumpDecisionIndex = firstEvidence ? extractDecisionIndex(firstEvidence.path) : null;\n const canJump = !!(onJumpToEvidence && jumpDecisionIndex !== null);\n\n const handleDismiss = (e: React.MouseEvent) => {\n e.stopPropagation();\n writeDismissed(dismissKey);\n setDismissed(true);\n };\n\n const handleJump = () => {\n if (canJump) onJumpToEvidence!(jumpDecisionIndex!);\n };\n\n const showTokenCtas = diagnosis?.kind === 'token_limit';\n\n return (\n <Box sx={{ px: 2.5, pb: 0.5, ...(sx || {}) }}>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 0.75,\n px: 1.25,\n py: 0.75,\n borderRadius: 2,\n bgcolor: `hsla(var(--severity-${tone}) / 0.06)`,\n border: `1px solid hsla(var(--severity-${tone}) / 0.18)`,\n }}\n >\n <Box\n {...(canJump\n ? {\n role: 'button' as const,\n tabIndex: 0,\n onClick: handleJump,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleJump();\n }\n },\n }\n : {})}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n cursor: canJump ? 'pointer' : 'default',\n borderRadius: 1,\n transition: 'background 0.15s ease',\n ...(canJump && {\n '&:hover': {\n bgcolor: `hsla(var(--severity-${tone}) / 0.08)`,\n },\n '&:focus-visible': {\n outline: 'none',\n boxShadow: `0 0 0 2px hsla(var(--severity-${tone}) / 0.25)`,\n },\n }),\n }}\n >\n <Icon\n size={13}\n style={{ color: `hsl(var(--severity-${tone}))`, flexShrink: 0 }}\n />\n <Typography\n sx={{\n flex: 1,\n minWidth: 0,\n fontSize: '0.74rem',\n color: 'hsl(var(--foreground))',\n lineHeight: 1.4,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n title={message}\n >\n {message}\n </Typography>\n {canJump && (\n <Tooltip title={`Open Decision #${(jumpDecisionIndex ?? 0) + 1} in detailed timeline`} placement=\"top\" arrow>\n <ArrowUpRight\n size={13}\n style={{ color: `hsl(var(--severity-${tone}))`, flexShrink: 0 }}\n />\n </Tooltip>\n )}\n <Tooltip title=\"Dismiss for this execution\" placement=\"top\" arrow>\n <IconButton\n size=\"small\"\n onClick={handleDismiss}\n sx={{\n p: 0.25,\n ml: 0.25,\n color: 'hsl(var(--muted-foreground))',\n '&:hover': {\n color: 'hsl(var(--foreground))',\n bgcolor: 'hsla(var(--foreground) / 0.06)',\n },\n }}\n aria-label=\"Dismiss diagnosis\"\n >\n <X size={12} />\n </IconButton>\n </Tooltip>\n </Box>\n {showTokenCtas && (\n <Box sx={{ pl: 2.5, pt: 0.25 }}>\n <AgentDiagnosisCtas diagnosis={diagnosis} tone={tone} />\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nexport default AgentRunDiagnosisBanner;\n","/**\n * Shared CTA strip rendered for an agent diagnosis.\n *\n * Used in BOTH:\n * - the inline AgentRunDiagnosisBanner shown above an agent run\n * - the tooltip inside AgentRunStatusBadge (the \"Needs attention\" pill)\n *\n * Currently only the `token_limit` diagnosis surfaces CTAs:\n * 1. Change LLM -> opens the global Agent drawer on the Local LLM tab\n * 2. Get more tokens -> opens the Shuffle support contact form\n *\n * Returns `null` when the diagnosis has no associated CTAs, so callers can\n * render it unconditionally.\n */\nimport { Box, Button, Tooltip } from '@mui/material';\nimport { ExternalLink, Settings2 } from 'lucide-react';\nimport type { OutputDiagnosis } from './agentDiagnosis';\n\ninterface Props {\n diagnosis: OutputDiagnosis | null | undefined;\n /** When true, renders compact buttons sized for a tooltip. */\n compact?: boolean;\n /** Tone that drives accent colors (matches banner tone). */\n tone?: 'critical' | 'medium';\n}\n\nconst openLocalLlmTab = (e: React.MouseEvent) => {\n e.stopPropagation();\n window.dispatchEvent(\n new CustomEvent('agent-drawer-open', { detail: { tab: 'localLLM' } }),\n );\n};\n\nconst openSupportContact = (e: React.MouseEvent) => {\n e.stopPropagation();\n window.open(\n 'https://shuffler.io/contact?category=Support',\n '_blank',\n 'noopener,noreferrer',\n );\n};\n\nexport const diagnosisHasCtas = (\n diagnosis: OutputDiagnosis | null | undefined,\n): boolean => diagnosis?.kind === 'token_limit';\n\nconst AgentDiagnosisCtas = ({ diagnosis, compact = false, tone = 'medium' }: Props) => {\n if (!diagnosisHasCtas(diagnosis)) return null;\n\n const height = compact ? 26 : 32;\n const fontSize = compact ? '0.7rem' : '0.78rem';\n const iconSize = compact ? 12 : 14;\n const px = compact ? 1 : 1.5;\n\n return (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: compact ? 0.5 : 1 }}>\n <Tooltip title=\"Configure your own LLM vendor (OpenAI-compatible endpoint)\" placement=\"top\" arrow>\n <Button\n size=\"small\"\n variant=\"contained\"\n disableElevation\n startIcon={<Settings2 size={iconSize} />}\n onClick={openLocalLlmTab}\n sx={{\n textTransform: 'none',\n fontSize,\n fontWeight: 600,\n height,\n px,\n bgcolor: `hsl(var(--severity-${tone}))`,\n color: 'hsl(var(--background))',\n '&:hover': { bgcolor: `hsla(var(--severity-${tone}) / 0.88)` },\n }}\n >\n Change LLM\n </Button>\n </Tooltip>\n <Tooltip title=\"Contact Shuffle Support to get more tokens\" placement=\"top\" arrow>\n <Button\n size=\"small\"\n variant=\"outlined\"\n endIcon={<ExternalLink size={iconSize} />}\n onClick={openSupportContact}\n sx={{\n textTransform: 'none',\n fontSize,\n fontWeight: 600,\n height,\n px,\n borderColor: `hsla(var(--severity-${tone}) / 0.5)`,\n color: 'hsl(var(--foreground))',\n '&:hover': {\n borderColor: `hsl(var(--severity-${tone}))`,\n bgcolor: `hsla(var(--severity-${tone}) / 0.08)`,\n },\n }}\n >\n Get more tokens\n </Button>\n </Tooltip>\n </Box>\n );\n};\n\nexport default AgentDiagnosisCtas;\n","/**\n * Shared diagnosis utilities for an agent execution result.\n *\n * Lives in the Shuffle-MCPs lib so every surface that displays an agent run\n * (AgentUI Simple/Detailed view, AgentExecutionDrawer, the incident-side\n * AgentRunResultViewer, the activity feed status pill, ...) uses the EXACT\n * same logic to decide whether the run \"needs review\" and what to tell the\n * user about it.\n *\n * Pure logic — no React, no MUI, no project-side imports.\n */\n\n/** Minimal run shape the diagnoser needs. Compatible with AgentRun and\n * AgentUI's internal ExecutionData. */\nexport interface DiagnosableRun {\n status?: string;\n result?: string;\n results?: Array<{ result?: string } | any> | null;\n}\n\n// ---------------------------------------------------------------------------\n// JSON parsing helpers\n// ---------------------------------------------------------------------------\n\nconst deepParseJsonStrings = (obj: any, depth = 0): any => {\n if (depth > 5) return obj;\n if (typeof obj === 'string') {\n const trimmed = obj.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']')) ||\n (trimmed.startsWith('\"') && trimmed.endsWith('\"'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null) {\n return deepParseJsonStrings(parsed, depth + 1);\n }\n return parsed;\n } catch {\n return obj;\n }\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));\n if (obj && typeof obj === 'object') {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deepParseJsonStrings(value, depth + 1);\n }\n return result;\n }\n return obj;\n};\n\nconst pickResultPayload = (run: DiagnosableRun): string | null => {\n const results = Array.isArray(run.results) ? run.results : [];\n const agentResult = results.find((r: any) => {\n const appName = String(r?.action?.app_name || r?.action?.label || '').toLowerCase();\n const appId = String(r?.action?.app_id || '').toLowerCase();\n return appId === 'shuffle_agent' || appName.includes('ai agent');\n });\n const payload = agentResult?.result || results.find((r: any) => typeof r?.result === 'string' && r.result.trim())?.result || (run as any).result;\n if (typeof payload === 'string') return payload;\n if (payload && typeof payload === 'object') {\n try { return JSON.stringify(payload); } catch { return null; }\n }\n return null;\n};\n\n/** Try to parse the agent result JSON, unwrapping AGENT-type executions. */\nexport const parseRunResult = (\n run: DiagnosableRun\n): { raw: string | null; parsed: any | null } => {\n const firstResult = pickResultPayload(run);\n if (!firstResult) {\n const directPayload = run as any;\n if (\n directPayload &&\n typeof directPayload === 'object' &&\n (Array.isArray(directPayload.decisions) || directPayload.decision_string !== undefined)\n ) {\n const deepParsed = deepParseJsonStrings(directPayload);\n let raw: string | null = null;\n try {\n raw = JSON.stringify(deepParsed);\n } catch {\n raw = '[agent run data]';\n }\n return { raw, parsed: deepParsed };\n }\n return { raw: null, parsed: null };\n }\n\n try {\n let parsed = JSON.parse(firstResult);\n if (\n parsed &&\n typeof parsed === 'object' &&\n parsed.type === 'AGENT' &&\n Array.isArray(parsed.results) &&\n parsed.results.length > 0\n ) {\n const innerResult = parsed.results[0]?.result;\n if (innerResult) {\n try {\n parsed = JSON.parse(innerResult);\n } catch {\n return { raw: innerResult, parsed: null };\n }\n }\n }\n const deepParsed = deepParseJsonStrings(parsed);\n return { raw: firstResult, parsed: deepParsed };\n } catch {\n return { raw: firstResult, parsed: null };\n }\n};\n\n/** Extract failure info from a failed/aborted run. */\nexport const getFailureInfo = (run: DiagnosableRun): { reason: string } | null => {\n const status = run.status?.toUpperCase();\n if (status !== 'FAILED' && status !== 'ABORTED') return null;\n\n const { parsed } = parseRunResult(run);\n if (parsed && typeof parsed === 'object') {\n if (parsed.success === false && parsed.reason) return { reason: parsed.reason };\n if (parsed.message) return { reason: parsed.message };\n if (parsed.error)\n return { reason: typeof parsed.error === 'string' ? parsed.error : JSON.stringify(parsed.error) };\n }\n return null;\n};\n\n/**\n * Restrict the search to the agent's own decision records and final\n * `decision_string`. Walking the full result picks up keywords from the\n * system prompt and produces false-positive \"Auth Failure\" diagnoses.\n */\nconst getDiagnosableScope = (parsed: any): unknown => {\n if (!parsed || typeof parsed !== 'object') return null;\n const scope: Record<string, unknown> = {};\n if (Array.isArray(parsed.decisions)) {\n // Keep positional alignment with parsed.decisions[N] so an evidence\n // path like `run_details[N]...` maps directly back to the Nth\n // decision in the agent's timeline. Decisions without run_details\n // are kept as `null` placeholders (the walker skips nulls).\n const runDetails = parsed.decisions.map((d: any) =>\n d && typeof d === 'object' && d.run_details ? d.run_details : null\n );\n if (runDetails.some((rd: unknown) => rd !== null)) scope.run_details = runDetails;\n const finalDecisions = parsed.decisions.map((d: any) => {\n if (!d || typeof d !== 'object') return null;\n const action = String(d.action || d.details?.action || '').toLowerCase();\n const category = String(d.category || '').toLowerCase();\n if (!['finish', 'finalise'].includes(action) && !['finish', 'finalise'].includes(category)) return null;\n return {\n reason: d.reason,\n fields: Array.isArray(d.fields) ? d.fields.map((f: any) => f?.value).filter(Boolean) : undefined,\n };\n });\n if (finalDecisions.some((d: unknown) => d !== null)) scope.decisions = finalDecisions;\n }\n if (parsed.decision_string !== undefined) scope.decision_string = parsed.decision_string;\n return Object.keys(scope).length > 0 ? scope : null;\n};\n\n/** Extract the originating decision index (in parsed.decisions / agentData.decisions)\n * from a diagnosis evidence path like `run_details[3].result.error`.\n * Returns null if the path does not start at a decision row. */\nexport const extractDecisionIndex = (path: string | undefined | null): number | null => {\n if (!path) return null;\n const m = /^(?:run_details|decisions)\\[(\\d+)\\]/.exec(path);\n if (!m) return null;\n const n = Number(m[1]);\n return Number.isFinite(n) ? n : null;\n};\n\n/** Detect if the output content hints at an error/failure even if the run\n * status is \"finished\". Only returns true when `diagnoseOutputWarning`\n * would produce a concrete, actionable diagnosis — never on vague keyword\n * matches alone. */\nexport const hasOutputWarning = (run: DiagnosableRun): boolean => {\n return diagnoseOutputWarning(run) !== null;\n};\n\n// ---------------------------------------------------------------------------\n// Diagnosis\n// ---------------------------------------------------------------------------\n\nexport type DiagnosisEvidence = {\n /** Dotted JSON path inside the parsed run result. */\n path: string;\n /** Trimmed snippet of the value at that path. */\n value: string;\n};\n\nexport type OutputDiagnosis = {\n kind: 'auth' | 'permission' | 'not_found' | 'rate_limit' | 'token_limit' | 'network' | 'validation' | 'generic';\n status?: number;\n title: string;\n explanation: string;\n remediation: string;\n snippet?: string;\n evidence: DiagnosisEvidence[];\n};\n\ntype ResultEntry = { path: string; value: string };\n\nconst collectEntries = (root: unknown): ResultEntry[] => {\n const out: ResultEntry[] = [];\n const walk = (v: unknown, path: string, depth: number): void => {\n if (depth > 8 || v == null) return;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n out.push({ path, value: String(v) });\n return;\n }\n if (Array.isArray(v)) {\n v.forEach((item, i) => walk(item, `${path}[${i}]`, depth + 1));\n return;\n }\n if (typeof v === 'object') {\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n const next = path ? `${path}.${k}` : k;\n walk(val, next, depth + 1);\n }\n }\n };\n walk(root, '', 0);\n return out;\n};\n\nconst trimEvidenceValue = (v: string, max = 180): string => {\n const cleaned = v.replace(/\\s+/g, ' ').trim();\n return cleaned.length <= max ? cleaned : `${cleaned.slice(0, max).trim()}…`;\n};\n\nconst TOKEN_LIMIT_PATTERN = /\\b(ai[_\\s-]*token[_\\s-]*limit|token[_\\s-]*limit|limit[_\\s-]*is[_\\s-]*reached|limit[_\\s-]*reached|context[_\\s-]*limit|maximum[_\\s-]*context|context[_\\s-]*length|too[_\\s-]*many[_\\s-]*tokens|exceeds?[_\\s-]*(the[_\\s-]*)?(token|context))\\b/;\n\nexport const diagnoseOutputWarning = (run: DiagnosableRun): OutputDiagnosis | null => {\n const { parsed, raw } = parseRunResult(run);\n\n // Token-limit detection runs FIRST and against the FULL payload (raw +\n // parsed), not the narrow decision-only scope. The \"AI Token limit\n // reached\" message is unambiguous and can appear in any field —\n // top-level reason, message, error, or even a wrapping AGENT result —\n // so we must not miss it just because the scope walker excluded it.\n const tokenLimitHaystack = (() => {\n let s = raw || '';\n if (parsed && typeof parsed === 'object') {\n try { s += '\\n' + JSON.stringify(parsed); } catch { /* ignore */ }\n }\n return s.toLowerCase();\n })();\n if (TOKEN_LIMIT_PATTERN.test(tokenLimitHaystack)) {\n const evidenceValue = raw ? trimEvidenceValue(raw) : 'AI token limit reached';\n return {\n kind: 'token_limit',\n title: 'AI token limit reached',\n explanation:\n 'The agent stopped because the prompt, context, and generated output exceeded the configured AI token limit.',\n remediation:\n 'Reduce the input size or connected context and re-run, or connect an API vendor/self-hosted model with a higher limit.',\n snippet: evidenceValue,\n evidence: [{ path: '(root)', value: evidenceValue }],\n };\n }\n\n if (!parsed || typeof parsed !== 'object') return null;\n\n const scope = getDiagnosableScope(parsed);\n if (!scope) return null;\n\n const entries = collectEntries(scope);\n if (raw && entries.length === 0) entries.push({ path: '', value: raw });\n\n const haystack = entries.map((e) => e.value).join('\\n');\n const lower = haystack.toLowerCase();\n\n const findEvidence = (\n test: (lowerVal: string, val: string) => boolean,\n max = 3\n ): DiagnosisEvidence[] => {\n const out: DiagnosisEvidence[] = [];\n for (const e of entries) {\n if (test(e.value.toLowerCase(), e.value)) {\n out.push({ path: e.path || '(root)', value: trimEvidenceValue(e.value) });\n if (out.length >= max) break;\n }\n }\n return out;\n };\n const findEvidenceByRegex = (re: RegExp, max = 3): DiagnosisEvidence[] =>\n findEvidence((l) => re.test(l), max);\n const findEvidenceByKeywords = (needles: string[], max = 3): DiagnosisEvidence[] =>\n findEvidence((l) => needles.some((n) => l.includes(n.toLowerCase())), max);\n\n let status: number | undefined;\n let statusEvidence: DiagnosisEvidence | null = null;\n const statusPatterns = [\n /\\bhttp[\\s/]?(\\d{3})\\b/i,\n /\\bstatus[\\s:_-]+(\\d{3})\\b/i,\n /\\bstatus[_\\s-]?code[\"\\s:]+(\\d{3})\\b/i,\n /\\bcode[\"\\s:]+(\\d{3})\\b/i,\n /\\[(\\d{3})\\]/,\n /\\((\\d{3})\\)/,\n /\\b(4\\d{2}|5\\d{2})\\b/,\n ];\n outer: for (const re of statusPatterns) {\n for (const e of entries) {\n const m = e.value.match(re);\n if (m) {\n const n = Number(m[1]);\n if (n >= 400 && n < 600) {\n status = n;\n statusEvidence = { path: e.path || '(root)', value: trimEvidenceValue(e.value) };\n break outer;\n }\n }\n }\n }\n\n const findSnippet = (needles: string[]): string | undefined => {\n for (const needle of needles) {\n const i = lower.indexOf(needle);\n if (i >= 0) {\n const start = Math.max(0, i - 40);\n const end = Math.min(haystack.length, i + 160);\n return (\n (start > 0 ? '…' : '') +\n haystack.slice(start, end).trim() +\n (end < haystack.length ? '…' : '')\n );\n }\n }\n return undefined;\n };\n\n const withStatusEvidence = (ev: DiagnosisEvidence[]): DiagnosisEvidence[] => {\n if (!statusEvidence) return ev;\n const dedup = ev.filter((e) => e.path !== statusEvidence!.path);\n return [statusEvidence, ...dedup].slice(0, 3);\n };\n\n if (\n status === 401 ||\n /\\b(unauthori[sz]ed|invalid[_\\s-]*(api[_\\s-]*key|token|credentials?)|authentication[_\\s-]*(failed|required)|missing[_\\s-]*(api[_\\s-]*key|token|authorization)|bearer[_\\s-]*token|expired[_\\s-]*token)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /unauthori[sz]ed|invalid[_\\s-]*(api[_\\s-]*key|token|credentials?)|authentication[_\\s-]*(failed|required)|missing[_\\s-]*(api[_\\s-]*key|token|authorization)|bearer[_\\s-]*token|expired[_\\s-]*token|\\b401\\b/\n );\n return {\n kind: 'auth',\n status,\n title: status === 401 ? 'Authentication failed (HTTP 401)' : 'Authentication failed',\n explanation:\n 'The upstream service rejected the request because the credentials were missing, invalid, or expired.',\n remediation:\n 'Open the integration in Apps → Authentication, reconnect or paste a fresh API key/token, then re-run the action.',\n snippet: findSnippet(['401', 'unauthorized', 'invalid api', 'invalid token', 'authentication']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 403 ||\n /\\b(forbidden|permission[_\\s-]*denied|not[_\\s-]*allowed|access[_\\s-]*denied|insufficient[_\\s-]*(scope|permission|privileges?)|missing[_\\s-]*scope)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /forbidden|permission[_\\s-]*denied|not[_\\s-]*allowed|access[_\\s-]*denied|insufficient[_\\s-]*(scope|permission|privileges?)|missing[_\\s-]*scope|\\b403\\b/\n );\n return {\n kind: 'permission',\n status,\n title: status === 403 ? 'Permission denied (HTTP 403)' : 'Permission denied',\n explanation:\n 'The credentials are valid, but the connected account does not have permission (or scope) to perform this action.',\n remediation:\n 'Re-authenticate the integration with the missing scope, or grant the connected account permission for this resource in the source app.',\n snippet: findSnippet(['403', 'forbidden', 'permission', 'scope', 'access denied']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 429 ||\n /\\b(rate[_\\s-]*limit|too[_\\s-]*many[_\\s-]*requests|quota[_\\s-]*exceeded|throttled)\\b/.test(lower)\n ) {\n const ev = findEvidenceByRegex(\n /rate[_\\s-]*limit|too[_\\s-]*many[_\\s-]*requests|quota[_\\s-]*exceeded|throttled|\\b429\\b/\n );\n return {\n kind: 'rate_limit',\n status,\n title: status === 429 ? 'Rate limited (HTTP 429)' : 'Rate limited',\n explanation: 'The upstream service is throttling requests from this integration.',\n remediation:\n \"Wait a minute and re-run, or reduce how often this action fires. Check the integration's rate-limit settings if the problem keeps happening.\",\n snippet: findSnippet(['429', 'rate limit', 'too many', 'quota', 'throttled']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n // Token-limit is detected at the top of this function (full-payload scan).\n\n if (\n status === 404 ||\n /\\b(not[_\\s-]*found|no such|does not exist|unknown[_\\s-]*(id|resource))\\b/.test(lower)\n ) {\n const ev = findEvidenceByRegex(\n /not[_\\s-]*found|no such|does not exist|unknown[_\\s-]*(id|resource)|\\b404\\b/\n );\n return {\n kind: 'not_found',\n status,\n title: status === 404 ? 'Resource not found (HTTP 404)' : 'Resource not found',\n explanation:\n 'The action ran, but the target resource (record, ticket, channel, file) could not be located.',\n remediation:\n 'Verify the ID or path the agent used is correct, and that the connected account can see that resource.',\n snippet: findSnippet(['404', 'not found', 'no such', 'does not exist']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n status === 400 ||\n status === 422 ||\n /\\b(bad[_\\s-]*request|validation[_\\s-]*(error|failed)|invalid[_\\s-]*(parameter|field|argument|body|payload))\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /bad[_\\s-]*request|validation[_\\s-]*(error|failed)|invalid[_\\s-]*(parameter|field|argument|body|payload)|\\b400\\b|\\b422\\b/\n );\n return {\n kind: 'validation',\n status,\n title: status ? `Invalid request (HTTP ${status})` : 'Invalid request',\n explanation:\n 'The upstream service rejected the request because the parameters were missing or malformed.',\n remediation:\n \"Check the action's required fields and the values the agent sent. The Debug section below shows the exact payload.\",\n snippet: findSnippet(['400', '422', 'bad request', 'validation', 'invalid']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n if (\n (typeof status === 'number' && status >= 500) ||\n /\\b(timeout|timed[_\\s-]*out|econnrefused|enotfound|network[_\\s-]*error|connection[_\\s-]*(refused|reset|closed)|service[_\\s-]*unavailable|bad[_\\s-]*gateway|gateway[_\\s-]*timeout)\\b/.test(\n lower\n )\n ) {\n const ev = findEvidenceByRegex(\n /timeout|timed[_\\s-]*out|econnrefused|enotfound|network[_\\s-]*error|connection[_\\s-]*(refused|reset|closed)|service[_\\s-]*unavailable|bad[_\\s-]*gateway|gateway[_\\s-]*timeout|\\b5\\d{2}\\b/\n );\n return {\n kind: 'network',\n status,\n title: status ? `Upstream error (HTTP ${status})` : 'Network or upstream error',\n explanation:\n 'The integration could not reach the upstream service, or the service returned a server error.',\n remediation:\n \"Re-run the action shortly. If it keeps failing, check the upstream service's status page and the integration's base URL.\",\n snippet: findSnippet(['500', '502', '503', '504', 'timeout', 'timed out', 'unavailable']),\n evidence: withStatusEvidence(ev),\n };\n }\n\n const namedFields: Array<keyof typeof parsed & string> = ['reason', 'error', 'message'];\n let namedReason: string | undefined;\n let namedEvidence: DiagnosisEvidence | null = null;\n for (const k of namedFields) {\n const v = (parsed as Record<string, unknown>)[k];\n if (typeof v === 'string' && v.trim()) {\n namedReason = v;\n namedEvidence = { path: k, value: trimEvidenceValue(v) };\n break;\n }\n }\n\n if ((parsed as { success?: unknown }).success === false || namedReason) {\n const ev: DiagnosisEvidence[] = [];\n if (namedEvidence) ev.push(namedEvidence);\n if ((parsed as { success?: unknown }).success === false) {\n ev.push({ path: 'success', value: 'false' });\n }\n return {\n kind: 'generic',\n status,\n title: status ? `Action failed (HTTP ${status})` : 'Action failed',\n explanation:\n namedReason || 'The action returned a failure but did not include a recognizable error code.',\n remediation: 'Open the Debug section below to see the full response from the integration.',\n snippet: namedReason,\n evidence: withStatusEvidence(ev).slice(0, 3),\n };\n }\n\n // No specific signal found — do NOT surface a generic \"may need review\"\n // banner. It is too vague to be actionable and just adds noise.\n return null;\n};\n","/**\n * AgentRunDrawer — standalone right-side drawer that hosts the canonical\n * `AgentUI` \"Run Agent\" experience plus optional caller-provided slots for\n * Permissions and Local LLM tabs.\n *\n * Replaces the project-only `AgentPermissionsDrawer`. It has zero\n * dependencies on host-app contexts (no react-router, no AuthContext, no\n * project services), so it works when the library is consumed standalone\n * via npm — pass `apiKey` / `apiBaseUrl` / `orgId` to authenticate the\n * embedded `AgentUI`.\n *\n * Design:\n * - Tabs: Run (always), Permissions (if `permissionsSlot`), Local LLM\n * (if `localLLMSlot`). When neither slot is provided, the tab strip is\n * hidden and the drawer shows only the AgentUI.\n * - All colors use HSL tokens so themes flow through. Falls back to\n * reasonable inline values when tokens are missing.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Drawer,\n IconButton,\n Tab,\n Tabs,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport {\n Play,\n Server,\n ShieldCheck,\n X as CloseIcon\n} from 'lucide-react';\n\nimport AgentIcon from './AgentIcon';\nimport AgentUI, { type AgentUIProps } from './AgentUI';\n\nexport type AgentRunDrawerTab = 'run' | 'permissions' | 'localLLM';\n\nexport interface AgentRunDrawerProps {\n open: boolean;\n onClose: () => void;\n /** Which tab to focus when the drawer opens. Default: 'run'. */\n initialTab?: AgentRunDrawerTab;\n /** Render content for the Permissions tab. Tab is hidden when omitted. */\n permissionsSlot?: React.ReactNode;\n /** Render content for the Local LLM tab. Tab is hidden when omitted. */\n localLLMSlot?: React.ReactNode;\n /**\n * Custom badge node next to the Local LLM tab label (e.g. a green check\n * when OpenAI auth is detected). Optional.\n */\n localLLMTabBadge?: React.ReactNode;\n /** Tooltip shown when the Permissions tab is rendered but disabled. */\n permissionsDisabled?: boolean;\n permissionsDisabledTooltip?: string;\n /** Forwarded to the embedded AgentUI (apiKey, apiBaseUrl, orgId, etc.). */\n agentUIProps?: Partial<AgentUIProps>;\n /** Drawer width override (default: 480 px on >=sm, full-width on xs). */\n width?: number;\n /** Header title. Default: \"Agent\". */\n title?: string;\n /** Header subtitle. Default: \"Run actions and manage permissions\". */\n subtitle?: string;\n /** Optional className forwarded to the Drawer Paper. */\n className?: string;\n /** Style overrides merged into the Drawer Paper sx. Use to override colors, padding, etc. */\n paperSx?: SxProps<Theme>;\n /** Style overrides for the header bar (icon + title + close). */\n headerSx?: SxProps<Theme>;\n /** Style overrides for the tab strip. */\n tabsSx?: SxProps<Theme>;\n /** Style overrides for the body container that wraps the active tab content. */\n bodySx?: SxProps<Theme>;\n}\n\nconst TAB_ORDER: AgentRunDrawerTab[] = ['run', 'permissions', 'localLLM'];\n\nconst AgentRunDrawer = ({\n open,\n onClose,\n initialTab = 'run',\n permissionsSlot,\n localLLMSlot,\n localLLMTabBadge,\n permissionsDisabled = false,\n permissionsDisabledTooltip = 'Coming soon',\n agentUIProps,\n width = 520,\n title = 'Agent',\n subtitle = 'Run actions and manage permissions',\n className,\n paperSx,\n headerSx,\n tabsSx,\n bodySx,\n}: AgentRunDrawerProps) => {\n const [activeTab, setActiveTab] = useState<AgentRunDrawerTab>(initialTab);\n\n // Reset tab whenever the drawer transitions from closed -> open so each\n // open honors the caller's initialTab (matches the legacy behavior).\n const prevOpenRef = useRef(open);\n useEffect(() => {\n if (open && !prevOpenRef.current) setActiveTab(initialTab);\n prevOpenRef.current = open;\n }, [open, initialTab]);\n\n const visibleTabs = TAB_ORDER.filter((t) => {\n if (t === 'run') return true;\n if (t === 'permissions') return !!permissionsSlot;\n if (t === 'localLLM') return !!localLLMSlot;\n return false;\n });\n const showTabs = visibleTabs.length > 1;\n\n // If the requested tab isn't visible, fall back to the first visible one.\n const safeActiveTab: AgentRunDrawerTab = visibleTabs.includes(activeTab)\n ? activeTab\n : 'run';\n\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n slotProps={{\n paper: {\n className,\n sx: [\n {\n width: { xs: '100%', sm: width },\n background: 'linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)',\n borderLeft: '1px solid hsl(var(--border))',\n boxShadow: '-8px 0 32px hsla(0, 0%, 0%, 0.4)',\n display: 'flex',\n flexDirection: 'column',\n },\n ...(Array.isArray(paperSx) ? paperSx : paperSx ? [paperSx] : []),\n ],\n },\n }}\n >\n {/* Header */}\n <Box\n sx={[\n {\n px: 3,\n py: 2.5,\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n borderBottom: '1px solid hsl(var(--border))',\n flexShrink: 0,\n },\n ...(Array.isArray(headerSx) ? headerSx : headerSx ? [headerSx] : []),\n ]}\n >\n <Box\n sx={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsla(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n flexShrink: 0,\n }}\n >\n <AgentIcon size={22} />\n </Box>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontWeight: 600, fontSize: '1.1rem', color: 'hsl(var(--foreground))' }}>\n {title}\n </Typography>\n <Typography sx={{ fontSize: '0.8rem', color: 'hsl(var(--muted-foreground))' }}>\n {subtitle}\n </Typography>\n </Box>\n <IconButton onClick={onClose} size=\"small\" sx={{ color: 'hsl(var(--muted-foreground))' }}>\n <CloseIcon size={16} />\n </IconButton>\n </Box>\n\n {/* Tabs (hidden when only Run is available) */}\n {showTabs && (\n <Box sx={{ borderBottom: '1px solid hsl(var(--border))', flexShrink: 0 }}>\n <Tabs\n value={safeActiveTab}\n onChange={(_, v) => setActiveTab(v as AgentRunDrawerTab)}\n sx={[\n {\n minHeight: 42,\n px: 3,\n '& .MuiTab-root': {\n minHeight: 42,\n textTransform: 'none',\n fontSize: '0.85rem',\n fontWeight: 500,\n color: 'hsl(var(--muted-foreground))',\n '&.Mui-selected': { color: 'hsl(var(--primary))' },\n },\n '& .MuiTabs-indicator': { bgcolor: 'hsl(var(--primary))' },\n },\n ...(Array.isArray(tabsSx) ? tabsSx : tabsSx ? [tabsSx] : []),\n ]}\n >\n {visibleTabs.includes('run') && (\n <Tab\n value=\"run\"\n label=\"Run\"\n icon={<Play size={14} />}\n iconPosition=\"start\"\n sx={{ gap: 0.75 }}\n />\n )}\n {visibleTabs.includes('permissions') && (\n <Tab\n value=\"permissions\"\n label={\n permissionsDisabled ? (\n <Tooltip title={permissionsDisabledTooltip} arrow>\n <Box component=\"span\" sx={{ display: 'inline-flex', alignItems: 'center' }}>\n Permissions\n </Box>\n </Tooltip>\n ) : (\n 'Permissions'\n )\n }\n icon={<ShieldCheck size={14} />}\n iconPosition=\"start\"\n disabled={permissionsDisabled}\n sx={{ gap: 0.75 }}\n />\n )}\n {visibleTabs.includes('localLLM') && (\n <Tab\n value=\"localLLM\"\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n Local LLM\n {localLLMTabBadge}\n </Box>\n }\n icon={<Server size={14} />}\n iconPosition=\"start\"\n sx={{ gap: 0.75 }}\n />\n )}\n </Tabs>\n </Box>\n )}\n\n {/* Body */}\n <Box sx={[{ flex: 1, overflowY: 'auto' }, ...(Array.isArray(bodySx) ? bodySx : bodySx ? [bodySx] : [])]}>\n {safeActiveTab === 'run' && (\n <Box sx={{ px: 2, py: 2 }}>\n <AgentUI\n compact\n hideHeroIcon\n title=\"\"\n subtitle={null}\n {...agentUIProps}\n />\n </Box>\n )}\n {safeActiveTab === 'permissions' && permissionsSlot && (\n <Box sx={{ px: 3, py: 2.5 }}>{permissionsSlot}</Box>\n )}\n {safeActiveTab === 'localLLM' && localLLMSlot && (\n <Box sx={{ px: 3, py: 2.5 }}>{localLLMSlot}</Box>\n )}\n </Box>\n </Drawer>\n );\n};\n\nexport default AgentRunDrawer;\n","/**\n * AgentActivityList — standalone list of agent workflow executions.\n *\n * Self-contained: no project hooks, contexts, or services. Pass\n * `apiKey` / `apiBaseUrl` / `orgId` to authenticate against any Shuffle\n * backend. `onRunClick(run)` is called when a row is clicked — the\n * consumer decides what happens next (typically: open AgentExecutionDrawer).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n InputAdornment,\n MenuItem,\n Select,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport {\n Activity,\n AlertCircle,\n CheckCircle,\n Clock,\n FileText,\n Globe,\n Loader2,\n Server,\n XCircle,\n Zap,\n Search as SearchIcon\n} from 'lucide-react';\n\nimport {\n searchAgentActivity,\n listAgentScheduleWorkflows,\n getAgentScheduleConfig,\n stopAgentSchedule,\n type AgentRun,\n type AgentScheduleWorkflow,\n} from './agentActivity';\nimport { diagnoseOutputWarning } from './agentDiagnosis';\nimport { Pencil, StopCircle, AlertTriangle } from 'lucide-react';\nimport { SegmentedControl } from './SegmentedControl';\n\n// ── Status / icon helpers ────────────────────────────────────────────────────\n\nconst STATUS_CONFIG: Record<\n string,\n { icon: React.ReactNode; color: string; label: string }\n> = {\n FINISHED: { icon: <CheckCircle size={16} />, color: 'hsl(var(--severity-low, 142 71% 45%))', label: 'Completed' },\n SUCCESS: { icon: <CheckCircle size={16} />, color: 'hsl(var(--severity-low, 142 71% 45%))', label: 'Completed' },\n FAILED: { icon: <XCircle size={16} />, color: 'hsl(var(--severity-critical, 0 72% 55%))', label: 'Failed' },\n ABORTED: { icon: <XCircle size={16} />, color: 'hsl(var(--severity-critical, 0 72% 55%))', label: 'Aborted' },\n EXECUTING: { icon: <Loader2 size={16} />, color: 'hsl(var(--severity-medium, 38 92% 50%))', label: 'Running' },\n RUNNING: { icon: <Loader2 size={16} />, color: 'hsl(var(--severity-medium, 38 92% 50%))', label: 'Running' },\n WAITING: { icon: <Clock size={16} />, color: 'hsl(var(--severity-info, 217 91% 60%))', label: 'Waiting' },\n LIMIT_REACHED: { icon: <AlertTriangle size={16} />, color: 'hsl(var(--severity-medium, 38 92% 50%))', label: 'Limit reached' },\n};\n\n/** Returns a synthetic \"LIMIT_REACHED\" status when the run finished but its\n * output indicates an AI token-limit hit. Otherwise returns the raw status. */\nconst getEffectiveStatus = (run: AgentRun): string => {\n const raw = (run.status || '').toUpperCase();\n if (raw === 'FINISHED' || raw === 'SUCCESS' || raw === 'FAILED' || raw === 'ABORTED') {\n try {\n const d = diagnoseOutputWarning(run as any);\n if (d?.kind === 'token_limit') return 'LIMIT_REACHED';\n } catch {\n // ignore\n }\n }\n return raw;\n};\n\nconst getRunIcon = (run: AgentRun): React.ReactNode => {\n const src = (run.execution_source || '').toLowerCase();\n const arg = (run.execution_argument || '').toLowerCase();\n if (src.includes('schedule') || src.includes('cron')) return <Clock size={18} />;\n if (src.includes('webhook') || src.includes('http')) return <Globe size={18} />;\n if (arg.includes('alert') || arg.includes('detect')) return <Activity size={18} />;\n if (arg.includes('report') || arg.includes('email')) return <FileText size={18} />;\n if (arg.includes('endpoint') || arg.includes('server')) return <Server size={18} />;\n return <Zap size={18} />;\n};\n\nconst getRunIconColor = (run: AgentRun): string => {\n const status = getEffectiveStatus(run);\n if (status === 'FINISHED' || status === 'SUCCESS') return 'hsl(var(--severity-low, 142 71% 45%))';\n if (status === 'FAILED' || status === 'ABORTED') return 'hsl(var(--severity-critical, 0 72% 55%))';\n if (status === 'LIMIT_REACHED') return 'hsl(var(--severity-medium, 38 92% 50%))';\n if (status === 'EXECUTING' || status === 'RUNNING') return 'hsl(var(--severity-medium, 38 92% 50%))';\n return 'hsl(var(--primary, 24 100% 50%))';\n};\n\nconst formatDuration = (run: AgentRun): string => {\n if (run.started_at && run.completed_at) {\n const start = Number(run.started_at);\n const end = Number(run.completed_at);\n if (!isNaN(start) && !isNaN(end)) {\n // Backend may return Unix milliseconds or seconds. Normalize to ms\n // while preserving sub-second precision.\n const toMs = (n: number) => (n > 1e12 ? n : n * 1000);\n const ms = Math.max(0, toMs(end) - toMs(start));\n if (ms < 1000) return `${(ms / 1000).toFixed(2)}s`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n }\n }\n if (run.duration) return `${run.duration.toFixed(2)}s`;\n return '';\n};\n\nconst getTimeAgo = (dateStr: string): string => {\n try {\n const ts = isNaN(Number(dateStr)) ? new Date(dateStr).getTime() : Number(dateStr) * 1000;\n if (isNaN(ts)) return dateStr;\n const diffSec = Math.max(0, Math.floor((Date.now() - ts) / 1000));\n if (diffSec < 60) return `${diffSec}s ago`;\n if (diffSec < 3600) return `${Math.floor(diffSec / 60)}m ago`;\n if (diffSec < 86400) return `${Math.floor(diffSec / 3600)}h ago`;\n return `${Math.floor(diffSec / 86400)}d ago`;\n } catch {\n return dateStr;\n }\n};\n\nconst getRunTitle = (run: AgentRun): string => {\n if (run.workflow?.name) return run.workflow.name;\n if (run.execution_argument) {\n try {\n const parsed = JSON.parse(run.execution_argument);\n if (parsed.title) return parsed.title;\n if (parsed.action) return parsed.action;\n if (parsed.name) return parsed.name;\n } catch {\n const clean = run.execution_argument.replace(/[{}\"]/g, '').trim();\n if (clean.length > 0 && clean.length < 80) return clean;\n }\n }\n return `Execution ${run.execution_id?.slice(0, 8) || '—'}`;\n};\n\nconst getRunSubtitle = (run: AgentRun): string => {\n if (run.result) {\n try {\n const p = JSON.parse(run.result);\n if (p.output && typeof p.output === 'string') {\n return p.output.length > 120 ? p.output.slice(0, 120) + '…' : p.output;\n }\n if (p.original_input && typeof p.original_input === 'string') {\n return p.original_input.length > 120 ? p.original_input.slice(0, 120) + '…' : p.original_input;\n }\n if (p.message && typeof p.message === 'string') return p.message;\n } catch {\n if (run.result.length < 120) return run.result;\n }\n }\n return run.execution_source || 'Agent execution';\n};\n\n// ── Run row ──────────────────────────────────────────────────────────────────\n\n/** Extract distinct tools/apps used in this run from results + decisions. */\nconst getRunTools = (run: AgentRun): string[] => {\n const out = new Set<string>();\n const add = (v?: string) => {\n if (!v) return;\n const s = String(v).trim();\n if (!s) return;\n // Skip the agent itself.\n if (/^(ai\\s*agent|shuffle\\s*agent|shuffle_agent)$/i.test(s)) return;\n out.add(s);\n };\n (run.results || []).forEach((r) => {\n add(r?.action?.app_name);\n if (!r?.action?.app_name) add(r?.action?.label);\n });\n (run.decisions || []).forEach((d) => {\n add(typeof d?.tool === 'string' ? d.tool : undefined);\n });\n return Array.from(out).slice(0, 6);\n};\n\ninterface RunRowProps {\n run: AgentRun;\n onClick: () => void;\n sx?: SxProps<Theme>;\n}\n\nconst AgentRunRow = ({ run, onClick, sx }: RunRowProps) => {\n const statusKey = getEffectiveStatus(run);\n const cfg = STATUS_CONFIG[statusKey] || STATUS_CONFIG.WAITING;\n const iconColor = getRunIconColor(run);\n const duration = formatDuration(run);\n const tools = getRunTools(run);\n\n return (\n <Box\n onClick={onClick}\n sx={[\n {\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n px: 2.5,\n py: 2,\n cursor: 'pointer',\n transition: 'background 0.15s ease, border-color 0.15s ease',\n '&:hover': {\n bgcolor: 'hsla(var(--muted) / 0.5)',\n borderColor: 'hsl(var(--muted-foreground) / 0.3)',\n },\n },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n >\n <Box\n sx={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: `${iconColor}15`,\n color: iconColor,\n flexShrink: 0,\n }}\n >\n {getRunIcon(run)}\n </Box>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.25 }}>\n <Typography\n sx={{\n fontSize: '0.9rem',\n fontWeight: 500,\n color: 'hsl(var(--foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {getRunTitle(run)}\n </Typography>\n <Box sx={{ display: 'flex', alignItems: 'center', color: cfg.color, flexShrink: 0 }}>\n {cfg.icon}\n </Box>\n </Box>\n\n <Typography\n sx={{\n fontSize: '0.78rem',\n color: 'hsl(var(--muted-foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {getRunSubtitle(run)}\n </Typography>\n\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 0.5 }}>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.7 }}>\n {run.started_at ? getTimeAgo(run.started_at) : '—'}\n </Typography>\n {duration && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>·</Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.7 }}>\n {duration}\n </Typography>\n </>\n )}\n </Box>\n </Box>\n\n {tools.length > 0 && (\n <Box\n sx={{\n display: { xs: 'none', sm: 'flex' },\n alignItems: 'center',\n gap: 0.5,\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n maxWidth: 220,\n flexShrink: 0,\n }}\n >\n {tools.map((t) => (\n <Tooltip key={t} title={t} arrow>\n <Chip\n label={t}\n size=\"small\"\n sx={{\n height: 20,\n fontSize: '0.68rem',\n maxWidth: 120,\n bgcolor: 'hsla(var(--muted) / 0.5)',\n color: 'hsl(var(--muted-foreground))',\n border: '1px solid hsl(var(--border))',\n '& .MuiChip-label': {\n px: 0.75,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n }}\n />\n </Tooltip>\n ))}\n </Box>\n )}\n </Box>\n );\n};\n\n// ── List ─────────────────────────────────────────────────────────────────────\n\nconst STATUS_FILTERS = [\n { label: 'All', value: '' },\n { label: 'Completed', value: 'FINISHED' },\n { label: 'Running', value: 'EXECUTING' },\n { label: 'Failed', value: 'ABORTED' },\n];\n\nexport interface AgentActivityListProps {\n /** Optional Shuffle API key. Falls back to the shared API_CONFIG. */\n apiKey?: string;\n /** Optional Shuffle backend base URL. Falls back to the shared API_CONFIG. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header. */\n orgId?: string;\n /** Called when a run row is clicked. */\n onRunClick?: (run: AgentRun) => void;\n /** Called when \"Edit\" is clicked on a selected scheduled workflow. */\n onEditWorkflow?: (info: { workflowId: string; name: string; prompt: string; apps: Array<{ name: string; id?: string }> }) => void;\n /** Show the search box. Default: true. */\n showSearchBar?: boolean;\n /** Show the status filter chips. Default: true. */\n showStatusChips?: boolean;\n /** Page size. Default: 50. */\n limit?: number;\n /** Empty-state heading. */\n emptyTitle?: string;\n /** Empty-state subtitle. */\n emptySubtitle?: string;\n /** Optional className forwarded to the root container. */\n className?: string;\n /** Style overrides merged into the root container sx. */\n sx?: SxProps<Theme>;\n /** Style overrides for the filter/search toolbar. */\n toolbarSx?: SxProps<Theme>;\n /** Style overrides for each individual run row. */\n rowSx?: SxProps<Theme>;\n}\n\nconst AgentActivityList = ({\n apiKey,\n apiBaseUrl,\n orgId,\n onRunClick,\n \n onEditWorkflow,\n showSearchBar = true,\n showStatusChips = true,\n limit = 50,\n emptyTitle = 'No agent activity found',\n emptySubtitle = 'The agent has not performed any actions yet',\n className,\n sx,\n toolbarSx,\n rowSx,\n}: AgentActivityListProps) => {\n const [runs, setRuns] = useState<AgentRun[]>([]);\n const [cursor, setCursor] = useState('');\n const [hasMore, setHasMore] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState('');\n const [searchQuery, setSearchQuery] = useState('');\n const [debouncedQuery, setDebouncedQuery] = useState('');\n const [agentWorkflows, setAgentWorkflows] = useState<AgentScheduleWorkflow[]>([]);\n const [workflowFilter, setWorkflowFilter] = useState('');\n const [stopOpen, setStopOpen] = useState(false);\n const [stopLoading, setStopLoading] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout>>();\n\n const selectedAgentWorkflow = agentWorkflows.find((w) => w.id === workflowFilter) || null;\n\n const openEditPrompt = useCallback(async () => {\n if (!workflowFilter) return;\n try {\n const { prompt, apps } = await getAgentScheduleConfig(workflowFilter, { apiKey, apiBaseUrl, orgId });\n onEditWorkflow?.({\n workflowId: workflowFilter,\n name: selectedAgentWorkflow?.name || 'Schedule',\n prompt,\n apps,\n });\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Failed to load workflow');\n }\n }, [workflowFilter, selectedAgentWorkflow, apiKey, apiBaseUrl, orgId, onEditWorkflow]);\n\n\n const confirmStop = useCallback(async () => {\n if (!workflowFilter) return;\n setStopLoading(true);\n try {\n await stopAgentSchedule(workflowFilter, { apiKey, apiBaseUrl, orgId });\n setStopOpen(false);\n // Refresh workflow list and clear the filter so list goes back to \"All\".\n const items = await listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId });\n setAgentWorkflows(items);\n setWorkflowFilter('');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Failed to stop schedule');\n } finally {\n setStopLoading(false);\n }\n }, [workflowFilter, apiKey, apiBaseUrl, orgId]);\n\n const updateSearchQuery = useCallback((q: string) => {\n setSearchQuery(q);\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => setDebouncedQuery(q), 350);\n }, []);\n\n useEffect(() => () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n }, []);\n\n const fetchRuns = useCallback(\n async (append = false, cursorParam = '') => {\n setIsLoading(true);\n setError(null);\n try {\n const result = await searchAgentActivity({\n limit,\n status: statusFilter,\n cursor: cursorParam,\n apiKey,\n apiBaseUrl,\n orgId,\n workflowId: workflowFilter || 'AGENT',\n });\n if (result.success) {\n setRuns((prev) => (append ? [...prev, ...result.runs] : result.runs));\n setCursor(result.cursor);\n setHasMore(!!result.cursor && result.runs.length > 0);\n } else {\n setError('Failed to fetch agent activity');\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch agent activity');\n } finally {\n setIsLoading(false);\n }\n },\n [statusFilter, limit, apiKey, apiBaseUrl, orgId, workflowFilter],\n );\n\n useEffect(() => {\n fetchRuns(false, '');\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [statusFilter, apiKey, apiBaseUrl, orgId, workflowFilter]);\n\n // Load the agentic workflow list (workflow_type = AGENT_SCHEDULE) once.\n useEffect(() => {\n let cancelled = false;\n listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId })\n .then((items) => { if (!cancelled) setAgentWorkflows(items); })\n .catch(() => { /* non-fatal — dropdown stays \"All\" only */ });\n return () => { cancelled = true; };\n }, [apiKey, apiBaseUrl, orgId]);\n\n const loadMore = useCallback(() => {\n if (cursor && !isLoading) fetchRuns(true, cursor);\n }, [cursor, isLoading, fetchRuns]);\n\n const filteredRuns = debouncedQuery\n ? runs.filter((r) => {\n const hay = [\n getRunTitle(r),\n getRunSubtitle(r),\n r.execution_id,\n r.execution_source,\n r.status,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n return hay.includes(debouncedQuery.toLowerCase());\n })\n : runs;\n\n return (\n <Box\n className={className}\n sx={[{ display: 'flex', flexDirection: 'column', gap: 2 }, ...(Array.isArray(sx) ? sx : sx ? [sx] : [])]}\n >\n {(showSearchBar || showStatusChips) && (\n <Box sx={[{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 1.5, flexWrap: 'wrap' }, ...(Array.isArray(toolbarSx) ? toolbarSx : toolbarSx ? [toolbarSx] : [])]}>\n <Select\n size=\"small\"\n value={workflowFilter}\n onChange={(e) => setWorkflowFilter(String(e.target.value))}\n displayEmpty\n renderValue={(val) => {\n if (!val) return 'All Agent runs';\n const wf = agentWorkflows.find((w) => w.id === val);\n return wf?.name || 'Selected workflow';\n }}\n sx={{\n height: 36,\n minWidth: 200,\n maxWidth: 260,\n fontSize: '0.85rem',\n bgcolor: 'hsl(var(--card))',\n color: 'hsl(var(--foreground))',\n borderRadius: 1.5,\n '& .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--border))' },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--muted-foreground) / 0.3)' },\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'hsl(var(--primary))' },\n }}\n MenuProps={{\n slotProps: {\n paper: {\n sx: {\n bgcolor: 'hsl(var(--card))',\n border: '1px solid hsl(var(--border))',\n color: 'hsl(var(--foreground))',\n maxHeight: 320,\n },\n },\n },\n }}\n >\n <MenuItem value=\"\" sx={{ fontSize: '0.85rem' }}>All Agent runs</MenuItem>\n {agentWorkflows.map((w) => (\n <MenuItem key={w.id} value={w.id} sx={{ fontSize: '0.85rem' }}>\n {w.name}\n </MenuItem>\n ))}\n </Select>\n {showSearchBar && (\n <TextField\n placeholder=\"Search results...\"\n size=\"small\"\n value={searchQuery}\n onChange={(e) => updateSearchQuery(e.target.value)}\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon size={18} color={'hsl(var(--muted-foreground))'} />\n </InputAdornment>\n ),\n },\n }}\n sx={{\n flex: 1,\n maxWidth: 280,\n minWidth: 160,\n '& .MuiOutlinedInput-root': {\n bgcolor: 'hsl(var(--card))',\n borderRadius: 1.5,\n fontSize: '0.85rem',\n height: 36,\n '& fieldset': { borderColor: 'hsl(var(--border))' },\n '&:hover fieldset': { borderColor: 'hsl(var(--muted-foreground) / 0.3)' },\n '&.Mui-focused fieldset': { borderColor: 'hsl(var(--primary))' },\n },\n '& .MuiInputBase-input': { color: 'hsl(var(--foreground))' },\n }}\n />\n )}\n {showStatusChips && (\n <SegmentedControl\n size=\"sm\"\n ariaLabel=\"Filter by status\"\n value={statusFilter}\n onChange={setStatusFilter}\n options={STATUS_FILTERS.map((f) => ({ value: f.value, label: f.label }))}\n />\n )}\n {isLoading && runs.length > 0 && (\n <CircularProgress size={16} sx={{ color: 'hsl(var(--primary))', ml: 0.5 }} />\n )}\n </Box>\n )}\n\n {selectedAgentWorkflow && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n p: 1.5,\n borderRadius: 2,\n border: '1px solid hsl(var(--border))',\n bgcolor: 'hsl(var(--card))',\n }}\n >\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography sx={{ fontSize: '0.85rem', fontWeight: 600, color: 'hsl(var(--foreground))', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {selectedAgentWorkflow.name}\n </Typography>\n {selectedAgentWorkflow.description && (\n <Typography sx={{ fontSize: '0.75rem', color: 'hsl(var(--muted-foreground))', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {selectedAgentWorkflow.description}\n </Typography>\n )}\n </Box>\n <Button\n size=\"small\"\n startIcon={<Pencil size={14} />}\n onClick={openEditPrompt}\n sx={{\n height: 36,\n border: '1px solid hsl(var(--border))',\n borderRadius: 1.5,\n color: 'hsl(var(--foreground))',\n textTransform: 'none',\n fontSize: '0.8rem',\n px: 1.5,\n '&:hover': { bgcolor: 'hsl(var(--muted))' },\n }}\n >\n Edit\n </Button>\n <Button\n size=\"small\"\n startIcon={<StopCircle size={14} />}\n onClick={() => setStopOpen(true)}\n sx={{\n height: 36,\n border: '1px solid hsl(var(--severity-critical, 0 72% 55%) / 0.4)',\n borderRadius: 1.5,\n color: 'hsl(var(--severity-critical, 0 72% 55%))',\n textTransform: 'none',\n fontSize: '0.8rem',\n px: 1.5,\n '&:hover': { bgcolor: 'hsla(var(--severity-critical, 0 72% 55%) / 0.08)' },\n }}\n >\n Stop schedule\n </Button>\n </Box>\n )}\n\n {isLoading && runs.length === 0 ? (\n <Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>\n <CircularProgress size={28} sx={{ color: 'hsl(var(--primary))' }} />\n </Box>\n ) : error ? (\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', py: 6 }}>\n <AlertCircle size={28} style={{ color: 'hsl(var(--severity-critical, 0 72% 55%))', marginBottom: 8 }} />\n <Typography\n sx={{ color: 'hsl(var(--severity-critical, 0 72% 55%))', fontSize: '0.9rem', mb: 1 }}\n >\n {error}\n </Typography>\n <Button\n size=\"small\"\n onClick={() => fetchRuns(false, '')}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none' }}\n >\n Try again\n </Button>\n </Box>\n ) : filteredRuns.length === 0 ? (\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', py: 8 }}>\n <Activity\n size={40}\n style={{ color: 'hsl(var(--muted-foreground))', marginBottom: 12 }}\n />\n <Typography sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.9rem' }}>\n {emptyTitle}\n </Typography>\n <Typography\n sx={{ color: 'hsl(var(--muted-foreground))', fontSize: '0.8rem', mt: 0.5, opacity: 0.7 }}\n >\n {emptySubtitle}\n </Typography>\n </Box>\n ) : (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n {filteredRuns.map((run, idx) => (\n <AgentRunRow\n key={run.execution_id || idx}\n run={run}\n onClick={() => onRunClick?.(run)}\n sx={rowSx}\n />\n ))}\n {hasMore && (\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 1 }}>\n <Button\n size=\"small\"\n onClick={loadMore}\n disabled={isLoading}\n sx={{ color: 'hsl(var(--primary))', textTransform: 'none', fontSize: '0.8rem' }}\n >\n {isLoading ? <CircularProgress size={14} sx={{ mr: 1 }} /> : null}\n Load more\n </Button>\n </Box>\n )}\n </Box>\n )}\n\n <Dialog\n open={stopOpen}\n onClose={() => (stopLoading ? null : setStopOpen(false))}\n slotProps={{ paper: { sx: { bgcolor: 'hsl(var(--card))', color: 'hsl(var(--foreground))', border: '1px solid hsl(var(--border))' } } }}\n >\n <DialogTitle sx={{ fontSize: '1rem', fontWeight: 600 }}>Stop schedule?</DialogTitle>\n <DialogContent>\n <Typography sx={{ fontSize: '0.85rem', color: 'hsl(var(--muted-foreground))' }}>\n This will stop \"{selectedAgentWorkflow?.name}\" and delete the scheduled workflow. Past executions remain visible. This cannot be undone.\n </Typography>\n </DialogContent>\n <DialogActions sx={{ px: 3, pb: 2 }}>\n <Button onClick={() => setStopOpen(false)} disabled={stopLoading} sx={{ textTransform: 'none', color: 'hsl(var(--muted-foreground))' }}>\n Cancel\n </Button>\n <Button\n onClick={confirmStop}\n disabled={stopLoading}\n sx={{ textTransform: 'none', bgcolor: 'hsl(var(--severity-critical, 0 72% 55%))', color: 'hsl(var(--primary-foreground))', '&:hover': { bgcolor: 'hsla(var(--severity-critical, 0 72% 55%) / 0.9)' } }}\n >\n {stopLoading ? <CircularProgress size={16} sx={{ color: 'hsl(var(--primary-foreground))', mr: 1 }} /> : null}\n Stop schedule\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n );\n};\n\nexport default AgentActivityList;\nexport { getRunTitle, getRunSubtitle, formatDuration, getTimeAgo, STATUS_CONFIG };\n","/**\n * Agent Activity service — standalone fetcher for agent workflow executions.\n *\n * Self-contained: uses only the lib's API_CONFIG / getApiUrl / getAuthHeader\n * so it works in npm consumers without any project-side hooks or contexts.\n */\n\nimport { API_CONFIG, getApiUrl, getAuthHeader } from './api';\n\nexport interface AgentRunResult {\n action?: {\n app_name?: string;\n label?: string;\n id?: string;\n };\n result?: string;\n status?: string;\n}\n\nexport interface AgentDecision {\n title?: string;\n description?: string;\n status?: string;\n timestamp?: string | number;\n duration?: number;\n action?: string;\n result?: string;\n tool?: string;\n reason?: string;\n category?: string;\n confidence?: number;\n runs?: string | number;\n fields?: unknown;\n approval_required?: boolean;\n run_details?: unknown;\n [key: string]: unknown;\n}\n\nexport interface AgentRun {\n execution_id: string;\n workflow_id: string;\n status: string;\n started_at: string;\n completed_at?: string;\n result?: string;\n results?: AgentRunResult[];\n decisions?: AgentDecision[];\n execution_argument?: string;\n execution_source?: string;\n authorization?: string;\n workflow?: {\n name?: string;\n description?: string;\n actions?: Array<{\n app_name?: string;\n label?: string;\n }>;\n };\n duration?: number;\n}\n\nexport interface AgentActivityResponse {\n success: boolean;\n runs: AgentRun[];\n cursor: string;\n}\n\nexport interface AgentActivityParams {\n cursor?: string;\n limit?: number;\n status?: string;\n startTime?: string;\n endTime?: string;\n suborgRuns?: boolean;\n /** Override the lib's shared apiKey for this call. */\n apiKey?: string;\n /** Override the lib's shared baseUrl for this call. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID — sent as the `Org-Id` header. */\n orgId?: string;\n /** Workflow ID to search. Defaults to the synthetic 'AGENT' grouping. */\n workflowId?: string;\n}\n\nconst resolveUrl = (path: string, baseUrl?: string): string =>\n baseUrl ? `${baseUrl.replace(/\\/+$/, '')}${path}` : getApiUrl(path);\n\nconst resolveHeaders = (apiKey?: string, orgId?: string): Record<string, string> => {\n const h: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : { ...getAuthHeader() };\n if (orgId) h['Org-Id'] = orgId;\n return h;\n};\n\n/**\n * Search agent workflow executions (workflow_id = \"AGENT\" by default).\n */\nexport const searchAgentActivity = async (\n params: AgentActivityParams = {}\n): Promise<AgentActivityResponse> => {\n const {\n cursor = '',\n limit = 50,\n status = '',\n startTime = '',\n endTime = '',\n suborgRuns = false,\n apiKey,\n apiBaseUrl,\n orgId,\n workflowId = 'AGENT',\n } = params;\n\n const payload = {\n workflow_id: workflowId,\n cursor,\n limit,\n status,\n start_time: startTime,\n end_time: endTime,\n suborg_runs: suborgRuns,\n };\n\n const response = await fetch(resolveUrl('/api/v1/workflows/search', apiBaseUrl), {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...resolveHeaders(apiKey, orgId),\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch agent activity: ${response.statusText}`);\n }\n\n const data = await response.json();\n return {\n success: data.success ?? false,\n runs: data.runs || [],\n cursor: data.cursor || '',\n };\n};\n\nexport interface AgentScheduleWorkflow {\n id: string;\n name: string;\n description?: string;\n}\n\n/**\n * List workflows of type AGENT_SCHEDULE — used to populate the agentic\n * workflow dropdown in the activity list.\n */\nexport const listAgentScheduleWorkflows = async (\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<AgentScheduleWorkflow[]> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const response = await fetch(resolveUrl('/api/v1/workflows', apiBaseUrl), {\n method: 'GET',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch workflows: ${response.statusText}`);\n }\n const data = await response.json();\n const list: any[] = Array.isArray(data) ? data : (data?.workflows || []);\n return list\n .filter((w) => w && w.workflow_type === 'AGENT_SCHEDULE')\n .map((w) => ({ id: w.id || w._id, name: w.name || 'Untitled', description: w.description }));\n};\n\n/** Find the AI Agent action's `input` parameter inside a workflow. */\nconst findAgentInputParam = (workflow: any): { action: any; param: any } | null => {\n const actions: any[] = workflow?.actions || [];\n for (const a of actions) {\n if ((a?.app_name || '').toLowerCase().includes('ai agent') || a?.app_id === 'shuffle_agent') {\n const params: any[] = a?.parameters || [];\n const p = params.find((x) => x?.name === 'input');\n if (p) return { action: a, param: p };\n }\n }\n return null;\n};\n\n/** Fetch a single workflow by ID. */\nexport const getWorkflow = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<any> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'GET',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n });\n if (!res.ok) throw new Error(`Failed to fetch workflow: ${res.statusText}`);\n return res.json();\n};\n\n/** Read the AI Agent prompt from a scheduled agent workflow. */\nexport const getAgentSchedulePrompt = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<{ workflow: any; prompt: string }> => {\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n return { workflow, prompt: String(found?.param?.value || '') };\n};\n\n/** Read the AI Agent prompt + selected app names from a scheduled agent\n * workflow. Apps are parsed from the AI Agent action's `app_name`\n * parameter (comma-separated list of app names). */\nexport const getAgentScheduleConfig = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<{ workflow: any; prompt: string; apps: Array<{ name: string; id?: string }> }> => {\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n const prompt = String(found?.param?.value || '');\n const action = found?.action;\n const actionParams: any[] = action?.parameters || [];\n const appNameParam = actionParams.find((x) => x?.name === 'app_name');\n const raw = String(appNameParam?.value || '');\n const apps = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((name) => ({ name }));\n return { workflow, prompt, apps };\n};\n\n/** Update the AI Agent prompt on a scheduled agent workflow. Overwrites\n * the `input` parameter with exactly what the caller passes — no merging,\n * no appended boilerplate. */\nexport const updateAgentSchedulePrompt = async (\n workflowId: string,\n newPrompt: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n if (!found) throw new Error('No AI Agent action found on this workflow');\n found.param.value = newPrompt;\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'PUT',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n body: JSON.stringify(workflow),\n });\n if (!res.ok) throw new Error(`Failed to update workflow: ${res.statusText}`);\n};\n\n/** Update both the prompt and the selected apps on a scheduled agent\n * workflow. The `apps` array is written as a comma-separated list of app\n * names to the AI Agent action's `app_name` parameter. */\nexport const updateAgentScheduleConfig = async (\n workflowId: string,\n config: { prompt: string; apps: Array<{ name: string; id?: string }> },\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const workflow = await getWorkflow(workflowId, params);\n const found = findAgentInputParam(workflow);\n if (!found) throw new Error('No AI Agent action found on this workflow');\n found.param.value = config.prompt;\n const action = found.action;\n const appValue = (config.apps || [])\n .filter((a) => !!a?.name)\n .map((a) => a.name)\n .join(',');\n const params_: any[] = action.parameters || [];\n const appNameParam = params_.find((x) => x?.name === 'app_name');\n if (appNameParam) {\n appNameParam.value = appValue;\n } else {\n params_.push({\n name: 'app_name',\n value: appValue,\n required: true,\n description: 'Comma-separated list of app names the agent is allowed to use.',\n });\n action.parameters = params_;\n }\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'PUT',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...resolveHeaders(apiKey, orgId) },\n body: JSON.stringify(workflow),\n });\n if (!res.ok) throw new Error(`Failed to update workflow: ${res.statusText}`);\n};\n\n/** Stop the schedule entirely by deleting the wrapper workflow. */\nexport const stopAgentSchedule = async (\n workflowId: string,\n params: { apiKey?: string; apiBaseUrl?: string; orgId?: string } = {},\n): Promise<void> => {\n const { apiKey, apiBaseUrl, orgId } = params;\n const headers = { ...resolveHeaders(apiKey, orgId) };\n\n // 1. Delete the schedule trigger(s) first so the cron stops firing.\n try {\n const workflow = await getWorkflow(workflowId, params);\n const triggers: any[] = workflow?.triggers || [];\n const scheduleIds = triggers\n .filter((t) => (t?.trigger_type || '').toUpperCase() === 'SCHEDULE')\n .map((t) => t?.id || t?.id_ || t?._id_)\n .filter(Boolean);\n await Promise.all(\n scheduleIds.map((sid) =>\n fetch(resolveUrl(`/api/v1/workflows/${workflowId}/schedule/${sid}`, apiBaseUrl), {\n method: 'DELETE',\n credentials: 'include',\n headers,\n }).catch(() => undefined),\n ),\n );\n } catch {\n // Non-fatal — proceed to delete the workflow regardless.\n }\n\n // 2. Delete the workflow itself.\n const res = await fetch(resolveUrl(`/api/v1/workflows/${workflowId}`, apiBaseUrl), {\n method: 'DELETE',\n credentials: 'include',\n headers,\n });\n if (!res.ok) throw new Error(`Failed to stop schedule: ${res.statusText}`);\n};\n\n// Re-export so consumers can read base config if needed.\nexport { API_CONFIG };\n\n","/**\n * AgentExecutionDrawer — standalone right-side drawer showing the canonical\n * `AgentUI` Simple/Detailed view for an existing agent run. Pre-loads the\n * execution data via the `initialExecution` prop on `AgentUI`, so no extra\n * `/streams/results` fetch (and no `authorization` token) is required.\n *\n * Self-contained: no project hooks, contexts, or services. Drop-in for both\n * the host app (the `/agent` page) and npm consumers of the lib.\n */\n\nimport { Box, Drawer, IconButton, Tooltip, Typography } from '@mui/material';\nimport {\n X as CloseIcon,\n ExternalLink as OpenInNewIcon\n} from 'lucide-react';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport AgentUI, { type AgentUIProps } from './AgentUI';\nimport AgentIcon from './AgentIcon';\nimport {\n STATUS_CONFIG,\n formatDuration,\n getRunTitle,\n getTimeAgo,\n} from './AgentActivityList';\nimport type { AgentRun } from './agentActivity';\n\nexport interface AgentExecutionDrawerProps {\n open: boolean;\n onClose: () => void;\n /** The run to display. When null and `open=true`, drawer renders empty. */\n run: AgentRun | null;\n /** Drawer width. Default: 720 px on >=sm, full-width on xs. */\n width?: number;\n /** Optional Shuffle API key, forwarded to the embedded AgentUI. */\n apiKey?: string;\n /** Optional Shuffle backend base URL, forwarded to the embedded AgentUI. */\n apiBaseUrl?: string;\n /** Optional Shuffle Org ID, forwarded to the embedded AgentUI. */\n orgId?: string;\n /** Optional className forwarded to the Drawer Paper. */\n className?: string;\n /** Style overrides merged into the Drawer Paper sx. */\n paperSx?: SxProps<Theme>;\n /** Style overrides for the header bar. */\n headerSx?: SxProps<Theme>;\n /** Style overrides for the body container that wraps the embedded AgentUI. */\n bodySx?: SxProps<Theme>;\n /** Optional content rendered at the top of the body, before the embedded\n * AgentUI. Use this to inject a shared \"Needs attention\" / failure\n * diagnosis banner so the drawer mirrors the timeline status pill. */\n topBanner?: React.ReactNode;\n /** Handler for scheduling the loaded agent prompt from the execution view. */\n onSchedule?: AgentUIProps['onSchedule'];\n}\n\nconst AgentExecutionDrawer = ({\n open,\n onClose,\n run,\n width = 720,\n apiKey,\n apiBaseUrl,\n orgId,\n className,\n paperSx,\n headerSx,\n bodySx,\n topBanner,\n onSchedule,\n}: AgentExecutionDrawerProps) => {\n const statusKey = (run?.status || '').toUpperCase();\n const cfg = STATUS_CONFIG[statusKey] || STATUS_CONFIG.WAITING;\n const duration = run ? formatDuration(run) : '';\n\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n slotProps={{\n paper: {\n className,\n sx: [\n {\n width: { xs: '100%', sm: width },\n maxWidth: '100vw',\n bgcolor: 'hsl(var(--background))',\n color: 'hsl(var(--foreground))',\n backgroundImage: 'none',\n borderLeft: '1px solid hsl(var(--border))',\n },\n ...(Array.isArray(paperSx) ? paperSx : paperSx ? [paperSx] : []),\n ],\n },\n }}\n >\n {/* Header */}\n <Box\n sx={[\n {\n display: 'flex',\n alignItems: 'center',\n gap: 1.5,\n px: 2.5,\n py: 1.75,\n borderBottom: '1px solid hsl(var(--border))',\n position: 'sticky',\n top: 0,\n zIndex: 2,\n bgcolor: 'hsl(var(--background))',\n },\n ...(Array.isArray(headerSx) ? headerSx : headerSx ? [headerSx] : []),\n ]}\n >\n <Box\n sx={{\n width: 36,\n height: 36,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'hsla(var(--primary) / 0.12)',\n color: 'hsl(var(--primary))',\n flexShrink: 0,\n }}\n >\n <AgentIcon size={20} />\n </Box>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, minWidth: 0 }}>\n <Typography\n sx={{\n fontSize: '0.95rem',\n fontWeight: 600,\n color: 'hsl(var(--foreground))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {run ? getRunTitle(run) : 'Agent execution'}\n </Typography>\n {run && (\n <Box sx={{ display: 'flex', alignItems: 'center', color: cfg.color, flexShrink: 0 }}>\n {cfg.icon}\n </Box>\n )}\n </Box>\n {run && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 0.25 }}>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {cfg.label}\n </Typography>\n {run.started_at && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>\n ·\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {getTimeAgo(run.started_at)}\n </Typography>\n </>\n )}\n {duration && (\n <>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))', opacity: 0.4 }}>\n ·\n </Typography>\n <Typography sx={{ fontSize: '0.72rem', color: 'hsl(var(--muted-foreground))' }}>\n {duration}\n </Typography>\n </>\n )}\n </Box>\n )}\n </Box>\n {run?.execution_id && (\n <Tooltip title=\"Open in new tab\">\n <IconButton\n component=\"a\"\n href={`/agents?execution_id=${encodeURIComponent(run.execution_id)}${run.authorization ? `&authorization=${encodeURIComponent(run.authorization)}` : ''}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <OpenInNewIcon size={16} />\n </IconButton>\n </Tooltip>\n )}\n <Tooltip title=\"Close\">\n <IconButton\n onClick={onClose}\n size=\"small\"\n sx={{\n color: 'hsl(var(--muted-foreground))',\n '&:hover': { color: 'hsl(var(--foreground))', bgcolor: 'hsl(var(--muted))' },\n }}\n >\n <CloseIcon size={16} />\n </IconButton>\n </Tooltip>\n </Box>\n\n {/* Body — embedded AgentUI seeded with the pre-loaded run */}\n <Box sx={[{ flex: 1, overflowY: 'auto', pt: 3 }, ...(Array.isArray(bodySx) ? bodySx : bodySx ? [bodySx] : [])]}>\n {topBanner}\n {run ? (\n <AgentUI\n key={run.execution_id}\n initialExecution={{\n execution_id: run.execution_id,\n status: run.status,\n started_at: run.started_at ? Number(run.started_at) : undefined,\n completed_at: run.completed_at ? Number(run.completed_at) : undefined,\n results: run.results,\n workflow: run.workflow,\n authorization: run.authorization,\n }}\n readUrlParams={false}\n autoLoadApps={false}\n hideHeroIcon\n hideAppPicker\n hideAttach\n disableStartTab\n compact\n maxWidth={width - 32}\n apiKey={apiKey}\n apiBaseUrl={apiBaseUrl}\n orgId={orgId}\n onSchedule={onSchedule}\n />\n ) : null}\n </Box>\n </Drawer>\n );\n};\n\nexport default AgentExecutionDrawer;\n","/**\n * useAppLookup — Resolve an app's display name, image, categories,\n * canonical Algolia objectID and matching auth entries from just\n * an app name (or id).\n *\n * Used by the standalone section components (Authentication, Try MCP,\n * Try individual actions) so consumers only need to pass `appName`.\n *\n * Resolution order:\n * 1. Algolia `appsearch` index (best-effort, may 429)\n * 2. /api/v1/apps fallback (private + activated apps)\n * 3. /api/v1/apps/:id/config to enrich with auth schema\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { API_CONFIG, getApiUrl, getAuthHeader } from '@/Shuffle-MCPs/api';\nimport { fetchAppsViaApiConfig } from '@/Shuffle-MCPs/appsCache';\nimport { useAppAuth } from '@/Shuffle-MCPs/useAppAuth';\nimport type { AlgoliaSearchApp } from './shuffle-mcp.helpers';\n\nexport interface AppLookupResult {\n loading: boolean;\n displayName: string;\n image: string;\n categories: string[];\n /** Canonical Algolia objectID (or Shuffle private app id). */\n algoliaId: string | null;\n /** Synthesized AlgoliaSearchApp suitable for AppAuthCard. */\n algoliaApp: AlgoliaSearchApp | null;\n /** Auth entries matching this app name. */\n matchingEntries: any[];\n hasValidAuth: boolean;\n hasAnyAuth: boolean;\n authCount: number;\n authState: any;\n // Pass-through helpers from useAppAuth (so consumers do not need a second hook):\n handleAuthChange: any;\n handleTestConnection: (appId: string, authId?: string) => any;\n handleSaveAuth: (appId: string, credentials: Record<string, string>) => Promise<boolean>;\n refreshAuth: () => void;\n}\n\nconst norm = (s: string) => s.toLowerCase().replace(/[\\s_\\-]+/g, '_');\n\nexport function useAppLookup(appName: string | null): AppLookupResult {\n const [loading, setLoading] = useState(false);\n const [info, setInfo] = useState<{\n name: string;\n description: string;\n image: string;\n categories: string[];\n } | null>(null);\n const [algoliaId, setAlgoliaId] = useState<string | null>(null);\n\n const {\n authStates,\n authenticatedApps,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n } = useAppAuth();\n\n useEffect(() => {\n if (!appName) {\n setInfo(null);\n setAlgoliaId(null);\n return;\n }\n setLoading(true);\n setInfo(null);\n setAlgoliaId(null);\n refreshAuth();\n\n const normalizedName = norm(appName);\n const searchName = appName.replace(/_/g, ' ');\n\n (async () => {\n let id: string | null = null;\n try {\n const { algoliasearch } = await import('algoliasearch');\n const client = algoliasearch('JNSS5CFDZZ', '33e4e3564f4f060e96e0531957bed552');\n const res = await client.search({\n requests: [{ indexName: 'appsearch', query: searchName, hitsPerPage: 10 }],\n });\n const hits = (res as any)?.results?.[0]?.hits || [];\n const match = hits.find((h: any) => h.name && norm(h.name) === normalizedName) || hits[0];\n if (match) {\n id = match.objectID;\n setAlgoliaId(id);\n setInfo({\n name: match.name || searchName,\n description: match.description || '',\n image: match.image_url || '',\n categories: match.categories || [],\n });\n }\n } catch {}\n\n let appsList: any[] | null = null;\n if (API_CONFIG.apiKey) {\n try {\n const apps = await fetchAppsViaApiConfig();\n if (Array.isArray(apps)) appsList = apps;\n } catch {}\n }\n\n if (!id && appsList) {\n const localMatch = appsList.find((a: any) => norm(a.name || '') === normalizedName);\n if (localMatch?.id) {\n id = localMatch.id;\n setAlgoliaId(localMatch.id);\n setInfo((prev) => prev ?? {\n name: localMatch.name || searchName,\n description: localMatch.description || '',\n image: localMatch.large_image || '',\n categories: localMatch.categories || [],\n });\n }\n }\n\n if (API_CONFIG.apiKey && id) {\n try {\n const response = await fetch(\n getApiUrl(`/api/v1/apps/${encodeURIComponent(id)}/config`),\n { credentials: 'include', headers: { ...getAuthHeader() } },\n );\n if (response.ok) {\n const data = await response.json();\n if (data?.name) {\n setInfo((prev) => ({\n name: data.name || prev?.name || searchName,\n description: data.description || prev?.description || '',\n image: data.large_image || prev?.image || '',\n categories: data.categories || prev?.categories || [],\n }));\n }\n }\n } catch {}\n }\n\n setInfo((prev) => prev ?? { name: searchName, description: '', image: '', categories: [] });\n setLoading(false);\n })();\n }, [appName]);\n\n const matchingEntries = useMemo(() => {\n if (!appName) return [];\n return authenticatedApps.filter(\n (auth) => auth.app?.name && norm(auth.app.name) === norm(appName),\n );\n }, [appName, authenticatedApps]);\n\n const image = useMemo(() => {\n if (info?.image) return info.image;\n for (const entry of matchingEntries) {\n const img = (entry as any).app?.large_image || (entry as any).large_image;\n if (img) return img;\n }\n return '';\n }, [info, matchingEntries]);\n\n const algoliaApp: AlgoliaSearchApp | null = useMemo(() => {\n if (!appName) return null;\n return {\n objectID: algoliaId || appName,\n name: appName,\n image_url: image,\n description: info?.description || '',\n categories: info?.categories || [],\n } as AlgoliaSearchApp;\n }, [appName, info, image, algoliaId]);\n\n const displayName = (info?.name || appName || '').replace(/_/g, ' ');\n const authState = authStates[appName || ''] || { systemId: appName || '', status: 'pending' as const, credentials: {} };\n\n return {\n loading,\n displayName,\n image,\n categories: info?.categories || [],\n algoliaId,\n algoliaApp,\n matchingEntries,\n hasValidAuth: matchingEntries.some((e) => e.validation?.valid === true),\n hasAnyAuth: matchingEntries.length > 0,\n authCount: matchingEntries.length,\n authState,\n handleAuthChange,\n handleTestConnection,\n handleSaveAuth,\n refreshAuth,\n };\n}\n"],"mappings":"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","names":["React","useState","useEffect","useRef","useCallback","useMemo","Tooltip","useState","useEffect","useMemo","useRef","CloseIcon","Box","Typography","IconButton","ReactMarkdown","remarkGfm","motion","useState","useCallback","useEffect","useState","useCallback","norm","fetchAppsViaApiConfig","algoliasearch","url","jsx","useState","useCallback","useState","fetchAuthenticatedApps","useCallback","useEffect","Box","Typography","Avatar","jsx","jsxs","Box","Typography","motion","useState","useEffect","useRef","CheckCircleIcon","Box","Typography","Button","CircularProgress","Chip","IconButton","Tooltip","motion","useEffect","useState","jsx","algoliasearch","useState","useEffect","jsx","Fragment","jsx","jsxs","useState","useRef","useEffect","auth","error","Box","Button","Typography","motion","Chip","Tooltip","IconButton","CheckCircleIcon","CircularProgress","base","jsx","jsxs","motion","Box","Typography","Box","Typography","motion","useState","useRef","ErrorOutlineIcon","Box","Typography","Avatar","CircularProgress","Chip","jsx","motion","ReactMarkdown","remarkGfm","jsx","jsxs","useState","useRef","Box","motion","Avatar","Typography","Chip","CircularProgress","ErrorOutlineIcon","ReactMarkdown","remarkGfm","jsx","jsxs","motion","Box","Typography","useState","useEffect","useMemo","useCallback","useRef","Box","Typography","Chip","Button","TextField","IconButton","Tooltip","Avatar","LockIcon","Fragment","jsx","jsxs","base","useMemo","useState","useCallback","useEffect","useRef","Box","Typography","Chip","TextField","Tooltip","IconButton","Button","LockIcon","Avatar","Fragment","jsx","jsxs","useState","useRef","useEffect","algoliasearch","useMemo","appId","jsxs","Box","jsx","Typography","IconButton","CloseIcon","Fragment","motion","motion","jsx","jsxs","Fragment","jsx","jsxs","React","useState","useRef","fetchAuthenticatedApps","useCallback","useEffect","norm","useMemo","Tooltip","useState","useEffect","CloseIcon","Box","Typography","IconButton","Drawer","Avatar","Tooltip","motion","AnimatePresence","Fragment","jsx","jsxs","useState","useEffect","norm","Drawer","Box","Typography","IconButton","CloseIcon","Tooltip","Avatar","AnimatePresence","motion","Box","Typography","Chip","jsx","jsxs","Box","Typography","Chip","useCallback","useEffect","useMemo","useRef","useState","AddIcon","CheckCircleIcon","CheckIcon","CloseIcon","LockIcon","OpenInNewIcon","PlayArrowRoundedIcon","RestartAltIcon","Avatar","Box","Button","Chip","CircularProgress","IconButton","InputBase","MenuItem","Select","TextField","Tooltip","Typography","remarkGfm","JsonView","norm","base","algoliasearch","Box","IconButton","Tooltip","Typography","Box","Button","Tooltip","jsx","jsxs","useEffect","useMemo","useState","deepParseJsonStrings","jsx","jsxs","useMemo","useState","useEffect","Box","Typography","Tooltip","IconButton","Fragment","jsx","jsxs","deepParseJsonStrings","CircularProgress","CheckCircleIcon","Tooltip","Box","useState","Avatar","CheckIcon","Chip","remarkGfm","IconButton","RestartAltIcon","OpenInNewIcon","TextField","Button","Typography","LockIcon","JsonView","resolveUrl","useCallback","resolveHeaders","useRef","useEffect","useMemo","norm","algoliasearch","apps","executionId","authorization","raw","eid","auth","m","Select","MenuItem","CloseIcon","InputBase","PlayArrowRoundedIcon","AddIcon","useEffect","useRef","useState","Box","Drawer","IconButton","Tooltip","Typography","CloseIcon","jsx","jsxs","useState","useRef","useEffect","Drawer","Box","Typography","IconButton","CloseIcon","Tooltip","useCallback","useEffect","useRef","useState","Box","Button","Chip","CircularProgress","Dialog","DialogContent","DialogTitle","MenuItem","Select","TextField","Tooltip","Typography","Server","AlertTriangle","Fragment","jsx","jsxs","AlertTriangle","Server","Box","Typography","Tooltip","Chip","useState","useRef","useCallback","useEffect","Select","MenuItem","TextField","CircularProgress","Button","Dialog","DialogTitle","DialogContent","Box","Drawer","IconButton","Tooltip","Typography","CloseIcon","OpenInNewIcon","Fragment","jsx","jsxs","Drawer","Box","Typography","Tooltip","IconButton","OpenInNewIcon","CloseIcon","useEffect","useMemo","useState","norm","useState","useEffect","algoliasearch","useMemo"]}