@circuitwall/jarela 1.9.2 → 1.9.3
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page.js +688 -427
- package/.next/standalone/.next/server/app/page.js.map +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
- package/.next/standalone/.next/server/chunks/4045.js.map +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/2747-4a6287cacd57d231.js.map +1 -1
- package/.next/standalone/.next/static/chunks/{1998-31a617131197a83a.js → 962-fe2372e00f85e23a.js} +111 -2
- package/.next/standalone/.next/static/chunks/962-fe2372e00f85e23a.js.map +1 -0
- package/.next/standalone/.next/static/chunks/app/layout-84c6f211a7a1ca36.js.map +1 -1
- package/.next/standalone/.next/static/chunks/app/{page-afdef9bd1108a656.js → page-c5b9f4407416c3f9.js} +332 -154
- package/.next/standalone/.next/static/chunks/app/page-c5b9f4407416c3f9.js.map +1 -0
- package/.next/standalone/.next/static/css/b8e04d59a2bfff04.css +5 -0
- package/.next/standalone/.next/static/css/b8e04d59a2bfff04.css.map +1 -0
- package/.next/standalone/package.json +1 -1
- package/CHANGELOG.md +25 -0
- package/components/credentials/CredentialsPanel.tsx +1 -1
- package/components/layout/AppShell.tsx +6 -0
- package/components/layout/MenuPanel.tsx +15 -91
- package/components/settings/AppearancePanel.tsx +93 -0
- package/components/settings/SettingsPanel.tsx +94 -0
- package/contexts/AppContext.tsx +1 -1
- package/hooks/useUrlSync.ts +1 -1
- package/lib/ui/navigate.ts +1 -1
- package/package.json +1 -1
- package/.next/standalone/.next/static/chunks/1998-31a617131197a83a.js.map +0 -1
- package/.next/standalone/.next/static/chunks/app/page-afdef9bd1108a656.js.map +0 -1
- package/.next/standalone/.next/static/css/44f9bbea39fef458.css +0 -5
- package/.next/standalone/.next/static/css/44f9bbea39fef458.css.map +0 -1
- /package/.next/standalone/.next/static/{rr-Rxxi6kkXe1Bw8-Hzq2 → EOkgU73YJOpR-vFcKMgL0}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{rr-Rxxi6kkXe1Bw8-Hzq2 → EOkgU73YJOpR-vFcKMgL0}/_ssgManifest.js +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static/chunks/app/page-afdef9bd1108a656.js","mappings":"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","sources":["webpack://_N_E/./contexts/ThemeContext.tsx","webpack://_N_E/./hooks/useAgentSession.ts","webpack://_N_E/./lib/ui/toasts.ts","webpack://_N_E/./hooks/useEventNotifications.ts","webpack://_N_E/./lib/ui/navigate.ts","webpack://_N_E/./hooks/useUrlSync.ts","webpack://_N_E/./lib/agents/effective-model.ts","webpack://_N_E/./hooks/useConfigurationIssues.ts","webpack://_N_E/./lib/ui/loading.ts","webpack://_N_E/./hooks/useSSE.ts","webpack://_N_E/./components/proposals/ApprovalsBanner.tsx","webpack://_N_E/./components/chat/InputBar.tsx","webpack://_N_E/./components/chat/ToolList.tsx","webpack://_N_E/./components/chat/ContextUsageBar.tsx","webpack://_N_E/./components/chat/CountdownRing.tsx","webpack://_N_E/./lib/bridges/message-role.ts","webpack://_N_E/./lib/api/extension-turn-prompt.ts","webpack://_N_E/./components/chat/MessageBubble.tsx","webpack://_N_E/./components/chat/ContextBoundary.tsx","webpack://_N_E/./hooks/useMessageFilters.ts","webpack://_N_E/./components/chat/MessageList.tsx","webpack://_N_E/./components/chat/chat-helpers.ts","webpack://_N_E/./lib/ui/error-report.ts","webpack://_N_E/./lib/ui/error-message.ts","webpack://_N_E/./components/chat/useChatErrorReporting.ts","webpack://_N_E/./components/chat/useChatQueue.ts","webpack://_N_E/./components/chat/useThreadCrossDeviceSync.ts","webpack://_N_E/./components/chat/useThreadData.ts","webpack://_N_E/./components/chat/useUserProfileAndAgent.ts","webpack://_N_E/./components/chat/ChatView.tsx","webpack://_N_E/./hooks/useMemory.ts","webpack://_N_E/./hooks/useDeepLinkScroll.ts","webpack://_N_E/./hooks/useEscapeKey.ts","webpack://_N_E/./components/memory/MemoryEditor.tsx","webpack://_N_E/./components/memory/MemoryValuePreview.tsx","webpack://_N_E/./components/ui/Select.tsx","webpack://_N_E/./components/memory/MemoryPanel.tsx","webpack://_N_E/./hooks/useModels.ts","webpack://_N_E/./lib/providers/provider-integration-map.ts","webpack://_N_E/./components/models/model-editor/form-state.ts","webpack://_N_E/./components/models/model-editor/useModelEditorForm.ts","webpack://_N_E/./lib/models/editor-payload.ts","webpack://_N_E/./components/models/model-editor/save-helpers.ts","webpack://_N_E/./components/models/model-editor/useModelSaveHandlers.ts","webpack://_N_E/./components/models/model-editor/EditorChrome.tsx","webpack://_N_E/./components/models/model-editor/ProbeAndFooter.tsx","webpack://_N_E/./components/credentials/IntegrationCard.tsx","webpack://_N_E/./components/credentials/AddCredentialDialog.tsx","webpack://_N_E/./components/models/model-editor/IdentitySection.tsx","webpack://_N_E/./components/models/model-editor/ModelIdSection.tsx","webpack://_N_E/./components/models/model-editor/CredentialSection.tsx","webpack://_N_E/./components/models/model-editor/ConnectionFields.tsx","webpack://_N_E/./components/models/model-editor/TuningFields.tsx","webpack://_N_E/./components/models/model-editor/github-copilot-auth-actions.ts","webpack://_N_E/./components/models/model-editor/useGitHubCopilotAuth.ts","webpack://_N_E/./components/models/model-editor/GitHubCopilotAuth.tsx","webpack://_N_E/./components/models/model-editor/ShrinkConfirmDialog.tsx","webpack://_N_E/./components/models/model-editor/ModelEditorBody.tsx","webpack://_N_E/./components/models/ModelEditor.tsx","webpack://_N_E/./components/models/ModelsPanel.tsx","webpack://_N_E/./components/integrations/NetworkSection.tsx","webpack://_N_E/./components/integrations/AllowedSitesSection.tsx","webpack://_N_E/./components/integrations/EnvAliasEditor.tsx","webpack://_N_E/./components/integrations/NetworkPanel.tsx","webpack://_N_E/./lib/integrations/categories.ts","webpack://_N_E/./components/credentials/CredentialsPanel.tsx","webpack://_N_E/./components/documents/FolderPickerDialog.tsx","webpack://_N_E/./components/documents/helpers.ts","webpack://_N_E/./components/documents/AddSourceFields.tsx","webpack://_N_E/./components/documents/AddSourceForm.tsx","webpack://_N_E/./components/documents/EmbeddingModelSection.tsx","webpack://_N_E/./components/documents/SearchProbe.tsx","webpack://_N_E/./components/documents/SourceList.tsx","webpack://_N_E/./components/documents/useDocumentsPanel.ts","webpack://_N_E/./components/documents/DocumentsPanel.tsx","webpack://_N_E/./hooks/useAgents.ts","webpack://_N_E/./hooks/useTools.ts","webpack://_N_E/./lib/agents/adaptive-persona-presets.ts","webpack://_N_E/./components/agents/agent-editor/useAgentExternalData.ts","webpack://_N_E/./components/agents/agent-editor/permissions.ts","webpack://_N_E/./components/agents/agent-editor/useAgentToolHandlers.ts","webpack://_N_E/./components/agents/agent-editor/useAgentEditorForm.ts","webpack://_N_E/./components/agents/agent-editor/useAgentSaveHandler.ts","webpack://_N_E/./components/agents/agent-editor/Section.tsx","webpack://_N_E/./components/agents/agent-editor/IdentitySection.tsx","webpack://_N_E/./components/agents/agent-editor/ModelSection.tsx","webpack://_N_E/./components/agents/agent-editor/ToolSelection.tsx","webpack://_N_E/./components/agents/agent-editor/ToolsSection.tsx","webpack://_N_E/./components/agents/agent-editor/DelegatesSection.tsx","webpack://_N_E/./components/agents/agent-editor/HarnessField.tsx","webpack://_N_E/./components/agents/agent-editor/HallucinationFields.tsx","webpack://_N_E/./components/agents/TierProportionBar.tsx","webpack://_N_E/./components/agents/agent-editor/TierOverrideField.tsx","webpack://_N_E/./components/agents/agent-editor/AdaptivePersonaFields.tsx","webpack://_N_E/./lib/voice/constants.ts","webpack://_N_E/./components/agents/agent-editor/VoiceFields.tsx","webpack://_N_E/./components/agents/agent-editor/AdvancedSection.tsx","webpack://_N_E/./components/agents/agent-editor/EditorChrome.tsx","webpack://_N_E/./components/agents/AgentEditor.tsx","webpack://_N_E/./components/agents/AgentsPanel.tsx","webpack://_N_E/./hooks/useLocationSharing.ts","webpack://_N_E/./lib/utils/time.ts","webpack://_N_E/./components/profile/ProfileEditor.tsx","webpack://_N_E/./components/profile/SecurityPanel.tsx","webpack://_N_E/./components/profile/RedactionPanel.tsx","webpack://_N_E/./components/profile/NetworkPanel.tsx","webpack://_N_E/./components/profile/ProfilePanel.tsx","webpack://_N_E/./components/mcp/MCPPanel.tsx","webpack://_N_E/./components/extensions/ExtensionsPanel.tsx","webpack://_N_E/./hooks/useBridges.ts","webpack://_N_E/./components/bridges/BridgeEditor.tsx","webpack://_N_E/./components/bridges/BridgesPanel.tsx","webpack://_N_E/./components/tools/BuiltinToolsPanel.tsx","webpack://_N_E/./hooks/usePackages.ts","webpack://_N_E/./components/tools/LangChainPackagesPanel.tsx","webpack://_N_E/./components/tools/ToolsPanel.tsx","webpack://_N_E/./lib/utils/cron.ts","webpack://_N_E/./components/scheduled-tasks/AgentModelBadge.tsx","webpack://_N_E/./components/triggers/ReactionEditor.tsx","webpack://_N_E/./components/scheduled-tasks/WatchersSection.tsx","webpack://_N_E/./components/scheduled-tasks/ScheduledTasksPanel.tsx","webpack://_N_E/./lib/agents/harness/types.ts","webpack://_N_E/./api/types.ts","webpack://_N_E/./components/harness/HarnessEditor.tsx","webpack://_N_E/./components/harness/HarnessPanel.tsx","webpack://_N_E/./components/logs/LogsPanel.tsx","webpack://_N_E/./components/env/EnvVarsPanel.tsx","webpack://_N_E/./components/ui/HeaderActivity.tsx","webpack://_N_E/./components/ui/NotificationStatus.tsx","webpack://_N_E/./components/ui/CryptoFallbackBanner.tsx","webpack://_N_E/./components/ui/UpdateAvailableBanner.tsx","webpack://_N_E/./components/ui/ServerStatus.tsx","webpack://_N_E/./components/ui/Toaster.tsx","webpack://_N_E/./components/ui/BootScreen.tsx","webpack://_N_E/./components/setup/ScreenLock.tsx","webpack://_N_E/./components/layout/MenuPanel.tsx","webpack://_N_E/./components/dashboard/dashboard-constants.ts","webpack://_N_E/./components/dashboard/CurrencyPickerRow.tsx","webpack://_N_E/./components/dashboard/DashboardHeader.tsx","webpack://_N_E/./lib/dashboard/format.ts","webpack://_N_E/./components/dashboard/Cards.tsx","webpack://_N_E/./components/dashboard/SummaryCards.tsx","webpack://_N_E/./components/dashboard/Series.tsx","webpack://_N_E/./components/dashboard/TokensCostSection.tsx","webpack://_N_E/./lib/dashboard/classify.ts","webpack://_N_E/./lib/dashboard/sort.ts","webpack://_N_E/./lib/dashboard/color.ts","webpack://_N_E/./lib/dashboard/geometry.ts","webpack://_N_E/./components/dashboard/Donuts.tsx","webpack://_N_E/./components/dashboard/ToolsAndAgentsRow.tsx","webpack://_N_E/./components/dashboard/VendorModelReportSection.tsx","webpack://_N_E/./components/dashboard/ModelPricingSection.tsx","webpack://_N_E/./components/dashboard/useCurrencyPreference.ts","webpack://_N_E/./components/dashboard/useDashboardData.ts","webpack://_N_E/./components/dashboard/DashboardPanel.tsx","webpack://_N_E/./components/layout/AppShell.tsx","webpack://_N_E/?75e2"],"sourcesContent":["\"use client\";\nimport { createContext, useCallback, useContext, useEffect, useState, type ReactNode } from \"react\";\n\nexport type Theme = \"light\" | \"dark\" | \"system\";\n\nconst STORAGE_KEY = \"jarela-theme\";\n\nfunction isTheme(v: unknown): v is Theme {\n return v === \"light\" || v === \"dark\" || v === \"system\";\n}\n\nfunction readStored(): Theme {\n if (typeof window === \"undefined\") return \"system\";\n try {\n const v = window.localStorage.getItem(STORAGE_KEY);\n return isTheme(v) ? v : \"system\";\n } catch {\n return \"system\";\n }\n}\n\nconst LIGHT_CHROME = \"#ffffff\";\nconst DARK_CHROME = \"#09090b\";\n\nfunction resolveChrome(theme: Theme): string {\n if (theme === \"light\") return LIGHT_CHROME;\n if (theme === \"dark\") return DARK_CHROME;\n if (typeof window === \"undefined\") return DARK_CHROME;\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK_CHROME : LIGHT_CHROME;\n}\n\n// Keep the single <meta name=\"theme-color\"> tag (installed by the pre-paint\n// script in app/layout.tsx) aligned with the active surface so the PWA's\n// desktop title bar and mobile address bar match the theme.\nfunction syncChrome(theme: Theme) {\n if (typeof document === \"undefined\") return;\n const meta = document.querySelector('meta[name=\"theme-color\"]');\n if (meta) meta.setAttribute(\"content\", resolveChrome(theme));\n}\n\nfunction apply(theme: Theme) {\n if (typeof document === \"undefined\") return;\n document.documentElement.setAttribute(\"data-theme\", theme);\n syncChrome(theme);\n}\n\ninterface Ctx {\n theme: Theme;\n setTheme: (t: Theme) => void;\n}\n\nconst ThemeContext = createContext<Ctx | null>(null);\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n // Initial state stays \"system\" on the server to match the pre-paint script,\n // which writes data-theme before React hydrates. The effect below syncs the\n // React state to whatever the script (or localStorage) decided.\n const [theme, setThemeState] = useState<Theme>(\"system\");\n\n useEffect(() => {\n const stored = readStored();\n setThemeState(stored);\n // When in \"system\" mode, mirror OS-level changes into the PWA chrome.\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const onChange = () => {\n if (readStored() === \"system\") syncChrome(\"system\");\n };\n mq.addEventListener?.(\"change\", onChange);\n return () => mq.removeEventListener?.(\"change\", onChange);\n }, []);\n\n const setTheme = useCallback((t: Theme) => {\n setThemeState(t);\n apply(t);\n try {\n window.localStorage.setItem(STORAGE_KEY, t);\n } catch {\n /* ignore quota / private-mode errors */\n }\n }, []);\n\n return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within ThemeProvider\");\n return ctx;\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\n\nexport function useAgentSession(agentId: string | null, preferredThreadId?: string | null) {\n const [threadId, setThreadId] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n // Critical: reset thread state immediately on agent change. Without this\n // the previous agent's threadId stays in state until the new fetch\n // resolves, and any consumer (ChatView, run attach, send) would briefly\n // operate on the wrong thread — sending messages to / loading messages\n // from agent A while the user is looking at agent B.\n setThreadId(null);\n setError(null);\n\n if (!agentId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n let cancelled = false;\n (async () => {\n try {\n // If the UI explicitly selected a thread (sidebar, toast, notification),\n // prefer it as long as it still belongs to this agent.\n if (preferredThreadId) {\n try {\n const d = await api.threads.get(preferredThreadId, { limit: 1 });\n if (cancelled) return;\n if (d.agent_id === agentId) {\n setThreadId(preferredThreadId);\n return;\n }\n } catch {\n // Fallback to the agent's default thread below.\n }\n }\n\n const t = await api.agents.getThread(agentId);\n if (cancelled) return;\n setThreadId(t.thread_id);\n } catch (err) {\n if (cancelled) return;\n setError(String(err));\n console.error(err);\n } finally {\n if (cancelled) return;\n setLoading(false);\n }\n })();\n\n // Cancel late responses if the user switches agents again before this\n // fetch resolves — otherwise the older fetch can overwrite the newer one.\n return () => { cancelled = true; };\n }, [agentId, preferredThreadId]);\n\n return { threadId, loading, error };\n}\n","\"use client\";\n// In-app toast pub/sub. Same shape as our loading store — module-level state,\n// React subscribers via a hook. Toasts come from the /events SSE feed and\n// optionally fan out to the Web Notification API too.\n//\n// Unread tracking is per-agent so the menu icon (header) and per-agent UI\n// surfaces (gear panel agent list, chat agent selector) can render their\n// own breakdowns from the same source of truth.\nimport { useEffect, useState } from \"react\";\n// Type-only import — no runtime cycle with error-report.ts.\nimport type { ErrorReportInput } from \"./error-report\";\n\n// Source the notification originated from — used by toasts/OS notifications\n// to label \"what triggered this\" so the user can tell a scheduled task ping\n// apart from a fresh agent reply or a bridged WhatsApp message.\nexport type NotifSource = \"run\" | \"task\" | \"bridge\" | \"system\";\n\nexport interface Toast {\n id: string;\n kind: \"info\" | \"success\" | \"error\";\n source: NotifSource;\n // Human label for the source, e.g. \"Scheduled task\", \"WhatsApp\", \"Reply\".\n sourceLabel: string;\n title: string;\n body: string;\n // Optional snippet of the actual content (assistant reply preview).\n preview?: string;\n // For click-to-navigate\n agent_id: string | null;\n thread_id: string | null;\n // Optional in-app deep link rendered as an action button on the toast\n // (e.g. \"Open in Settings →\" after an approval). Parsed by lib/ui/navigate.\n href?: string;\n hrefLabel?: string;\n // For unread charm tracking\n created_at: number;\n // Auto-dismiss timeout in ms (0 = sticky)\n ttl: number;\n // Full technical details (stack trace, JSON envelope) revealed by the\n // expand chevron on error toasts. Set by pushErrorToast.\n details?: string;\n // When present the Toaster renders the \"Report this issue\" button which\n // opens a pre-filled GitHub issue. Set by pushErrorToast.\n reportInput?: ErrorReportInput;\n}\n\nlet toasts: Toast[] = [];\nconst listeners = new Set<(t: Toast[]) => void>();\n\n// Per-agent unread counts. The `null` bucket holds events with no agent\n// (system messages). Total = sum of all buckets.\nconst unreadByAgent = new Map<string | null, number>();\nconst unreadListeners = new Set<() => void>();\n\nfunction notify() {\n for (const l of listeners) l(toasts);\n}\nfunction notifyUnread() {\n for (const l of unreadListeners) l();\n}\n\nexport function pushToast(input: Omit<Toast, \"id\" | \"created_at\">): string {\n const id = `t-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const t: Toast = { ...input, id, created_at: Date.now() };\n toasts = [...toasts, t];\n const key = t.agent_id;\n unreadByAgent.set(key, (unreadByAgent.get(key) ?? 0) + 1);\n notify();\n notifyUnread();\n if (t.ttl > 0) {\n setTimeout(() => dismissToast(id), t.ttl);\n }\n return id;\n}\n\nexport function dismissToast(id: string): void {\n const before = toasts.length;\n toasts = toasts.filter((t) => t.id !== id);\n if (toasts.length !== before) notify();\n}\n\nexport function clearUnread(): void {\n if (unreadByAgent.size === 0) return;\n unreadByAgent.clear();\n notifyUnread();\n}\n\nexport function clearUnreadForAgent(agentId: string | null): void {\n if (!unreadByAgent.has(agentId)) return;\n unreadByAgent.delete(agentId);\n notifyUnread();\n}\n\nfunction snapshotByAgent(): Map<string | null, number> {\n return new Map(unreadByAgent);\n}\n\nfunction totalUnread(): number {\n let n = 0;\n for (const v of unreadByAgent.values()) n += v;\n return n;\n}\n\nexport function useToasts(): Toast[] {\n const [s, setS] = useState<Toast[]>(toasts);\n useEffect(() => {\n const fn = (t: Toast[]) => setS(t);\n listeners.add(fn);\n setS(toasts);\n return () => { listeners.delete(fn); };\n }, []);\n return s;\n}\n\nexport function useUnreadCount(): number {\n const [n, setN] = useState<number>(() => totalUnread());\n useEffect(() => {\n const fn = () => setN(totalUnread());\n unreadListeners.add(fn);\n fn();\n return () => { unreadListeners.delete(fn); };\n }, []);\n return n;\n}\n\n// Read-only snapshot of per-agent unread counts. Subscribers re-render on\n// every push/clear — cheap because the map is tiny.\nexport function useUnreadByAgent(): Map<string | null, number> {\n const [m, setM] = useState<Map<string | null, number>>(() => snapshotByAgent());\n useEffect(() => {\n const fn = () => setM(snapshotByAgent());\n unreadListeners.add(fn);\n fn();\n return () => { unreadListeners.delete(fn); };\n }, []);\n return m;\n}\n\nexport function useUnreadForAgent(agentId: string | null): number {\n const m = useUnreadByAgent();\n return m.get(agentId) ?? 0;\n}\n","\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { pushToast, type NotifSource } from \"@/lib/ui/toasts\";\n\ninterface RunCompleted {\n type: \"run_completed\";\n thread_id: string;\n agent_id: string | null;\n status: \"done\" | \"error\";\n preview: string;\n ts: number;\n}\n\ninterface TaskCompleted {\n type: \"task_completed\";\n task_id: string;\n agent_id: string;\n prompt: string;\n thread_id: string;\n status: \"done\" | \"error\" | \"skipped\";\n preview: string;\n error?: string;\n ts: number;\n}\n\ninterface BridgeMessageReceived {\n type: \"bridge_message_received\";\n bridge_id: string;\n remote_jid: string;\n push_name: string | null;\n is_group: boolean;\n thread_id: string;\n agent_id: string;\n preview: string;\n ts: number;\n}\n\n// Browser-extension page-capture pushed a new user message into a thread.\n// Surfaces only as a thread refresh — no toast, no OS notification, since\n// the user just made the capture themselves and is already aware of it.\ninterface ThreadMessageAdded {\n type: \"thread_message_added\";\n thread_id: string;\n agent_id: string;\n source: \"page_capture\";\n ts: number;\n}\n\n// Background health probe state-transition. Surfaced as a sticky toast\n// so the user can act on an expired token / unreachable vendor before\n// the next agent run hits the same failure mid-conversation.\ninterface HealthAlert {\n type: \"health_alert\";\n probe: string;\n label: string;\n category: \"integration\" | \"llm\";\n status: \"auth_failed\" | \"transient\" | \"error\" | \"recovered\";\n error: string | null;\n ts: number;\n}\n\ntype NotifEvent = RunCompleted | TaskCompleted | BridgeMessageReceived;\ntype StreamEvent = NotifEvent | ThreadMessageAdded | HealthAlert;\n\ninterface AgentSummary {\n id: string;\n name: string;\n}\n\ninterface Options {\n // Predicate: should this event surface as a toast / OS notification?\n // Returning false suppresses both — used when the user is currently\n // viewing the agent that completed (the message is already on screen).\n shouldNotify: (ev: NotifEvent) => boolean;\n // For titling the toast / notification.\n resolveAgentName: (agentId: string | null) => string;\n // Optional: return a URL to the agent's avatar so OS notifications show\n // the agent icon instead of the generic Jarela logo. Null/undefined →\n // fall back to /icon-192.png.\n resolveAgentIcon?: (agentId: string | null) => string | null | undefined;\n}\n\n// Subscribes to /api/v1/events. Each event:\n// - Always pushes an in-app toast (Teams-style card, bottom-right of the\n// Jarela window). Works whenever the window is visible — including in\n// the Edge sidebar.\n// - Additionally fires a Web Notification when the window is NOT focused\n// (background tab, minimized, focused-on-another-app). The OS surfaces\n// it even when Jarela isn't visible. Requires browser permission;\n// gracefully no-op when not granted.\n// Persist the last-seen-event timestamp across reloads/relaunches.\n// Without this, mobile users who background the PWA (which suspends SSE on\n// iOS) miss every scheduler/cron event that fires while they were away,\n// because the next mount initialised `lastTs` to Date.now() and the\n// server's recentSince() replay returned nothing.\nconst LAST_TS_KEY = \"jarela.notif.lastTs\";\nfunction loadLastTs(): number {\n if (typeof window === \"undefined\") return 0;\n try {\n const raw = window.localStorage.getItem(LAST_TS_KEY);\n const n = raw ? Number(raw) : 0;\n if (!Number.isFinite(n) || n <= 0) return 0;\n // Clamp to the bus's RECENT_LIMIT window — older events are gone from\n // memory anyway, and we don't want to spam the user with day-old toasts\n // on the first reopen of a long-idle PWA.\n const MAX_WINDOW_MS = 6 * 60 * 60 * 1000; // 6h\n return Math.max(n, Date.now() - MAX_WINDOW_MS);\n } catch { return 0; }\n}\nfunction saveLastTs(ts: number): void {\n if (typeof window === \"undefined\") return;\n try { window.localStorage.setItem(LAST_TS_KEY, String(ts)); } catch { /* quota / privacy mode */ }\n}\n\nexport function useEventNotifications(options: Options) {\n const lastTsRef = useRef<number>(loadLastTs());\n const optsRef = useRef(options);\n optsRef.current = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof EventSource === \"undefined\") return;\n\n let es: EventSource | null = null;\n let cancelled = false;\n let backoff = 500;\n // Tracked so we can cancel a pending reconnect on unmount; otherwise\n // the timer fires after the component is gone and the resulting\n // EventSource leaks (and the cancelled-check doesn't help — we need\n // to also stop the timer that scheduled it).\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n function connect() {\n if (cancelled) return;\n const url = `/api/v1/events?since=${lastTsRef.current}`;\n es = new EventSource(url);\n\n es.onmessage = (msg) => {\n backoff = 500;\n let ev: StreamEvent;\n try { ev = JSON.parse(msg.data) as StreamEvent; } catch { return; }\n if (!ev.ts) return;\n\n // Page-capture push: re-fetch the affected thread AND drop a small\n // toast so the user can see *which* agent received the capture\n // without having to switch to the chat view first. The capture\n // itself was made by the user, but the routing target (default\n // agent's most-recent thread) isn't necessarily the agent they're\n // currently looking at.\n if (ev.type === \"thread_message_added\") {\n lastTsRef.current = Math.max(lastTsRef.current, ev.ts);\n saveLastTs(lastTsRef.current);\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"jarela:thread-updated\", {\n detail: { thread_id: ev.thread_id, agent_id: ev.agent_id },\n }));\n }\n // Extension refine/fill/rewrite turns share this bus only to\n // refresh open chat views — they don't warrant a toast since the\n // user just triggered the action from the extension popup/menu.\n if (ev.source !== \"page_capture\") return;\n const agentName = optsRef.current.resolveAgentName(ev.agent_id);\n pushToast({\n kind: \"info\",\n source: \"system\",\n sourceLabel: \"Page capture\",\n title: `📎 Captured to ${agentName}`,\n body: \"A page snippet was added to the most recent thread. Open Jarela to follow up.\",\n agent_id: ev.agent_id,\n thread_id: ev.thread_id,\n ttl: 5000,\n });\n return;\n }\n\n // Background health probes: surface as a sticky toast so the user\n // notices before the agent burns a turn on an expired token. The\n // runner already dedups so every health_alert is worth showing.\n if (ev.type === \"health_alert\") {\n lastTsRef.current = Math.max(lastTsRef.current, ev.ts);\n saveLastTs(lastTsRef.current);\n const recovered = ev.status === \"recovered\";\n pushToast({\n kind: recovered ? \"success\" : \"error\",\n source: \"system\",\n sourceLabel: ev.category === \"llm\" ? \"LLM provider\" : \"Integration\",\n title: recovered ? `${ev.label} recovered` : `${ev.label} is failing`,\n body: ev.error ?? (recovered ? \"Probe is green again.\" : \"Probe failed.\"),\n agent_id: null,\n thread_id: null,\n href: \"/setup\",\n hrefLabel: \"Open setup\",\n ttl: recovered ? 6000 : 0,\n });\n return;\n }\n\n // Ignore event types this hook doesn't surface (bridge_status,\n // bridge_unrouted, …). The badge would otherwise increment on every\n // pairing-state ping.\n if (\n ev.type !== \"run_completed\" &&\n ev.type !== \"task_completed\" &&\n ev.type !== \"bridge_message_received\"\n ) return;\n // Silent scheduled tasks that chose NO_REPLY publish status=\"skipped\".\n // Suppress the badge/toast/OS notification — they intentionally\n // produced nothing for the user to see.\n if (ev.type === \"task_completed\" && ev.status === \"skipped\") return;\n lastTsRef.current = Math.max(lastTsRef.current, ev.ts);\n saveLastTs(lastTsRef.current);\n // Broadcast a thread-updated event regardless of whether we'll\n // surface a toast / OS notification. Other tabs / devices that\n // have the chat open for the same thread need to refetch their\n // message list even when shouldNotify() suppresses the ping\n // (e.g. the user is actively viewing this agent on the PC while\n // sending the message from iOS — without this they had to refresh\n // the chat window to see what they typed on the phone).\n const evThreadId = (ev as { thread_id?: string }).thread_id;\n if (evThreadId && typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"jarela:thread-updated\", {\n detail: { thread_id: evThreadId, agent_id: ev.agent_id ?? null },\n }));\n }\n handleEvent(ev);\n };\n\n es.onerror = () => {\n es?.close();\n es = null;\n if (cancelled) return;\n reconnectTimer = setTimeout(connect, Math.min(backoff, 30_000));\n backoff = Math.min(backoff * 2, 30_000);\n };\n }\n\n function handleEvent(ev: NotifEvent) {\n if (!optsRef.current.shouldNotify(ev)) return;\n\n const { title, body, kind, source, sourceLabel } =\n format(ev, optsRef.current.resolveAgentName);\n\n // Always push an in-app toast — it is the source of truth for the\n // per-agent unread badge (header menu icon, gear panel, chat agent\n // selector). The OS Web Notification is layered on top when permission\n // is granted so the user still gets a system ping if Jarela isn't\n // focused.\n pushToast({\n kind,\n source,\n sourceLabel,\n title,\n body,\n preview: ev.preview || undefined,\n agent_id: ev.agent_id,\n thread_id: ev.thread_id || null,\n ttl: 6000,\n });\n\n const canOSNotify =\n typeof Notification !== \"undefined\" && Notification.permission === \"granted\";\n if (canOSNotify) {\n try {\n const customIcon = optsRef.current.resolveAgentIcon?.(ev.agent_id) ?? null;\n // Tag uniquely per source/identity so a new run replaces the old\n // run-toast for the same thread, but doesn't collide with a task\n // or bridge ping that happens to share an id.\n const tag =\n ev.type === \"run_completed\" ? `run:${ev.thread_id}` :\n ev.type === \"task_completed\" ? `task:${ev.task_id}` :\n /* bridge_message_received */ `bridge:${ev.bridge_id}:${ev.remote_jid}`;\n const n = new Notification(title, {\n body: ev.preview ? `${body}\\n\\n${ev.preview}` : body,\n tag,\n icon: customIcon || \"/icon-192.png\",\n });\n // Click handler: focus the Jarela window, jump to the exact thread\n // the event happened in (or fall back to just the agent), dismiss\n // the OS notification.\n n.onclick = () => {\n window.focus();\n const agentId = ev.agent_id;\n const threadId = (ev as { thread_id?: string }).thread_id ?? null;\n if (agentId) {\n window.dispatchEvent(new CustomEvent(\"jarela:focus-agent\", {\n detail: { agentId, threadId },\n }));\n }\n n.close();\n };\n } catch { /* OS rejected — toast is already up, nothing else to do */ }\n }\n }\n\n connect();\n // When the PWA comes back to the foreground (iOS suspends SSE in the\n // background, often without firing onerror), force a fresh reconnect so\n // the server's recentSince() replays anything that happened while away.\n const onVisible = () => {\n if (document.visibilityState !== \"visible\") return;\n if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }\n try { es?.close(); } catch { /* */ }\n es = null;\n backoff = 500;\n connect();\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n return () => {\n cancelled = true;\n if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }\n document.removeEventListener(\"visibilitychange\", onVisible);\n es?.close();\n };\n }, []);\n}\n\nfunction format(ev: NotifEvent, resolveName: (id: string | null) => string): {\n title: string; body: string; kind: \"info\" | \"success\" | \"error\";\n source: NotifSource; sourceLabel: string;\n} {\n const name = resolveName(ev.agent_id);\n if (ev.type === \"run_completed\") {\n return ev.status === \"error\"\n ? { title: `${name} — error`, body: ev.preview || \"Run failed.\",\n kind: \"error\", source: \"run\", sourceLabel: \"Reply\" }\n : { title: `${name} replied`, body: ev.preview || \"Response ready.\",\n kind: \"info\", source: \"run\", sourceLabel: \"Reply\" };\n }\n if (ev.type === \"task_completed\") {\n if (ev.status === \"error\") {\n return {\n title: `${name} — scheduled task failed`,\n body: ev.error ?? \"Task failed.\",\n kind: \"error\", source: \"task\", sourceLabel: \"Scheduled task\",\n };\n }\n return {\n // Show only the assistant reply preview — the prompt is what the user\n // already knows they scheduled, the value of the notification is the\n // answer that just arrived.\n title: `${name} — scheduled task completed`,\n body: ev.preview || \"(no output)\",\n kind: \"success\", source: \"task\", sourceLabel: \"Scheduled task\",\n };\n }\n // bridge_message_received\n // Direction matches the data flow: the inbound side messaged the agent.\n // Title reads \"<sender> → <agent>\" so the user sees who reached out to\n // which of their agents at a glance. For group chats the channel label\n // already says \"WhatsApp group\"; we also tag the sender with \"(group)\"\n // inside the title so it still reads correctly without the source pill.\n const who = ev.push_name || ev.remote_jid;\n const sender = ev.is_group ? `${who} (group)` : who;\n const channel = ev.is_group ? \"WhatsApp group\" : \"WhatsApp\";\n return {\n title: `${sender} → ${name}`,\n body: ev.preview || \"(no reply)\",\n kind: \"info\", source: \"bridge\", sourceLabel: channel,\n };\n}\n\nexport async function ensureNotificationPermission(): Promise<NotificationPermission> {\n if (typeof Notification === \"undefined\") return \"denied\";\n if (Notification.permission !== \"default\") return Notification.permission;\n try { return await Notification.requestPermission(); } catch { return \"denied\"; }\n}\n\nexport type { NotifEvent, AgentSummary };\n","// Parse in-app deep-link hrefs into the {tab, item, hash} shape that\n// AppContext understands. Consumers (Toaster button, markdown <a> in\n// MessageBubble) call this and dispatch SET_TAB + SET_SELECTION themselves;\n// keeping the parser pure means it works outside React too.\n\nimport type { Tab } from \"@/contexts/AppContext\";\n\nexport interface ParsedHref {\n tab?: Tab;\n item?: string;\n // When a `thread` query param is present, the link points at a specific\n // chat thread. `agent` is required so the AppShell can dispatch\n // SELECT_THREAD (which carries both ids); a thread-only href is treated\n // as incomplete and falls back to tab navigation.\n thread?: string;\n agent?: string;\n hash?: string;\n external: boolean;\n}\n\nconst TABS: Tab[] = [\"chat\", \"dashboard\", \"agents\", \"memory\", \"models\", \"credentials\", \"mcp\", \"extensions\", \"tools\", \"tasks\", \"bridges\", \"profile\", \"harness\", \"documents\"];\n\nexport function parseHref(input: string | null | undefined): ParsedHref {\n if (!input) return { external: false };\n let href = input;\n\n // Absolute URL with scheme (http, https, mailto, tel, …) → external.\n if (/^[a-z][a-z0-9+.-]*:/i.test(href)) return { external: true };\n\n let hash: string | undefined;\n const hashIdx = href.indexOf(\"#\");\n if (hashIdx >= 0) {\n hash = href.slice(hashIdx + 1) || undefined;\n href = href.slice(0, hashIdx);\n }\n\n let queryStr = \"\";\n const qIdx = href.indexOf(\"?\");\n if (qIdx >= 0) queryStr = href.slice(qIdx + 1);\n\n const params = new URLSearchParams(queryStr);\n const tabRaw = params.get(\"tab\");\n const tab = TABS.includes(tabRaw as Tab) ? (tabRaw as Tab) : undefined;\n const item = params.get(\"item\") ?? undefined;\n const thread = params.get(\"thread\") ?? undefined;\n const agent = params.get(\"agent\") ?? undefined;\n return { tab, item, thread, agent, hash, external: false };\n}\n\n// Build the URL we want to push when the reducer is the source of truth.\nexport function buildHref(tab: Tab, item?: string | null, hash?: string | null): string {\n const params = new URLSearchParams();\n if (tab !== \"chat\") params.set(\"tab\", tab);\n if (item) params.set(\"item\", item);\n const qs = params.toString();\n const fragment = hash ? `#${hash.replace(/^#/, \"\")}` : \"\";\n return `/${qs ? `?${qs}` : \"\"}${fragment}`;\n}\n","\"use client\";\n// Bidirectional sync between AppContext (tab + selectedItem) and the URL's\n// search params. Mounted once in AppShell.\n//\n// On mount: read window.location → dispatch SET_TAB + SET_SELECTION so a\n// fresh load lands on the deep-linked surface. On reducer change: replace\n// the URL via history.replaceState so reload preserves the surface.\n//\n// We use history.replaceState directly rather than next/navigation's\n// router.replace() because the latter triggers a soft navigation that can\n// re-mount route segments — we just want the address bar to mirror state\n// without disturbing the <Activity>-based tab keepalive in AppShell.\n\nimport { useEffect, useRef } from \"react\";\nimport { useAppContext, type Tab } from \"@/contexts/AppContext\";\nimport { buildHref, parseHref } from \"@/lib/ui/navigate\";\n\nconst TABS: Tab[] = [\"chat\", \"dashboard\", \"agents\", \"memory\", \"documents\", \"models\", \"credentials\", \"mcp\", \"extensions\", \"tools\", \"tasks\", \"bridges\", \"profile\", \"harness\"];\n\nexport function useUrlSync() {\n const { state, dispatch } = useAppContext();\n // Idempotency guard: avoid re-firing the initial dispatch when the URL we\n // just wrote matches the state that wrote it.\n const lastWrittenRef = useRef<string | null>(null);\n\n // Initial read + popstate (back/forward) listener.\n useEffect(() => {\n function applyFromUrl() {\n if (typeof window === \"undefined\") return;\n const href = `${window.location.search}${window.location.hash}`;\n const parsed = parseHref(href);\n const tab = parsed.tab ?? \"chat\";\n if (TABS.includes(tab)) {\n dispatch({ type: \"SET_TAB\", tab });\n dispatch({ type: \"SET_SELECTION\", tab, itemId: parsed.item ?? null });\n }\n }\n applyFromUrl();\n window.addEventListener(\"popstate\", applyFromUrl);\n return () => window.removeEventListener(\"popstate\", applyFromUrl);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Mirror reducer → URL. Preserve any existing #fragment so message anchors\n // survive tab toggles.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const item = state.selectedItem[state.activeTab] ?? null;\n const hash = window.location.hash.replace(/^#/, \"\") || null;\n const next = buildHref(state.activeTab, item, hash);\n const current = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n if (current === next || lastWrittenRef.current === next) return;\n lastWrittenRef.current = next;\n window.history.replaceState(null, \"\", next);\n }, [state.activeTab, state.selectedItem]);\n}\n","import type { AgentConfig, ModelConfig } from \"@/api/types\";\n\n/**\n * Resolve which `ModelConfig` will actually be used for an agent at runtime.\n *\n * Mirrors what `lib/agents/llm.ts` does server-side: when an agent has\n * `model_config_name` set, that wins; otherwise the workspace-wide default\n * model is used. Both client (BridgeEditor, AgentEditor capability hints)\n * and server need the same logic — this is the single source of truth.\n *\n * Returns `null` only when neither the requested config nor the default\n * exists in the provided list (typically: no models configured yet).\n */\nexport function resolveAgentModel(\n agent: Pick<AgentConfig, \"model_config_name\"> | null | undefined,\n models: readonly ModelConfig[],\n): ModelConfig | null {\n const defaultModel = models.find((m) => m.is_default) ?? null;\n if (!agent?.model_config_name) return defaultModel;\n return models.find((m) => m.name === agent.model_config_name) ?? defaultModel;\n}\n\nexport type AgentModelStatus =\n | { state: \"ok\"; model: ModelConfig }\n // Agent references a specific model_config_name that no longer exists.\n // Server-side this falls back to the default model, but if the user\n // explicitly picked a model they likely want a heads-up rather than a\n // silent substitution.\n | { state: \"missing\"; requested: string; fallback: ModelConfig | null }\n // Agent has no explicit model AND no workspace default is set. Any run\n // will throw `no_model` at the LLM layer — for unattended runs\n // (scheduled tasks, watchers) this fails without the operator watching.\n | { state: \"no-model\" }\n // Agent row itself wasn't found (e.g. deleted between fetches). Anything\n // pointing at this agent will fail at the trigger handler.\n | { state: \"no-agent\" };\n\n/**\n * Diagnose whether an agent has a runnable model RIGHT NOW. Used by the\n * Scheduled Tasks and Watchers panels to surface model-availability issues\n * before an unattended run silently no-ops with `no_model`.\n */\nexport function agentModelStatus(\n agent: Pick<AgentConfig, \"model_config_name\"> | null | undefined,\n models: readonly ModelConfig[],\n): AgentModelStatus {\n if (!agent) return { state: \"no-agent\" };\n const defaultModel = models.find((m) => m.is_default) ?? null;\n if (agent.model_config_name) {\n const exact = models.find((m) => m.name === agent.model_config_name);\n if (exact) return { state: \"ok\", model: exact };\n return { state: \"missing\", requested: agent.model_config_name, fallback: defaultModel };\n }\n if (defaultModel) return { state: \"ok\", model: defaultModel };\n return { state: \"no-model\" };\n}\n","\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { api } from \"@/api/client\";\nimport { agentModelStatus } from \"@/lib/agents/effective-model\";\nimport { dismissToast, pushToast } from \"@/lib/ui/toasts\";\n\n// Stable IDs for each kind of configuration issue we surface, scoped by\n// the affected agent / model name so we can dedupe across refreshes and\n// also dismiss when the issue is fixed without spamming on every reload.\ntype IssueId =\n | `no-models`\n | `no-default-model`\n | `agent-missing-model:${string}`\n | `agent-no-model:${string}`;\n\n/**\n * Watches model/agent CRUD and surfaces configuration issues as sticky\n * top toasts with deep-links to the relevant setup panel. Without this\n * the only visible warnings were inline badges in the Scheduled Tasks\n * panel — operators using only the Chat surface had no clue an agent\n * was silently falling back to the default (or had no model at all).\n *\n * Dedupes via a tracked Map of issue → toast id; reconciles on every\n * refresh so resolved issues get auto-dismissed.\n */\nexport function useConfigurationIssues(): void {\n const activeRef = useRef<Map<IssueId, string>>(new Map());\n\n useEffect(() => {\n let cancelled = false;\n\n async function refresh() {\n let models, agents;\n try {\n [models, agents] = await Promise.all([api.models.list({ force: true }), api.agents.list()]);\n } catch {\n return; // server unreachable — don't fight the offline banner\n }\n if (cancelled) return;\n\n const next = new Set<IssueId>();\n const pushIssue = (\n id: IssueId,\n kind: \"error\" | \"info\",\n title: string,\n body: string,\n href: string,\n hrefLabel: string,\n ) => {\n next.add(id);\n if (activeRef.current.has(id)) return; // already shown — keep stable\n const toastId = pushToast({\n kind,\n source: \"system\",\n sourceLabel: \"Configuration\",\n title,\n body,\n agent_id: null,\n thread_id: null,\n href,\n hrefLabel,\n ttl: 0, // sticky until fixed\n });\n activeRef.current.set(id, toastId);\n };\n\n if (models.length === 0) {\n pushIssue(\n \"no-models\",\n \"error\",\n \"No model configured\",\n \"Agents can't run until at least one model config exists.\",\n \"?tab=models\",\n \"Open Models →\",\n );\n } else if (!models.some((m) => m.is_default)) {\n pushIssue(\n \"no-default-model\",\n \"info\",\n \"No default model set\",\n \"Agents without an explicit model will fail. Pick one default.\",\n \"?tab=models\",\n \"Open Models →\",\n );\n }\n\n for (const a of agents) {\n const status = agentModelStatus(a, models);\n if (status.state === \"missing\") {\n pushIssue(\n `agent-missing-model:${a.id}`,\n \"info\",\n `Agent \"${a.name}\" model is missing`,\n status.fallback\n ? `Bound model \"${status.requested}\" was deleted — runs fall back to default \"${status.fallback.name}\".`\n : `Bound model \"${status.requested}\" was deleted and no default is set — runs will fail.`,\n `?tab=agents&item=${encodeURIComponent(a.id)}`,\n \"Fix in Agents →\",\n );\n } else if (status.state === \"no-model\") {\n pushIssue(\n `agent-no-model:${a.id}`,\n \"error\",\n `Agent \"${a.name}\" has no model`,\n \"Pick a model or set a workspace default.\",\n `?tab=agents&item=${encodeURIComponent(a.id)}`,\n \"Fix in Agents →\",\n );\n }\n }\n\n // Dismiss any toast whose underlying issue no longer applies.\n for (const [id, toastId] of activeRef.current.entries()) {\n if (!next.has(id)) {\n dismissToast(toastId);\n activeRef.current.delete(id);\n }\n }\n }\n\n void refresh();\n const onChange = () => { void refresh(); };\n window.addEventListener(\"jarela:models-changed\", onChange);\n window.addEventListener(\"jarela:agents-changed\", onChange);\n return () => {\n cancelled = true;\n window.removeEventListener(\"jarela:models-changed\", onChange);\n window.removeEventListener(\"jarela:agents-changed\", onChange);\n };\n }, []);\n}\n","\"use client\";\n// Tiny global loading-state store. Any component can register itself as\n// \"currently busy\"; the top-level progress bar reads the aggregate count and\n// shows itself whenever count > 0. Module-level state is fine here — all\n// usage is client-side and there's exactly one progress bar per page.\nimport { useEffect, useState } from \"react\";\n\nlet activeCount = 0;\nconst listeners = new Set<(n: number) => void>();\n\nfunction notify() {\n for (const l of listeners) l(activeCount);\n}\n\n// Returns a cleanup function — call it when work finishes (or on effect unmount).\nexport function startLoading(): () => void {\n activeCount += 1;\n notify();\n let cleared = false;\n return () => {\n if (cleared) return;\n cleared = true;\n activeCount = Math.max(0, activeCount - 1);\n notify();\n };\n}\n\n// Subscribe to the aggregate count. Re-renders the caller when it changes.\nexport function useLoadingCount(): number {\n const [n, setN] = useState(activeCount);\n useEffect(() => {\n const fn = (v: number) => setN(v);\n listeners.add(fn);\n setN(activeCount);\n return () => { listeners.delete(fn); };\n }, []);\n return n;\n}\n\n// Convenience: tracks `active` automatically. When `active` flips true, register;\n// when it flips false (or component unmounts), unregister.\nexport function useTrackLoading(active: boolean): void {\n useEffect(() => {\n if (!active) return;\n return startLoading();\n }, [active]);\n}\n\n// ---------------------------------------------------------------------------\n// Activity label channel. Independent of the loading count: callers that\n// want to surface a human-readable \"what's happening right now\" string\n// (e.g. \"thinking…\", \"using web_search\") push onto a small stack. The\n// header reads the top of the stack and renders it inline.\n// ---------------------------------------------------------------------------\n\nlet activitySeq = 0;\nconst activityStack: Array<{ id: number; label: string }> = [];\nconst activityListeners = new Set<(label: string | null) => void>();\n\nfunction currentActivity(): string | null {\n return activityStack.length > 0 ? activityStack[activityStack.length - 1].label : null;\n}\n\nfunction notifyActivity() {\n const top = currentActivity();\n for (const l of activityListeners) l(top);\n}\n\n// Push a label and return a setter+clearer for the same slot. The setter\n// keeps the same stack id so updating a label (e.g. tool name changing\n// mid-run) doesn't reorder layered activities. `clear` removes the slot.\nexport function pushActivity(label: string): {\n set: (next: string) => void;\n clear: () => void;\n} {\n const id = ++activitySeq;\n activityStack.push({ id, label });\n notifyActivity();\n return {\n set(next: string) {\n const slot = activityStack.find((s) => s.id === id);\n if (slot && slot.label !== next) {\n slot.label = next;\n notifyActivity();\n }\n },\n clear() {\n const idx = activityStack.findIndex((s) => s.id === id);\n if (idx >= 0) {\n activityStack.splice(idx, 1);\n notifyActivity();\n }\n },\n };\n}\n\nexport function useActivityLabel(): string | null {\n const [label, setLabel] = useState<string | null>(currentActivity());\n useEffect(() => {\n const fn = (v: string | null) => setLabel(v);\n activityListeners.add(fn);\n setLabel(currentActivity());\n return () => { activityListeners.delete(fn); };\n }, []);\n return label;\n}\n","\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { api, submitRun, subscribeRun } from \"@/api/client\";\nimport type { ContentPart, SSEEventType, StreamOptions } from \"@/api/types\";\nimport type { ToolEvent } from \"@/components/chat/ToolList\";\nimport { pushActivity } from \"@/lib/ui/loading\";\n\nexport type { ToolEvent };\n\n// Single-transport agent run hook (ADR-0008): one POST to submit + one\n// `EventSource` (under the hood) to subscribe. The hook keeps a stable\n// surface for `ChatView` — `start`, `attach`, `stop`, `streaming`,\n// `streamingContent`, etc. — even though the transport underneath collapsed\n// from three legs (WS sidecar / SSE-POST / SSE-GET reattach) to one.\nexport function useSSE(onDone?: () => void) {\n const [streaming, setStreaming] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const [thinkingContent, setThinkingContent] = useState(\"\");\n const [toolEvents, setToolEvents] = useState<ToolEvent[]>([]);\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const threadIdRef = useRef<string | null>(null);\n // Live \"what is the agent doing\" label, surfaced in the app header. The\n // slot stays open for the duration of one run; we mutate its label as\n // tool calls come and go so the header text updates in place without\n // pushing/popping (which would flicker stacked activities).\n const activityRef = useRef<ReturnType<typeof pushActivity> | null>(null);\n const activeToolsRef = useRef<Map<string, string>>(new Map());\n\n // Streaming-delta batching. SSE emits one event per chunk (often per\n // token, sometimes per character). Calling setState on every event\n // forced a full ChatView re-render per delta — on long threads that\n // adds noticeable jank because the message list, queued bubbles, and\n // markdown subtrees all participate. We accumulate deltas into refs\n // and flush once per animation frame, which collapses bursty streams\n // into ~60 renders/sec regardless of token rate.\n const pendingTextRef = useRef(\"\");\n const pendingThinkingRef = useRef(\"\");\n const rafIdRef = useRef<number | null>(null);\n\n const flushPending = useCallback(() => {\n rafIdRef.current = null;\n if (pendingTextRef.current) {\n const delta = pendingTextRef.current;\n pendingTextRef.current = \"\";\n setStreamingContent((p) => p + delta);\n }\n if (pendingThinkingRef.current) {\n const delta = pendingThinkingRef.current;\n pendingThinkingRef.current = \"\";\n setThinkingContent((p) => p + delta);\n }\n }, []);\n\n const scheduleFlush = useCallback(() => {\n if (rafIdRef.current !== null) return;\n if (typeof requestAnimationFrame === \"undefined\") {\n // SSR / test environments — flush synchronously so React state\n // assertions in unit tests still see the appended deltas.\n flushPending();\n return;\n }\n rafIdRef.current = requestAnimationFrame(flushPending);\n }, [flushPending]);\n\n const cancelPendingFlush = useCallback(() => {\n if (rafIdRef.current !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(rafIdRef.current);\n }\n rafIdRef.current = null;\n pendingTextRef.current = \"\";\n pendingThinkingRef.current = \"\";\n }, []);\n\n const openActivity = useCallback((initial: string) => {\n activityRef.current?.clear();\n activeToolsRef.current.clear();\n activityRef.current = pushActivity(initial);\n }, []);\n\n const closeActivity = useCallback(() => {\n activityRef.current?.clear();\n activityRef.current = null;\n activeToolsRef.current.clear();\n }, []);\n\n // Always release the activity label if the hook unmounts mid-run, so a\n // dangling \"thinking…\" can't outlive its session.\n useEffect(() => closeActivity, [closeActivity]);\n\n // Cancel any pending rAF flush on unmount so it doesn't fire against a\n // dead component (React would warn about setState-after-unmount).\n useEffect(() => () => { cancelPendingFlush(); }, [cancelPendingFlush]);\n\n const consume = useCallback(async (\n iterable: AsyncIterable<string>,\n ): Promise<void> => {\n for await (const raw of iterable) {\n const event = JSON.parse(raw) as SSEEventType;\n if (event.type === \"text_delta\") {\n pendingTextRef.current += event.delta;\n scheduleFlush();\n activityRef.current?.set(\"Responding…\");\n } else if (event.type === \"thinking_delta\") {\n pendingThinkingRef.current += event.delta;\n scheduleFlush();\n if (activeToolsRef.current.size === 0) activityRef.current?.set(\"Thinking…\");\n } else if (event.type === \"tool_call\") {\n // Flush any buffered text before the tool event so the order on\n // screen matches the order on the wire.\n flushPending();\n setToolEvents((prev) => [\n ...prev,\n { id: event.id, phase: \"call\", name: event.name, payload: event.arguments },\n ]);\n activeToolsRef.current.set(event.id, event.name);\n activityRef.current?.set(`Using ${event.name}…`);\n } else if (event.type === \"tool_result\") {\n flushPending();\n setToolEvents((prev) => [\n ...prev,\n { id: event.id, phase: \"result\", name: event.name, payload: event.result },\n ]);\n activeToolsRef.current.delete(event.id);\n const remaining = activeToolsRef.current.values().next().value as string | undefined;\n activityRef.current?.set(remaining ? `Using ${remaining}…` : \"Thinking…\");\n } else if (event.type === \"done\") {\n flushPending();\n setStreaming(false);\n closeActivity();\n // Don't clear streamingContent here — it would cause a visual gap\n // between \"stream done\" and \"refetched messages arrived\" where the\n // assistant bubble disappears for ~100ms. The consumer (ChatView)\n // calls clearStreamingContent after refetch lands, swapping the\n // streaming bubble for the persisted message in a single render.\n // Don't clear thinkingContent either: thinking isn't persisted on\n // the message, so clearing here would yank it out from under a user\n // who's still reading. It clears on the next start()/attach().\n onDone?.();\n break;\n } else if (event.type === \"error\") {\n cancelPendingFlush();\n setStreaming(false);\n setStreamingContent(\"\");\n setThinkingContent(\"\");\n closeActivity();\n setError(event.message);\n break;\n }\n }\n }, [onDone, closeActivity, flushPending, scheduleFlush, cancelPendingFlush]);\n\n const start = useCallback(async (\n threadId: string,\n message: string,\n options?: StreamOptions,\n attachments?: ContentPart[],\n hotSince?: string | null,\n ): Promise<{ accepted: boolean }> => {\n abortRef.current?.abort();\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n threadIdRef.current = threadId;\n cancelPendingFlush();\n setStreaming(true);\n setStreamingContent(\"\");\n setThinkingContent(\"\");\n setToolEvents([]);\n setError(null);\n openActivity(\"Sending…\");\n\n try {\n // Command: register the run server-side. 202 = we own this turn; 409\n // = another tab/device owns it (caller re-queues, we still subscribe\n // so the user sees the in-flight turn's deltas render).\n const submit = await submitRun(threadId, message, ctrl.signal, options, attachments, hotSince);\n\n // Query: subscribe to the run's chunk stream. Always opens the GET,\n // regardless of whether we got 202 or 409 — if 409 a run is already\n // in flight on the server and we want to observe it.\n await consume(subscribeRun(threadId, ctrl.signal, options));\n return { accepted: submit.accepted };\n } catch (err) {\n if ((err as Error).name !== \"AbortError\") {\n setError(String(err));\n }\n return { accepted: false };\n } finally {\n // Always release the gate when the stream ends — defends against the\n // consume() loop returning without ever observing a terminal `done`\n // event (e.g. the EventSource closed cleanly with zero events). If\n // we relied solely on the `done` branch inside consume(), the chat\n // would stay locked behind the Stop button forever.\n //\n // We intentionally do NOT clear streamingContent / thinkingContent\n // here — the consumer (ChatView) swaps them for the persisted\n // assistant bubble once the refetch lands; clearing now would yank\n // the text out from under the user. The next start()/attach() resets\n // them.\n setStreaming(false);\n closeActivity();\n }\n }, [consume, openActivity, closeActivity, cancelPendingFlush]);\n\n // Stop the active run. Three-part: (1) tell the server to abort the\n // agent stream so the LangGraph loop unwinds; (2) tear down local\n // streaming state immediately so the UI gates release and the queue\n // drains — we cannot rely on the server's `error`+`done` round-trip\n // because step (3) closes the EventSource before those broadcasts\n // arrive; (3) abort the local controller so the EventSource closes\n // and the iterator's finally{} fires. Without step (2) the consume()\n // loop exits via its abort path (no terminal event) and never calls\n // setStreaming(false) / onDone — the chat appears frozen and the only\n // recovery is a full refresh.\n const stop = useCallback(() => {\n const tid = threadIdRef.current;\n if (tid) {\n void api.threads.abortRun(tid).catch(() => { /* server already idle */ });\n }\n flushPending();\n setStreaming(false);\n // Keep streamingContent and thinkingContent visible until the next\n // start()/attach() — same pattern as the `done` branch in consume().\n closeActivity();\n abortRef.current?.abort();\n onDone?.();\n }, [onDone, closeActivity, flushPending]);\n\n // Attach to an in-flight run for the given thread (server-side run kept\n // going because the user switched away, or because this is a fresh\n // navigation into a session whose run is still streaming). Sets\n // `streaming` optimistically BEFORE the GET resolves so the input bar\n // gates / Stop button shows / queue drain blocks immediately on session\n // open — otherwise there's a race window where the UI thinks no run is\n // active, accepts a new POST, and the server rejects it with 409.\n const attach = useCallback(async (threadId: string) => {\n abortRef.current?.abort();\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n threadIdRef.current = threadId;\n cancelPendingFlush();\n setStreaming(true);\n setStreamingContent(\"\");\n setThinkingContent(\"\");\n setToolEvents([]);\n setError(null);\n openActivity(\"Reconnecting…\");\n\n try {\n await consume(subscribeRun(threadId, ctrl.signal));\n } catch (err) {\n if ((err as Error).name !== \"AbortError\") {\n onDone?.();\n }\n } finally {\n // Always release the optimistic gate when the stream ends — whether\n // via terminal `done`/`error` event, a thrown failure, or a clean\n // EventSource close with no events (idle thread, server returned 404\n // so the iterator exited without yielding). Without this, navigating\n // into an idle thread leaves streaming=true forever: the Stop button\n // hangs in the composer and the \"Reconnecting…\" badge never clears.\n setStreaming(false);\n closeActivity();\n }\n }, [consume, onDone, openActivity, closeActivity, cancelPendingFlush]);\n\n // Called by the consumer after a refetch lands, so the streaming bubble\n // gets swapped for the persisted assistant message in a single render.\n const clearStreamingContent = useCallback(() => { setStreamingContent(\"\"); }, []);\n\n return { streaming, streamingContent, thinkingContent, toolEvents, error, start, stop, attach, clearStreamingContent };\n}\n","\"use client\";\nimport { Check, ChevronDown, ChevronUp, ShieldAlert, X } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { IntegrationDefinition, PendingAction } from \"@/api/types\";\nimport { pushToast } from \"@/lib/ui/toasts\";\n\n// Compute the deep-link URL + label for a successfully-approved action so\n// the resulting toast lets the user jump to the row that just changed.\n// Returns null for kinds without a sensible settings target.\nfunction approvalToastTarget(action: PendingAction): { href: string; hrefLabel: string; title: string } | null {\n const p = action.payload as Record<string, unknown>;\n const str = (k: string) => (typeof p[k] === \"string\" ? (p[k] as string) : undefined);\n switch (action.kind) {\n case \"enable_integration\": {\n const id = str(\"id\");\n return id ? { href: `?tab=credentials&item=${encodeURIComponent(id)}`, hrefLabel: \"Open in Credentials →\", title: `${id} enabled` } : null;\n }\n case \"start_oauth\": {\n const id = str(\"integration_id\");\n return id ? { href: `?tab=credentials&item=${encodeURIComponent(id)}`, hrefLabel: \"Open in Credentials →\", title: `${id} authorized` } : null;\n }\n case \"set_provider_key\": {\n const name = str(\"name\") ?? str(\"provider\");\n return name ? { href: `?tab=models&item=${encodeURIComponent(name)}`, hrefLabel: \"Open in Models →\", title: `${name} key saved` } : null;\n }\n case \"install_mcp\":\n case \"toggle_mcp\": {\n const name = str(\"name\") ?? str(\"registry_id\");\n return name ? { href: `?tab=mcp&item=${encodeURIComponent(name)}`, hrefLabel: \"Open in MCP →\", title: `MCP server ${action.kind === \"install_mcp\" ? \"installed\" : \"updated\"}` } : null;\n }\n case \"update_agent\":\n case \"update_agent_tools\": {\n const id = str(\"agent_id\");\n return id ? { href: `?tab=agents&item=${encodeURIComponent(id)}`, hrefLabel: \"Open agent →\", title: \"Agent updated\" } : null;\n }\n case \"upsert_harness\": {\n // Prefer the harness id from the apply result (creates assign a fresh\n // custom:<uuid>); fall back to the payload id for edits.\n const result = (action.result ?? null) as Record<string, unknown> | null;\n const resultId = result && typeof result[\"id\"] === \"string\" ? (result[\"id\"] as string) : undefined;\n const id = resultId ?? str(\"id\");\n return id ? { href: `?tab=harness&item=${encodeURIComponent(id)}`, hrefLabel: \"Open in Harness →\", title: \"Harness saved\" } : { href: \"?tab=harness\", hrefLabel: \"Open Harness →\", title: \"Harness saved\" };\n }\n default:\n return null;\n }\n}\n\nfunction pushApprovalToast(action: PendingAction) {\n const t = approvalToastTarget(action);\n if (!t) return;\n pushToast({\n kind: \"success\",\n source: \"system\",\n sourceLabel: \"Setup\",\n title: t.title,\n body: action.reason ?? \"Change applied.\",\n agent_id: action.agent_id ?? null,\n thread_id: null,\n href: t.href,\n hrefLabel: t.hrefLabel,\n ttl: 8000,\n });\n}\n\n// A small banner that appears above the input bar whenever the agent has\n// queued one or more proposals for the user's approval. Each row shows\n// what the change is + the agent's reason + approve/deny buttons.\n//\n// Polled every 4s and on tab visibility change. We could subscribe via\n// /api/v1/events instead, but the load is trivial and polling avoids one\n// more SSE stream from leaking memory if the component unmounts.\n//\n// ADR-0010 kinds (`set_provider_key`, `enable_integration`, `start_oauth`)\n// require user-side material the agent never sees — Approve opens a small\n// secret-collection modal whose values ride to the server in `extras` and\n// (for OAuth) trigger a window.open to the vendor consent screen.\n\ntype SecretFormState = {\n action: PendingAction;\n fields: Array<{ key: string; label: string; secret: boolean; required: boolean; placeholder?: string }>;\n values: Record<string, string>;\n submitting: boolean;\n error: string | null;\n};\n\nexport function ApprovalsBanner({\n agentId,\n onChange,\n}: {\n agentId: string | null;\n onChange?: () => void;\n}) {\n const [pending, setPending] = useState<PendingAction[]>([]);\n const [open, setOpen] = useState(false);\n const [busyIds, setBusyIds] = useState<Set<string>>(new Set());\n const [secretForm, setSecretForm] = useState<SecretFormState | null>(null);\n\n async function refresh() {\n try {\n const all = await api.pending.list(\"pending\");\n const filtered = agentId ? all.filter((a) => a.agent_id === agentId) : all;\n setPending(filtered);\n } catch (e) { console.error(e); }\n }\n\n useEffect(() => {\n void refresh();\n const id = setInterval(refresh, 4000);\n const onVisible = () => { if (!document.hidden) void refresh(); };\n document.addEventListener(\"visibilitychange\", onVisible);\n return () => { clearInterval(id); document.removeEventListener(\"visibilitychange\", onVisible); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId]);\n\n function markBusy(id: string, busy: boolean) {\n setBusyIds((p) => {\n const n = new Set(p);\n if (busy) n.add(id); else n.delete(id);\n return n;\n });\n }\n\n // Approve flow for kinds whose payload contains no secrets and no follow-up.\n async function plainApprove(action: PendingAction) {\n markBusy(action.id, true);\n try {\n await api.pending.approve(action.id);\n pushApprovalToast(action);\n await refresh();\n onChange?.();\n } catch (e) { console.error(e); }\n finally { markBusy(action.id, false); }\n }\n\n async function deny(action: PendingAction) {\n markBusy(action.id, true);\n try {\n await api.pending.deny(action.id);\n await refresh();\n onChange?.();\n } catch (e) { console.error(e); }\n finally { markBusy(action.id, false); }\n }\n\n // Approve a `start_oauth` proposal: the apply step returns a kickoff_path\n // and we have to actually open the vendor authorize URL. Today both gmail\n // and outlook expose dedicated start endpoints — we dispatch on\n // integration_id rather than blindly POSTing to kickoff_path so the typed\n // API client stays the contract.\n async function approveStartOauth(action: PendingAction) {\n const integrationId = (action.payload as { integration_id?: string }).integration_id;\n markBusy(action.id, true);\n try {\n await api.pending.approve(action.id);\n let resp: { authorize_url: string } | null = null;\n if (integrationId === \"gmail\") resp = await api.integrations.gmailOauthStart({});\n else if (integrationId === \"outlook\") resp = await api.integrations.outlookOauthStart({});\n if (resp?.authorize_url) window.open(resp.authorize_url, \"_blank\", \"noopener,noreferrer\");\n pushApprovalToast(action);\n await refresh();\n onChange?.();\n } catch (e) { console.error(e); }\n finally { markBusy(action.id, false); }\n }\n\n // For `set_provider_key`, schema is fixed: api_key (secret, required) plus\n // optional base_url for self-hosted endpoints. We don't ship the agent's\n // declared `is_default`/`provider`/`model_id` here — those rode in via the\n // payload and the server reads them from the action row.\n function openProviderKeyModal(action: PendingAction) {\n setSecretForm({\n action,\n fields: [\n { key: \"api_key\", label: \"API key\", secret: true, required: true, placeholder: \"sk-…\" },\n { key: \"base_url\", label: \"Base URL (optional)\", secret: false, required: false, placeholder: \"https://…\" },\n ],\n values: {},\n submitting: false,\n error: null,\n });\n }\n\n // For `enable_integration`, fields come from the credentials schema the\n // server already advertises. Fetch on open rather than caching — the list\n // is small and the modal stays mounted only while the user fills it.\n async function openIntegrationModal(action: PendingAction) {\n const integrationId = (action.payload as { id?: string }).id;\n if (!integrationId) return;\n markBusy(action.id, true);\n try {\n const list = await api.integrations.list();\n const def = list.definitions.find((d: IntegrationDefinition) => d.name === integrationId);\n if (!def) {\n await deny(action);\n return;\n }\n setSecretForm({\n action,\n fields: def.fields.map((f) => ({\n key: f.key,\n label: f.label,\n secret: f.secret,\n required: f.required,\n placeholder: f.placeholder,\n })),\n values: {},\n submitting: false,\n error: null,\n });\n } catch (e) { console.error(e); }\n finally { markBusy(action.id, false); }\n }\n\n async function submitSecretForm() {\n if (!secretForm) return;\n const missing = secretForm.fields\n .filter((f) => f.required && !secretForm.values[f.key]?.trim())\n .map((f) => f.label);\n if (missing.length > 0) {\n setSecretForm({ ...secretForm, error: `Required: ${missing.join(\", \")}` });\n return;\n }\n setSecretForm({ ...secretForm, submitting: true, error: null });\n try {\n const extras: Record<string, string> = {};\n for (const [k, v] of Object.entries(secretForm.values)) {\n if (typeof v === \"string\" && v.trim()) extras[k] = v.trim();\n }\n await api.pending.approve(secretForm.action.id, extras);\n pushApprovalToast(secretForm.action);\n setSecretForm(null);\n await refresh();\n onChange?.();\n } catch (e) {\n setSecretForm({\n ...secretForm,\n submitting: false,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n function approve(action: PendingAction) {\n switch (action.kind) {\n case \"set_provider_key\": return openProviderKeyModal(action);\n case \"enable_integration\": return openIntegrationModal(action);\n case \"start_oauth\": return approveStartOauth(action);\n default: return plainApprove(action);\n }\n }\n\n if (pending.length === 0 && !secretForm) return null;\n\n return (\n <>\n {pending.length > 0 && (\n <div className=\"mx-4 mb-2 rounded-lg border border-amber-700/60 bg-amber-950/30 overflow-hidden\">\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-xs text-amber-800 dark:text-amber-200 hover:bg-amber-900/20 transition-colors\"\n >\n <ShieldAlert size={13} className=\"text-amber-700 dark:text-amber-400 shrink-0\" />\n <span className=\"font-medium\">\n {pending.length} {pending.length === 1 ? \"change\" : \"changes\"} awaiting your approval\n </span>\n <span className=\"ml-auto opacity-70\">{open ? <ChevronUp size={13} /> : <ChevronDown size={13} />}</span>\n </button>\n\n {open && (\n <div className=\"border-t border-amber-700/40 divide-y divide-amber-700/30\">\n {pending.map((a) => {\n const busy = busyIds.has(a.id);\n return (\n <div key={a.id} className=\"px-3 py-2.5 text-xs\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className=\"font-mono uppercase tracking-wide text-[10px] text-amber-700 dark:text-amber-400/80\">{a.kind}</span>\n {a.reason && <span className=\"text-amber-100/90\">{a.reason}</span>}\n </div>\n <pre className=\"text-[11px] text-amber-800 dark:text-amber-200/70 font-mono whitespace-pre-wrap break-words bg-amber-950/40 rounded p-2 mb-2\">\n {JSON.stringify(a.payload, null, 2)}\n </pre>\n <div className=\"flex gap-1.5 justify-end\">\n <button\n onClick={() => deny(a)}\n disabled={busy}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-subtle hover:text-fg hover:border-fg-faint disabled:opacity-50\"\n >\n <X size={11} /> Deny\n </button>\n <button\n onClick={() => approve(a)}\n disabled={busy}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded bg-emerald-700 hover:bg-emerald-600 text-white disabled:opacity-50\"\n >\n <Check size={11} /> {busy ? \"Applying…\" : \"Approve\"}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n {secretForm && (\n <SecretFormModal\n state={secretForm}\n onChangeValue={(key, val) =>\n setSecretForm({ ...secretForm, values: { ...secretForm.values, [key]: val } })\n }\n onCancel={() => setSecretForm(null)}\n onSubmit={() => void submitSecretForm()}\n />\n )}\n </>\n );\n}\n\nfunction SecretFormModal({\n state,\n onChangeValue,\n onCancel,\n onSubmit,\n}: {\n state: SecretFormState;\n onChangeValue: (key: string, val: string) => void;\n onCancel: () => void;\n onSubmit: () => void;\n}) {\n const title =\n state.action.kind === \"set_provider_key\"\n ? \"Provide API key\"\n : state.action.kind === \"enable_integration\"\n ? \"Enable integration\"\n : \"Provide credentials\";\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 px-4\">\n <div className=\"w-full max-w-md rounded-xl border border-border bg-surface-2 shadow-xl\">\n <div className=\"px-4 py-3 border-b border-border\">\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n {state.action.reason && (\n <p className=\"text-xs text-fg-subtle mt-1\">{state.action.reason}</p>\n )}\n </div>\n <div className=\"p-4 space-y-3\">\n <pre className=\"text-[11px] text-fg-subtle font-mono whitespace-pre-wrap break-words bg-surface rounded p-2 border border-border\">\n {JSON.stringify(state.action.payload, null, 2)}\n </pre>\n {state.fields.map((f) => (\n <div key={f.key} className=\"space-y-1\">\n <label htmlFor={`sec-${f.key}`} className=\"text-xs font-medium text-fg-subtle\">\n {f.label}{f.required ? \" *\" : \"\"}\n </label>\n <input\n id={`sec-${f.key}`}\n type={f.secret ? \"password\" : \"text\"}\n value={state.values[f.key] ?? \"\"}\n onChange={(e) => onChangeValue(f.key, e.target.value)}\n placeholder={f.placeholder}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"w-full px-3 py-2 rounded border border-border bg-surface text-fg placeholder:text-fg-faint focus:border-emerald-500 focus:outline-none text-sm font-mono\"\n />\n </div>\n ))}\n {state.error && (\n <div className=\"rounded p-2 text-xs border border-rose-700/50 bg-rose-950/30 text-rose-300\">\n {state.error}\n </div>\n )}\n <p className=\"text-[11px] text-fg-faint\">\n Sent only to your local Jarela database (encrypted at rest). The agent never sees these values.\n </p>\n </div>\n <div className=\"px-4 py-3 border-t border-border flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={state.submitting}\n className=\"px-3 py-1.5 text-xs rounded border border-border text-fg-subtle hover:text-fg hover:border-fg-faint disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={onSubmit}\n disabled={state.submitting}\n className=\"px-3 py-1.5 text-xs rounded bg-emerald-700 hover:bg-emerald-600 text-white disabled:opacity-50\"\n >\n {state.submitting ? \"Saving…\" : \"Approve and save\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { Mic, Paperclip, Send, Square, X } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState, type ClipboardEvent, type KeyboardEvent } from \"react\";\nimport type { ContentPart } from \"@/api/types\";\n\ninterface Props {\n attachments: ContentPart[];\n onAttachmentsChange: (a: ContentPart[]) => void;\n // Default Send / Enter. Caller decides idle-send vs steer based on streaming state.\n onSubmit: (text: string) => void;\n // Cmd/Ctrl+Enter — explicit \"queue this turn\" path. Caller queues regardless of streaming.\n onQueue: (text: string) => void;\n // Pure interrupt — abort the in-flight run without follow-up.\n onStop: () => void;\n streaming: boolean;\n disabled?: boolean;\n placeholder?: string;\n // Voice push-to-talk — only rendered when the active agent has\n // voice_enabled. Tapping mic records via MediaRecorder; on stop the audio\n // is POSTed to /api/v1/voice/transcribe and the transcript is handed back\n // to the parent (which is responsible for submitting it and arming the\n // auto-speak-on-reply flag).\n voiceEnabled?: boolean;\n agentId?: string | null;\n onVoiceTranscript?: (text: string) => void;\n}\n\nconst ACCEPT = \"image/*,text/*,.ts,.tsx,.js,.jsx,.json,.md,.py,.go,.rs,.yaml,.yml,.toml,.sh,.sql,.pdf\";\n\n// Registry of slash-commands. Keep in sync with handlers in ChatView.tsx.\n// To add: append here, then handle the literal in ChatView.handleSubmit.\nconst SLASH_COMMANDS: Array<{ name: string; description: string }> = [\n { name: \"/new\", description: \"save session to memory and start fresh\" },\n { name: \"/btw\", description: \"redirect: abort current run and send this instead\" },\n];\n\n// iOS standalone-PWA detection. Used to gate `focus({preventScroll:true})`,\n// which keeps iOS from scrolling the layout viewport when the keyboard opens.\n// Sizing is handled globally by the `--actual-vh` bootstrap in app/layout.tsx:\n// when the keyboard opens, visualViewport.height shrinks, --actual-vh\n// shrinks, the AppShell shrinks, and the input bar naturally lands above the\n// keyboard. No translateY on the compose bar - that's double compensation.\nfunction isIosStandalonePwa(): boolean {\n if (typeof window === \"undefined\") return false;\n const ua = window.navigator.userAgent || \"\";\n const isiOS = /iPhone|iPad|iPod/i.test(ua);\n if (!isiOS) return false;\n return window.matchMedia(\"(display-mode: standalone)\").matches\n || window.matchMedia(\"(display-mode: fullscreen)\").matches\n || (window.navigator as Navigator & { standalone?: boolean }).standalone === true;\n}\n\nfunction fileToContentPart(file: File): Promise<ContentPart> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n if (file.type.startsWith(\"image/\") || file.type === \"application/pdf\") {\n reader.onload = () => {\n const dataUrl = reader.result as string;\n const data = dataUrl.split(\",\")[1] ?? \"\";\n if (file.type === \"application/pdf\") {\n resolve({ type: \"file\", name: file.name, media_type: \"application/pdf\", data });\n } else {\n resolve({ type: \"image\", media_type: file.type, data });\n }\n };\n reader.onerror = () => reject(new Error(`Failed to read ${file.name}`));\n reader.readAsDataURL(file);\n } else {\n reader.onload = () => resolve({ type: \"file\", name: file.name, media_type: file.type || \"text/plain\", data: reader.result as string });\n reader.onerror = () => reject(new Error(`Failed to read ${file.name}`));\n reader.readAsText(file);\n }\n });\n}\n\nfunction attachmentKey(a: ContentPart, i: number): string {\n if (a.type === \"text\") return `text:${i}:${a.text.length}`;\n const name = a.type === \"file\" ? a.name : \"\";\n return `${a.type}:${a.media_type}:${name}:${a.data.length}:${a.data.slice(0, 16)}`;\n}\n\nexport function InputBar({ attachments, onAttachmentsChange, onSubmit, onQueue, onStop, streaming, disabled, placeholder, voiceEnabled, agentId, onVoiceTranscript }: Props) {\n // Text state is intentionally LOCAL. Lifting it to ChatView would re-render\n // the entire message list (every MessageBubble + ReactMarkdown pass) on\n // every keystroke, which is the root cause of typing feeling sluggish on\n // long threads. Parent only needs the text at submit/queue time.\n const [value, setValue] = useState(\"\");\n const fileInputRef = useRef<HTMLInputElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [hlIdx, setHlIdx] = useState(0);\n const [recording, setRecording] = useState(false);\n const [transcribing, setTranscribing] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n const recorderRef = useRef<MediaRecorder | null>(null);\n const chunksRef = useRef<Blob[]>([]);\n const iosPwaFix = isIosStandalonePwa();\n\n useEffect(() => {\n return () => {\n const r = recorderRef.current;\n if (r && r.state !== \"inactive\") {\n try { r.stop(); } catch { /* ignore */ }\n }\n r?.stream?.getTracks().forEach((t) => t.stop());\n };\n }, []);\n\n async function startRecording() {\n if (!voiceEnabled || !agentId || recording || transcribing) return;\n setVoiceError(null);\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n // Prefer webm/opus when available — universally supported by Chromium\n // and Firefox. Safari only ships mp4/aac; the empty-string fallback\n // lets the browser pick whatever it can encode.\n const mime =\n MediaRecorder.isTypeSupported(\"audio/webm;codecs=opus\") ? \"audio/webm;codecs=opus\"\n : MediaRecorder.isTypeSupported(\"audio/webm\") ? \"audio/webm\"\n : MediaRecorder.isTypeSupported(\"audio/mp4\") ? \"audio/mp4\"\n : \"\";\n const rec = mime ? new MediaRecorder(stream, { mimeType: mime }) : new MediaRecorder(stream);\n chunksRef.current = [];\n rec.ondataavailable = (e) => { if (e.data.size > 0) chunksRef.current.push(e.data); };\n rec.onstop = async () => {\n stream.getTracks().forEach((t) => t.stop());\n const blob = new Blob(chunksRef.current, { type: rec.mimeType || \"audio/webm\" });\n chunksRef.current = [];\n if (blob.size === 0) { setRecording(false); return; }\n setRecording(false);\n setTranscribing(true);\n try {\n const fd = new FormData();\n fd.append(\"agent_id\", agentId);\n fd.append(\"audio\", blob, `voice.${(rec.mimeType || \"audio/webm\").includes(\"mp4\") ? \"mp4\" : \"webm\"}`);\n const res = await fetch(\"/api/v1/voice/transcribe\", { method: \"POST\", body: fd });\n if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error ?? `HTTP ${res.status}`);\n const { text } = (await res.json()) as { text: string };\n const trimmed = text.trim();\n if (trimmed) onVoiceTranscript?.(trimmed);\n } catch (err) {\n setVoiceError(err instanceof Error ? err.message : String(err));\n } finally {\n setTranscribing(false);\n }\n };\n rec.start();\n recorderRef.current = rec;\n setRecording(true);\n } catch (err) {\n setVoiceError(err instanceof Error ? err.message : String(err));\n setRecording(false);\n }\n }\n\n function stopRecording() {\n const r = recorderRef.current;\n if (r && r.state !== \"inactive\") {\n try { r.stop(); } catch { /* ignore */ }\n }\n }\n\n // After parent clears the input (send/queue/programmatic reset), collapse\n // the textarea back to its single-line min-height. Without this the inline\n // style.height set during typing persists, leaving an empty multi-line box.\n useEffect(() => {\n if (value.length === 0 && textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n }, [value]);\n\n // Slash-command autocomplete is active only when the entire trimmed input\n // is a `/`-prefixed token (no spaces). That keeps the popover from\n // flashing when the user is mid-sentence and happens to type a slash.\n const suggestions = useMemo(() => {\n const trimmed = value.trimStart();\n if (!trimmed.startsWith(\"/\") || /\\s/.test(trimmed)) return [];\n const q = trimmed.toLowerCase();\n return SLASH_COMMANDS.filter((c) => c.name.startsWith(q));\n }, [value]);\n const showSuggestions = suggestions.length > 0 && !streaming && !disabled;\n const activeIdx = Math.min(hlIdx, Math.max(suggestions.length - 1, 0));\n\n function applySuggestion(name: string) {\n setValue(`${name} `);\n setHlIdx(0);\n }\n\n // Fire submit/queue with the current text and clear locally. The parent\n // doesn't see the live value during typing — only at this moment.\n function fireSubmit() {\n if (disabled) return;\n if (!value.trim() && !attachments.length) return;\n const text = value;\n setValue(\"\");\n onSubmit(text);\n }\n function fireQueue() {\n if (disabled) return;\n if (!value.trim() && !attachments.length) return;\n const text = value;\n setValue(\"\");\n onQueue(text);\n }\n\n function handleKeyDown(e: KeyboardEvent<HTMLTextAreaElement>) {\n if (showSuggestions) {\n if (e.key === \"Tab\" || (e.key === \"Enter\" && !e.shiftKey)) {\n // Tab always completes; Enter completes only when the current input\n // is not yet a full command (so `/new<Enter>` still submits).\n const exact = suggestions.find((s) => s.name === value.trim());\n if (!(e.key === \"Enter\" && exact)) {\n e.preventDefault();\n applySuggestion(suggestions[activeIdx].name);\n return;\n }\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setHlIdx((i) => (i + 1) % suggestions.length);\n return;\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setHlIdx((i) => (i - 1 + suggestions.length) % suggestions.length);\n return;\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n setValue(\"\");\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n // Cmd/Ctrl+Enter is the explicit \"queue\" shortcut. Plain Enter goes\n // through onSubmit, which is steer-when-streaming / send-when-idle.\n if (e.metaKey || e.ctrlKey) fireQueue();\n else fireSubmit();\n }\n }\n\n function handlePaste(e: ClipboardEvent<HTMLTextAreaElement>) {\n const items = Array.from(e.clipboardData.items);\n const imageItems = items.filter((i) => i.kind === \"file\" && i.type.startsWith(\"image/\"));\n if (!imageItems.length) return;\n e.preventDefault();\n imageItems.forEach((item) => {\n const file = item.getAsFile();\n if (!file) return;\n fileToContentPart(file)\n .then((part) => onAttachmentsChange([...attachments, part]))\n .catch(console.error);\n });\n }\n\n async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {\n const files = Array.from(e.target.files ?? []);\n if (!files.length) return;\n const parts = await Promise.all(files.map(fileToContentPart)).catch((err) => { console.error(err); return []; });\n onAttachmentsChange([...attachments, ...parts]);\n e.target.value = \"\";\n }\n\n function removeAttachment(idx: number) {\n onAttachmentsChange(attachments.filter((_, i) => i !== idx));\n }\n\n return (\n <div\n className=\"glass border-t border-border/60 px-3 sm:px-4 pt-2\"\n style={{\n paddingBottom: \"max(0.25rem, env(safe-area-inset-bottom))\",\n }}\n >\n {/* Attachment previews */}\n {attachments.length > 0 && (\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {attachments.map((a, i) => (\n // Content-derived key — using the index reused DOM nodes when\n // earlier attachments were removed, flashing the wrong preview\n // (and the wrong filename) into the slot of the survivor.\n <div key={attachmentKey(a, i)} className=\"relative group shrink-0\">\n {a.type === \"image\" ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={`data:${a.media_type};base64,${a.data}`}\n alt=\"attachment\"\n className=\"h-14 w-14 object-cover rounded-lg border border-border\"\n />\n ) : (\n <div className=\"h-10 px-2.5 flex items-center gap-1.5 rounded-lg border border-border bg-surface-3 text-[11px] text-fg-muted max-w-[140px]\">\n <Paperclip size={11} className=\"shrink-0 text-fg-faint\" />\n <span className=\"truncate\">{(a as ContentPart & { name: string }).name}</span>\n </div>\n )}\n <button\n onClick={() => removeAttachment(i)}\n className=\"absolute -top-1.5 -right-1.5 hidden group-hover:flex w-4 h-4 rounded-full bg-surface-3 text-fg items-center justify-center\"\n >\n <X size={9} />\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"relative flex gap-2 items-end\">\n {/* Slash-command popover. Anchored to the textarea via the relative\n parent so it floats above the input without affecting layout. */}\n {showSuggestions && (\n <div className=\"absolute left-[52px] right-[52px] bottom-full mb-1 z-10 max-h-48 overflow-y-auto rounded-xl border border-border/60 bg-surface-2/95 shadow-lg backdrop-blur\">\n {suggestions.map((s, i) => (\n <button\n key={s.name}\n type=\"button\"\n onMouseDown={(e) => { e.preventDefault(); applySuggestion(s.name); }}\n onMouseEnter={() => setHlIdx(i)}\n className={`w-full text-left px-3 py-2 flex items-baseline gap-2 text-sm transition-colors ${\n i === activeIdx ? \"bg-surface-3 text-fg\" : \"text-fg-muted hover:bg-surface-3/60\"\n }`}\n >\n <span className=\"font-mono text-accent\">{s.name}</span>\n <span className=\"text-xs text-fg-faint truncate\">{s.description}</span>\n </button>\n ))}\n <div className=\"px-3 py-1 text-[10px] text-fg-faint border-t border-border/40\">\n Tab to complete · ↑↓ to navigate · Esc to clear\n </div>\n </div>\n )}\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept={ACCEPT}\n className=\"hidden\"\n onChange={handleFileChange}\n disabled={disabled}\n />\n\n {/* Attach button */}\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={disabled || streaming}\n className=\"shrink-0 h-11 w-11 flex items-center justify-center rounded-xl text-fg-faint hover:text-fg hover:bg-surface-3 transition-colors disabled:opacity-40 disabled:cursor-not-allowed\"\n title=\"Attach file or image\"\n >\n <Paperclip size={16} />\n </button>\n\n {voiceEnabled && agentId && (\n <button\n onClick={recording ? stopRecording : startRecording}\n disabled={disabled || streaming || transcribing}\n className={`shrink-0 h-11 w-11 flex items-center justify-center rounded-xl transition-colors disabled:opacity-40 disabled:cursor-not-allowed ${\n recording\n ? \"bg-rose-500 text-white animate-pulse\"\n : \"text-fg-faint hover:text-fg hover:bg-surface-3\"\n }`}\n title={recording ? \"Stop recording\" : transcribing ? \"Transcribing…\" : \"Record voice message\"}\n aria-label={recording ? \"Stop recording\" : \"Record voice message\"}\n >\n {recording ? <Square size={14} /> : <Mic size={16} />}\n </button>\n )}\n\n <textarea\n className=\"flex-1 resize-none bg-surface-3/60 text-fg text-sm rounded-xl px-3 py-2 border border-border/60 focus:outline-none focus:ring-1 focus:ring-accent focus:border-accent/40 placeholder:text-fg-faint max-h-[84px] min-h-[44px] transition-colors\"\n ref={textareaRef}\n placeholder={placeholder ?? \"Message…\"}\n rows={1}\n value={value}\n onMouseDown={(e) => {\n if (iosPwaFix) {\n e.preventDefault();\n e.currentTarget.focus({ preventScroll: true });\n }\n }}\n onChange={(e) => {\n setValue(e.target.value);\n e.target.style.height = \"auto\";\n e.target.style.height = `${Math.min(e.target.scrollHeight, 84)}px`;\n }}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n disabled={disabled}\n />\n\n {streaming && (\n <button\n onClick={onStop}\n className=\"glass-btn-stop shrink-0 h-11 w-11 flex items-center justify-center rounded-xl text-white transition-colors\"\n title=\"Stop (interrupt without sending)\"\n aria-label=\"Stop\"\n >\n <Square size={16} />\n </button>\n )}\n <button\n onClick={fireSubmit}\n disabled={(!value.trim() && !attachments.length) || disabled}\n className=\"glass-btn-send shrink-0 h-11 w-11 flex items-center justify-center rounded-xl text-white transition-colors disabled:opacity-40 disabled:cursor-not-allowed\"\n title={streaming\n ? \"Steer — abort current and send this instead (⌘/Ctrl+Enter to queue)\"\n : \"Send (⌘/Ctrl+Enter to queue)\"}\n aria-label={streaming ? \"Steer\" : \"Send\"}\n >\n <Send size={16} />\n </button>\n </div>\n {voiceError && (\n <p className=\"mt-1 text-[11px] text-rose-500\" role=\"alert\">{voiceError}</p>\n )}\n {transcribing && !voiceError && (\n <p className=\"mt-1 text-[11px] text-fg-faint\" aria-live=\"polite\">Transcribing…</p>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\n\nexport interface ToolEvent {\n id: string;\n phase: \"call\" | \"result\";\n name: string;\n payload: unknown;\n}\n\n// Above this many events the list collapses to a one-line summary by\n// default. Tool-heavy turns (sprint-report skills, multi-step research)\n// can otherwise eat half a screen with rows the user rarely re-reads.\nconst COLLAPSE_THRESHOLD = 3;\n\n// Shared between live-streaming tool events (driven by useSSE) and persisted\n// tool events (loaded with each assistant message from /threads/:id). Kept in\n// its own file to avoid a circular import between MessageList -> MessageBubble\n// when both need to render it.\nexport function ToolList({ events }: { events: ToolEvent[] }) {\n const [openId, setOpenId] = useState<string | null>(null);\n const [expanded, setExpanded] = useState(events.length <= COLLAPSE_THRESHOLD);\n\n if (!expanded) {\n // Compact summary: count + the unique tool names that ran. Clicking\n // the row expands the full event list (calls + results, payloads).\n const uniqueNames = Array.from(new Set(events.map((e) => e.name))).filter(Boolean);\n const callCount = events.filter((e) => e.phase === \"call\").length;\n const errorCount = events.filter((e) => e.phase === \"result\" && isErrorPayload(e.payload)).length;\n return (\n <div className=\"my-1.5 w-full min-w-0 max-w-full overflow-hidden\">\n <button\n onClick={() => setExpanded(true)}\n className=\"w-full min-w-0 flex items-center gap-1.5 text-[11px] hover:bg-surface-2/40 px-1 py-0.5 rounded-md text-left\"\n >\n <ChevronRight size={10} className=\"shrink-0 text-fg-faint\" />\n <span className=\"inline-flex items-center gap-1.5 shrink-0 px-2 py-0.5 rounded-full bg-surface-2/60 border border-border/50 text-fg-muted\">\n <span className={`w-1.5 h-1.5 rounded-full ${errorCount > 0 ? \"bg-rose-500\" : \"bg-emerald-500\"}`} aria-hidden />\n <span className=\"font-medium\">\n {callCount} tool{callCount === 1 ? \"\" : \"s\"}\n {errorCount > 0 && <span className=\"text-rose-700 dark:text-rose-400/90\"> · {errorCount} err</span>}\n </span>\n </span>\n <span className=\"truncate text-fg-faint font-normal flex-1 min-w-0\">\n {uniqueNames.join(\" · \")}\n </span>\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"my-1.5 w-full min-w-0 max-w-full overflow-hidden\">\n {events.length > COLLAPSE_THRESHOLD && (\n <button\n onClick={() => setExpanded(false)}\n className=\"w-full min-w-0 flex items-center gap-1.5 text-[11px] hover:bg-surface-2/40 px-1 py-0.5 rounded text-left text-fg-faint\"\n >\n <ChevronRight size={10} className=\"shrink-0 rotate-90 transition-transform\" />\n <span className=\"font-mono uppercase tracking-wide shrink-0\">collapse</span>\n </button>\n )}\n {events.map((event, idx) => {\n const key = `${event.id}-${event.phase}-${idx}`;\n const open = openId === key;\n const summary = previewPayload(event.payload);\n const isError = isErrorPayload(event.payload);\n // Phase-colored dot inside each pill: sky=call, emerald=ok, rose=error.\n const dotColor = event.phase === \"call\"\n ? \"bg-sky-500\"\n : isError ? \"bg-rose-500\" : \"bg-emerald-500\";\n return (\n <div key={key} className=\"min-w-0 max-w-full\">\n <button\n onClick={() => setOpenId(open ? null : key)}\n className=\"w-full min-w-0 flex items-center gap-1.5 text-[11px] hover:bg-surface-2/40 px-1 py-0.5 rounded-md text-left\"\n >\n <ChevronRight size={10} className={`transition-transform shrink-0 ${open ? \"rotate-90\" : \"\"} text-fg-faint`} />\n <span className=\"inline-flex items-center gap-1.5 shrink-0 px-2 py-0.5 rounded-full bg-surface-2/60 border border-border/50 text-fg-muted\">\n <span className={`w-1.5 h-1.5 rounded-full ${dotColor}`} aria-hidden />\n <span className=\"font-medium\">{event.name}</span>\n </span>\n {!open && <span className=\"truncate text-fg-faint italic font-normal flex-1 min-w-0\">{summary}</span>}\n </button>\n {open && (\n <pre className=\"ml-5 mt-1 mb-1 px-2 py-1.5 text-[11px] text-fg-muted whitespace-pre font-mono bg-surface/60 rounded-lg border border-border/50 max-w-[calc(100%-1.25rem)] overflow-x-auto\">\n {JSON.stringify(event.payload, null, 2)}\n </pre>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction previewPayload(payload: unknown): string {\n try {\n const s = typeof payload === \"string\" ? payload : JSON.stringify(payload);\n const oneLine = s.replace(/\\s+/g, \" \");\n return oneLine.length > 80 ? oneLine.slice(0, 80) + \"…\" : oneLine;\n } catch {\n return \"\";\n }\n}\n\nfunction isErrorPayload(payload: unknown): boolean {\n if (typeof payload === \"string\") return /error/i.test(payload);\n if (payload && typeof payload === \"object\" && \"error\" in payload) return true;\n return false;\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport type { MessageUsage } from \"@/api/types\";\n\ninterface Props {\n usage: MessageUsage;\n // Thread-level cap from ThreadDetail.context_window_tokens. Used as the\n // bar's 100% baseline when the per-row snapshot doesn't carry its own\n // (older rows persisted before the tier columns existed).\n fallbackContextWindow: number;\n}\n\nfunction fmtTokens(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;\n return String(n);\n}\n\n/**\n * Thin diagnostic bar shown under each assistant turn. The full bar width\n * represents the agent's full context window. Inside it:\n *\n * - Hot / Warm / Facts / Overhead each get a *slot* whose width = the\n * budget that tier was allocated at run time.\n * - Within each slot, the *filled* portion shows the tokens that tier\n * actually consumed; the unfilled remainder shows headroom.\n *\n * A tier pegged at its slot's right edge (no headroom) is the signal to\n * widen its share on the agent's tier-proportion slider. A tier with a lot\n * of empty space could give some up. Trailing unallocated window space\n * (output-token reserve) is rendered as a dim track.\n *\n * Pre-tier-columns rows have NULL per-tier fields; we fall back to a single\n * grey \"total input\" segment so the bar still surfaces *something*.\n */\nexport function ContextUsageBar({ usage, fallbackContextWindow }: Props) {\n const [showDetails, setShowDetails] = useState(false);\n\n const cap = (usage.context_window_tokens ?? fallbackContextWindow) || 0;\n if (cap <= 0) return null;\n\n const hasTierBreakdown =\n usage.hot_tokens !== null\n && usage.warm_tokens !== null\n && usage.facts_tokens !== null\n && usage.overhead_tokens !== null\n && usage.hot_budget_tokens !== null\n && usage.warm_budget_tokens !== null\n && usage.facts_budget_tokens !== null;\n\n if (!hasTierBreakdown) {\n const usedPct = Math.min(100, (usage.input_tokens / cap) * 100);\n return (\n <div className=\"w-full\">\n <div\n className=\"h-[3px] w-full overflow-hidden bg-surface-3\"\n title={`${usage.input_tokens.toLocaleString()} / ${cap.toLocaleString()} input tokens (${usedPct.toFixed(1)}%) — tier breakdown unavailable on legacy rows`}\n >\n <div className=\"h-full bg-fg-faint/40\" style={{ width: `${usedPct}%` }} />\n </div>\n </div>\n );\n }\n\n const hotBudget = usage.hot_budget_tokens!;\n const warmBudget = usage.warm_budget_tokens!;\n const factsBudget = usage.facts_budget_tokens!;\n const hotUsed = usage.hot_tokens!;\n const warmUsed = usage.warm_tokens!;\n const factsUsed = usage.facts_tokens!;\n const overheadUsed = usage.overhead_tokens!;\n // Anthropic prompt-cache breakdown (ADR-0062). Disjoint from\n // hot/warm/facts/overhead: those tiers count fresh input, while these\n // count tokens served from / written to the prompt cache. Surface them\n // in the tooltip and expanded panel so the user can see when caching\n // is firing for this turn.\n const cacheRead = usage.cache_read_input_tokens ?? 0;\n const cacheCreation = usage.cache_creation_input_tokens ?? 0;\n const cacheActive = cacheRead > 0 || cacheCreation > 0;\n\n // Overhead's \"budget\" is whatever it actually consumed — there's no slider\n // for it. Shown as a fixed-size segment so it doesn't visually compete\n // with the tunable tiers.\n const overheadBudget = overheadUsed;\n const totalBudget = hotBudget + warmBudget + factsBudget + overheadBudget;\n const trailing = Math.max(0, cap - totalBudget);\n\n const toPct = (n: number) => (cap > 0 ? (n / cap) * 100 : 0);\n\n return (\n <div className=\"w-full\">\n <button\n type=\"button\"\n onClick={() => setShowDetails((v) => !v)}\n className=\"block w-full text-left\"\n aria-label={`Context usage: ${fmtTokens(hotUsed + warmUsed + factsUsed + overheadUsed)} of ${fmtTokens(cap)} tokens`}\n title={[\n `Context window: ${cap.toLocaleString()} tokens (the model's full capacity)`,\n `This turn's prompt used ${(hotUsed + warmUsed + factsUsed + overheadUsed).toLocaleString()} tokens`,\n `Reply generated: ${usage.output_tokens.toLocaleString()} tokens`,\n ...(cacheActive\n ? [\n \"\",\n `Prompt cache: ${cacheRead.toLocaleString()} read · ${cacheCreation.toLocaleString()} written`,\n \"(cache reads bill at 0.1× input, writes at 1.25×)\",\n ]\n : []),\n \"\",\n \"Each coloured slot's width = budget for that tier; filled portion = actually used.\",\n \"Red = tier overflowed its budget. Grey tail = headroom reserved for the reply.\",\n \"Click to expand numbers.\",\n ].join(\"\\n\")}\n >\n <div className=\"flex h-[3px] w-full overflow-hidden bg-surface-3\">\n <Slot widthPct={toPct(hotBudget)} usedPct={hotBudget > 0 ? (hotUsed / hotBudget) * 100 : 0} fill=\"bg-accent/70\" empty=\"bg-accent/15\" overflow={hotUsed > hotBudget} title={`Hot — recent messages\\n${hotUsed.toLocaleString()} / ${hotBudget.toLocaleString()} tokens used (${hotBudget > 0 ? Math.round((hotUsed/hotBudget)*100) : 0}%)`} />\n <Slot widthPct={toPct(warmBudget)} usedPct={warmBudget > 0 ? (warmUsed / warmBudget) * 100 : 0} fill=\"bg-amber-500/70\" empty=\"bg-amber-500/15\" overflow={warmUsed > warmBudget} title={`Warm — summarised older history\\n${warmUsed.toLocaleString()} / ${warmBudget.toLocaleString()} tokens used (${warmBudget > 0 ? Math.round((warmUsed/warmBudget)*100) : 0}%)`} />\n <Slot widthPct={toPct(factsBudget)} usedPct={factsBudget > 0 ? (factsUsed / factsBudget) * 100 : 0} fill=\"bg-teal-500/70\" empty=\"bg-teal-500/15\" overflow={factsUsed > factsBudget} title={`Facts — retrieved memory + recall\\n${factsUsed.toLocaleString()} / ${factsBudget.toLocaleString()} tokens used (${factsBudget > 0 ? Math.round((factsUsed/factsBudget)*100) : 0}%)`} />\n <Slot widthPct={toPct(overheadBudget)} usedPct={100} fill=\"bg-fg-faint/60\" empty=\"bg-fg-faint/15\" overflow={false} title={`Overhead — system prompt + scaffolding\\n${overheadUsed.toLocaleString()} tokens (no budget — measured after assembly)`} />\n {trailing > 0 && <div className=\"h-full bg-surface-3\" style={{ width: `${toPct(trailing)}%` }} aria-hidden title={`Reserved for reply: ${trailing.toLocaleString()} tokens (${Math.round((trailing/cap)*100)}% of window)`} />}\n </div>\n </button>\n {cacheActive && !showDetails && (\n <div\n className=\"mt-0.5 px-2 text-[10px] text-violet-500/80\"\n title={[\n \"Prompt cache (ADR-0062). Reads bill at 0.1× input, writes at 1.25×.\",\n cacheRead > 0 ? `${cacheRead.toLocaleString()} tokens served from cache.` : \"\",\n cacheCreation > 0 ? `${cacheCreation.toLocaleString()} tokens written to cache.` : \"\",\n ].filter(Boolean).join(\"\\n\")}\n >\n {cacheRead > 0 && <>cache hit · {fmtTokens(cacheRead)} read</>}\n {cacheRead > 0 && cacheCreation > 0 && \" · \"}\n {cacheCreation > 0 && <>cache write · {fmtTokens(cacheCreation)}</>}\n </div>\n )}\n {showDetails && (\n <div className=\"mt-1 px-2 pb-1 grid grid-cols-2 gap-x-3 gap-y-0.5 text-[10px] text-fg-faint\">\n <Row label=\"Hot\" color=\"text-accent\" used={hotUsed} budget={hotBudget} hint=\"Recent messages kept verbatim\" />\n <Row label=\"Warm\" color=\"text-amber-500\" used={warmUsed} budget={warmBudget} hint=\"Older history compressed into rolling summary\" />\n <Row label=\"Facts\" color=\"text-teal-500\" used={factsUsed} budget={factsBudget} hint=\"Retrieved long-term memory + recall snippets\" />\n <Row label=\"Overhead\" color=\"text-fg-muted\" used={overheadUsed} budget={overheadUsed} hint=\"System prompt + per-message scaffolding\" />\n {cacheActive && (\n <span\n className=\"col-span-2 text-violet-500\"\n title={[\n \"Prompt cache (ADR-0062). Disjoint from the tiers above.\",\n `Read ${cacheRead.toLocaleString()} tokens — billed at 0.1× input rate.`,\n `Wrote ${cacheCreation.toLocaleString()} tokens — billed at 1.25× input rate.`,\n \"Reads pay off on subsequent turns; writes are an investment.\",\n ].join(\"\\n\")}\n >\n <span className=\"text-violet-500\">Cache</span>{\" \"}\n read {fmtTokens(cacheRead)}\n {cacheCreation > 0 ? ` · created ${fmtTokens(cacheCreation)}` : \"\"}\n </span>\n )}\n <span\n className=\"col-span-2 mt-0.5 border-t border-border pt-0.5\"\n title={`Output: tokens the model generated in its reply.\\nWindow: total context capacity of this model.`}\n >\n Output: {fmtTokens(usage.output_tokens)} · Window: {fmtTokens(cap)}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nfunction Slot({ widthPct, usedPct, fill, empty, overflow, title }: { widthPct: number; usedPct: number; fill: string; empty: string; overflow: boolean; title?: string }) {\n if (widthPct <= 0) return null;\n const filledOfSlot = Math.min(100, Math.max(0, usedPct));\n return (\n <div className={`relative h-full ${empty}`} style={{ width: `${widthPct}%` }} title={title}>\n <div\n className={`absolute inset-y-0 left-0 ${overflow ? \"bg-rose-500/80\" : fill}`}\n style={{ width: `${filledOfSlot}%` }}\n />\n </div>\n );\n}\n\nfunction Row({ label, color, used, budget, hint }: { label: string; color: string; used: number; budget: number; hint?: string }) {\n const pct = budget > 0 ? Math.min(999, Math.round((used / budget) * 100)) : 0;\n return (\n <span title={hint}>\n <span className={color}>{label}</span> {fmtTokens(used)}\n <span className=\"text-fg-faint/70\"> / {fmtTokens(budget)} ({pct}%)</span>\n </span>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { runtimeConfig } from \"@/api/runtime-config\";\n\n// Drains a small SVG ring over the run's *effective* wall-clock budget\n// (`runMaxMs`), mirroring the adaptive logic in lib/agents/run-registry.ts:\n// the wall-clock bounds agent + provider time only, so time spent inside\n// tool calls does not advance the ring. While `inflightToolCount > 0` the\n// drain pauses; when all tools resolve it resumes from where it left off.\n//\n// Progress is driven in JS via rAF (not a CSS keyframe) so the pause can\n// happen mid-stream without a janky restart. A separate spinner arc keeps\n// rotating regardless — that's the \"still alive\" cue.\nexport function CountdownRing({ inflightToolCount = 0 }: { inflightToolCount?: number }) {\n // Re-resolve runMaxMs on mount so the EnvVarsPanel can change the budget\n // and new streams pick it up without a page reload.\n const [deadlineMs, setDeadlineMs] = useState(() => runtimeConfig().runMaxMs);\n useEffect(() => {\n setDeadlineMs(runtimeConfig().runMaxMs);\n }, []);\n\n const r = 5.5;\n const c = 2 * Math.PI * r;\n const spinnerArc = c * 0.25;\n\n const progressRef = useRef<SVGCircleElement | null>(null);\n // Cumulative ms the ring has drained — only advances while no tools\n // are inflight. Kept in a ref so the rAF loop never triggers re-renders.\n const activeMsRef = useRef(0);\n // performance.now() of the previous tick. Reset to null on pause/resume\n // so the paused interval doesn't get retroactively counted.\n const lastTickRef = useRef<number | null>(null);\n const inflightRef = useRef(inflightToolCount);\n\n useEffect(() => {\n inflightRef.current = inflightToolCount;\n lastTickRef.current = null;\n }, [inflightToolCount]);\n\n useEffect(() => {\n if (typeof requestAnimationFrame === \"undefined\") return;\n let raf = 0;\n const tick = () => {\n const now = performance.now();\n if (inflightRef.current === 0) {\n if (lastTickRef.current !== null) {\n activeMsRef.current += now - lastTickRef.current;\n }\n lastTickRef.current = now;\n } else {\n lastTickRef.current = null;\n }\n const node = progressRef.current;\n if (node) {\n const progress = Math.min(1, activeMsRef.current / Math.max(1, deadlineMs));\n node.style.strokeDashoffset = (c * progress).toFixed(3);\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => { if (raf) cancelAnimationFrame(raf); };\n }, [c, deadlineMs]);\n\n return (\n <span\n className=\"jarela-countdown-ring\"\n aria-label=\"agent working\"\n role=\"status\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <circle\n cx=\"7\"\n cy=\"7\"\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.18\"\n strokeWidth=\"1.4\"\n />\n <circle\n ref={progressRef}\n cx=\"7\"\n cy=\"7\"\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeDasharray={c.toFixed(3)}\n strokeDashoffset=\"0\"\n transform=\"rotate(-90 7 7)\"\n />\n <circle\n className=\"jarela-countdown-spinner\"\n cx=\"7\"\n cy=\"7\"\n r={r}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeDasharray={`${spinnerArc.toFixed(3)} ${(c - spinnerArc).toFixed(3)}`}\n />\n </svg>\n </span>\n );\n}\n","/**\n * Cross-adapter framing for bridge inbound messages.\n *\n * Bridge conversations are inherently multi-party: the paired user, one or\n * more counterparts (1:1 partner or group members), and the agent that's\n * observing/assisting. Without role framing, the LLM tends to read every\n * inbound message as a direct command — even when the message was sent by\n * the user's chat partner, who has no idea an agent is in the loop.\n *\n * This module is the single source of truth for that framing. Every bridge\n * adapter (WhatsApp today; Telegram/Slack/Discord/email tomorrow) populates\n * `InboundMessage.role` with one of these values, and the dispatcher feeds\n * the message through `formatBridgePrompt` to produce the prefix the agent\n * sees. Adding a new adapter is a matter of mapping its platform-specific\n * \"who sent this\" signal onto `MessageRole`; the framing code does not need\n * to change.\n */\n\n/**\n * Who sent the message from the agent's perspective.\n *\n * - `user`: the paired account holder themselves — typed on their phone,\n * in their browser, etc. The agent treats these as the user's own\n * reaction/input to the conversation. Useful as an intent signal but\n * NOT a direct command to the agent (the user is talking to the\n * counterpart, not the agent).\n *\n * - `counterpart`: another participant in the chat — 1:1 partner in a DM,\n * or another member in a group chat. The agent treats these as\n * conversation context the user has not yet reacted to. Not a request\n * directed at the agent.\n *\n * - `agent`: the agent's own prior output, surfaced inbound when the\n * adapter cannot suppress its echo (rare). Adapters with reliable\n * echo-filtering (e.g. WhatsApp's `sentIdsSet`) should never emit this\n * value; it exists for adapters where deduplication is best-effort.\n */\nexport type MessageRole = \"user\" | \"counterpart\" | \"agent\";\n\nexport interface BridgePromptInput {\n /** The bridge instance id (so multi-bridge agents can disambiguate). */\n bridge_id: string;\n /** The chat-level identifier on the platform (DM partner JID, group id, channel id, etc.). */\n chat_id: string;\n /** Best-effort human-readable chat label. */\n chat_name: string;\n /** Whether the chat is a group / channel / multi-party room. */\n is_group: boolean;\n /** Sender role — see `MessageRole`. */\n role: MessageRole;\n /** Sender's platform identifier (for groups: the specific member; for DMs: the partner). */\n sender_id: string;\n /** Best-effort sender display name. */\n sender_name: string;\n /** The raw message text the user / counterpart / agent sent. */\n text: string;\n /**\n * Route-level silent (observer) mode. When true, the agent must not\n * reply on the chat — it can only surface internal status updates to\n * the paired user. See `roleNote` for the exact instructions.\n */\n silent?: boolean;\n}\n\n// Parsed chat-friendly envelope extracted from a bridge prompt body.\n// Used by the chat UI so rendering stays in lockstep with formatter changes.\nexport interface BridgePromptContext {\n bridgeId: string;\n chatJid: string;\n chatName: string;\n isGroup: boolean;\n senderJid: string;\n senderName: string;\n body: string;\n}\n\n/**\n * Build the prompt prefix the agent receives for one bridge-inbound message.\n *\n * Output shape:\n *\n * <one-line semantic note framing the role>\n *\n * [bridge:<id>]\n * [chat_id:<id>]\n * [chat_name:<label>]\n * [chat_type:dm|group]\n * [message_role:user|counterpart|agent]\n * [sender_id:<id>]\n * [sender_name:<label>]\n * ([group_name:<label>] [participant_id:<id>] [participant_name:<label>] for groups)\n *\n * <raw text>\n *\n * The metadata block is keyed-tag for parseability; the leading note is\n * prose so the LLM has an explicit framing without having to learn the\n * convention. Both are stable across adapters.\n */\nexport function formatBridgePrompt(input: BridgePromptInput): string {\n const note = roleNote(input.role, input.is_group, input.silent === true);\n const lines = [\n `[bridge:${input.bridge_id}]`,\n `[chat_id:${input.chat_id}]`,\n `[chat_name:${input.chat_name}]`,\n `[chat_type:${input.is_group ? \"group\" : \"dm\"}]`,\n `[message_role:${input.role}]`,\n `[sender_id:${input.sender_id}]`,\n `[sender_name:${input.sender_name}]`,\n ];\n if (input.is_group) {\n lines.push(`[group_name:${input.chat_name}]`);\n lines.push(`[participant_id:${input.sender_id}]`);\n lines.push(`[participant_name:${input.sender_name}]`);\n }\n return `${note}\\n\\n${lines.join(\"\\n\")}\\n\\n${input.text}`;\n}\n\n// Parses bridge prompt envelopes rendered by formatBridgePrompt().\n// Back-compat: also accepts legacy keys (chat_jid/sender_jid) and optional\n// prose preface before the [bridge:...] metadata block.\nexport function parseBridgePrompt(raw: string): BridgePromptContext | null {\n const start = raw.indexOf(\"[bridge:\");\n if (start < 0) return null;\n const src = raw.slice(start);\n\n const headers: Record<string, string> = {};\n const lines = src.split(\"\\n\");\n let i = 0;\n for (; i < lines.length; i++) {\n const line = lines[i];\n if (line === \"\") { i++; break; }\n const m = /^\\[([a-z_]+):([\\s\\S]*)\\]$/.exec(line);\n if (!m) return null;\n headers[m[1]] = m[2];\n }\n\n const chatId = headers.chat_id || headers.chat_jid;\n const senderId = headers.sender_id || headers.sender_jid || chatId;\n if (!headers.bridge || !chatId || !headers.chat_type) return null;\n\n return {\n bridgeId: headers.bridge,\n chatJid: chatId,\n chatName: headers.chat_name || chatId,\n isGroup: headers.chat_type === \"group\",\n senderJid: senderId,\n senderName: headers.sender_name || senderId || \"Unknown\",\n body: lines.slice(i).join(\"\\n\").trimEnd(),\n };\n}\n\nfunction roleNote(role: MessageRole, isGroup: boolean, silent: boolean): string {\n if (silent) {\n // Observer mode overrides the per-role framing: the agent is forbidden\n // from speaking on the chat regardless of who sent the inbound message.\n // It only reports internally to the paired user.\n if (role === \"agent\") {\n return \"The message below is your own prior output, surfaced again because the bridge adapter could not suppress its echo. Use it only as a record of what you previously said — do not respond to it.\";\n }\n return (\n \"Silent / observer mode is enabled for this route. You are standing on the paired user's side and only monitoring the chat — you must NEVER write to the chat, draft a chat reply, or imitate a participant. \" +\n \"Report only to the paired user, as a concise internal summary of important events, risks, or user-actionable changes (informational tone, not conversational). \" +\n \"If nothing important happened, reply with exactly the single token NO_REPLY and nothing else.\"\n );\n }\n switch (role) {\n case \"user\":\n return \"The paired user themselves sent the message below in this conversation. Treat it as the user's own reaction/input to the prior chat — they are speaking to the other party, not directly to you. Use it to update your understanding of the user's intent.\";\n case \"counterpart\":\n return isGroup\n ? \"The message below was sent by another member of this group chat, addressed to the paired user. Respond on the user's behalf, in their voice, following your agent instructions and persona — do not introduce yourself as an assistant or break character. If your instructions tell you to stay silent or escalate to the user, do that instead.\"\n : \"The message below was sent by the user's counterpart in this 1:1 chat, addressed to the paired user. Respond on the user's behalf, in their voice, following your agent instructions and persona — do not introduce yourself as an assistant or break character. If your instructions tell you to stay silent or escalate to the user, do that instead.\";\n case \"agent\":\n return \"The message below is your own prior output, surfaced again because the bridge adapter could not suppress its echo. Use it only as a record of what you previously said — do not respond to it.\";\n }\n}\n","// Browser-extension turn message (refine / fill / rewrite_clipboard).\n// `composePrompt` lives next to the server handler so the format is\n// authored once. `parseExtensionTurn` reverses it for the chat UI so the\n// user bubble can show a tight collapsible card instead of raw text.\n\nimport { z } from \"zod\";\n\nexport const ExtensionActionEnum = z.enum([\"refine\", \"fill\", \"rewrite_clipboard\"]);\nexport type ExtensionAction = z.infer<typeof ExtensionActionEnum>;\n\nexport interface ExtensionPromptInput {\n instruction: string;\n text?: string;\n url?: string;\n title?: string;\n selector?: string;\n page_context?: string;\n}\n\nexport function composePrompt(action: ExtensionAction, input: ExtensionPromptInput): string {\n const header = action === \"refine\"\n ? \"[Extension refine turn] Improve or refine the selected content based on the instruction below.\"\n : action === \"fill\"\n ? \"[Extension fill turn] Produce text intended to be inserted into the currently focused editable field. Use nearby form context and page context to stay relevant. Return only the final field text.\"\n : \"[Extension rewrite to clipboard turn] Rewrite ONLY the text under 'Selected context:' according to the instruction. Ignore any URL/title/heading hints — they are NOT the rewrite target. Return ONLY the rewritten text, no commentary, no quotes, no labels.\";\n\n const lines = [header, `Instruction: ${input.instruction}`];\n // rewrite_clipboard is intentionally selection-sovereign: the selection IS\n // the input. Page metadata adds noise and the model has been observed\n // echoing the page H1/H2 as the \"rewrite\" instead of operating on the\n // selection. Strip every page hint for this action.\n if (action !== \"rewrite_clipboard\") {\n if (input.url) lines.push(`URL: ${input.url}`);\n if (input.title) lines.push(`Title: ${input.title}`);\n if (input.selector) lines.push(`Selector: ${input.selector}`);\n if (input.page_context) lines.push(\"\", \"Page/form context:\", input.page_context);\n }\n lines.push(\"\", \"Selected context:\", input.text && input.text.trim().length > 0 ? input.text : \"(none provided)\");\n return lines.join(\"\\n\");\n}\n\nexport interface ExtensionTurnContext {\n action: ExtensionAction;\n actionLabel: string;\n instruction: string;\n url: string | null;\n title: string | null;\n selector: string | null;\n pageContext: string | null;\n selectedText: string | null;\n}\n\nconst ACTION_LABEL: Record<ExtensionAction, string> = {\n fill: \"Fill focused field\",\n refine: \"Refine selection\",\n rewrite_clipboard: \"Rewrite to clipboard\",\n};\n\nexport function parseExtensionTurn(raw: string): ExtensionTurnContext | null {\n const headerRe = /^\\[Extension (refine|fill|rewrite to clipboard) turn\\][^\\n]*\\n/;\n const hm = headerRe.exec(raw);\n if (!hm) return null;\n const actionWord = hm[1];\n const action: ExtensionAction =\n actionWord === \"fill\" ? \"fill\"\n : actionWord === \"refine\" ? \"refine\"\n : \"rewrite_clipboard\";\n\n let rest = raw.slice(hm[0].length);\n function takeLine(label: string): string | null {\n const re = new RegExp(`^${label}:\\\\s*([^\\\\n]*)\\\\n?`);\n const m = re.exec(rest);\n if (!m) return null;\n rest = rest.slice(m[0].length);\n return m[1].trim() || null;\n }\n const instruction = takeLine(\"Instruction\") ?? \"\";\n const url = takeLine(\"URL\");\n const title = takeLine(\"Title\");\n const selector = takeLine(\"Selector\");\n\n let pageContext: string | null = null;\n const pageHeaderRe = /^\\nPage\\/form context:\\n/;\n if (pageHeaderRe.test(rest)) {\n rest = rest.replace(pageHeaderRe, \"\");\n const idx = rest.indexOf(\"\\n\\nSelected context:\");\n if (idx >= 0) {\n pageContext = rest.slice(0, idx).trim() || null;\n rest = rest.slice(idx + 2);\n }\n }\n\n let selectedText: string | null = null;\n const selHeaderRe = /^\\n?Selected context:\\n([\\s\\S]*)$/;\n const sm = selHeaderRe.exec(rest);\n if (sm) {\n const body = sm[1].trim();\n selectedText = body === \"(none provided)\" ? null : (body || null);\n }\n\n return {\n action,\n actionLabel: ACTION_LABEL[action],\n instruction,\n url,\n title,\n selector,\n pageContext,\n selectedText,\n };\n}\n","\"use client\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeSanitize, { defaultSchema } from \"rehype-sanitize\";\nimport \"highlight.js/styles/github-dark.css\";\nimport { Bot, Check, ChevronRight, Clock, Copy, Eye, EyeOff, Globe, Link as LinkIcon, Link2, Loader2, MessageCircle, Paperclip, Pause, Play, RotateCcw, ShieldCheck, User, Users, X, Zap } from \"lucide-react\";\nimport type { AgentConfig, Message, UserProfile } from \"@/api/types\";\nimport type { ContentPart } from \"@/api/types\";\nimport { ToolList } from \"@/components/chat/ToolList\";\nimport { ContextUsageBar } from \"@/components/chat/ContextUsageBar\";\nimport { CountdownRing } from \"@/components/chat/CountdownRing\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { parseHref } from \"@/lib/ui/navigate\";\nimport { pushToast } from \"@/lib/ui/toasts\";\nimport { parseBridgePrompt, type BridgePromptContext } from \"@/lib/bridges/message-role\";\nimport { parseExtensionTurn, type ExtensionTurnContext } from \"@/lib/api/extension-turn-prompt\";\n\ninterface ExtractedRef {\n title: string;\n url: string;\n}\n\n// Best-effort plain-text projection of a (possibly structured) message body\n// for the TTS endpoint. Strips markdown noise, code fences, refs blocks,\n// and structured content parts so the spoken output doesn't read aloud\n// asterisks, backticks, or URLs. The string is also cropped to keep TTS\n// requests cheap — voices read about 150wpm so 5000 chars is several minutes.\nfunction plainTextForTts(content: unknown): string {\n let text = \"\";\n if (typeof content === \"string\") text = content;\n else if (Array.isArray(content)) {\n for (const part of content) {\n if (part && typeof part === \"object\" && \"type\" in part) {\n const p = part as { type: string; text?: string };\n if (p.type === \"text\" && typeof p.text === \"string\") text += `${p.text}\\n`;\n }\n }\n }\n text = text\n .replace(/<refs>[\\s\\S]*?<\\/refs>/gi, \" \")\n .replace(/```[\\s\\S]*?```/g, \" [code] \")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, \" \")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/[#>*_~]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return text.length > 5000 ? text.slice(0, 5000) : text;\n}\n\n// Splits \"<refs>…</refs>\" off the end of a message, returning the parsed refs\n// and the body without the block. Defensive against partial blocks emitted\n// mid-stream and against the agent forgetting the closing tag.\nfunction extractRefs(text: string): { body: string; refs: ExtractedRef[] } {\n const match = /<refs>([\\s\\S]*?)<\\/refs>/i.exec(text);\n if (!match) return { body: text, refs: [] };\n const inner = match[1];\n const refs: ExtractedRef[] = [];\n const linkRe = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n let m: RegExpExecArray | null;\n while ((m = linkRe.exec(inner)) !== null) {\n const url = m[2].trim();\n if (/^https?:\\/\\//.test(url)) refs.push({ title: m[1].trim(), url });\n }\n // Also catch bare-URL lines for resilience.\n if (refs.length === 0) {\n for (const line of inner.split(\"\\n\")) {\n const u = line.trim().match(/^https?:\\/\\/\\S+/);\n if (u) refs.push({ title: u[0].replace(/^https?:\\/\\/(www\\.)?/, \"\").slice(0, 60), url: u[0] });\n }\n }\n const body = (text.slice(0, match.index) + text.slice(match.index + match[0].length)).trimEnd();\n return { body, refs };\n}\n\n// Mid-stream guard for the agent's optional trailing\n// ```jarela-references` fence. The server-side parser folds that block\n// into the citation manifest and strips it from the persisted body, but\n// during streaming the in-flight buffer still contains it. Cut from the\n// opening fence onward so the user never sees raw JSON flash on screen.\n// Once the closing fence has arrived the body is identical to what the\n// server will persist either way; cutting from the open is the simple\n// path that handles partial-block and complete-block cases uniformly.\nfunction stripDeclaredReferencesFence(text: string): string {\n const idx = text.indexOf(\"```jarela-references\");\n if (idx < 0) return text;\n return text.slice(0, idx).trimEnd();\n}\n\n// Tracks which TTS clips have started auto-playing this session so a clip\n// only autoplays once. Re-renders of the same <audio> (message refetched,\n// scroll into view, list re-render) won't trigger a replay. Keyed by the\n// full href (including any `?autoplay=1`). Cleared on hard refresh — exactly\n// the \"session\" semantics we want.\nconst playedAutoplayHrefs = new Set<string>();\n\nfunction InlineAudio({ href }: { href: string }) {\n // Decide autoPlay at mount time: opt in only if the URL asked for it AND\n // we haven't already auto-played this exact clip in this session.\n const wantsAuto = /[?&]autoplay=1\\b/.test(href);\n const [auto] = useState(() => wantsAuto && !playedAutoplayHrefs.has(href));\n return (\n <audio\n controls\n preload=\"metadata\"\n autoPlay={auto}\n src={href}\n className=\"my-2 w-full max-w-md\"\n onPlay={() => {\n if (wantsAuto) playedAutoplayHrefs.add(href);\n }}\n />\n );\n}\n\n// Detects messages produced by the page-capture endpoint (composeBody in\n// lib/api/page-capture.ts) so the chat UI can render them as a collapsed\n// card instead of dumping ~100KB of page text into the bubble. The format\n// is fixed by composeBody; if either side changes, update both.\ninterface CapturedContext {\n title: string;\n url: string;\n selector: string | null;\n truncated: boolean;\n originalBytes: number | null;\n body: string;\n}\n\nfunction parseCapturedContext(raw: string): CapturedContext | null {\n if (!raw.startsWith(\"📎 Captured from \")) return null;\n const linkRe = /^📎 Captured from \\[([^\\]]+)\\]\\((https?:\\/\\/[^)]+)\\)\\s*\\n?/;\n const bareRe = /^📎 Captured from <(https?:\\/\\/[^>]+)>\\s*\\n?/;\n let title = \"\";\n let url = \"\";\n let rest = raw;\n const lm = linkRe.exec(raw);\n if (lm) { title = lm[1]; url = lm[2]; rest = raw.slice(lm[0].length); }\n else {\n const bm = bareRe.exec(raw);\n if (!bm) return null;\n url = bm[1]; title = url; rest = raw.slice(bm[0].length);\n }\n const out: CapturedContext = { title, url, selector: null, truncated: false, originalBytes: null, body: \"\" };\n const sm = /^Element: `([^`]+)`\\s*\\n?/.exec(rest);\n if (sm) { out.selector = sm[1]; rest = rest.slice(sm[0].length); }\n const tm = /^>\\s*⚠[^\\n]*?\\(original was ([\\d,]+) bytes\\)[^\\n]*\\n?/.exec(rest);\n if (tm) {\n out.truncated = true;\n out.originalBytes = Number(tm[1].replace(/,/g, \"\"));\n rest = rest.slice(tm[0].length);\n }\n rest = rest.replace(/^\\s*\\n/, \"\").replace(/^---\\s*\\n?/, \"\").replace(/^\\n+/, \"\");\n out.body = rest;\n return out;\n}\n\n// Header-always-visible card for page captures. Body collapsed by default;\n// the user can expand to read the captured page text inline. The agent\n// already has the full text in the thread regardless of expand state — this\n// is purely a UI affordance to keep ~100KB blobs from blowing the chat layout.\nfunction CapturedContextCard({ ctx, accent }: { ctx: CapturedContext; accent: boolean }) {\n const hostname = (() => { try { return new URL(ctx.url).hostname; } catch { return ctx.url; } })();\n const chips = (\n <>\n <a\n href={ctx.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"inline-flex items-center gap-1 underline decoration-dotted hover:decoration-solid truncate max-w-[18rem]\"\n title={ctx.url}\n >\n <LinkIcon size={9} className=\"shrink-0\" />\n <span className=\"truncate\">{hostname}</span>\n </a>\n {ctx.selector && (\n <span\n className={`px-1.5 py-0.5 rounded font-mono ${accent ? \"bg-white/15\" : \"bg-surface-3\"}`}\n title={ctx.selector}\n >\n {ctx.selector.length > 36 ? `…${ctx.selector.slice(-33)}` : ctx.selector}\n </span>\n )}\n {ctx.truncated && (\n <span\n className={`px-1.5 py-0.5 rounded ${accent ? \"bg-amber-300/25 text-amber-50\" : \"bg-amber-900/30 text-amber-300\"}`}\n title={ctx.originalBytes ? `Original was ${ctx.originalBytes.toLocaleString()} bytes` : undefined}\n >\n truncated to 100KB\n </span>\n )}\n </>\n );\n const sections: Array<{ label: string; content: ReactNode; defaultOpen?: boolean; hint?: string }> = ctx.body\n ? [{\n label: \"Captured content\",\n defaultOpen: false,\n content: <p className=\"whitespace-pre-wrap text-[12.5px] leading-relaxed opacity-90\">{ctx.body}</p>,\n }]\n : [];\n return (\n <StructuredTurnCard\n categoryKey=\"page_capture\"\n Icon={Paperclip}\n title={ctx.title || hostname}\n titleTooltip={ctx.url}\n chips={chips}\n sections={sections}\n accent={accent}\n />\n );\n}\n\n// Browser-extension turn card. The prompt format and parser live in\n// `lib/api/extension-turn-prompt` so the compose/parse pair stays in sync\n// between the server handler and this view.\nfunction ExtensionTurnCard({ ctx, accent }: { ctx: ExtensionTurnContext; accent: boolean }) {\n const hostname = ctx.url ? (() => { try { return new URL(ctx.url!).hostname; } catch { return ctx.url!; } })() : null;\n const chips = (ctx.url || ctx.selector || ctx.selectedText) ? (\n <>\n {ctx.url && hostname && (\n <a\n href={ctx.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"inline-flex items-center gap-1 underline decoration-dotted hover:decoration-solid truncate max-w-[18rem]\"\n title={ctx.url}\n >\n <LinkIcon size={9} className=\"shrink-0\" />\n <span className=\"truncate\">{ctx.title || hostname}</span>\n </a>\n )}\n {ctx.selector && (\n <span\n className={`px-1.5 py-0.5 rounded font-mono ${accent ? \"bg-white/15\" : \"bg-surface-3\"}`}\n title={ctx.selector}\n >\n {ctx.selector.length > 36 ? `…${ctx.selector.slice(-33)}` : ctx.selector}\n </span>\n )}\n {ctx.selectedText && (\n <span className={`px-1.5 py-0.5 rounded ${accent ? \"bg-white/15\" : \"bg-surface-3\"}`}>\n {`${ctx.selectedText.length.toLocaleString()} chars selected`}\n </span>\n )}\n </>\n ) : null;\n\n const sections: Array<{ label: string; content: ReactNode; defaultOpen?: boolean; hint?: string }> = [];\n if (ctx.instruction) {\n sections.push({\n label: \"Instruction\",\n defaultOpen: false,\n content: <MarkdownContent text={ctx.instruction} />,\n });\n }\n if (ctx.selectedText || ctx.pageContext) {\n sections.push({\n label: \"Context\",\n defaultOpen: false,\n content: (\n <div className=\"flex flex-col gap-2\">\n {ctx.selectedText && (\n <div>\n <div className={`text-[9.5px] uppercase tracking-wide mb-0.5 ${accent ? \"text-white/55\" : \"text-fg-faint\"}`}>Selected</div>\n <p className=\"whitespace-pre-wrap text-[12.5px] leading-relaxed opacity-90\">{ctx.selectedText}</p>\n </div>\n )}\n {ctx.pageContext && (\n <div>\n <div className={`text-[9.5px] uppercase tracking-wide mb-0.5 ${accent ? \"text-white/55\" : \"text-fg-faint\"}`}>Page</div>\n <p className=\"whitespace-pre-wrap text-[12px] leading-relaxed opacity-80\">{ctx.pageContext}</p>\n </div>\n )}\n </div>\n ),\n });\n }\n\n return (\n <StructuredTurnCard\n categoryKey=\"extension\"\n Icon={Zap}\n title={ctx.actionLabel}\n chips={chips}\n sections={sections}\n accent={accent}\n />\n );\n}\n\n// Small source-channel badge shown at the top of assistant bubbles that\n// were triggered by automation (bridge reply, scheduled task reply, etc.).\n// Lets the user tell at a glance which automation channel generated the\n// response without needing to scroll up to the corresponding user bubble.\nconst CATEGORY_BADGE: Record<string, { label: string; Icon: React.ElementType; cls: string }> = {\n scheduled_task: { label: \"Scheduled\", Icon: Clock, cls: \"text-violet-400/90 border-violet-500/30 bg-violet-950/30\" },\n watcher: { label: \"Watcher\", Icon: Eye, cls: \"text-amber-400/90 border-amber-500/30 bg-amber-950/30\" },\n bridge: { label: \"Bridge\", Icon: MessageCircle, cls: \"text-sky-400/90 border-sky-500/30 bg-sky-950/30\" },\n page_capture: { label: \"Capture\", Icon: Globe, cls: \"text-teal-400/90 border-teal-500/30 bg-teal-950/30\" },\n extension: { label: \"Extension\", Icon: Zap, cls: \"text-indigo-400/90 border-indigo-500/30 bg-indigo-950/30\" },\n synthetic: { label: \"System\", Icon: Bot, cls: \"text-fg-faint border-border/40 bg-surface-2\" },\n};\n\nfunction CategorySourceBadge({ category }: { category: string }) {\n const def = CATEGORY_BADGE[category];\n if (!def) return null;\n const { label, Icon, cls } = def;\n return (\n <div className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full border text-[10px] font-medium mb-1.5 self-start ${cls}`}>\n <Icon size={9} className=\"shrink-0\" />\n <span>{label} reply</span>\n </div>\n );\n}\n\n// Same chip used on the user-bubble side of an automated turn (extension,\n// bridge, capture, scheduled task, watcher). Bare label — no \"reply\"\n// suffix — so the chip reads as a source tag, not a response indicator.\nfunction UserCategoryChip({ category }: { category: string }) {\n const def = CATEGORY_BADGE[category];\n if (!def) return null;\n const { label, Icon, cls } = def;\n return (\n <span className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full border text-[9.5px] font-medium shrink-0 ${cls}`}>\n <Icon size={9} className=\"shrink-0\" />\n <span>{label}</span>\n </span>\n );\n}\n\n// Compact disclosure used inside every automation-turn card so each\n// section (instruction, context, captured content, change diff) has the\n// same chevron + label affordance.\nfunction CollapsibleSection({\n label,\n defaultOpen,\n accent,\n hint,\n children,\n}: {\n label: string;\n defaultOpen?: boolean;\n accent: boolean;\n hint?: string;\n children: ReactNode;\n}) {\n const [open, setOpen] = useState(Boolean(defaultOpen));\n return (\n <div className=\"flex flex-col gap-1 min-w-0\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={`flex items-center gap-1 text-left text-[10.5px] ${accent ? \"text-white/75 hover:text-white/95\" : \"text-fg-muted hover:text-fg\"}`}\n aria-expanded={open}\n >\n <ChevronRight size={11} className={`shrink-0 transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n <span className=\"uppercase tracking-wide\">{label}</span>\n {hint && <span className={`ml-1 normal-case ${accent ? \"text-white/55\" : \"text-fg-faint\"}`}>{hint}</span>}\n </button>\n {open && <div className=\"pl-4 min-w-0\">{children}</div>}\n </div>\n );\n}\n\n// Shared skeleton for every automation-turn user bubble. Top row is a\n// small category chip + icon + title; an optional chip row holds metadata\n// pills (host, selector, dm/group); the body is a list of collapsible\n// sections. This keeps extension/bridge/capture/trigger bubbles visually\n// consistent so the operator can scan an automation thread quickly.\nfunction StructuredTurnCard({\n categoryKey,\n Icon,\n title,\n titleTooltip,\n chips,\n sections,\n accent,\n}: {\n categoryKey: string | null;\n Icon: React.ElementType;\n title: string;\n titleTooltip?: string;\n chips?: ReactNode;\n sections: Array<{ label: string; content: ReactNode; defaultOpen?: boolean; hint?: string }>;\n accent: boolean;\n}) {\n return (\n <div className=\"flex flex-col gap-2 min-w-0\">\n <div className=\"flex items-center gap-1.5 min-w-0 flex-wrap\">\n {categoryKey && <UserCategoryChip category={categoryKey} />}\n <Icon size={12} className={`shrink-0 ${accent ? \"text-white/85\" : \"text-fg-muted\"}`} />\n <span\n className={`text-[13px] font-medium truncate min-w-0 ${accent ? \"text-white/95\" : \"text-fg\"}`}\n title={titleTooltip}\n >\n {title}\n </span>\n </div>\n {chips && (\n <div className={`flex flex-wrap items-center gap-1.5 text-[10px] ${accent ? \"text-white/75\" : \"text-fg-faint\"}`}>\n {chips}\n </div>\n )}\n {sections.length > 0 && (\n <div className=\"flex flex-col gap-1.5\">\n {sections.map((s, i) => (\n <CollapsibleSection\n key={i}\n label={s.label}\n defaultOpen={s.defaultOpen}\n hint={s.hint}\n accent={accent}\n >\n {s.content}\n </CollapsibleSection>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// Auto-collapses any bubble whose rendered content would exceed `threshold`\n// pixels. Applied to long user/assistant text so a captured-and-pasted code\n// block or a multi-screen agent answer doesn't push the rest of the\n// conversation off-screen. Detection is observation-based (ResizeObserver on\n// scrollHeight) so it works for markdown, code blocks, images, and embeds\n// uniformly without needing a per-content-type heuristic.\nfunction CollapsibleLong({\n children,\n threshold = 480,\n accent,\n streaming = false,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n threshold?: number;\n accent: boolean;\n streaming?: boolean;\n defaultOpen?: boolean;\n}) {\n const innerRef = useRef<HTMLDivElement>(null);\n const [overflows, setOverflows] = useState(false);\n const [open, setOpen] = useState(defaultOpen);\n // Latched true once the user has been treated as \"actively reading\" this\n // bubble — either the first measurement saw the content fit, OR the\n // bubble was ever observed streaming, OR it was rendered as the latest\n // turn (just streamed, the user is mid-read). From that point, growing\n // past the threshold or remounting must NOT snap it closed.\n const firstFitRef = useRef(defaultOpen);\n const wasStreamingRef = useRef(false);\n if (streaming) wasStreamingRef.current = true;\n\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n const check = () => {\n const over = el.scrollHeight > threshold + 24;\n setOverflows(over);\n if (!firstFitRef.current) {\n if (!over || wasStreamingRef.current || defaultOpen) {\n firstFitRef.current = true;\n setOpen(true);\n }\n }\n };\n check();\n const ro = new ResizeObserver(check);\n ro.observe(el);\n return () => ro.disconnect();\n }, [threshold, defaultOpen]);\n\n const collapsed = overflows && !open;\n\n return (\n <div className=\"flex flex-col\">\n <div\n ref={innerRef}\n className={collapsed ? \"relative overflow-hidden\" : \"\"}\n style={collapsed ? { maxHeight: threshold } : undefined}\n >\n {children}\n {collapsed && (\n <div\n className={`pointer-events-none absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t ${\n accent ? \"from-black/30\" : \"from-surface-1/90\"\n } to-transparent`}\n />\n )}\n </div>\n {overflows && (\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={`mt-1.5 self-start inline-flex items-center gap-1 text-[11px] ${\n accent ? \"text-white/85 hover:text-white\" : \"text-fg-faint hover:text-fg-muted\"\n }`}\n aria-expanded={open}\n >\n <ChevronRight size={10} className={`transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n {open ? \"Show less\" : \"Show more\"}\n </button>\n )}\n </div>\n );\n}\n\n// Sanitizer schema = GitHub default + extras the agent is told it can use.\n// Anything not listed here gets stripped (scripts, event handlers, javascript: URLs).\nconst sanitizeSchema = {\n ...defaultSchema,\n tagNames: [\n ...(defaultSchema.tagNames ?? []),\n \"details\", \"summary\", \"mark\", \"kbd\", \"sub\", \"sup\", \"abbr\", \"small\",\n \"aside\", \"figure\", \"figcaption\", \"dl\", \"dt\", \"dd\",\n \"audio\", \"source\",\n ],\n attributes: {\n ...(defaultSchema.attributes ?? {}),\n \"*\": [...((defaultSchema.attributes ?? {})[\"*\"] ?? []), \"className\", \"title\"],\n aside: [\"className\"],\n abbr: [\"title\"],\n details: [\"open\"],\n audio: [\"src\", \"controls\", \"preload\", \"loop\", \"autoplay\", \"muted\"],\n source: [\"src\", \"type\"],\n },\n};\n\n// Module-scope plugin arrays — passing fresh array literals to ReactMarkdown\n// on every render of MarkdownContent forced react-markdown's internal\n// useMemo() inputs to differ each time, defeating its plugin-pipeline\n// memoization. Hoisting these makes the references stable across renders.\nconst MD_REMARK_PLUGINS = [remarkGfm];\n// rehype-highlight runs after rehype-raw (so any raw HTML <code> blocks are\n// also highlighted) and before rehype-sanitize (so the spans/classes it adds\n// pass through the sanitizer's allow-list rather than being stripped).\nconst MD_REHYPE_PLUGINS: import(\"unified\").PluggableList = [\n rehypeRaw,\n [rehypeHighlight, { detect: true, ignoreMissing: true }],\n [rehypeSanitize, sanitizeSchema],\n];\n\nfunction reactChildrenToText(children: ReactNode): string {\n if (children == null || typeof children === \"boolean\") return \"\";\n if (typeof children === \"string\" || typeof children === \"number\") return String(children);\n if (Array.isArray(children)) return children.map(reactChildrenToText).join(\"\");\n if (typeof children === \"object\" && \"props\" in (children as object)) {\n return reactChildrenToText((children as { props: { children?: ReactNode } }).props.children);\n }\n return \"\";\n}\n\ntype Props = {\n message: Message | { role: \"assistant\"; content: string; streaming?: boolean };\n agentConfig?: AgentConfig | null;\n userProfile?: UserProfile | null;\n showAvatar?: boolean;\n threadId?: string | null;\n // When false, suppress the inline ToolList for this message. Driven by\n // the chat-panel filter toolbar's `tool_use` toggle.\n showToolEvents?: boolean;\n // Thread-level fallback for the ContextUsageBar baseline when a row's\n // usage snapshot predates the per-row context_window_tokens column.\n contextWindowTokens?: number | null;\n // True for the very last message in the rendered list. The just-streamed\n // assistant turn the user is currently reading must NOT auto-collapse\n // when its persisted version mounts (different component instance from\n // the streaming bubble, so the streaming-latch can't carry over).\n isLatest?: boolean;\n // Resend this user prompt as a new turn. Hidden when undefined; also\n // hidden for category-tagged messages (bridge / scheduled_task / watcher)\n // since those originate from automation and re-sending the persisted\n // body would replay it as a regular user prompt.\n onRetry?: (text: string, attachments: ContentPart[]) => void;\n // Number of tool calls currently in flight for the streaming run. Drives\n // the CountdownRing's adaptive pause so the wall-clock indicator mirrors\n // run-registry's effective-elapsed semantics (tool time is excluded).\n inflightToolCount?: number;\n};\n\nconst GRADIENTS = [\n \"from-violet-500 to-indigo-600\",\n \"from-blue-500 to-cyan-600\",\n \"from-emerald-500 to-teal-600\",\n \"from-orange-500 to-amber-600\",\n \"from-rose-500 to-pink-600\",\n \"from-fuchsia-500 to-purple-600\",\n];\n\nfunction gradientFor(id: string): string {\n let h = 0;\n for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) | 0;\n return GRADIENTS[Math.abs(h) % GRADIENTS.length];\n}\n\nfunction AgentAvatar({ config }: { config?: AgentConfig | null }) {\n if (config?.icon) {\n // eslint-disable-next-line @next/next/no-img-element\n return <img src={config.icon} alt={config.name} className=\"w-7 h-7 rounded-lg object-cover\" />;\n }\n if (config) {\n return (\n <div className={`w-7 h-7 rounded-lg bg-gradient-to-br ${gradientFor(config.id)} flex items-center justify-center text-xs font-bold text-white select-none`}>\n {config.name.charAt(0).toUpperCase()}\n </div>\n );\n }\n return (\n <div className=\"w-7 h-7 rounded-lg bg-surface-3 flex items-center justify-center\">\n <Bot size={13} className=\"text-fg-faint\" />\n </div>\n );\n}\n\nfunction UserAvatar({ profile }: { profile?: UserProfile | null }) {\n if (profile?.icon) {\n // eslint-disable-next-line @next/next/no-img-element\n return <img src={profile.icon} alt={profile.name || \"You\"} className=\"w-7 h-7 rounded-lg object-cover\" />;\n }\n if (profile?.name) {\n return (\n <div className=\"w-7 h-7 rounded-lg bg-accent flex items-center justify-center text-xs font-bold text-white select-none\">\n {profile.name.charAt(0).toUpperCase()}\n </div>\n );\n }\n return (\n <div className=\"w-7 h-7 rounded-lg bg-surface-3 flex items-center justify-center\">\n <User size={13} className=\"text-fg-faint\" />\n </div>\n );\n}\n\n// Detects messages forwarded by the bridge dispatcher (lib/bridges/dispatcher.ts:\n// `contextLines.join(\"\\n\") + \"\\n\\n\" + msg.text`) so the chat UI can render the\n// metadata as a compact header card instead of dumping six bracketed `[key:value]`\n// lines at the top of every bubble. Format is fixed by dispatcher; if either\n// side changes, update both.\nconst parseBridgeContext = parseBridgePrompt;\n\nconst SILENT_TRIGGER_RE = /\\n+\\[SILENT_TRIGGER\\][^\\n]*(?:\\n(?!\\n).*)*$/;\n\ninterface ScheduledTaskCardData {\n kind: \"scheduled_task\";\n prompt: string;\n silent: boolean;\n}\n\ninterface WatcherCardData {\n kind: \"watcher\";\n label: string;\n tool: string;\n args: string;\n diff: string;\n directive: string;\n silent: boolean;\n}\n\ntype TriggerCardData = ScheduledTaskCardData | WatcherCardData;\n\n// Strip the `[SILENT_TRIGGER] …` envelope that runTriggerAgent appends\n// in silent mode so the card can render the user's original prompt and\n// surface a separate \"Silent\" pill instead of leaking framework prose.\nfunction stripSilentEnvelope(text: string): { text: string; silent: boolean } {\n const m = SILENT_TRIGGER_RE.exec(text);\n if (!m) return { text, silent: false };\n return { text: text.slice(0, m.index).trimEnd(), silent: true };\n}\n\nfunction parseTriggerMessage(category: string | null | undefined, raw: string): TriggerCardData | null {\n if (category === \"scheduled_task\") {\n const { text, silent } = stripSilentEnvelope(raw);\n return { kind: \"scheduled_task\", prompt: text, silent };\n }\n if (category === \"watcher\") {\n const { text, silent } = stripSilentEnvelope(raw);\n const headerRe = /^Watcher\\s+\"([^\"]*)\"\\s+detected a change\\.\\s*\\n+Tool:\\s*([^\\n]+)\\s*\\nArgs:\\s*([\\s\\S]*?)\\n+---\\s*Diff[^\\n]*---\\s*\\n([\\s\\S]*?)\\n\\n([\\s\\S]*)$/;\n const m = headerRe.exec(text);\n if (!m) return null;\n return {\n kind: \"watcher\",\n label: m[1],\n tool: m[2].trim(),\n args: m[3].trim(),\n diff: m[4].trim(),\n directive: m[5].trim(),\n silent,\n };\n }\n return null;\n}\n\n// Compact header card for trigger-originated user messages (scheduled\n// tasks + watchers, ADR-0027/ADR-0032). Surfaces the trigger type with\n// an icon + label so the operator can tell at a glance that the prompt\n// came from automation and not from them. Watchers additionally expose\n// the diff context in a collapsed section to keep large diffs out of\n// the main bubble height.\nfunction TriggerMessageCard({ data }: { data: TriggerCardData }) {\n const Icon = data.kind === \"scheduled_task\" ? Clock : Eye;\n const title = data.kind === \"scheduled_task\" ? \"Scheduled task\" : `Watcher: ${data.label || \"(unnamed)\"}`;\n const chips = (data.kind === \"watcher\" || data.silent) ? (\n <>\n {data.kind === \"watcher\" && (\n <span className=\"px-1.5 py-0.5 rounded-full bg-white/15 text-[9.5px] uppercase tracking-wide shrink-0\">\n {data.tool}\n </span>\n )}\n {data.silent && (\n <span className=\"flex items-center gap-1 px-1.5 py-0.5 rounded-full bg-white/15 text-[9.5px] uppercase tracking-wide shrink-0\" title=\"Silent trigger: reply only if material\">\n <EyeOff size={9} />\n silent\n </span>\n )}\n </>\n ) : null;\n\n const body = data.kind === \"scheduled_task\" ? data.prompt : data.directive;\n const sections: Array<{ label: string; content: ReactNode; defaultOpen?: boolean; hint?: string }> = [\n {\n label: data.kind === \"scheduled_task\" ? \"Prompt\" : \"Directive\",\n defaultOpen: true,\n content: <MarkdownContent text={body} />,\n },\n ];\n if (data.kind === \"watcher\" && (data.args || data.diff)) {\n sections.push({\n label: \"Change context\",\n defaultOpen: false,\n content: (\n <div className=\"flex flex-col gap-1\">\n {data.args && <pre className=\"m-0 px-2 py-1.5 rounded bg-black/25 text-[11px] leading-snug whitespace-pre-wrap break-words text-white/90 max-h-72 overflow-auto\">{data.args}</pre>}\n {data.diff && <pre className=\"m-0 px-2 py-1.5 rounded bg-black/25 text-[11px] leading-snug whitespace-pre-wrap break-words text-white/90 max-h-96 overflow-auto\">{data.diff}</pre>}\n </div>\n ),\n });\n }\n\n return (\n <StructuredTurnCard\n categoryKey={data.kind === \"scheduled_task\" ? \"scheduled_task\" : \"watcher\"}\n Icon={Icon}\n title={title}\n chips={chips}\n sections={sections}\n accent={true}\n />\n );\n}\n\n// Compact header card for inbound bridge messages. Shows sender + chat\n// context as a single line of metadata above the actual message text, so a\n// WhatsApp DM looks like \"Alice • DM\\n<text>\" and a group message looks\n// like \"Alice in Family Chat • Group\\n<text>\". Always on the user-bubble\n// (accent) side because bridge messages are persisted with role=user.\nfunction BridgeMessageCard({ ctx }: { ctx: BridgePromptContext }) {\n const showChat = ctx.isGroup && ctx.chatName && ctx.chatName !== ctx.senderName;\n const title = showChat ? `${ctx.senderName} in ${ctx.chatName}` : ctx.senderName;\n const Icon = ctx.isGroup ? Users : MessageCircle;\n const chips = (\n <span className=\"px-1.5 py-0.5 rounded-full bg-white/15 text-[9.5px] uppercase tracking-wide shrink-0\">\n {ctx.isGroup ? \"group\" : \"dm\"}\n </span>\n );\n const sections: Array<{ label: string; content: ReactNode; defaultOpen?: boolean; hint?: string }> = [\n {\n label: \"Message\",\n defaultOpen: true,\n hint: ctx.body ? undefined : \"(empty)\",\n content: ctx.body ? (\n <MarkdownContent text={ctx.body} />\n ) : (\n <p className=\"text-[12px] italic text-white/65\">(empty message)</p>\n ),\n },\n ];\n return (\n <StructuredTurnCard\n categoryKey=\"bridge\"\n Icon={Icon}\n title={title}\n titleTooltip={ctx.senderJid}\n chips={chips}\n sections={sections}\n accent={true}\n />\n );\n}\n\nfunction parseContent(raw: string): string | ContentPart[] {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length > 0 &&\n typeof parsed[0] === \"object\" &&\n parsed[0] !== null &&\n \"type\" in (parsed[0] as object)\n ) {\n return parsed as ContentPart[];\n }\n } catch {\n // not valid JSON content\n }\n return raw;\n}\n\n// Markdown image renderer with a one-time automatic retry. If both attempts\n// fail (common on transient local-network/SW races), show a compact fallback\n// with explicit actions instead of a broken image icon.\nfunction ResilientMarkdownImage({ src, alt }: { src?: string | Blob; alt?: string }) {\n const [retryNonce, setRetryNonce] = useState(0);\n const [failed, setFailed] = useState(false);\n\n const normalizedSrc = typeof src === \"string\" ? src : src instanceof Blob ? URL.createObjectURL(src) : \"\";\n const effectiveSrc = normalizedSrc\n ? `${normalizedSrc}${normalizedSrc.includes(\"?\") ? \"&\" : \"?\"}retry=${retryNonce}`\n : \"\";\n\n if (!normalizedSrc) {\n return (\n <div className=\"my-2 px-3 py-2 rounded border border-rose-800/60 bg-rose-950/30 text-xs text-rose-700 dark:text-rose-300\">\n Invalid image URL in markdown.\n </div>\n );\n }\n\n if (failed) {\n return (\n <div className=\"my-2 px-3 py-2 rounded border border-amber-700/50 bg-amber-900/20 text-xs text-amber-300\">\n <div>Image failed to load.</div>\n <div className=\"mt-1 flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"px-2 py-1 rounded border border-amber-500/60 hover:bg-amber-900/30\"\n onClick={() => {\n setFailed(false);\n setRetryNonce((n) => n + 1);\n }}\n >\n Retry\n </button>\n <a\n href={normalizedSrc}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline decoration-dotted hover:decoration-solid break-all\"\n >\n Open image\n </a>\n </div>\n </div>\n );\n }\n\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={effectiveSrc}\n alt={alt ?? \"image\"}\n loading=\"lazy\"\n className=\"rounded-lg border border-border/50\"\n onError={() => {\n if (retryNonce === 0) {\n setRetryNonce(1);\n return;\n }\n setFailed(true);\n }}\n />\n );\n}\n\n// Renders a Google Maps Embed inside an iframe whose src points at our\n// server-side proxy (/api/v1/maps/embed). The proxy injects the API key so\n// it never appears in chat HTML. Triggered by ```map fenced blocks emitted\n// by the agent — see PRESENTATION_CTX in lib/agents/run-thread.ts.\nfunction MapEmbed({ payload }: { payload: string }) {\n const [retryNonce, setRetryNonce] = useState(0);\n const [failed, setFailed] = useState(false);\n let params: URLSearchParams | null = null;\n let parseError: string | null = null;\n try {\n const obj = JSON.parse(payload) as Record<string, unknown>;\n const sp = new URLSearchParams();\n for (const k of [\"q\", \"center\", \"zoom\", \"origin\", \"destination\", \"search\", \"mode\"] as const) {\n const v = obj[k];\n if (typeof v === \"string\" && v.length > 0) sp.set(k, v);\n else if (typeof v === \"number\") sp.set(k, String(v));\n }\n if ([...sp.keys()].length === 0) parseError = \"no recognized fields (q / center / origin+destination / search)\";\n else params = sp;\n } catch (e) {\n parseError = e instanceof Error ? e.message : String(e);\n }\n\n if (!params) {\n return (\n <div className=\"my-2 px-3 py-2 rounded border border-rose-800/60 bg-rose-950/30 text-xs text-rose-700 dark:text-rose-300\">\n Invalid map block: {parseError}\n </div>\n );\n }\n const src = `/api/v1/maps/embed?${params.toString()}${retryNonce > 0 ? `&retry=${retryNonce}` : \"\"}`;\n\n if (failed) {\n const q = params.get(\"q\") ?? params.get(\"search\") ?? params.get(\"center\") ?? \"\";\n const direct = q\n ? `https://www.google.com/maps?q=${encodeURIComponent(q)}`\n : \"https://www.google.com/maps\";\n return (\n <div className=\"my-2 px-3 py-2 rounded border border-amber-700/50 bg-amber-900/20 text-xs text-amber-300\">\n <div>Map failed to load.</div>\n <div className=\"mt-1 flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"px-2 py-1 rounded border border-amber-500/60 hover:bg-amber-900/30\"\n onClick={() => {\n setFailed(false);\n setRetryNonce((n) => n + 1);\n }}\n >\n Retry\n </button>\n <a\n href={direct}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline decoration-dotted hover:decoration-solid\"\n >\n Open in Google Maps\n </a>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"my-2 rounded overflow-hidden border border-border bg-surface-2\">\n <iframe\n src={src}\n title=\"Map\"\n width=\"100%\"\n height=\"320\"\n loading=\"lazy\"\n referrerPolicy=\"no-referrer-when-downgrade\"\n allowFullScreen\n style={{ border: 0, display: \"block\" }}\n onError={() => {\n if (retryNonce === 0) {\n setRetryNonce(1);\n return;\n }\n setFailed(true);\n }}\n />\n </div>\n );\n}\n\n// Memoized: this component appears under every assistant bubble and during\n// streaming gets re-rendered on every rAF flush. The inner ReactMarkdown\n// pipeline (remark + rehype passes, syntax highlighting via rehypeHighlight,\n// custom <a> / <code> renderers) is the expensive part — re-running it\n// against unchanged text on every parent render shows up as jank on long\n// threads. With memo, only the in-flight bubble re-renders during streaming;\n// persisted siblings sit idle.\nconst MarkdownContent = memo(function MarkdownContent({ text, streaming, onInAppLink, unverifiedLinks, sourceManifest, inflightToolCount = 0 }: { text: string; streaming?: boolean; onInAppLink?: (href: string) => void; unverifiedLinks?: ReadonlySet<string>; sourceManifest?: ReadonlyMap<number, { href: string; label: string }>; inflightToolCount?: number }) {\n // Inline-citation pre-processor. The agent writes `[3]` markers in-prose;\n // we resolve each to a markdown link `[3](href)` BEFORE react-markdown\n // parses the string so the existing <a> renderer below picks it up with\n // no special-casing. Markers whose number isn't in the manifest are\n // left untouched (they'll show as plain `[3]` text) so an invented\n // number is visibly un-linked rather than silently mis-routed.\n const renderedText = useMemo(() => {\n if (!sourceManifest || sourceManifest.size === 0) return text;\n return text.replace(/(?<!\\])\\[(\\d+)\\]/g, (match, raw: string) => {\n const entry = sourceManifest.get(parseInt(raw, 10));\n return entry ? `[${raw}](${entry.href})` : match;\n });\n }, [text, sourceManifest]);\n return (\n <div className=\"prose prose-invert prose-sm max-w-none jarela-rich\">\n <ReactMarkdown\n remarkPlugins={MD_REMARK_PLUGINS}\n rehypePlugins={MD_REHYPE_PLUGINS}\n components={{\n a({ href, children, ...rest }) {\n const parsed = href ? parseHref(href) : undefined;\n const isUnverified = !!(href && unverifiedLinks?.has(href));\n // Detect citation markers: link text is literally `[N]` where N\n // is a positive integer. These are rendered as small superscript\n // chips (Wikipedia-style) so they're scannable as citations and\n // distinct from ordinary inline links.\n const isCitationMarker =\n Array.isArray(children) && children.length === 1\n ? typeof children[0] === \"string\" && /^\\[\\d+\\]$/.test(children[0])\n : typeof children === \"string\" && /^\\[\\d+\\]$/.test(children);\n const citationText = isCitationMarker\n ? (Array.isArray(children) ? (children[0] as string) : (children as string))\n : null;\n // Inline audio: any link to a local /api/v1/files/*.{wav,mp3,ogg,webm,m4a}\n // becomes a native <audio controls> player. The original anchor\n // text is dropped — the player IS the answer. An `?autoplay=1`\n // query string lets the agent (via generate_voice) ask the\n // browser to start playback immediately.\n if (href && /^\\/api\\/v1\\/files\\/[^?#]+\\.(wav|mp3|ogg|webm|m4a)(\\?|#|$)/i.test(href)) {\n return <InlineAudio href={href} />;\n }\n const inApp = !!parsed && !parsed.external && (!!parsed.tab || !!parsed.hash || (!!parsed.thread && !!parsed.agent));\n const unverifiedCls = isUnverified ? \"decoration-warn decoration-wavy underline-offset-2\" : \"\";\n const unverifiedTitle = isUnverified ? \"Agent did not visit this source in this conversation — the citation may be invented.\" : undefined;\n // Citation-marker rendering: superscript chip with a tooltip\n // showing the source label so the user can preview what the\n // marker points to without clicking. The href is still active\n // (jumps to anchor for #msg-… or opens external for URLs).\n if (isCitationMarker && href) {\n const markerNum = parseInt(citationText!.replace(/[\\[\\]]/g, \"\"), 10);\n const entry = Number.isFinite(markerNum) ? sourceManifest?.get(markerNum) : undefined;\n const title = entry?.label ?? unverifiedTitle ?? href;\n const isAnchor = href.startsWith(\"#\");\n return (\n <a\n {...rest}\n href={href}\n target={isAnchor || inApp ? undefined : \"_blank\"}\n rel={isAnchor || inApp ? undefined : \"noopener noreferrer\"}\n title={title}\n onClick={inApp && onInAppLink ? (e) => { e.preventDefault(); onInAppLink(href); } : undefined}\n className=\"jarela-citation\"\n >\n {citationText}\n </a>\n );\n }\n if (inApp && href && onInAppLink) {\n return (\n <a\n {...rest}\n href={href}\n title={unverifiedTitle ?? rest.title}\n className={`${rest.className ?? \"\"} ${unverifiedCls}`.trim()}\n onClick={(e) => { e.preventDefault(); onInAppLink(href); }}\n >\n {children}\n {isUnverified && <sup className=\"text-warn ml-0.5\" aria-label=\"unverified citation\">⚠</sup>}\n </a>\n );\n }\n return (\n <a\n {...rest}\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={unverifiedTitle ?? rest.title}\n className={`${rest.className ?? \"\"} ${unverifiedCls}`.trim()}\n >\n {children}\n {isUnverified && <sup className=\"text-warn ml-0.5\" aria-label=\"unverified citation\">⚠</sup>}\n </a>\n );\n },\n pre({ children }) {\n // CodeFence renders its own <pre>, so collapse react-markdown's\n // outer wrapper to avoid <pre><pre>...</pre></pre>.\n return <>{children}</>;\n },\n code({ className, children }) {\n const match = /language-(\\w+)/.exec(className ?? \"\");\n if (match?.[1] === \"map\") {\n return <MapEmbed payload={reactChildrenToText(children).replace(/\\n$/, \"\")} />;\n }\n return match ? (\n <CodeFence language={match[1]} className={className ?? \"\"}>{children}</CodeFence>\n ) : (\n <code className=\"bg-surface-2 px-1 rounded text-fg-muted break-all\">{children}</code>\n );\n },\n img({ src, alt }) {\n return <ResilientMarkdownImage src={src} alt={alt} />;\n },\n }}\n >\n {renderedText}\n </ReactMarkdown>\n {streaming && ( <span className=\"inline-flex items-center align-middle ml-1\">\n <CountdownRing inflightToolCount={inflightToolCount} />\n </span>\n )}\n </div>\n );\n});\n\nfunction ReferencesPanel({ sources }: { sources: ReadonlyArray<{ n: number; label: string; href: string }> }) {\n const [open, setOpen] = useState(false);\n if (sources.length === 0) return null;\n return (\n <div className=\"mt-1.5\">\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"inline-flex items-center gap-1 text-[11px] text-fg-faint hover:text-fg-muted transition-colors\"\n aria-expanded={open}\n >\n <ChevronRight size={10} className={`transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n <LinkIcon size={10} />\n <span>{sources.length} {sources.length === 1 ? \"reference\" : \"references\"}</span>\n </button>\n {open && (\n <ol className=\"mt-1 space-y-0.5 pl-4 list-none\">\n {sources.map((s) => {\n const isAnchor = s.href.startsWith(\"#\");\n const isMemory = s.href.startsWith(\"memory://\");\n return (\n <li key={s.n} className=\"text-[11px] flex items-start gap-1.5\">\n <span className=\"text-fg-faint tabular-nums shrink-0 w-5 text-right\">[{s.n}]</span>\n {isAnchor || isMemory ? (\n <a\n href={isAnchor ? s.href : \"#\"}\n onClick={isMemory ? (e) => e.preventDefault() : undefined}\n className=\"text-sky-700 dark:text-sky-400 hover:underline truncate inline-block max-w-full align-middle\"\n title={s.href}\n >\n {s.label}\n </a>\n ) : (\n <a\n href={s.href}\n target={s.href.startsWith(\"http\") ? \"_blank\" : undefined}\n rel={s.href.startsWith(\"http\") ? \"noopener noreferrer\" : undefined}\n className=\"text-sky-700 dark:text-sky-400 hover:underline truncate inline-block max-w-full align-middle\"\n title={s.href}\n >\n {s.label}\n </a>\n )}\n </li>\n );\n })}\n </ol>\n )}\n </div>\n );\n}\n\nfunction CitationsSummary({ claims, checkerModel }: { claims: ReadonlyArray<{ text?: string; link: string | null; verified: boolean; reason?: string; impact?: \"high\" | \"med\" | \"low\" }>; checkerModel: string }) {\n const [open, setOpen] = useState(false);\n if (claims.length === 0) return null;\n\n // Group + count by impact so the trigger is a compact, scannable summary.\n type ClaimT = (typeof claims)[number];\n const buckets: Record<\"high\" | \"med\" | \"low\", ClaimT[]> = { high: [], med: [], low: [] };\n for (const c of claims) {\n const k = c.impact === \"high\" ? \"high\" : c.impact === \"low\" ? \"low\" : \"med\";\n buckets[k].push(c);\n }\n const uncitedHigh = buckets.high.filter((c) => !c.verified).length;\n const totalUncited = claims.filter((c) => !c.verified).length;\n const total = claims.length;\n const allCited = totalUncited === 0;\n\n // Trigger label prefers the loudest signal: uncited-high > total uncited > all good.\n const trigger = uncitedHigh > 0\n ? `${uncitedHigh} high-impact claim${uncitedHigh === 1 ? \"\" : \"s\"} uncited`\n : totalUncited > 0\n ? `${totalUncited} of ${total} claim${total === 1 ? \"\" : \"s\"} uncited`\n : `${total} claim${total === 1 ? \"\" : \"s\"} cited`;\n\n const impactBadge = (impact: \"high\" | \"med\" | \"low\") => {\n const styles =\n impact === \"high\" ? \"bg-warn/15 text-warn\"\n : impact === \"low\" ? \"bg-fg-faint/10 text-fg-faint\"\n : \"bg-fg-subtle/15 text-fg-subtle\";\n return (\n <span className={`text-[9px] uppercase tracking-wider px-1 py-px rounded ${styles} shrink-0`}>\n {impact}\n </span>\n );\n };\n\n return (\n <div className=\"mt-1.5\">\n <button\n onClick={() => setOpen((v) => !v)}\n className={`inline-flex items-center gap-1 text-[11px] transition-colors ${allCited ? \"text-fg-faint hover:text-fg-muted\" : \"text-warn hover:opacity-80\"}`}\n title={checkerModel ? `Citations checked by ${checkerModel}` : undefined}\n aria-expanded={open}\n >\n <ChevronRight size={10} className={`transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n <span>{trigger}</span>\n </button>\n {open && (\n <div className=\"mt-1 pl-4 space-y-2\">\n {([\"high\", \"med\", \"low\"] as const).map((bucket) => {\n const list = buckets[bucket];\n if (list.length === 0) return null;\n return (\n <ul key={bucket} className=\"space-y-0.5\">\n {list.map((c, i) => (\n <li key={`${bucket}-${i}`} className={`text-[11px] flex items-start gap-1.5 ${c.verified ? \"text-fg-subtle\" : \"text-warn\"}`}>\n <span className=\"shrink-0\">{c.verified ? \"✓\" : \"⚠\"}</span>\n {impactBadge(bucket)}\n <span className=\"min-w-0 flex-1\">\n <span>{c.text ?? \"(claim)\"}</span>\n {c.link && (\n <span className=\"ml-1 text-fg-faint truncate inline-block max-w-[60ch] align-middle\">— {c.link}</span>\n )}\n {!c.verified && c.reason && (\n <span className=\"block text-[10px] text-fg-faint italic mt-px\">{c.reason}</span>\n )}\n </span>\n </li>\n ))}\n </ul>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// Shield indicator (ADR-0064 transparency requirement). Renders when the\n// turn redacted at least one sensitive value before sending to the LLM.\n// The user's local view always shows real values (rehydrated at render\n// time) — this affordance is the visible signal that secrets stayed on\n// the device. Tooltip explains the trust boundary; click expands to a\n// per-type breakdown.\nfunction RedactionShield({\n summary,\n}: {\n summary: ReadonlyArray<{ type_hint: string; count: number }>;\n}) {\n const [open, setOpen] = useState(false);\n if (summary.length === 0) return null;\n const total = summary.reduce((acc, e) => acc + e.count, 0);\n return (\n <div className=\"mt-1.5\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"inline-flex items-center gap-1 text-[11px] text-emerald-700 dark:text-emerald-400/85 hover:opacity-80 transition-colors\"\n title=\"Sensitive values were replaced with placeholders before being sent to the LLM. Real values stayed on this device.\"\n aria-expanded={open}\n >\n <ChevronRight size={10} className={`transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n <ShieldCheck size={11} />\n <span>{total} {total === 1 ? \"value\" : \"values\"} held back from LLM</span>\n </button>\n {open && (\n <div className=\"mt-1 pl-4\">\n <ul className=\"space-y-0.5\">\n {summary.map((e, i) => (\n <li key={`${e.type_hint}-${i}`} className=\"text-[11px] text-fg-muted\">\n <span className=\"tabular-nums\">{e.count}</span>\n {\" × \"}\n <span className=\"font-mono opacity-85\">{e.type_hint}</span>\n </li>\n ))}\n </ul>\n <div className=\"mt-1 text-[10px] text-fg-faint italic\">\n Real values stay on this device. Add patterns at <span className=\"font-mono\">~/.jarela/redaction-patterns.json</span>.\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction RefsFooter({ refs }: { refs: ExtractedRef[] }) {\n const [open, setOpen] = useState(false);\n if (refs.length === 0) return null;\n return (\n <div className=\"mt-1.5\">\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"inline-flex items-center gap-1 text-[11px] text-fg-faint hover:text-fg-muted transition-colors\"\n >\n <ChevronRight size={10} className={`transition-transform ${open ? \"rotate-90\" : \"\"}`} />\n <LinkIcon size={10} />\n <span>{refs.length} {refs.length === 1 ? \"reference\" : \"references\"}</span>\n </button>\n {open && (\n <ul className=\"mt-1 space-y-0.5 pl-4\">\n {refs.map((r, i) => (\n <li key={`${i}-${r.url}`} className=\"text-[11px]\">\n <a\n href={r.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sky-700 dark:text-sky-400 hover:text-sky-700 dark:hover:text-sky-300 hover:underline truncate inline-block max-w-full align-middle\"\n title={r.url}\n >\n {r.title || r.url}\n </a>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction CodeFence({ language, className, children }: { language: string; className: string; children: ReactNode }) {\n const [copied, setCopied] = useState(false);\n const codeText = useMemo(() => reactChildrenToText(children).replace(/\\n$/, \"\"), [children]);\n\n const copyCode = useCallback(() => {\n void navigator.clipboard.writeText(codeText).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n }).catch(console.error);\n }, [codeText]);\n\n // rehype-highlight already populated `className` with `hljs language-X`\n // plus per-token spans inside `children`. The `hljs` class drives styling\n // from the imported github-dark theme.\n return (\n <div className=\"relative my-2 rounded-md overflow-hidden border border-border/60\">\n <div className=\"flex items-center justify-between px-2 py-1 text-[10px] bg-surface-3 text-fg-faint uppercase tracking-wide\">\n <span>{language}</span>\n <button\n onClick={copyCode}\n className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded border border-border/60 bg-surface-2 text-fg-muted hover:text-fg transition-colors\"\n title=\"Copy code\"\n aria-label=\"Copy code\"\n >\n {copied ? <Check size={10} /> : <Copy size={10} />}\n <span>{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n </div>\n <pre className=\"m-0 p-3 text-xs leading-relaxed overflow-x-auto bg-[#0d1117]\">\n <code className={className}>{children}</code>\n </pre>\n </div>\n );\n}\n\nfunction ContentPartView({ part, isUser, onInAppLink, unverifiedLinks, sourceManifest }: { part: ContentPart; isUser: boolean; onInAppLink?: (href: string) => void; unverifiedLinks?: ReadonlySet<string>; sourceManifest?: ReadonlyMap<number, { href: string; label: string }> }) {\n if (part.type === \"text\") {\n return isUser\n ? <p className=\"whitespace-pre-wrap\">{part.text}</p>\n : <MarkdownContent text={part.text} onInAppLink={onInAppLink} unverifiedLinks={unverifiedLinks} sourceManifest={sourceManifest} />;\n }\n if (part.type === \"image\") {\n return <ClickableImage media_type={part.media_type} data={part.data} />;\n }\n // File attachment — render an inline player for audio/video so voice\n // notes and short clips from the WhatsApp bridge are usable in-bubble.\n // Other file types still fall through to a download/open-in-new-tab link.\n const file = part as ContentPart & { type: \"file\"; name: string; media_type: string; data: string };\n const dataUrl = `data:${file.media_type};base64,${file.data}`;\n // For text files our data field is plain text, not base64. Detect and wrap.\n const href = /^text\\/|^application\\/json$/.test(file.media_type)\n ? `data:${file.media_type};charset=utf-8,${encodeURIComponent(file.data)}`\n : dataUrl;\n if (file.media_type.startsWith(\"audio/\")) {\n return (\n <div className=\"mt-1 max-w-md\">\n {/* Native controls keep play/pause/seek consistent with the OS;\n the filename hint below disambiguates voice-note vs file. */}\n <audio controls className=\"w-full\" src={dataUrl} />\n <div className=\"mt-0.5 text-[10px] text-fg-faint truncate\">{file.name}</div>\n </div>\n );\n }\n if (file.media_type.startsWith(\"video/\")) {\n return (\n <div className=\"mt-1 max-w-md\">\n <video\n controls\n playsInline\n className=\"w-full rounded-xl border border-border/40\"\n style={{ maxHeight: \"400px\" }}\n src={dataUrl}\n />\n <div className=\"mt-0.5 text-[10px] text-fg-faint truncate\">{file.name}</div>\n </div>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1.5 mt-1 rounded-lg border border-border/60 bg-surface-3/60 hover:bg-surface-3 hover:border-border text-[11px] text-fg-muted transition-colors\"\n title=\"Open in new tab\"\n >\n <Paperclip size={11} className=\"text-fg-faint shrink-0\" />\n <span className=\"truncate max-w-[200px]\">{file.name}</span>\n </a>\n );\n}\n\n// Image attachment — thumbnail in the bubble, click for a full-screen lightbox.\nfunction ClickableImage({ media_type, data }: { media_type: string; data: string }) {\n const [open, setOpen] = useState(false);\n const src = `data:${media_type};base64,${data}`;\n return (\n <>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={src}\n alt=\"attached image\"\n onClick={() => setOpen(true)}\n className=\"max-w-full rounded-xl mt-1 border border-border/40 cursor-zoom-in hover:border-fg-faint transition-colors\"\n style={{ maxHeight: \"400px\", objectFit: \"contain\" }}\n />\n {open && (\n <div\n onClick={() => setOpen(false)}\n className=\"fixed inset-0 z-[60] bg-black/85 backdrop-blur-sm flex items-center justify-center p-4 cursor-zoom-out animate-in fade-in\"\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={src}\n alt=\"attached image\"\n className=\"max-w-full max-h-full object-contain rounded-lg shadow-2xl\"\n onClick={(e) => e.stopPropagation()}\n />\n <button\n onClick={(e) => { e.stopPropagation(); setOpen(false); }}\n className=\"absolute top-4 right-4 p-2 rounded-full bg-black/40 hover:bg-black/60 text-white\"\n aria-label=\"Close\"\n >\n <X size={16} />\n </button>\n <a\n href={src}\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"absolute bottom-4 right-4 px-3 py-1.5 rounded-md bg-black/40 hover:bg-black/60 text-white text-xs\"\n >\n Open in new tab\n </a>\n </div>\n )}\n </>\n );\n}\n\nfunction messageTextForCopy(content: string | ContentPart[]): string {\n if (typeof content === \"string\") return content;\n return content.map((part) => {\n if (part.type === \"text\") return part.text;\n if (part.type === \"file\") return `[File: ${part.name}]`;\n if (part.type === \"image\") return `[Image: ${part.media_type}]`;\n return \"\";\n }).filter(Boolean).join(\"\\n\\n\");\n}\n\n// Memoized: while a run streams, ChatView re-renders on every text_delta to\n// update the live streaming bubble. Without React.memo, every persisted\n// MessageBubble re-renders too — for a 50-message thread that's 50\n// reconciliations per character. Props are pure data (no callbacks), and\n// `messages` array preserves identity for unchanged rows after the\n// `concat` in handleDone, so default shallow-equality is enough.\nexport const MessageBubble = memo(function MessageBubble({ message, agentConfig, userProfile, showAvatar = true, threadId = null, showToolEvents = true, contextWindowTokens = null, isLatest = false, onRetry, inflightToolCount = 0 }: Props) {\n const { dispatch } = useAppContext();\n const isUser = message.role === \"user\";\n const streaming = \"streaming\" in message && message.streaming;\n // Memoize the JSON-or-plain-text parse: `parseContent` runs JSON.parse on\n // anything that looks like a serialized ContentPart[]. For the streaming\n // bubble this is called on every rAF flush as `content` grows; without\n // memoization we'd re-parse the entire (growing) blob each frame.\n const parsed = useMemo(() => parseContent(message.content), [message.content]);\n const messageId = \"id\" in message ? message.id : null;\n\n const handleInAppLink = useCallback((href: string) => {\n const p = parseHref(href);\n // A `thread`+`agent` pair (emitted by delegate_to_agent's cite_as link\n // and by toast deep links) is a SELECT_THREAD intent — fire the\n // dedicated action so AppShell sets activeThreadId AND activeAgentId\n // atomically. Falling back to SET_TAB+SET_SELECTION would not load the\n // thread because chat tab keys off activeThreadId, not selectedItem.\n if (p.thread && p.agent) {\n dispatch({ type: \"SELECT_THREAD\", threadId: p.thread, agentId: p.agent });\n } else if (p.tab) {\n dispatch({ type: \"SET_TAB\", tab: p.tab });\n dispatch({ type: \"SET_SELECTION\", tab: p.tab, itemId: p.item ?? null });\n }\n if (p.hash && typeof window !== \"undefined\") {\n const samePath = `${window.location.pathname}${window.location.search}`;\n // Force a hashchange even if the hash matches the current value so the\n // in-thread anchor scrolls again on repeat clicks.\n if (window.location.hash === `#${p.hash}`) {\n window.history.replaceState(null, \"\", samePath);\n }\n window.history.replaceState(null, \"\", `${samePath}#${p.hash}`);\n window.dispatchEvent(new HashChangeEvent(\"hashchange\"));\n }\n }, [dispatch]);\n\n const copyLink = useCallback(() => {\n if (!messageId || typeof window === \"undefined\") return;\n const params = new URLSearchParams();\n if (threadId) params.set(\"thread\", threadId);\n const qs = params.toString();\n const url = `${window.location.origin}/${qs ? `?${qs}` : \"\"}#msg-${messageId}`;\n void navigator.clipboard.writeText(url).then(() => {\n pushToast({\n kind: \"success\",\n source: \"system\",\n sourceLabel: \"Chat\",\n title: \"Link copied\",\n body: \"Paste anywhere to jump back to this message.\",\n agent_id: null,\n thread_id: threadId,\n ttl: 2200,\n });\n }).catch(console.error);\n }, [messageId, threadId]);\n\n // Retry only makes sense for plain user prompts the operator typed. Bridge\n // / scheduled-task / watcher rows carry their own metadata header and\n // re-sending them as a vanilla user message would be wrong.\n const category = \"category\" in message ? message.category : null;\n const canRetry = isUser && !category && !!onRetry && !streaming;\n const handleRetry = useCallback(() => {\n if (!onRetry) return;\n if (typeof parsed === \"string\") {\n onRetry(parsed, []);\n return;\n }\n let text = \"\";\n const atts: ContentPart[] = [];\n for (const part of parsed) {\n if (part.type === \"text\" && !text) text = part.text;\n else atts.push(part);\n }\n onRetry(text, atts);\n }, [onRetry, parsed]);\n\n const [copiedMessage, setCopiedMessage] = useState(false);\n const copyMessage = useCallback(() => {\n const text = messageTextForCopy(parsed);\n if (!text) return;\n void navigator.clipboard.writeText(text).then(() => {\n setCopiedMessage(true);\n setTimeout(() => setCopiedMessage(false), 1200);\n pushToast({\n kind: \"success\",\n source: \"system\",\n sourceLabel: \"Chat\",\n title: \"Message copied\",\n body: \"Copied message content to clipboard.\",\n agent_id: null,\n thread_id: threadId,\n ttl: 2000,\n });\n }).catch(console.error);\n }, [parsed, threadId]);\n\n // —— TTS playback ——\n // The Play button is rendered for assistant bubbles whose agent has\n // voice_enabled. We don't pre-generate audio — the first click POSTs the\n // plain-text body to /api/v1/voice/tts and plays the returned WAV. The\n // <audio> element is created lazily and the object URL is revoked on\n // unmount to avoid leaks. Auto-speak listens for a window event keyed by\n // messageId so ChatView can arm it from outside the bubble.\n const voiceEnabled = !isUser && !!agentConfig?.voice_enabled;\n const ttsAbleText = !isUser ? plainTextForTts(message.content) : \"\";\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const audioUrlRef = useRef<string | null>(null);\n const [audioState, setAudioState] = useState<\"idle\" | \"loading\" | \"playing\" | \"paused\" | \"error\">(\"idle\");\n const [audioError, setAudioError] = useState<string | null>(null);\n\n const releaseAudio = useCallback(() => {\n const a = audioRef.current;\n if (a) {\n try { a.pause(); } catch { /* ignore */ }\n a.src = \"\";\n audioRef.current = null;\n }\n if (audioUrlRef.current) {\n URL.revokeObjectURL(audioUrlRef.current);\n audioUrlRef.current = null;\n }\n }, []);\n\n useEffect(() => () => releaseAudio(), [releaseAudio]);\n\n const speak = useCallback(async () => {\n if (!voiceEnabled || !agentConfig || streaming) return;\n if (!ttsAbleText.trim()) return;\n // Resume an existing buffer instead of re-fetching.\n if (audioRef.current && audioUrlRef.current) {\n if (audioState === \"playing\") {\n audioRef.current.pause();\n setAudioState(\"paused\");\n } else {\n try { await audioRef.current.play(); setAudioState(\"playing\"); }\n catch (err) { setAudioError(err instanceof Error ? err.message : String(err)); setAudioState(\"error\"); }\n }\n return;\n }\n setAudioError(null);\n setAudioState(\"loading\");\n try {\n const res = await fetch(\"/api/v1/voice/tts\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ agent_id: agentConfig.id, text: ttsAbleText }),\n });\n if (!res.ok) {\n const body = await res.json().catch(() => ({} as { error?: string }));\n throw new Error(body.error ?? `HTTP ${res.status}`);\n }\n const blob = await res.blob();\n const url = URL.createObjectURL(blob);\n audioUrlRef.current = url;\n const audio = new Audio(url);\n audio.onended = () => setAudioState(\"idle\");\n audio.onpause = () => setAudioState((s) => (s === \"playing\" ? \"paused\" : s));\n audio.onerror = () => { setAudioState(\"error\"); setAudioError(\"playback failed\"); };\n audioRef.current = audio;\n await audio.play();\n setAudioState(\"playing\");\n } catch (err) {\n setAudioError(err instanceof Error ? err.message : String(err));\n setAudioState(\"error\");\n }\n }, [voiceEnabled, agentConfig, streaming, ttsAbleText, audioState]);\n\n useEffect(() => {\n if (!voiceEnabled || !messageId) return;\n function onSpeak(e: Event) {\n const detail = (e as CustomEvent<{ messageId?: string }>).detail;\n if (detail?.messageId === messageId) void speak();\n }\n window.addEventListener(\"jarela:speak-message\", onSpeak as EventListener);\n return () => window.removeEventListener(\"jarela:speak-message\", onSpeak as EventListener);\n }, [voiceEnabled, messageId, speak]);\n\n // Extract <refs> from assistant messages so they render as a compact footer\n // under the bubble instead of inline. While streaming, only show them after\n // the closing </refs> tag has arrived (otherwise we'd flicker partial refs).\n let refs: ExtractedRef[] = [];\n let renderedString: string | null = null;\n if (!isUser && typeof parsed === \"string\") {\n if (!streaming || /<\\/refs>/i.test(parsed)) {\n const r = extractRefs(parsed);\n renderedString = r.body;\n refs = r.refs;\n } else {\n renderedString = parsed;\n }\n // Also hide the agent's trailing ```jarela-references` JSON block —\n // this is a machine-readable side channel for populating the citation\n // manifest, not user-facing prose. The server strips it before\n // persisting, but the streaming buffer still carries it until the\n // turn ends, so we'd otherwise flash raw JSON for one frame.\n if (renderedString) {\n renderedString = stripDeclaredReferencesFence(renderedString);\n }\n }\n\n // Citation-checker verdict from messages.metadata. Present whenever the\n // agent's `citation_strictness` is not `off` AND a checker model is\n // configured AND the checker call succeeded. The checker emits one row\n // per factual claim, ranked by impact (high → med → low).\n const citations = !isUser && \"metadata\" in message\n ? (message.metadata as { citations?: { checker_model?: string; claims?: Array<{ text?: string; link: string | null; verified: boolean; reason?: string; impact?: \"high\" | \"med\" | \"low\" }>; unverified_links?: string[]; sources?: Array<{ n: number; label: string; href: string }> } } | null | undefined)?.citations ?? null\n : null;\n // ADR-0064 transparency surface — values the redaction layer kept off\n // the wire during this turn. Read from the same metadata blob; absent\n // on legacy rows and on turns where nothing matched.\n const redactionSummary = !isUser && \"metadata\" in message\n ? (message.metadata as { redaction_summary?: Array<{ type_hint: string; count: number }> } | null | undefined)?.redaction_summary ?? null\n : null;\n const unverifiedLinks = useMemo<ReadonlySet<string> | undefined>(\n () => citations?.unverified_links?.length ? new Set(citations.unverified_links) : undefined,\n [citations],\n );\n // Numbered source manifest the agent saw at prompt time. The chat UI\n // resolves each inline `[N]` marker in the assistant text to a clickable\n // link/anchor against this map. Persisted on every assistant turn where\n // the agent's `citation_strictness` was not `off`; absent on legacy rows\n // and on turns where the manifest was empty.\n const sourceManifest = useMemo<ReadonlyMap<number, { href: string; label: string }> | undefined>(() => {\n if (!citations?.sources?.length) return undefined;\n return new Map(citations.sources.map((s) => [s.n, { href: s.href, label: s.label }]));\n }, [citations]);\n\n // Format created_at for the hover timestamp. Streaming bubbles don't have\n // one — we show \"now\" so the hover affordance is still consistent.\n const createdAt = \"created_at\" in message ? message.created_at : null;\n const timeLabel = createdAt\n ? new Date(createdAt).toLocaleTimeString(undefined, { hour: \"numeric\", minute: \"2-digit\" })\n : null;\n\n return (\n <div className={`group flex ${isUser ? \"flex-row-reverse\" : \"flex-row\"} gap-2 mb-1.5 items-end`}>\n {/* Avatar — spacer when not shown to maintain alignment */}\n <div className=\"shrink-0 w-7\">\n {showAvatar && (isUser\n ? <UserAvatar profile={userProfile} />\n : <AgentAvatar config={agentConfig} />\n )}\n </div>\n\n <div className={`flex flex-col max-w-[88%] sm:max-w-[75%] min-w-0 ${isUser ? \"items-end\" : \"items-start\"}`}>\n {(timeLabel || messageId) && (\n <div className={`flex items-center gap-1 mb-0.5 px-1 opacity-0 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity ${isUser ? \"flex-row-reverse\" : \"\"}`}>\n {timeLabel && (\n <span className=\"text-[10px] text-fg-faint\" aria-hidden>{timeLabel}</span>\n )}\n {messageId && (\n <button\n onClick={copyLink}\n className=\"text-fg-faint hover:text-fg p-0.5 rounded\"\n title=\"Copy link to this message\"\n aria-label=\"Copy link to this message\"\n >\n <Link2 size={11} />\n </button>\n )}\n <button\n onClick={copyMessage}\n className=\"text-fg-faint hover:text-fg p-0.5 rounded\"\n title={copiedMessage ? \"Copied\" : \"Copy message text\"}\n aria-label=\"Copy message text\"\n >\n {copiedMessage ? <Check size={11} /> : <Copy size={11} />}\n </button>\n {canRetry && (\n <button\n onClick={handleRetry}\n className=\"text-fg-faint hover:text-fg p-0.5 rounded\"\n title=\"Resend this prompt as a new turn\"\n aria-label=\"Resend this prompt as a new turn\"\n >\n <RotateCcw size={11} />\n </button>\n )}\n {voiceEnabled && !streaming && ttsAbleText.trim() && (\n <button\n onClick={() => void speak()}\n className={`p-0.5 rounded ${audioState === \"error\" ? \"text-rose-500\" : \"text-fg-faint hover:text-fg\"}`}\n title={audioError ?? (audioState === \"playing\" ? \"Pause\" : audioState === \"loading\" ? \"Loading…\" : \"Play voice\")}\n aria-label={audioState === \"playing\" ? \"Pause voice\" : \"Play voice\"}\n disabled={audioState === \"loading\"}\n >\n {audioState === \"loading\" ? <Loader2 size={11} className=\"animate-spin\" />\n : audioState === \"playing\" ? <Pause size={11} />\n : <Play size={11} />}\n </button>\n )}\n </div>\n )}\n <div\n className={`rounded-2xl px-4 py-3 text-sm leading-relaxed max-w-full overflow-hidden ${\n isUser ? \"glass-bubble-accent text-white rounded-br-sm\" : \"glass-bubble text-fg rounded-bl-sm\"\n }`}\n >\n {typeof parsed === \"string\" ? (\n isUser ? (\n (() => {\n const trigger = parseTriggerMessage(category, parsed);\n if (trigger) return <TriggerMessageCard data={trigger} />;\n const bridge = parseBridgeContext(parsed);\n if (bridge) return <BridgeMessageCard ctx={bridge} />;\n const ext = parseExtensionTurn(parsed);\n if (ext) return <ExtensionTurnCard ctx={ext} accent={true} />;\n const ctx = parseCapturedContext(parsed);\n if (ctx) return <CapturedContextCard ctx={ctx} accent={true} />;\n return (\n <CollapsibleLong accent={true}>\n <p className=\"whitespace-pre-wrap\">{parsed}</p>\n </CollapsibleLong>\n );\n })()\n ) : (\n <div className=\"flex flex-col\">\n {category && <CategorySourceBadge category={category} />}\n <CollapsibleLong accent={false} streaming={streaming} defaultOpen={isLatest}>\n <MarkdownContent text={renderedString ?? parsed} streaming={streaming} onInAppLink={handleInAppLink} unverifiedLinks={unverifiedLinks} sourceManifest={sourceManifest} inflightToolCount={inflightToolCount} />\n </CollapsibleLong>\n </div>\n )\n ) : (\n <div className=\"flex flex-col gap-1.5\">\n {(() => {\n // Bridge messages that carry attachments get persisted as a\n // ContentPart[] whose first text part holds the bracketed\n // [bridge:.] header + body. Detect that case so the user\n // bubble shows the card on top of the media parts instead of\n // a raw bracket dump above them.\n const firstText = isUser && parsed[0]?.type === \"text\" && typeof parsed[0].text === \"string\"\n ? parsed[0].text\n : null;\n const bridge = firstText ? parseBridgeContext(firstText) : null;\n if (bridge) {\n return (\n <>\n <BridgeMessageCard ctx={bridge} />\n {parsed.slice(1).map((part, i) => (\n <ContentPartView key={i + 1} part={part} isUser={isUser} onInAppLink={handleInAppLink} />\n ))}\n </>\n );\n }\n return parsed.map((part, i) => (\n <ContentPartView key={i} part={part} isUser={isUser} onInAppLink={handleInAppLink} unverifiedLinks={unverifiedLinks} sourceManifest={sourceManifest} />\n ));\n })()}\n {streaming && (\n <span className=\"inline-flex items-center align-middle ml-1\">\n <CountdownRing inflightToolCount={inflightToolCount} />\n </span>\n )}\n </div>\n )}\n {!isUser && !streaming && \"usage\" in message && message.usage && (contextWindowTokens ?? message.usage.context_window_tokens) ? (\n <div className=\"-mx-4 -mb-3 mt-3\">\n <ContextUsageBar\n usage={message.usage}\n fallbackContextWindow={contextWindowTokens ?? 0}\n />\n </div>\n ) : null}\n </div>\n {!isUser && !streaming && showToolEvents && \"tool_events\" in message && Array.isArray(message.tool_events) && message.tool_events.length > 0 && (\n <ToolList events={message.tool_events} />\n )}\n {citations && Array.isArray(citations.sources) && citations.sources.length > 0 && (\n <ReferencesPanel sources={citations.sources} />\n )}\n {citations && Array.isArray(citations.claims) && citations.claims.length > 0 && (\n <CitationsSummary claims={citations.claims} checkerModel={citations.checker_model ?? \"\"} />\n )}\n {redactionSummary && redactionSummary.length > 0 && (\n <RedactionShield summary={redactionSummary} />\n )}\n {refs.length > 0 && <RefsFooter refs={refs} />}\n </div>\n </div>\n );\n});\n","\"use client\";\n// Inline visual artefacts for ADR-0042: the warm-summary card and the\n// context-boundary divider that sits below it. Rendered by MessageList in\n// the message stream — between summarised history (above) and the active\n// hot context (below). Both stay inside the existing token system\n// (accent / surface-2 / fg-* / border) so they read as native chat chrome.\n\nimport { useState } from \"react\";\nimport { Archive, ChevronDown, ChevronUp } from \"lucide-react\";\nimport ReactMarkdown from \"react-markdown\";\n\ninterface WarmSummaryCardProps {\n /** Number of messages older than the boundary that the summary covers. */\n olderCount: number;\n /** Latest persisted summary text, NULL/empty if not yet computed. */\n summary: string | null;\n /** ISO timestamp the cached summary covers; compared to `hotSince` to know freshness. */\n summaryBefore: string | null;\n /** Pin position. When this differs from `summaryBefore`, the card shows a placeholder. */\n hotSince: string | null;\n /** Wall-clock the summary was computed at; rendered as a relative footer chip. */\n computedAt: string | null;\n /** True while a turn is streaming — promotes the placeholder to a \"computing…\" state. */\n streaming: boolean;\n}\n\nexport function WarmSummaryCard({\n olderCount,\n summary,\n summaryBefore,\n hotSince,\n computedAt,\n streaming,\n}: WarmSummaryCardProps) {\n const [expanded, setExpanded] = useState(false);\n const fresh = !!summary && summaryBefore === hotSince;\n const computing = !fresh && streaming;\n\n return (\n <div\n className={[\n \"relative my-4 rounded-2xl border bg-gradient-to-br shadow-sm\",\n \"from-accent/[0.06] via-surface-2 to-surface-2\",\n fresh ? \"border-accent/30\" : \"border-border\",\n ].join(\" \")}\n >\n <div className=\"flex items-center gap-2 px-4 pt-3 pb-1.5\">\n <Archive className=\"w-3.5 h-3.5 text-accent shrink-0\" />\n <span className=\"text-xs font-semibold text-fg\">\n Summary of {olderCount} earlier message{olderCount === 1 ? \"\" : \"s\"}\n </span>\n <span className=\"text-[10px] uppercase tracking-wider px-1.5 py-px rounded text-accent bg-accent/10 border border-accent/20\">\n warm context\n </span>\n <span className=\"ml-auto text-[10px] text-fg-faint\">\n {computedAt ? `Generated ${formatRelative(computedAt)}` : \"Not yet computed\"}\n </span>\n </div>\n\n <div className=\"px-4 pb-3\">\n {fresh ? (\n <div\n className={[\n \"prose prose-sm dark:prose-invert max-w-none text-fg-muted\",\n \"prose-p:my-1.5 prose-headings:mt-2 prose-headings:mb-1\",\n expanded ? \"\" : \"line-clamp-6\",\n ].join(\" \")}\n >\n <ReactMarkdown>{stripWarmHeader(summary!)}</ReactMarkdown>\n </div>\n ) : (\n <div className=\"flex items-center gap-2 text-xs text-fg-faint italic\">\n {computing && (\n <span className=\"inline-block w-2 h-2 rounded-full bg-accent animate-pulse\" aria-hidden />\n )}\n <span>\n {computing\n ? \"Re-summarising older context for this turn…\"\n : \"Summary will appear after your next reply.\"}\n </span>\n </div>\n )}\n </div>\n\n {fresh && summaryLong(summary!) && (\n <button\n type=\"button\"\n onClick={() => setExpanded((x) => !x)}\n className=\"absolute right-3 bottom-2 inline-flex items-center gap-1 text-[10px] text-fg-faint hover:text-fg-muted transition-colors\"\n >\n {expanded ? (<><ChevronUp className=\"w-3 h-3\" /> Show less</>)\n : (<><ChevronDown className=\"w-3 h-3\" /> Show more</>)}\n </button>\n )}\n </div>\n );\n}\n\ninterface ContextBoundaryDividerProps {\n // Stats for the chip readout: how many messages went into the warm\n // summary, the size of their flattened transcript, and the size of the\n // resulting summary. All three are NULL on threads whose summary\n // predates the stat columns — the chip falls back to just the label.\n sourceMessages?: number | null;\n sourceChars?: number | null;\n summaryChars?: number | null;\n}\n\nexport function ContextBoundaryDivider({\n sourceMessages,\n sourceChars,\n summaryChars,\n}: ContextBoundaryDividerProps = {}) {\n const hasStats =\n typeof sourceMessages === \"number\" && sourceMessages > 0 &&\n typeof sourceChars === \"number\" && sourceChars > 0;\n const ratio = hasStats && typeof summaryChars === \"number\" && summaryChars > 0 && sourceChars! > 0\n ? Math.max(0, Math.round((1 - summaryChars / sourceChars!) * 100))\n : null;\n return (\n <div className=\"relative my-3 select-none\" aria-label=\"context boundary\">\n <div className=\"absolute inset-0 flex items-center\" aria-hidden>\n <div className=\"w-full border-t border-dashed border-accent/40\" />\n </div>\n <div className=\"relative flex justify-center\">\n <div\n className=\"inline-flex items-center gap-2 px-3 py-1 rounded-full text-[10px] font-medium uppercase tracking-wider bg-surface border border-accent/40 text-accent shadow-sm\"\n title={\n hasStats\n ? `Compacted ${sourceMessages} message${sourceMessages === 1 ? \"\" : \"s\"} (${sourceChars!.toLocaleString()} chars) into ${typeof summaryChars === \"number\" ? `${summaryChars.toLocaleString()} chars` : \"memory\"}`\n : undefined\n }\n >\n <span>Context boundary</span>\n {hasStats && (\n <>\n <span className=\"opacity-40\" aria-hidden>·</span>\n <span className=\"normal-case tracking-normal font-normal text-fg-muted\">\n {sourceMessages} msg{sourceMessages === 1 ? \"\" : \"s\"} ·{\" \"}\n {formatBytes(sourceChars!)}\n {typeof summaryChars === \"number\" && summaryChars > 0 && (\n <>\n {\" → \"}\n {formatBytes(summaryChars)}\n {ratio !== null && ratio > 0 && (\n <span className=\"ml-1 text-[9px] text-accent/80\">(−{ratio}%)</span>\n )}\n </>\n )}\n </span>\n </>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// Compact character-count formatter: 4321 → \"4.3k\", 18234 → \"18k\".\nfunction formatBytes(n: number): string {\n if (!Number.isFinite(n) || n < 0) return \"0\";\n if (n < 1000) return `${n}`;\n const k = n / 1000;\n return k >= 100 ? `${Math.round(k)}k` : `${k.toFixed(1).replace(/\\.0$/, \"\")}k`;\n}\n\n// `buildWarmSummary` prepends a couple of plain-text header lines that read\n// awkwardly inside a card that already has its own header. Strip them.\nfunction stripWarmHeader(raw: string): string {\n return raw\n .replace(/^--- Warm context summary ---\\n/, \"\")\n .replace(/^Compressed recap of earlier messages outside the hot window:\\n/, \"\")\n .trimStart();\n}\n\nfunction summaryLong(raw: string): boolean {\n // Heuristic: more than 6 lines or > 600 chars after the header strip.\n const stripped = stripWarmHeader(raw);\n return stripped.length > 600 || stripped.split(\"\\n\").length > 6;\n}\n\nfunction formatRelative(iso: string): string {\n const then = new Date(iso).getTime();\n const diff = Date.now() - then;\n if (!Number.isFinite(diff) || diff < 0) return \"\";\n const s = Math.round(diff / 1000);\n if (s < 60) return `${s}s ago`;\n const m = Math.round(s / 60);\n if (m < 60) return `${m}m ago`;\n const h = Math.round(m / 60);\n if (h < 24) return `${h}h ago`;\n const d = Math.round(h / 24);\n return `${d}d ago`;\n}\n","\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// ADR-0022: per-agent message-channel display filters.\n//\n// Canonical channel keys — single source of truth for the chat-panel\n// filter toolbar. The first three correspond 1:1 to the persisted\n// `messages.category` column; `tool_use` and `thinking` are pure UI\n// toggles that hide already-rendered sub-content without touching\n// persistence. Mirrors `DISPLAY_FILTER_KEYS` in\n// `lib/stores/agent-configs.ts` — keep both lists in sync.\nexport const MESSAGE_FILTER_KEYS = [\n \"scheduled_task\",\n \"watcher\",\n \"bridge\",\n \"extension\",\n \"page_capture\",\n \"synthetic\",\n \"tool_use\",\n \"thinking\",\n] as const;\nexport type MessageFilterKey = (typeof MESSAGE_FILTER_KEYS)[number];\n\nexport type MessageFilters = Record<MessageFilterKey, boolean>;\n\nconst LEGACY_GLOBAL_KEY = \"jarela:msg-category-filters\";\nconst CACHE_KEY_PREFIX = \"jarela:msg-filters:\"; // + agentId\nconst MIGRATION_FLAG_KEY = \"jarela:msg-filters:legacy-migrated\";\n\nconst DEFAULTS: MessageFilters = {\n scheduled_task: true,\n watcher: true,\n bridge: true,\n extension: true,\n page_capture: true,\n synthetic: true,\n tool_use: true,\n thinking: true,\n};\n\nfunction readCache(agentId: string): MessageFilters | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(CACHE_KEY_PREFIX + agentId);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<MessageFilters>;\n return { ...DEFAULTS, ...parsed };\n } catch {\n return null;\n }\n}\n\nfunction writeCache(agentId: string, filters: MessageFilters): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(CACHE_KEY_PREFIX + agentId, JSON.stringify(filters));\n } catch {\n /* private-mode quota; in-memory state remains correct */\n }\n}\n\nfunction readLegacyGlobal(): Partial<MessageFilters> | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(LEGACY_GLOBAL_KEY);\n if (!raw) return null;\n return JSON.parse(raw) as Partial<MessageFilters>;\n } catch {\n return null;\n }\n}\n\n/**\n * Per-agent message-channel display filters.\n *\n * Source of truth lives on `agent_configs.display_filters` (JSON column).\n * The hook fetches on mount / when `agentId` changes, caches in\n * localStorage keyed by agent id to avoid toolbar flicker on reload, and\n * writes through to `PUT /api/v1/agents/:id/display-filters` on every\n * toggle (merged server-side so multi-tab toggles don't clobber).\n *\n * If `agentId` is null/undefined (e.g. agent list still loading) the hook\n * falls back to defaults — toggling is a no-op until an id is provided.\n *\n * Legacy migration: the previous build used a single global localStorage\n * key (`jarela:msg-category-filters`). On first run we copy that value\n * into the first agent's filters, set a one-shot migration flag, and\n * remove the global key. After that the agent column is canonical.\n */\nexport function useMessageFilters(agentId?: string | null) {\n const [filters, setFilters] = useState<MessageFilters>(() =>\n agentId ? readCache(agentId) ?? DEFAULTS : DEFAULTS,\n );\n // Guard against late-arriving GET responses overwriting a more-recent\n // user toggle. We bump this on every toggle; stale fetches are dropped.\n const seqRef = useRef(0);\n\n // Sync from server when the agent changes.\n useEffect(() => {\n if (!agentId) {\n // Agent switched to none — reset to defaults. setState in effect is\n // intentional here: agentId is the external key driving this state.\n setFilters(DEFAULTS);\n return;\n }\n const cached = readCache(agentId);\n if (cached) setFilters(cached);\n else setFilters(DEFAULTS);\n\n const mySeq = ++seqRef.current;\n let cancelled = false;\n\n (async () => {\n try {\n // One-shot legacy migration: if we still have the old global key\n // AND we haven't migrated yet, push it onto THIS agent (the user\n // is interacting with it now, so it's the most reasonable owner)\n // and clear both the global key and the flag's reverse case.\n const legacy =\n typeof window !== \"undefined\" &&\n !window.localStorage.getItem(MIGRATION_FLAG_KEY)\n ? readLegacyGlobal()\n : null;\n\n if (legacy) {\n await fetch(`/api/v1/agents/${encodeURIComponent(agentId)}/display-filters`, {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ filters: legacy }),\n }).catch(() => {});\n try {\n window.localStorage.setItem(MIGRATION_FLAG_KEY, \"1\");\n window.localStorage.removeItem(LEGACY_GLOBAL_KEY);\n } catch {}\n }\n\n const res = await fetch(\n `/api/v1/agents/${encodeURIComponent(agentId)}/display-filters`,\n { method: \"GET\" },\n );\n if (!res.ok) return;\n const body = (await res.json()) as { filters: Partial<MessageFilters> };\n if (cancelled || mySeq !== seqRef.current) return;\n const merged = { ...DEFAULTS, ...body.filters };\n setFilters(merged);\n writeCache(agentId, merged);\n } catch {\n /* offline / first-launch race — defaults are fine */\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [agentId]);\n\n const toggle = useCallback(\n (key: MessageFilterKey) => {\n setFilters((prev) => {\n const next = { ...prev, [key]: !prev[key] };\n if (agentId) {\n writeCache(agentId, next);\n seqRef.current++;\n // Fire-and-forget; cache + state already reflect the new value.\n // If the request fails we keep the optimistic state — next page\n // load will reconcile from the server.\n void fetch(`/api/v1/agents/${encodeURIComponent(agentId)}/display-filters`, {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ filters: { [key]: next[key] } }),\n }).catch(() => {});\n }\n return next;\n });\n },\n [agentId],\n );\n\n const reset = useCallback(() => {\n if (!agentId) {\n setFilters(DEFAULTS);\n return;\n }\n setFilters(DEFAULTS);\n writeCache(agentId, DEFAULTS);\n seqRef.current++;\n void fetch(`/api/v1/agents/${encodeURIComponent(agentId)}/display-filters`, {\n method: \"PUT\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ filters: null }),\n }).catch(() => {});\n }, [agentId]);\n\n return { filters, toggle, reset };\n}\n","\"use client\";\nimport { memo, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { ChevronRight, Clock, X, ArrowDown, Eye, EyeOff } from \"lucide-react\";\nimport type { AgentConfig, ContentPart, Message, UserProfile } from \"@/api/types\";\nimport { ToolList, type ToolEvent } from \"./ToolList\";\nimport { MessageBubble } from \"./MessageBubble\";\nimport { ContextBoundaryDivider, WarmSummaryCard } from \"./ContextBoundary\";\nimport { useMessageFilters, MESSAGE_FILTER_KEYS, type MessageFilterKey } from \"@/hooks/useMessageFilters\";\n\ninterface SystemNotice {\n id: string;\n text: string;\n}\n\ninterface QueuedMessageView {\n id: string;\n text: string;\n attachmentCount: number;\n}\n\ninterface Props {\n threadId?: string | null;\n messages: Message[];\n notices?: SystemNotice[];\n agentConfig?: AgentConfig | null;\n userProfile?: UserProfile | null;\n streamingContent?: string;\n thinkingContent?: string;\n toolEvents?: ToolEvent[];\n hasMore?: boolean;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n queuedMessages?: QueuedMessageView[];\n onRemoveQueued?: (id: string) => void;\n // ADR-0042 — explicit context boundary state. The boundary divider is\n // rendered in the message stream right after the last message older than\n // `hotSince` (or above the first loaded message when the pin sits earlier\n // than the visible window). The warm-summary card sits directly above\n // the divider and shows the latest persisted recap.\n hotSince?: string | null;\n warmSummary?: string | null;\n warmSummaryBefore?: string | null;\n warmSummaryComputedAt?: string | null;\n warmSummarySourceMessages?: number | null;\n warmSummarySourceChars?: number | null;\n onSetContextPin?: (hot_since: string | null) => void;\n streaming?: boolean;\n // Thread-level context window cap, forwarded to each MessageBubble so\n // the ContextUsageBar has a baseline for rows whose own usage snapshot\n // predates the per-row column.\n contextWindowTokens?: number | null;\n // Resend a previously-sent user prompt as a new turn. Forwarded to each\n // user-role MessageBubble; absent => retry button is hidden.\n onRetryMessage?: (text: string, attachments: ContentPart[]) => void;\n}\n\nexport function MessageList({ threadId, messages, notices, agentConfig, userProfile, streamingContent, thinkingContent, toolEvents, hasMore, loadingMore, onLoadMore, queuedMessages, onRemoveQueued, hotSince, warmSummary, warmSummaryBefore, warmSummaryComputedAt, warmSummarySourceMessages, warmSummarySourceChars, onSetContextPin, streaming, contextWindowTokens, onRetryMessage }: Props) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const { filters, toggle, reset } = useMessageFilters(agentConfig?.id ?? null);\n const autoRecoveredRef = useRef<string | null>(null);\n\n // Apply category filter. Messages with no `category` (NULL = ordinary\n // chat) are always shown; tagged messages are gated by their toggle.\n // The `tool_use` and `thinking` filters do NOT remove whole messages —\n // they're handled below by gating the inline ToolList / ThinkingLine.\n const visibleMessages = useMemo(() => {\n return messages.filter((m) => {\n const cat = m.category;\n if (!cat) return true;\n if (cat === \"scheduled_task\") return filters.scheduled_task;\n if (cat === \"watcher\") return filters.watcher;\n if (cat === \"bridge\") return filters.bridge;\n if (cat === \"extension\") return filters.extension;\n if (cat === \"page_capture\") return filters.page_capture;\n if (cat === \"synthetic\") return filters.synthetic;\n // Unknown future categories: show by default so forward-compat clients\n // never silently drop content the server thinks should be visible.\n return true;\n });\n }, [messages, filters.scheduled_task, filters.watcher, filters.bridge, filters.extension, filters.page_capture, filters.synthetic]);\n\n const hiddenCount = messages.length - visibleMessages.length;\n\n // Self-heal stale/accidental filter states that blank an entire thread.\n // If a thread has persisted messages but every one is filtered out, users\n // perceive this as \"chat is empty\". Auto-reset once per thread snapshot so\n // content remains visible without requiring manual recovery.\n useEffect(() => {\n if (messages.length === 0 || streamingContent) return;\n if (visibleMessages.length > 0) return;\n if (hiddenCount !== messages.length) return;\n const lastId = messages[messages.length - 1]?.id ?? \"none\";\n const key = `${threadId ?? \"no-thread\"}:${messages.length}:${lastId}`;\n if (autoRecoveredRef.current === key) return;\n autoRecoveredRef.current = key;\n reset();\n }, [threadId, messages, visibleMessages.length, hiddenCount, streamingContent, reset]);\n\n // Surface a category chip in the toolbar only if it can actually do\n // something useful right now: scheduled_task/bridge/synthetic chips\n // appear only when at least one such message exists in the loaded\n // transcript; tool_use appears when any assistant message has tool\n // events; thinking appears when there's live thinking content (the\n // only place it currently surfaces).\n const availableChips = useMemo(() => {\n const set = new Set<MessageFilterKey>();\n for (const m of messages) {\n if (m.category === \"scheduled_task\") set.add(\"scheduled_task\");\n else if (m.category === \"watcher\") set.add(\"watcher\");\n else if (m.category === \"bridge\") set.add(\"bridge\");\n else if (m.category === \"extension\") set.add(\"extension\");\n else if (m.category === \"page_capture\") set.add(\"page_capture\");\n else if (m.category === \"synthetic\") set.add(\"synthetic\");\n if (m.tool_events && m.tool_events.length > 0) set.add(\"tool_use\");\n }\n if (thinkingContent) set.add(\"thinking\");\n if (toolEvents && toolEvents.length > 0) set.add(\"tool_use\");\n return MESSAGE_FILTER_KEYS.filter((k) => set.has(k));\n }, [messages, thinkingContent, toolEvents]);\n // Count of tool_call ids that haven't been matched by a tool_result yet.\n // Drives the streaming-bubble's CountdownRing pause so the wall-clock\n // indicator matches the run-registry's effective-elapsed semantics\n // (tool execution time is excluded from the agent's budget).\n const inflightToolCount = useMemo(() => {\n if (!toolEvents || toolEvents.length === 0) return 0;\n const open = new Set<string>();\n for (const ev of toolEvents) {\n if (ev.phase === \"call\") open.add(ev.id);\n else if (ev.phase === \"result\") open.delete(ev.id);\n }\n return open.size;\n }, [toolEvents]);\n // Tracks whether the user was at the bottom on the most recent scroll event.\n // After every render, if true, we snap to bottom — which means: while the\n // user is at the bottom they \"follow\" automatically; if they scroll away,\n // they stay where they are; when they scroll back to the bottom they resume\n // following. No timers, no growth checks, no programmatic-scroll guards —\n // the only signal is the user's own scroll position. CSS `overflow-anchor`\n // (browser-default) handles the pagination case (older content prepended\n // keeps visible content stable).\n const atBottomRef = useRef(true);\n const [showScrollButton, setShowScrollButton] = useState(false);\n\n // Anchor for older-message pagination. When the user scrolls near the top\n // and we call onLoadMore, we snapshot the viewport (scrollHeight + scrollTop)\n // here. After the parent prepends the new messages and React commits, the\n // layout effect below compensates scrollTop by the height delta so the\n // content the user was looking at stays at the same on-screen position\n // instead of remaining pinned to scrollTop=0 (which makes the viewport\n // \"jump\" to the very oldest message).\n const prependAnchorRef = useRef<{ scrollHeight: number; scrollTop: number } | null>(null);\n\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n // Don't snap to bottom while we're in the middle of restoring scroll\n // after a load-more prepend — the layout effect below owns scrollTop\n // until the anchor is consumed.\n if (prependAnchorRef.current) return;\n if (atBottomRef.current) el.scrollTop = el.scrollHeight;\n }); // intentionally no deps — runs after every render\n\n // Keep the bottom pinned when the scroll container *itself* resizes —\n // not just when messages change. When the on-screen keyboard opens,\n // `100dvh` shrinks AppShell, which shrinks this container without\n // triggering a React render, so the post-render effect above never\n // fires. Without this observer the latest messages drop below the\n // visible area and the user has to scroll down to find them.\n useEffect(() => {\n const el = scrollRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n if (prependAnchorRef.current) return;\n if (atBottomRef.current) el.scrollTop = el.scrollHeight;\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n // Restore scroll position after older messages have been prepended.\n // useLayoutEffect runs synchronously after DOM mutations but before paint,\n // so the user never sees the intermediate \"scrolled to oldest\" frame.\n useLayoutEffect(() => {\n const el = scrollRef.current;\n const anchor = prependAnchorRef.current;\n if (!el || !anchor) return;\n if (loadingMore) return; // wait until the fetch settled\n const delta = el.scrollHeight - anchor.scrollHeight;\n if (delta > 0) {\n el.scrollTop = anchor.scrollTop + delta;\n atBottomRef.current = false;\n }\n prependAnchorRef.current = null;\n }, [messages, loadingMore]);\n\n function handleScroll(e: React.UIEvent<HTMLDivElement>) {\n const el = e.currentTarget;\n if (hasMore && !loadingMore && onLoadMore && el.scrollTop < 60) {\n // Snapshot BEFORE asking the parent to fetch so we can compensate the\n // scroll position once the new (older) messages arrive in props.\n prependAnchorRef.current = { scrollHeight: el.scrollHeight, scrollTop: el.scrollTop };\n onLoadMore();\n }\n const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n atBottomRef.current = isAtBottom;\n setShowScrollButton(!isAtBottom && messages.length > 0);\n }\n\n // Resolve `#msg-<id>` deep links: scroll the matching bubble into view and\n // flash the same highlight ring used by settings deep links. Re-runs when\n // the message list grows (so a fresh-loaded page that contained the target\n // resolves once it's in the DOM) and on every `hashchange` so the same\n // in-thread link can be clicked twice.\n useEffect(() => {\n function scrollToHashTarget() {\n if (typeof window === \"undefined\") return;\n const hash = window.location.hash;\n if (!hash.startsWith(\"#msg-\")) return;\n const id = decodeURIComponent(hash.slice(5));\n const root = scrollRef.current;\n if (!root) return;\n requestAnimationFrame(() => {\n const safe = id.replace(/\"/g, '\\\\\"');\n const el = root.querySelector(`[data-message-id=\"${safe}\"]`) as HTMLElement | null;\n if (!el) return;\n atBottomRef.current = false;\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n el.classList.add(\"jarela-deep-link-flash\");\n setTimeout(() => el.classList.remove(\"jarela-deep-link-flash\"), 1600);\n // Strip the hash so the next streaming message / list-length change\n // doesn't yank the view back to this anchor. replaceState avoids\n // triggering a hashchange event (which would re-enter this handler).\n const { pathname, search } = window.location;\n window.history.replaceState(null, \"\", pathname + search);\n });\n }\n scrollToHashTarget();\n window.addEventListener(\"hashchange\", scrollToHashTarget);\n return () => window.removeEventListener(\"hashchange\", scrollToHashTarget);\n }, [messages.length]);\n\n // Handle orientation changes and resizes to maintain scroll position\n useEffect(() => {\n function handleResize() {\n const el = scrollRef.current;\n if (!el || !atBottomRef.current) return;\n // Re-snap to bottom on resize/orientation change if user was already at bottom\n requestAnimationFrame(() => {\n el.scrollTop = el.scrollHeight;\n });\n }\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"orientationchange\", handleResize);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n window.removeEventListener(\"orientationchange\", handleResize);\n };\n }, []);\n\n function scrollToBottom() {\n const el = scrollRef.current;\n if (!el) return;\n atBottomRef.current = true;\n el.scrollTop = el.scrollHeight;\n setShowScrollButton(false);\n }\n\n // The filter toolbar uses `position: fixed` (anchored just below the\n // fixed AppShell header) so iOS PWA rubberband-bounce and any layout\n // shift in the surrounding flex column can't pull it under the header\n // and strand it there. We mirror its actual rendered height into a\n // shrink-0 spacer in the flex column so the scroll viewport doesn't\n // slide underneath — ResizeObserver because the chip row can wrap to\n // two lines on narrow viewports with many active categories.\n const toolbarRef = useRef<HTMLDivElement | null>(null);\n const [toolbarH, setToolbarH] = useState(0);\n useEffect(() => {\n const el = toolbarRef.current;\n if (!el) { setToolbarH(0); return; }\n const ro = new ResizeObserver((entries) => {\n const h = entries[0]?.contentRect.height ?? 0;\n setToolbarH(h);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [availableChips.length]);\n\n return (\n <div className=\"flex-1 flex flex-col min-h-0 relative\">\n {/* Fixed-positioned toolbar pinned right below the AppShell header.\n A shrink-0 spacer below reserves its vertical space in the flex\n column so the message viewport doesn't slide under it. */}\n {availableChips.length > 0 && (\n <>\n <div\n ref={toolbarRef}\n className=\"fixed left-0 right-0 z-30\"\n style={{ top: \"calc(3rem + var(--app-safe-top))\" }}\n >\n <FilterToolbar\n chips={availableChips}\n filters={filters}\n onToggle={toggle}\n hiddenCount={hiddenCount}\n />\n </div>\n <div className=\"shrink-0\" aria-hidden style={{ height: toolbarH }} />\n </>\n )}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n className=\"flex-1 overflow-y-auto px-4 py-4 panel-scrollbar\"\n style={{\n // Scroll-anchor jumps (deep-link to a message) land below the\n // floating header, not under it.\n scrollPaddingTop: \"calc(3rem + var(--app-safe-top))\",\n }}\n >\n {hasMore && (\n <div className=\"text-center py-1.5 text-[11px] text-fg-faint select-none\">\n {loadingMore ? \"Loading earlier messages…\" : \"Scroll up for earlier messages\"}\n </div>\n )}\n {visibleMessages.length === 0 && !streamingContent && (\n <div className=\"flex items-center justify-center h-full text-fg-faint text-sm select-none\">\n {messages.length === 0 ? (\n <span>Send a message to begin</span>\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-center px-4\">\n <span>{hiddenCount} message{hiddenCount === 1 ? \" is\" : \"s are\"} hidden by filters</span>\n <button\n type=\"button\"\n onClick={reset}\n className=\"control-tap text-xs px-2.5 py-1 rounded-md border border-border bg-surface-2 text-fg-muted hover:text-fg hover:bg-surface-3 transition-colors\"\n >\n Show all messages\n </button>\n </div>\n )}\n </div>\n )}\n {(() => {\n // ADR-0042. The boundary divider + warm summary card live INSIDE the\n // message stream so they scroll with content (not above as a fixed\n // banner). `boundaryIndex` is the index of the first hot message in\n // the visible list; everything before it is older-than-pin and gets\n // covered by the warm summary card sitting above the divider.\n //\n // If `hotSince` sits strictly after every loaded message (the\n // post-/compact \"/new\" state), every visible message is warm and\n // the boundary is rendered AFTER the last bubble.\n const boundaryIndex = hotSince\n ? visibleMessages.findIndex((m) => m.created_at >= hotSince)\n : -1;\n const pinAfterAll =\n !!hotSince && visibleMessages.length > 0 && boundaryIndex === -1\n && visibleMessages[visibleMessages.length - 1].created_at < hotSince;\n const hasBoundary = !!hotSince && (boundaryIndex !== -1 || pinAfterAll);\n const olderInVisible = pinAfterAll\n ? visibleMessages.length\n : hasBoundary ? boundaryIndex : 0;\n // \"+ N more we don't know about yet\" — older pages are likely unloaded.\n const olderCountLabel = olderInVisible + (hasMore ? 1 : 0);\n\n const renderBoundary = (key: string) => (\n <div key={key}>\n <WarmSummaryCard\n olderCount={olderCountLabel}\n summary={warmSummary ?? null}\n summaryBefore={warmSummaryBefore ?? null}\n hotSince={hotSince ?? null}\n computedAt={warmSummaryComputedAt ?? null}\n streaming={!!streaming}\n />\n <ContextBoundaryDivider\n sourceMessages={warmSummarySourceMessages ?? null}\n sourceChars={warmSummarySourceChars ?? null}\n summaryChars={warmSummary ? warmSummary.length : null}\n />\n </div>\n );\n\n const nodes = visibleMessages.flatMap((msg, i) => {\n const startsTurn = i === 0 || visibleMessages[i - 1].role !== msg.role;\n const out = [] as React.ReactNode[];\n if (hasBoundary && !pinAfterAll && i === boundaryIndex) {\n out.push(renderBoundary(`boundary-${msg.id}`));\n }\n out.push(\n <div\n key={msg.id}\n id={`msg-${msg.id}`}\n data-message-id={msg.id}\n className={startsTurn && i > 0 ? \"mt-3\" : undefined}\n >\n <MessageBubble\n message={msg}\n threadId={threadId ?? null}\n agentConfig={agentConfig}\n userProfile={userProfile}\n showAvatar={startsTurn}\n showToolEvents={filters.tool_use}\n contextWindowTokens={contextWindowTokens ?? null}\n isLatest={i === visibleMessages.length - 1 && !streamingContent}\n onRetry={onRetryMessage}\n />\n </div>,\n );\n return out;\n });\n if (pinAfterAll) nodes.push(renderBoundary(\"boundary-tail\"));\n return nodes;\n })()}\n {thinkingContent && filters.thinking && <ThinkingLine text={thinkingContent} />}\n {toolEvents && toolEvents.length > 0 && filters.tool_use && <ToolList events={toolEvents} />}\n {streamingContent && (\n <StreamingBubble\n content={streamingContent}\n threadId={threadId ?? null}\n agentConfig={agentConfig ?? null}\n showAvatar={messages.length === 0 || messages[messages.length - 1].role !== \"assistant\"}\n inflightToolCount={inflightToolCount}\n />\n )}\n {queuedMessages && queuedMessages.length > 0 && (\n <div className=\"flex flex-col gap-1 mt-2 mb-1\">\n {queuedMessages.map((q) => (\n <QueuedBubble key={q.id} item={q} onRemove={onRemoveQueued} />\n ))}\n </div>\n )}\n {notices?.map((n) => (\n <div key={n.id} className=\"flex justify-center my-3\">\n <span className=\"text-xs italic text-fg-faint bg-surface-2 px-3 py-1 rounded-full border border-border\">\n {n.text}\n </span>\n </div>\n ))}\n </div>\n {showScrollButton && (\n <button\n onClick={scrollToBottom}\n style={{ top: `calc(3rem + var(--app-safe-top) + ${toolbarH}px + 0.75rem)` }}\n className=\"absolute left-1/2 -translate-x-1/2 p-2 rounded-full bg-accent/40 hover:bg-accent/80 text-white backdrop-blur-sm shadow-md transition-all animate-in fade-in slide-in-from-top-2 duration-200 z-20\"\n title=\"Scroll to latest message\"\n aria-label=\"Scroll to latest message\"\n >\n <ArrowDown size={18} />\n </button>\n )}\n </div>\n );\n}\n\n// Compact horizontal toolbar of category-visibility chips. Only renders\n// chips whose category is currently represented in the visible transcript,\n// so the toolbar stays empty for plain user/assistant threads. Hidden\n// counter on the right tells the user how many messages are gated out by\n// the current filter so the absence isn't mysterious.\nconst CHIP_LABELS: Record<MessageFilterKey, string> = {\n scheduled_task: \"scheduled\",\n watcher: \"watcher\",\n bridge: \"bridge\",\n extension: \"extension\",\n page_capture: \"captures\",\n synthetic: \"system\",\n tool_use: \"tools\",\n thinking: \"thinking\",\n};\nfunction FilterToolbar({\n chips,\n filters,\n onToggle,\n hiddenCount,\n}: {\n chips: readonly MessageFilterKey[];\n filters: Record<MessageFilterKey, boolean>;\n onToggle: (key: MessageFilterKey) => void;\n hiddenCount: number;\n}) {\n return (\n <div className=\"px-4 py-1.5 flex items-center gap-1.5 flex-wrap bg-surface/80 backdrop-blur border-b border-border/40 text-[11px]\">\n <span className=\"text-fg-faint mr-0.5 select-none\">show:</span>\n {chips.map((key) => {\n const on = filters[key];\n const Icon = on ? Eye : EyeOff;\n return (\n <button\n key={key}\n onClick={() => onToggle(key)}\n className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full border transition-colors ${\n on\n ? \"bg-surface-2 border-border text-fg-muted hover:text-fg\"\n : \"bg-transparent border-border/40 text-fg-faint hover:text-fg-muted line-through decoration-fg-faint/60\"\n }`}\n title={on ? `Hide ${CHIP_LABELS[key]} messages` : `Show ${CHIP_LABELS[key]} messages`}\n aria-pressed={on}\n >\n <Icon size={10} />\n <span>{CHIP_LABELS[key]}</span>\n </button>\n );\n })}\n {hiddenCount > 0 && (\n <span className=\"ml-auto text-fg-faint select-none\" aria-live=\"polite\">\n {hiddenCount} hidden\n </span>\n )}\n </div>\n );\n}\n\n// Streaming-bubble wrapper. Wraps the in-flight assistant bubble so the\n// `message` object passed to MessageBubble keeps a stable identity across\n// renders that don't actually change the streaming text — without this\n// the inline `{ role, content, streaming: true }` literal in the parent\n// JSX would defeat MessageBubble's React.memo on every parent re-render.\nconst StreamingBubble = memo(function StreamingBubble({\n content,\n threadId,\n agentConfig,\n showAvatar,\n inflightToolCount,\n}: {\n content: string;\n threadId: string | null;\n agentConfig: AgentConfig | null;\n showAvatar: boolean;\n inflightToolCount: number;\n}) {\n const message = useMemo(\n () => ({ role: \"assistant\" as const, content, streaming: true }),\n [content],\n );\n return (\n <MessageBubble\n message={message}\n threadId={threadId}\n agentConfig={agentConfig}\n showAvatar={showAvatar}\n inflightToolCount={inflightToolCount}\n />\n );\n});\n\nfunction ThinkingLine({ text }: { text: string }) {\n const [open, setOpen] = useState(false);\n const preview = text.replace(/\\s+/g, \" \").trim();\n const tail = preview.length > 60 ? preview.slice(-60) : preview;\n return (\n <div className=\"my-1.5\">\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center gap-1.5 text-[11px] text-amber-700 dark:text-amber-400/70 hover:text-amber-700 dark:hover:text-amber-300 px-1 py-0.5\"\n >\n <ChevronRight size={10} className={`transition-transform shrink-0 ${open ? \"rotate-90\" : \"\"}`} />\n <span className=\"font-medium\">thinking</span>\n {!open && <span className=\"truncate text-amber-700 dark:text-amber-300/40 italic font-normal flex-1 text-left\">{tail}</span>}\n </button>\n {open && (\n <pre className=\"ml-5 mt-1 px-2 py-1.5 text-[11px] text-amber-900 dark:text-amber-100/90 whitespace-pre-wrap break-words font-mono bg-amber-100/60 dark:bg-amber-950/30 rounded border border-amber-300 dark:border-amber-900/30\">\n {text}\n </pre>\n )}\n </div>\n );\n}\n\n// Ghosted user-bubble shown for messages the user typed while a previous run\n// was still streaming. The chat input doesn't block; submissions stack up here\n// and drain automatically as the agent finishes each turn. Click X to remove\n// before it fires.\nfunction QueuedBubble({\n item, onRemove,\n}: {\n item: { id: string; text: string; attachmentCount: number };\n onRemove?: (id: string) => void;\n}) {\n return (\n <div className=\"flex flex-row-reverse gap-2 items-end opacity-60 group\">\n <div className=\"shrink-0 w-7\" />\n <div className=\"max-w-[75%] rounded-2xl rounded-br-sm px-4 py-2.5 text-sm leading-relaxed bg-accent/40 border border-accent/40 border-dashed text-fg relative\">\n <div className=\"flex items-center gap-1.5 text-[10px] uppercase tracking-wider text-accent/80 mb-1\">\n <Clock size={10} />\n <span>queued</span>\n {item.attachmentCount > 0 && (\n <span className=\"text-fg-muted/70 normal-case tracking-normal\">\n · {item.attachmentCount} attachment{item.attachmentCount === 1 ? \"\" : \"s\"}\n </span>\n )}\n </div>\n <p className=\"whitespace-pre-wrap break-words\">{item.text}</p>\n {onRemove && (\n <button\n onClick={() => onRemove(item.id)}\n className=\"absolute -top-2 -right-2 w-5 h-5 rounded-full bg-surface-3 border border-border text-fg-muted hover:text-rose-700 dark:hover:text-rose-400 hover:border-rose-700 hidden group-hover:flex items-center justify-center\"\n title=\"Remove from queue\"\n >\n <X size={11} />\n </button>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\nimport type { ContentPart, Message } from \"@/api/types\";\n\nexport interface QueuedMessage {\n id: string;\n text: string;\n attachments: ContentPart[];\n}\n\nexport interface SystemNotice {\n id: string;\n text: string;\n}\n\nexport interface ThreadMetaApplier {\n setHotSince: (v: string | null) => void;\n setWarmSummary: (v: string | null) => void;\n setWarmSummaryBefore: (v: string | null) => void;\n setWarmSummaryComputedAt: (v: string | null) => void;\n setWarmSummarySourceMessages: (v: number | null) => void;\n setWarmSummarySourceChars: (v: number | null) => void;\n setContextWindowTokens: (v: number | null) => void;\n}\n\nexport interface ThreadGetPayload {\n hot_since?: string | null;\n warm_summary?: string | null;\n warm_summary_before?: string | null;\n warm_summary_computed_at?: string | null;\n warm_summary_source_messages?: number | null;\n warm_summary_source_chars?: number | null;\n context_window_tokens?: number | null;\n}\n\n// Append-with-dedupe. After a run finishes, two independent code paths can\n// both fetch the freshly-persisted user+assistant rows and append them:\n// 1) handleDone (driven by the SSE `done` event for the local run), and\n// 2) the `jarela:thread-updated` window listener (driven by the\n// cross-device events bus notification for the same run).\n// Dedupe by id at the append site so either ordering converges to the\n// same list.\nexport function appendUnique(prev: Message[], incoming: Message[]): Message[] {\n if (incoming.length === 0) return prev;\n const seen = new Set(prev.map((m) => m.id));\n const fresh = incoming.filter((m) => !seen.has(m.id));\n return fresh.length === 0 ? prev : prev.concat(fresh);\n}\n\nexport function applyThreadMeta(meta: ThreadMetaApplier, payload: ThreadGetPayload): void {\n meta.setHotSince(payload.hot_since ?? null);\n meta.setWarmSummary(payload.warm_summary ?? null);\n meta.setWarmSummaryBefore(payload.warm_summary_before ?? null);\n meta.setWarmSummaryComputedAt(payload.warm_summary_computed_at ?? null);\n meta.setWarmSummarySourceMessages(payload.warm_summary_source_messages ?? null);\n meta.setWarmSummarySourceChars(payload.warm_summary_source_chars ?? null);\n meta.setContextWindowTokens(payload.context_window_tokens ?? null);\n}\n\nexport function makeQueuedId(prefix = \"q\"): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n}\n","\"use client\";\n// Generalized user-facing error reporting. Wraps the toast pub/sub with an\n// expand-to-details treatment plus a one-click \"Report this issue\" path that\n// opens a pre-filled GitHub issue at the configured issue tracker. No\n// outbound network from the app — the user reviews and submits the issue\n// themselves, which keeps the no-telemetry stance intact.\n//\n// Forks set NEXT_PUBLIC_APP_ISSUE_URL to redirect \"Report a bug\" away from\n// upstream (CircuitWall/jarela) and to their own tracker.\n\nimport { pushToast } from \"./toasts\";\nimport { getAppIssueUrl } from \"@/lib/env/app-config\";\n\n// GitHub's \"new issue\" URL works up to ~8KB before some clients silently drop\n// the body. Stay well under that and tell the user to copy the full report\n// from clipboard if we have to truncate.\nconst MAX_ISSUE_BODY_BYTES = 7000;\n\nexport interface ErrorReportInput {\n // Short user-facing headline, e.g. \"Couldn't toggle MCP server\".\n title: string;\n // Optional plain-language one-liner under the title.\n summary?: string;\n // The original error. Accept anything — we'll stringify safely.\n error: unknown;\n // Free-form context echoed into the issue body. Keep keys short.\n // e.g. { panel: \"scheduled-tasks\", action: \"task.toggle\", task_id: \"t_42\" }\n context?: Record<string, unknown>;\n}\n\nexport interface ReportEnv {\n appVersion: string;\n userAgent: string;\n url: string;\n ts: string;\n}\n\n// Pure: extract the most useful string representation of an unknown error.\n// Prefer `Error.stack` (includes message + frames), fall back to message,\n// fall back to String(). Never throws.\nexport function stringifyError(err: unknown): string {\n if (err == null) return \"(no error provided)\";\n if (err instanceof Error) {\n return err.stack ?? err.message ?? err.name ?? \"Error\";\n }\n if (typeof err === \"string\") return err;\n try {\n return JSON.stringify(err, null, 2);\n } catch {\n // JSON.stringify can throw on circular refs.\n return String(err);\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown> | undefined): string {\n if (!ctx) return \"\";\n const keys = Object.keys(ctx);\n if (keys.length === 0) return \"\";\n const lines = keys.map((k) => {\n const v = ctx[k];\n let rendered: string;\n if (v == null) rendered = String(v);\n else if (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\") {\n rendered = String(v);\n } else {\n try { rendered = JSON.stringify(v); } catch { rendered = String(v); }\n }\n return `- ${k}: ${rendered}`;\n });\n return `**Context:**\\n${lines.join(\"\\n\")}\\n\\n`;\n}\n\n// Pure: build the markdown body and the issue title.\nexport function formatReport(\n input: ErrorReportInput,\n env: ReportEnv,\n): { title: string; body: string } {\n const summary = input.summary ?? input.title;\n const errStr = stringifyError(input.error);\n const ctxBlock = formatContext(input.context);\n const body =\n `**What failed:** ${summary}\\n\\n` +\n `**Error:**\\n` +\n \"```\\n\" +\n `${errStr}\\n` +\n \"```\\n\\n\" +\n ctxBlock +\n `**Environment:**\\n` +\n `- App version: ${env.appVersion}\\n` +\n `- User agent: ${env.userAgent}\\n` +\n `- URL: ${env.url}\\n` +\n `- Timestamp: ${env.ts}\\n\\n` +\n `---\\n` +\n `<!-- Anything else about what you were doing when this happened? -->\\n`;\n return { title: input.title, body };\n}\n\n// Pure: GitHub issue URL with title+body+labels prefilled. If the body would\n// push the URL past MAX_ISSUE_BODY_BYTES we truncate and add a footer line\n// pointing the user at the clipboard copy.\nexport function buildIssueUrl(report: { title: string; body: string }): string {\n let body = report.body;\n if (Buffer.byteLength(body, \"utf8\") > MAX_ISSUE_BODY_BYTES) {\n const footer = \"\\n\\n_(report truncated — paste the full version from your clipboard)_\\n\";\n const room = MAX_ISSUE_BODY_BYTES - Buffer.byteLength(footer, \"utf8\");\n // Truncate by characters then re-check bytes to land safely under the cap.\n let truncated = body.slice(0, Math.max(room, 0));\n while (Buffer.byteLength(truncated, \"utf8\") > room && truncated.length > 0) {\n truncated = truncated.slice(0, -1);\n }\n body = truncated + footer;\n }\n const params = new URLSearchParams({\n title: report.title,\n body,\n labels: \"user-report\",\n });\n return `${getAppIssueUrl()}?${params.toString()}`;\n}\n\n// Cached app version. We fetch once on the first error, then reuse for the\n// session. Failure to read the endpoint isn't a real problem — we just\n// surface \"unknown\" rather than blocking the user from filing an issue.\nlet cachedVersion: string | null = null;\nlet inFlight: Promise<string> | null = null;\n\nasync function readAppVersion(): Promise<string> {\n if (cachedVersion) return cachedVersion;\n if (inFlight) return inFlight;\n inFlight = (async () => {\n try {\n const res = await fetch(\"/api/v1/update\", { method: \"GET\" });\n if (!res.ok) return \"unknown\";\n const j = (await res.json()) as { version?: string };\n cachedVersion = j.version ?? \"unknown\";\n return cachedVersion;\n } catch {\n // Endpoint missing in tests, or offline first launch. Don't surface.\n return \"unknown\";\n } finally {\n inFlight = null;\n }\n })();\n return inFlight;\n}\n\nexport function buildEnv(appVersion: string): ReportEnv {\n const ua =\n typeof navigator !== \"undefined\" && typeof navigator.userAgent === \"string\"\n ? navigator.userAgent\n : \"unknown\";\n const url =\n typeof window !== \"undefined\" && window.location\n ? window.location.pathname\n : \"/\";\n return {\n appVersion,\n userAgent: ua,\n url,\n ts: new Date().toISOString(),\n };\n}\n\n// Push a sticky error toast carrying the details + report payload. The\n// Toaster reads `details` and `reportInput` and renders the expand chevron\n// plus Copy / Report buttons. We don't await the version fetch — the\n// initial render uses \"unknown\" and the next push gets the real value.\nexport function pushErrorToast(input: ErrorReportInput): string {\n const details = stringifyError(input.error);\n // Kick off (or reuse) the version fetch but don't block the toast.\n void readAppVersion();\n return pushToast({\n kind: \"error\",\n source: \"system\",\n sourceLabel: \"Error\",\n title: input.title,\n body: input.summary ?? \"Click to expand for details\",\n agent_id: null,\n thread_id: null,\n ttl: 0,\n details,\n reportInput: input,\n });\n}\n\n// Used by Toaster when the user clicks Copy or Report. Awaits the cached\n// version (or the in-flight fetch) so the report is accurate.\nexport async function buildReport(\n input: ErrorReportInput,\n): Promise<{ title: string; body: string; url: string }> {\n const appVersion = cachedVersion ?? (await readAppVersion());\n const env = buildEnv(appVersion);\n const report = formatReport(input, env);\n return { ...report, url: buildIssueUrl(report) };\n}\n\n// Test seam: reset the version cache.\nexport function _resetVersionCacheForTests(): void {\n cachedVersion = null;\n inFlight = null;\n}\n","\"use client\";\n// Centralized human-friendly error-title mapping. Used by pushErrorToast\n// callers so the headline a user sees is consistent across the UI:\n// \"Not authorized\" / \"Server error\" / \"Network unreachable\" / \"Cancelled\".\n// The original error string still rides along as `details` for the expand\n// chevron and the Report button. Unknown errors fall back to the\n// caller-supplied label.\n\nimport { pushErrorToast } from \"./error-report\";\n\ninterface HttpLikeError {\n status?: number;\n code?: string | number;\n name?: string;\n message?: string;\n}\n\nfunction asHttpLike(err: unknown): HttpLikeError | null {\n if (err == null) return null;\n if (typeof err === \"object\") return err as HttpLikeError;\n return null;\n}\n\nfunction extractStatus(err: unknown): number | null {\n const h = asHttpLike(err);\n if (!h) return null;\n if (typeof h.status === \"number\") return h.status;\n // ApiError-style: status is the first 3-digit run in the message.\n const m = typeof h.message === \"string\" ? /\\b([45]\\d{2})\\b/.exec(h.message) : null;\n if (m) return Number(m[1]);\n return null;\n}\n\nfunction isAbort(err: unknown): boolean {\n const h = asHttpLike(err);\n if (!h) return false;\n if (h.name === \"AbortError\") return true;\n if (h.code === \"ABORT_ERR\" || h.code === 20) return true;\n return false;\n}\n\nfunction isNetwork(err: unknown): boolean {\n const h = asHttpLike(err);\n if (!h) return false;\n const msg = typeof h.message === \"string\" ? h.message.toLowerCase() : \"\";\n if (/failed to fetch|networkerror|network request|econn|enotfound|etimedout|fetch failed/.test(msg)) {\n return true;\n }\n if (h.code === \"ECONNREFUSED\" || h.code === \"ENOTFOUND\" || h.code === \"ETIMEDOUT\") return true;\n return false;\n}\n\n/**\n * Map any error to a short, user-facing headline. Falls back to\n * `fallback` for shapes we don't recognise — the underlying error string\n * is still surfaced as toast details, so unknown errors aren't lost.\n */\nexport function friendlyErrorTitle(err: unknown, fallback: string): string {\n if (isAbort(err)) return \"Cancelled\";\n if (isNetwork(err)) return \"Network unreachable\";\n const status = extractStatus(err);\n if (status != null) {\n if (status === 401 || status === 403) return \"Not authorized\";\n if (status === 404) return \"Not found\";\n if (status === 408) return \"Request timed out\";\n if (status === 409) return \"Conflict\";\n if (status === 413) return \"Too large\";\n if (status === 422) return \"Invalid input\";\n if (status === 423) return \"Locked\";\n if (status === 429) return \"Too many requests\";\n if (status >= 500 && status <= 504) return \"Server error\";\n if (status >= 400 && status < 500) return \"Request rejected\";\n }\n return fallback;\n}\n\n/**\n * One-call error-to-toast helper. Always shows a friendly headline; the\n * raw error stays in details. Provide `fallbackTitle` for the unknown-\n * error branch. `context` is echoed into the Report-an-Issue body.\n */\nexport function reportError(input: {\n error: unknown;\n fallbackTitle: string;\n summary?: string;\n context?: Record<string, unknown>;\n}): void {\n pushErrorToast({\n title: friendlyErrorTitle(input.error, input.fallbackTitle),\n summary: input.summary,\n error: input.error,\n context: input.context,\n });\n}\n","\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { reportError } from \"@/lib/ui/error-message\";\n\ninterface Params {\n sessionError?: string | null;\n streamError: string | null | undefined;\n agentId: string | null;\n threadId: string | null;\n}\n\n// Surface session-load and stream errors as toasts instead of disabling the\n// input or rendering an inline red banner. Toasts are dismissible,\n// dedupe-by-id, and carry the Report path. The chat stays interactive so\n// the user can retry without reloading.\nexport function useChatErrorReporting({ sessionError, streamError, agentId, threadId }: Params) {\n const lastSessionErrorRef = useRef<string | null>(null);\n useEffect(() => {\n if (!sessionError) { lastSessionErrorRef.current = null; return; }\n if (lastSessionErrorRef.current === sessionError) return;\n lastSessionErrorRef.current = sessionError;\n reportError({\n error: sessionError,\n fallbackTitle: \"Couldn't load session\",\n summary: \"The agent's thread didn't load. Retry by re-selecting the agent.\",\n context: { agent_id: agentId, panel: \"chat\", action: \"session.load\" },\n });\n }, [sessionError, agentId]);\n\n const lastStreamErrorRef = useRef<string | null>(null);\n useEffect(() => {\n if (!streamError) { lastStreamErrorRef.current = null; return; }\n if (lastStreamErrorRef.current === streamError) return;\n lastStreamErrorRef.current = streamError;\n reportError({\n error: streamError,\n fallbackTitle: \"Chat stream error\",\n context: { agent_id: agentId, thread_id: threadId, panel: \"chat\", action: \"stream\" },\n });\n }, [streamError, agentId, threadId]);\n}\n","\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ContentPart } from \"@/api/types\";\nimport { makeQueuedId, type QueuedMessage } from \"./chat-helpers\";\n\ninterface Params {\n threadId: string | null;\n streaming: boolean;\n compacting: boolean;\n launchRun: (text: string, atts: ContentPart[]) => Promise<void>;\n}\n\nexport interface ChatQueueApi {\n queue: QueuedMessage[];\n queueRef: React.MutableRefObject<QueuedMessage[]>;\n drainQueueRef: React.MutableRefObject<() => void>;\n isReady: () => boolean;\n enqueue: (text: string, atts: ContentPart[]) => void;\n prepend: (text: string, atts: ContentPart[]) => void;\n removeQueued: (id: string) => void;\n retry: (text: string, atts: ContentPart[]) => void;\n}\n\n// Owns the FIFO queue of messages typed while a run was already streaming\n// or the session wasn't ready. The chat input stays unblocked; we drain\n// this queue after each run finishes. Multiple queued user messages get\n// merged into one prompt (joined by a blank line) with all attachments\n// concatenated, so the agent sees one coherent turn instead of N\n// round-trips. The readiness guard makes out-of-band invocations safe\n// no-ops.\nexport function useChatQueue({ threadId, streaming, compacting, launchRun }: Params): ChatQueueApi {\n const [queue, setQueue] = useState<QueuedMessage[]>([]);\n const queueRef = useRef<QueuedMessage[]>([]);\n queueRef.current = queue;\n\n // Mirror readiness state into refs so the drain closure reads the live\n // values instead of whatever was captured during the render that built\n // it. handleCompact's finally calls drainQueueRef.current() synchronously\n // right after setCompacting(false) — at that point React hasn't committed\n // the new render, so a closure-captured `compacting` would still be true\n // and the drain would bail out, leaving queued messages stranded.\n const streamingRef = useRef(streaming);\n streamingRef.current = streaming;\n const compactingRef = useRef(compacting);\n compactingRef.current = compacting;\n const threadIdRef = useRef(threadId);\n threadIdRef.current = threadId;\n\n const drainQueueRef = useRef<() => void>(() => {});\n // `launchRun` is plain function re-created each render; read through ref\n // to keep drain stable.\n const launchRunRef = useRef(launchRun);\n launchRunRef.current = launchRun;\n\n drainQueueRef.current = () => {\n if (streamingRef.current || compactingRef.current || !threadIdRef.current) return;\n setQueue((q) => {\n if (q.length === 0) return q;\n const text = q.map((m) => m.text).join(\"\\n\\n\");\n const atts = q.flatMap((m) => m.attachments);\n Promise.resolve().then(() => { void launchRunRef.current(text, atts); });\n return [];\n });\n };\n\n // Belt-and-braces: also drain whenever readiness flips back to ready.\n // Covers paths that change `streaming` / `compacting` without calling\n // drainQueueRef.current() in a finally (e.g. compact error before the\n // finally lands, or external state updates from useThreadCrossDeviceSync).\n useEffect(() => {\n if (streaming || compacting || !threadId) return;\n if (queue.length === 0) return;\n drainQueueRef.current();\n }, [streaming, compacting, threadId, queue.length]);\n\n const isReady = useCallback(\n () => !streaming && !compacting && !!threadId && queueRef.current.length === 0,\n [streaming, compacting, threadId],\n );\n\n const enqueue = useCallback((text: string, atts: ContentPart[]) => {\n setQueue((q) => [...q, { id: makeQueuedId(), text, attachments: atts }]);\n }, []);\n\n const prepend = useCallback((text: string, atts: ContentPart[]) => {\n setQueue((q) => [{ id: makeQueuedId(), text, attachments: atts }, ...q]);\n }, []);\n\n const removeQueued = useCallback((id: string) => {\n setQueue((q) => q.filter((m) => m.id !== id));\n }, []);\n\n const retry = useCallback((text: string, atts: ContentPart[]) => {\n if (!threadId) return;\n if (isReady()) {\n void launchRunRef.current(text, atts);\n return;\n }\n setQueue((q) => [...q, { id: makeQueuedId(), text, attachments: atts }]);\n }, [threadId, isReady]);\n\n return { queue, queueRef, drainQueueRef, isReady, enqueue, prepend, removeQueued, retry };\n}\n","\"use client\";\nimport { useEffect, type RefObject } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { Message } from \"@/api/types\";\nimport { appendUnique, applyThreadMeta, type ThreadMetaApplier } from \"./chat-helpers\";\n\ninterface Params {\n threadId: string | null;\n streamingRef: RefObject<boolean>;\n messagesRef: RefObject<Message[]>;\n setMessages: (updater: (prev: Message[]) => Message[]) => void;\n setHasMore: (v: boolean) => void;\n applyMeta: ThreadMetaApplier;\n}\n\n// Cross-device thread sync. When ANOTHER client (iOS PWA, bridge, scheduled\n// task) appends to this thread, the server publishes a notification on the\n// events bus. `useEventNotifications` dispatches a `jarela:thread-updated`\n// window event for every such ping. If it matches the thread we're viewing\n// and we're not currently the source of the run (no local stream in flight),\n// forward-fetch new messages so the chat list updates without a manual\n// page refresh.\nexport function useThreadCrossDeviceSync({\n threadId,\n streamingRef,\n messagesRef,\n setMessages,\n setHasMore,\n applyMeta,\n}: Params) {\n useEffect(() => {\n if (!threadId) return;\n function handler(e: Event) {\n const detail = (e as CustomEvent<{ thread_id: string }>).detail;\n if (!detail || detail.thread_id !== threadId) return;\n // The local run's own handleDone path already refetches — skip to\n // avoid double-fetching while a turn is mid-stream on this device.\n if (streamingRef.current) return;\n const cur = messagesRef.current ?? [];\n const anchor = cur.length > 0 ? cur[cur.length - 1].created_at : undefined;\n const fetchPromise = anchor\n ? api.threads.get(threadId, { after: anchor })\n : api.threads.get(threadId);\n fetchPromise.then((d) => {\n if (anchor) {\n if (d.messages.length === 0) return;\n setMessages((prev) => appendUnique(prev, d.messages));\n } else {\n setMessages(() => d.messages);\n setHasMore(d.has_more);\n }\n applyThreadMeta(applyMeta, d);\n }).catch(console.error);\n }\n window.addEventListener(\"jarela:thread-updated\", handler);\n return () => window.removeEventListener(\"jarela:thread-updated\", handler);\n // applyMeta and setters are stable refs from useState/object literal in caller.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId]);\n}\n","\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { Message } from \"@/api/types\";\nimport { applyThreadMeta, type SystemNotice, type ThreadMetaApplier } from \"./chat-helpers\";\n\ninterface Params {\n threadId: string | null;\n attach: (threadId: string) => Promise<unknown>;\n}\n\nexport interface ThreadDataApi {\n messages: Message[];\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n messagesRef: React.MutableRefObject<Message[]>;\n notices: SystemNotice[];\n setNotices: React.Dispatch<React.SetStateAction<SystemNotice[]>>;\n addNotice: (text: string) => void;\n hasMore: boolean;\n setHasMore: React.Dispatch<React.SetStateAction<boolean>>;\n loadingMore: boolean;\n messagesLoading: boolean;\n hotSince: string | null;\n warmSummary: string | null;\n warmSummaryBefore: string | null;\n warmSummaryComputedAt: string | null;\n warmSummarySourceMessages: number | null;\n warmSummarySourceChars: number | null;\n contextWindowTokens: number | null;\n metaApplier: ThreadMetaApplier;\n loadOlder: () => Promise<void>;\n setContextPin: (next: string | null) => Promise<void>;\n}\n\nexport function useThreadData({ threadId, attach }: Params): ThreadDataApi {\n const [messages, setMessages] = useState<Message[]>([]);\n const [notices, setNotices] = useState<SystemNotice[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [messagesLoading, setMessagesLoading] = useState(false);\n const [hotSince, setHotSince] = useState<string | null>(null);\n const [warmSummary, setWarmSummary] = useState<string | null>(null);\n const [warmSummaryBefore, setWarmSummaryBefore] = useState<string | null>(null);\n const [warmSummaryComputedAt, setWarmSummaryComputedAt] = useState<string | null>(null);\n const [warmSummarySourceMessages, setWarmSummarySourceMessages] = useState<number | null>(null);\n const [warmSummarySourceChars, setWarmSummarySourceChars] = useState<number | null>(null);\n const [contextWindowTokens, setContextWindowTokens] = useState<number | null>(null);\n\n const messagesRef = useRef<Message[]>([]);\n messagesRef.current = messages;\n\n const metaApplier: ThreadMetaApplier = {\n setHotSince, setWarmSummary, setWarmSummaryBefore,\n setWarmSummaryComputedAt, setWarmSummarySourceMessages,\n setWarmSummarySourceChars, setContextWindowTokens,\n };\n\n const addNotice = useCallback((text: string) => {\n setNotices((p) => [...p, { id: `notice-${Date.now()}`, text }]);\n }, []);\n\n useEffect(() => {\n if (!threadId) {\n setMessages([]);\n setNotices([]);\n setHasMore(false);\n setMessagesLoading(false);\n setHotSince(null);\n setWarmSummary(null);\n setWarmSummaryBefore(null);\n setWarmSummaryComputedAt(null);\n setWarmSummarySourceMessages(null);\n setWarmSummarySourceChars(null);\n setContextWindowTokens(null);\n return;\n }\n let cancelled = false;\n setMessagesLoading(true);\n setMessages([]);\n setHasMore(false);\n setHotSince(null);\n setWarmSummary(null);\n setWarmSummaryBefore(null);\n setWarmSummaryComputedAt(null);\n setWarmSummarySourceMessages(null);\n setWarmSummarySourceChars(null);\n setContextWindowTokens(null);\n api.threads.get(threadId).then((d) => {\n if (cancelled) return;\n setMessages(d.messages);\n setHasMore(d.has_more);\n applyThreadMeta(metaApplier, d);\n }).catch((err) => { if (!cancelled) console.error(err); })\n .finally(() => {\n if (cancelled) return;\n setMessagesLoading(false);\n // Attach to any in-flight run for THIS thread. attach() sets\n // streaming=true optimistically and signals completion via onDone\n // (which drains the queue), so we must NOT fire drainQueueRef here.\n attach(threadId).catch(() => { /* best-effort */ });\n });\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId, attach]);\n\n // ADR-0042. Move the user's boundary line. Optimistic update so the chat\n // chrome reacts instantly; PATCH then confirms server-side. Boundary\n // moves invalidate the cached summary — clear it locally too so the UI\n // shows a placeholder until the next run refreshes it.\n const setContextPin = useCallback(async (next: string | null) => {\n if (!threadId) return;\n setHotSince(next);\n if (warmSummaryBefore !== next) {\n setWarmSummary(null);\n setWarmSummaryBefore(null);\n setWarmSummaryComputedAt(null);\n setWarmSummarySourceMessages(null);\n setWarmSummarySourceChars(null);\n }\n try {\n const updated = await api.threads.setContextPin(threadId, next);\n setHotSince(updated.hot_since);\n setWarmSummary(updated.warm_summary);\n setWarmSummaryBefore(updated.warm_summary_before);\n setWarmSummaryComputedAt(updated.warm_summary_computed_at);\n setWarmSummarySourceMessages(updated.warm_summary_source_messages);\n setWarmSummarySourceChars(updated.warm_summary_source_chars);\n } catch (err) {\n console.error(\"setContextPin failed\", err);\n }\n }, [threadId, warmSummaryBefore]);\n\n const loadOlder = useCallback(async () => {\n if (!threadId || loadingMore || !hasMore || messages.length === 0) return;\n setLoadingMore(true);\n try {\n const oldest = messages[0].created_at;\n const d = await api.threads.get(threadId, { before: oldest, limit: 50 });\n setMessages((prev) => [...d.messages, ...prev]);\n setHasMore(d.has_more);\n } catch (err) {\n console.error(err);\n } finally {\n setLoadingMore(false);\n }\n // Depend on `messages.length` rather than the array identity so streaming\n // appends don't recreate this callback.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId, loadingMore, hasMore, messages.length]);\n\n return {\n messages, setMessages, messagesRef, notices, setNotices, addNotice,\n hasMore, setHasMore, loadingMore, messagesLoading,\n hotSince, warmSummary, warmSummaryBefore, warmSummaryComputedAt,\n warmSummarySourceMessages, warmSummarySourceChars, contextWindowTokens,\n metaApplier, loadOlder, setContextPin,\n };\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, UserProfile } from \"@/api/types\";\n\ninterface Result {\n userProfile: UserProfile | null;\n profileLoading: boolean;\n agentConfig: AgentConfig | null;\n agentConfigLoading: boolean;\n}\n\nexport function useUserProfileAndAgent(agentId: string | null): Result {\n const [userProfile, setUserProfile] = useState<UserProfile | null>(null);\n const [profileLoading, setProfileLoading] = useState(true);\n const [agentConfig, setAgentConfig] = useState<AgentConfig | null>(null);\n const [agentConfigLoading, setAgentConfigLoading] = useState(false);\n\n useEffect(() => {\n setProfileLoading(true);\n api.profile.get().then(setUserProfile).catch(console.error).finally(() => setProfileLoading(false));\n }, []);\n\n useEffect(() => {\n if (!agentId) {\n setAgentConfig(null);\n setAgentConfigLoading(false);\n return;\n }\n setAgentConfigLoading(true);\n api.agents.get(agentId).then(setAgentConfig).catch(console.error).finally(() => setAgentConfigLoading(false));\n }, [agentId]);\n\n return { userProfile, profileLoading, agentConfig, agentConfigLoading };\n}\n","\"use client\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { ContentPart, Message } from \"@/api/types\";\nimport { useSSE } from \"@/hooks/useSSE\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { useTrackLoading } from \"@/lib/ui/loading\";\nimport { ApprovalsBanner } from \"@/components/proposals/ApprovalsBanner\";\nimport { InputBar } from \"./InputBar\";\nimport { MessageList } from \"./MessageList\";\nimport {\n appendUnique, applyThreadMeta, makeQueuedId,\n type ThreadMetaApplier,\n} from \"./chat-helpers\";\nimport { useChatErrorReporting } from \"./useChatErrorReporting\";\nimport { useChatQueue, type ChatQueueApi } from \"./useChatQueue\";\nimport { useThreadCrossDeviceSync } from \"./useThreadCrossDeviceSync\";\nimport { useThreadData } from \"./useThreadData\";\nimport { useUserProfileAndAgent } from \"./useUserProfileAndAgent\";\n\ninterface Props {\n threadId: string | null;\n agentId: string | null;\n sessionLoading?: boolean;\n sessionError?: string | null;\n onMessageSent: () => void;\n}\n\nexport function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSent }: Props) {\n const { state } = useAppContext();\n const [attachments, setAttachments] = useState<ContentPart[]>([]);\n const [compacting, setCompacting] = useState(false);\n const { userProfile, profileLoading, agentConfig, agentConfigLoading } =\n useUserProfileAndAgent(agentId);\n\n // attach() comes from useSSE which we call later. Bridge via a ref so\n // useThreadData's effect can call it after both hooks render.\n const attachRef = useRef<((id: string) => Promise<unknown>) | null>(null);\n const stableAttach = useCallback(\n (id: string) => attachRef.current?.(id) ?? Promise.resolve(undefined),\n [],\n );\n const thread = useThreadData({ threadId, attach: stableAttach });\n\n // When the next user turn came from a voice transcription, arm this flag\n // so handleDone can fire a `jarela:speak-message` event at the new\n // assistant message id and the bubble auto-plays the TTS reply once.\n const pendingAutoSpeakRef = useRef(false);\n // Need clearStreamingContent before useSSE returns it. Use a ref so\n // handleDone isn't dependent on the hook's return value.\n const clearStreamingRef = useRef<() => void>(() => {});\n const drainQueueRef = useRef<() => void>(() => {});\n const queueApiRef = useRef<ChatQueueApi | null>(null);\n\n const handleDone = useCallback(() => {\n if (!threadId) return;\n finalizeRunFromServer({\n threadId,\n messagesRef: thread.messagesRef,\n setMessages: thread.setMessages,\n setHasMore: thread.setHasMore,\n applyMeta: thread.metaApplier,\n clearStreaming: () => clearStreamingRef.current(),\n pendingAutoSpeakRef,\n }).finally(() => drainQueueRef.current());\n onMessageSent();\n // hook setters/refs are stable; intentionally exclude `thread`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId, onMessageSent]);\n\n const sse = useSSE(handleDone);\n attachRef.current = sse.attach;\n clearStreamingRef.current = sse.clearStreamingContent;\n\n useChatErrorReporting({ sessionError, streamError: sse.error, agentId, threadId });\n\n const streamingRef = useRef(false);\n streamingRef.current = sse.streaming;\n\n useThreadCrossDeviceSync({\n threadId,\n streamingRef,\n messagesRef: thread.messagesRef,\n setMessages: thread.setMessages,\n setHasMore: thread.setHasMore,\n applyMeta: thread.metaApplier,\n });\n\n useTrackLoading(!!sessionLoading);\n useTrackLoading(sse.streaming);\n useTrackLoading(compacting);\n useTrackLoading(thread.loadingMore);\n useTrackLoading(thread.messagesLoading);\n useTrackLoading(agentConfigLoading);\n\n // Actually fire a run for one message. Used by direct submit and by the\n // queue's drain after a previous run finishes.\n const launchRun = useCallback(async (text: string, atts: ContentPart[]) => {\n if (!threadId) return;\n const optId = `opt-${makeQueuedId(\"\")}`;\n const optimisticContent = atts.length\n ? JSON.stringify([{ type: \"text\" as const, text }, ...atts])\n : text;\n thread.setMessages((p) => [\n ...p,\n { id: optId, role: \"user\", content: optimisticContent, created_at: new Date().toISOString() },\n ]);\n const { accepted } = await sse.start(\n threadId,\n text,\n { filters: { include_tools: true, include_thinking: true }, ui_experience_mode: state.experienceMode },\n atts.length ? atts : undefined,\n thread.hotSince,\n );\n if (!accepted) {\n // Server rejected because another run was in flight (second tab,\n // other device). attach() return value feeds our deltas. Roll back\n // the optimistic user bubble and re-queue this message so the\n // drain after the in-flight run's `done` resubmits cleanly.\n thread.setMessages((p) => p.filter((m) => m.id !== optId));\n queueApiRef.current?.prepend(text, atts);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId, sse, state.experienceMode]);\n\n const queue = useChatQueue({ threadId, streaming: sse.streaming, compacting, launchRun });\n queueApiRef.current = queue;\n drainQueueRef.current = queue.drainQueueRef.current;\n\n async function handleCompact() {\n if (!agentId) return;\n setCompacting(true);\n try {\n const result = await api.agents.compact(agentId);\n if (result.compacted) {\n // Server moved the hot/warm pin to just after the last existing\n // message and persisted the warm summary. Mirror that in-place so\n // the boundary divider drops to the bottom of the chat and the\n // warm card shows the fresh summary — without wiping the visible\n // transcript. The user can still scroll up to read prior turns;\n // older history past JARELA_MAX_THREAD_MESSAGES has been pruned\n // server-side but its content lives on inside the warm summary.\n thread.metaApplier.setHotSince(result.hot_since ?? null);\n thread.metaApplier.setWarmSummary(result.warm_summary ?? null);\n thread.metaApplier.setWarmSummaryBefore(result.warm_summary_before ?? null);\n thread.metaApplier.setWarmSummaryComputedAt(result.warm_summary_computed_at ?? null);\n thread.metaApplier.setWarmSummarySourceMessages(result.warm_summary_source_messages ?? null);\n thread.metaApplier.setWarmSummarySourceChars(result.warm_summary_source_chars ?? null);\n } else {\n thread.addNotice(\"Nothing to compact yet — send some messages first.\");\n }\n } catch (err) {\n thread.addNotice(`Compaction failed: ${String(err)}`);\n } finally {\n setCompacting(false);\n queue.drainQueueRef.current();\n }\n }\n\n // Default Send / Enter. Send-when-idle, STEER-when-streaming.\n // Steer = prepend message to queue and abort the current run; the existing\n // handleDone → drain machinery picks the prepended item up first once\n // the abort settles.\n async function handleSubmit(rawInput: string) {\n let msg = rawInput.trim();\n if (!msg || !agentId) return;\n if (msg.toLowerCase() === \"/new\") { await handleCompact(); return; }\n // /btw is intent flavor — strip the prefix so the agent never sees it.\n if (msg.toLowerCase().startsWith(\"/btw \")) {\n msg = msg.slice(5).trim();\n if (!msg) return;\n }\n const atts = attachments;\n setAttachments([]);\n if (queue.isReady()) { await launchRun(msg, atts); return; }\n queue.prepend(msg, atts);\n if (sse.streaming) sse.stop();\n }\n\n // Ctrl/Cmd+Enter — explicit \"queue this turn\" path. Always appends; never\n // aborts. When idle and the queue is empty we just send normally.\n async function handleQueue(rawInput: string) {\n const msg = rawInput.trim();\n if (!msg || !agentId) return;\n if (msg.toLowerCase() === \"/new\" || msg.toLowerCase().startsWith(\"/btw \")) {\n await handleSubmit(rawInput);\n return;\n }\n const atts = attachments;\n setAttachments([]);\n if (queue.isReady()) { await launchRun(msg, atts); return; }\n queue.enqueue(msg, atts);\n }\n\n const handleVoiceTranscript = (text: string) => {\n const msg = text.trim();\n if (!msg || !agentId) return;\n if (agentConfig?.voice_auto_speak !== false) pendingAutoSpeakRef.current = true;\n if (queue.isReady()) { void launchRun(msg, []); return; }\n queue.enqueue(msg, []);\n };\n\n const handleRetryMessage = useCallback((text: string, atts: ContentPart[]) => {\n const msg = text.trim();\n if (!msg || !agentId) return;\n queue.retry(msg, atts);\n }, [agentId, queue]);\n\n // Shallow projection so the queued-bubble subtree doesn't re-reconcile\n // on every streaming delta.\n const queuedMessages = useMemo(\n () => queue.queue.map((q) => ({ id: q.id, text: q.text, attachmentCount: q.attachments.length })),\n [queue.queue],\n );\n\n return (\n <div className=\"flex flex-col h-full\">\n <MessageList\n threadId={threadId}\n messages={thread.messages}\n notices={thread.notices}\n agentConfig={agentConfig}\n userProfile={userProfile}\n // streamingContent stays visible past `streaming=false` so the bubble\n // doesn't disappear before the refetch arrives. Cleared atomically\n // via clearStreamingRef once the persisted message lands.\n streamingContent={sse.streamingContent || undefined}\n // Keep the live thinking line visible past `streaming=false` so a\n // user who's still reading isn't yanked out mid-sentence.\n thinkingContent={sse.thinkingContent || undefined}\n toolEvents={sse.streaming ? sse.toolEvents : undefined}\n hasMore={thread.hasMore}\n loadingMore={thread.loadingMore}\n onLoadMore={thread.loadOlder}\n queuedMessages={queuedMessages}\n onRemoveQueued={queue.removeQueued}\n hotSince={thread.hotSince}\n warmSummary={thread.warmSummary}\n warmSummaryBefore={thread.warmSummaryBefore}\n warmSummaryComputedAt={thread.warmSummaryComputedAt}\n warmSummarySourceMessages={thread.warmSummarySourceMessages}\n warmSummarySourceChars={thread.warmSummarySourceChars}\n onSetContextPin={thread.setContextPin}\n streaming={sse.streaming}\n contextWindowTokens={thread.contextWindowTokens}\n onRetryMessage={handleRetryMessage}\n />\n\n <ApprovalsBanner agentId={agentId} />\n\n <InputBar\n attachments={attachments}\n onAttachmentsChange={setAttachments}\n onSubmit={handleSubmit}\n onQueue={handleQueue}\n onStop={sse.stop}\n streaming={sse.streaming}\n voiceEnabled={!!agentConfig?.voice_enabled}\n agentId={agentId}\n onVoiceTranscript={handleVoiceTranscript}\n disabled={!agentId}\n placeholder={composerPlaceholder({\n compacting,\n sessionLoading: !!sessionLoading,\n messagesLoading: thread.messagesLoading,\n agentConfigLoading,\n profileLoading,\n })}\n />\n </div>\n );\n}\n\ninterface FinalizeParams {\n threadId: string;\n messagesRef: React.MutableRefObject<Message[]>;\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n setHasMore: (v: boolean) => void;\n applyMeta: ThreadMetaApplier;\n clearStreaming: () => void;\n pendingAutoSpeakRef: React.MutableRefObject<boolean>;\n}\n\n// Forward-fetch only the messages persisted after our newest known one.\n// Typically two rows (user + assistant) instead of the full 50-row page,\n// so this is O(turn) instead of O(thread). Falls back to full reload if\n// no anchor (fresh thread, race).\n//\n// Anchor on the last *persisted* row, never an `opt-*` optimistic — the\n// optimistic's created_at is from the client clock and could skip the\n// just-persisted user row if it skews ahead of the server.\nasync function finalizeRunFromServer(p: FinalizeParams): Promise<void> {\n const cur = p.messagesRef.current.filter((m) => !m.id.startsWith(\"opt-\"));\n const anchor = cur.length > 0 ? cur[cur.length - 1].created_at : undefined;\n const d = anchor\n ? await api.threads.get(p.threadId, { after: anchor })\n : await api.threads.get(p.threadId);\n if (anchor) {\n // Drop optimistic user bubbles before appending — their `opt-*` ids\n // don't match the server-assigned ids of the persisted rows.\n p.setMessages((prev) => appendUnique(prev.filter((m) => !m.id.startsWith(\"opt-\")), d.messages));\n } else {\n p.setMessages(d.messages);\n p.setHasMore(d.has_more);\n }\n applyThreadMeta(p.applyMeta, d);\n p.clearStreaming();\n if (p.pendingAutoSpeakRef.current) {\n p.pendingAutoSpeakRef.current = false;\n const latest = [...d.messages].reverse().find((m) => m.role === \"assistant\" && m.id);\n if (latest?.id && typeof window !== \"undefined\") {\n requestAnimationFrame(() => {\n window.dispatchEvent(new CustomEvent(\"jarela:speak-message\", { detail: { messageId: latest.id } }));\n });\n }\n }\n}\n\nfunction composerPlaceholder(s: {\n compacting: boolean;\n sessionLoading: boolean;\n messagesLoading: boolean;\n agentConfigLoading: boolean;\n profileLoading: boolean;\n}): string | undefined {\n if (s.compacting) return \"Compacting session… your messages will queue\";\n if (s.sessionLoading) return \"Loading session… your messages will queue\";\n if (s.messagesLoading) return \"Loading chat history…\";\n if (s.agentConfigLoading) return \"Loading agent…\";\n if (s.profileLoading) return \"Loading profile…\";\n return undefined;\n}\n","\"use client\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { MemoryItem } from \"@/api/types\";\n\nexport function useMemory(namespace?: string, search?: string) {\n const [items, setItems] = useState<MemoryItem[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try { setItems(await api.memory.list(namespace, search)); } finally { setLoading(false); }\n }, [namespace, search]);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const create = useCallback(async (ns: string, key: string, value: unknown) => {\n const item = await api.memory.create(ns, key, value);\n setItems((p) => [item, ...p]);\n return item;\n }, []);\n\n const update = useCallback(async (ns: string, key: string, value: unknown) => {\n const item = await api.memory.update(ns, key, value);\n setItems((p) => p.map((i) => (i.namespace === ns && i.key === key ? item : i)));\n return item;\n }, []);\n\n const remove = useCallback(async (ns: string, key: string) => {\n await api.memory.delete(ns, key);\n setItems((p) => p.filter((i) => !(i.namespace === ns && i.key === key)));\n }, []);\n\n return { items, loading, refresh, create, update, remove };\n}\n","\"use client\";\n// Shared scroll-to + highlight effect for settings panels. Each panel renders\n// its rows with stable DOM ids (e.g. id=\"integration-gmail\"); this hook reads\n// state.selectedItem[tab] and, when it changes, scrolls that row into view\n// and adds a one-shot highlight ring.\n//\n// We use querySelector inside the panel's container ref to avoid colliding\n// with id collisions across panels (a memory key shouldn't match an mcp\n// server name even if the strings overlap).\n\nimport { useEffect, useRef, type RefObject } from \"react\";\nimport { useAppContext, type Tab } from \"@/contexts/AppContext\";\n\nconst HIGHLIGHT_CLASS = \"jarela-deep-link-flash\";\nconst HIGHLIGHT_MS = 1600;\n\nexport function useDeepLinkScroll(tab: Tab, idPrefix: string, containerRef: RefObject<HTMLElement | null>) {\n const { state } = useAppContext();\n const item = state.selectedItem[tab];\n const lastSeenRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!item) {\n lastSeenRef.current = null;\n return;\n }\n if (lastSeenRef.current === item) return;\n const root = containerRef.current ?? document;\n // Defer one frame so freshly-rendered rows exist in the DOM.\n const raf = requestAnimationFrame(() => {\n const safe = item.replace(/\"/g, '\\\\\"');\n const el = root.querySelector(`[data-deep-link-id=\"${safe}\"]`) as HTMLElement | null;\n if (!el) return;\n lastSeenRef.current = item;\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n el.classList.add(HIGHLIGHT_CLASS);\n setTimeout(() => el.classList.remove(HIGHLIGHT_CLASS), HIGHLIGHT_MS);\n });\n return () => cancelAnimationFrame(raf);\n // idPrefix is stable; we don't depend on it for re-runs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [item, tab]);\n}\n","import { useEffect } from \"react\";\n\n/**\n * Listen for the Escape key at window scope and invoke `onEscape`.\n *\n * Used by modal/dialog editors that need a \"press Escape to close\" affordance.\n * Skip this when the dismiss should be focus-scoped — wire a local\n * `onKeyDown` on the element instead.\n */\nexport function useEscapeKey(onEscape: () => void, enabled: boolean = true): void {\n useEffect(() => {\n if (!enabled) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onEscape();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onEscape, enabled]);\n}\n","\"use client\";\nimport { X } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport type { MemoryItem } from \"@/api/types\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\n\ninterface Props {\n item?: MemoryItem;\n onSave: (namespace: string, key: string, value: unknown) => Promise<void>;\n onClose: () => void;\n}\n\nexport function MemoryEditor({ item, onSave, onClose }: Props) {\n const [namespace, setNamespace] = useState(item?.namespace ?? \"\");\n const [key, setKey] = useState(item?.key ?? \"\");\n const [valueStr, setValueStr] = useState(item ? JSON.stringify(item.value, null, 2) : \"\");\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const isEdit = !!item;\n\n useEscapeKey(onClose);\n\n async function handleSave() {\n setError(null);\n let parsed: unknown;\n try { parsed = JSON.parse(valueStr); } catch { setError(\"Value must be valid JSON\"); return; }\n if (!namespace.trim() || !key.trim()) { setError(\"Namespace and key are required\"); return; }\n setSaving(true);\n try { await onSave(namespace.trim(), key.trim(), parsed); onClose(); }\n catch (e) {\n pushErrorToast({\n title: \"Couldn't save memory entry\",\n error: e,\n context: { panel: \"memory\", action: \"memory.save\", namespace: namespace.trim(), key: key.trim() },\n });\n }\n finally { setSaving(false); }\n }\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4\">\n <div className=\"bg-surface-2 border border-border rounded-2xl w-full max-w-md shadow-xl\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h3 className=\"text-sm font-semibold text-fg\">{isEdit ? \"Edit memory\" : \"New memory\"}</h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\"><X size={16} /></button>\n </div>\n <div className=\"p-4 space-y-3\">\n {([\"Namespace\", \"Key\"] as const).map((label) => (\n <label key={label} className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">{label}</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent disabled:opacity-50\"\n value={label === \"Namespace\" ? namespace : key}\n onChange={(e) => label === \"Namespace\" ? setNamespace(e.target.value) : setKey(e.target.value)}\n placeholder={label === \"Namespace\" ? \"e.g. user/preferences\" : \"e.g. theme\"}\n disabled={isEdit}\n />\n </label>\n ))}\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Value (JSON)</span>\n <textarea\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent font-mono h-28 resize-none\"\n value={valueStr}\n onChange={(e) => setValueStr(e.target.value)}\n placeholder='{\"key\": \"value\"}'\n />\n </label>\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{error}</p>}\n </div>\n <div className=\"flex justify-end gap-2 px-4 pb-4\">\n <button onClick={onClose} className=\"px-3 py-1.5 text-sm text-fg-subtle hover:text-fg transition-colors\">Cancel</button>\n <button onClick={handleSave} disabled={saving} className=\"px-4 py-1.5 text-sm bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors disabled:opacity-50\">\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { ChevronRight } from \"lucide-react\";\nimport { useState } from \"react\";\n\n// Memory values are arbitrary JSON. The list rendering used to flatten\n// them with a single `JSON.stringify(item.value)`, which is unreadable\n// once values contain more than a few fields. This component renders a\n// typed, compact summary inline with an optional pretty-printed\n// expansion. It also masks values whose key name strongly suggests a\n// secret so a glance at the panel doesn't leak tokens to anyone\n// peering at the screen.\n\nconst SECRET_KEY_PATTERN =\n /(^|_)(token|secret|password|passwd|api_?key|client_secret|refresh_token|access_token|private_?key|auth)($|_)/i;\nconst SECRET_MASK = \"********\";\nconst MAX_INLINE_FIELDS = 4;\nconst MAX_INLINE_STRING = 80;\n\nfunction isSecretKey(key: string): boolean {\n return SECRET_KEY_PATTERN.test(key);\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\n/** Format a leaf value for inline display. Strings stay unquoted so\n * short notes read naturally; everything else falls back to JSON. */\nfunction formatLeaf(v: unknown, key?: string): string {\n if (key && typeof v === \"string\" && isSecretKey(key)) return SECRET_MASK;\n if (v === null) return \"null\";\n if (typeof v === \"string\") return truncate(v, MAX_INLINE_STRING);\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n if (Array.isArray(v)) {\n if (v.length === 0) return \"[]\";\n return `${v.length} item${v.length === 1 ? \"\" : \"s\"}`;\n }\n if (typeof v === \"object\") {\n const keys = Object.keys(v as object);\n if (keys.length === 0) return \"{}\";\n return `${keys.length} field${keys.length === 1 ? \"\" : \"s\"}`;\n }\n return truncate(JSON.stringify(v), MAX_INLINE_STRING);\n}\n\n/** Pretty-print for the expanded view, with secret masking applied at\n * every nesting level (so a nested `{ credentials: { api_token } }`\n * doesn't sneak past the inline mask). */\nfunction maskedReplacer(): (key: string, value: unknown) => unknown {\n return (key, value) => {\n if (typeof value === \"string\" && isSecretKey(key)) return SECRET_MASK;\n return value;\n };\n}\n\nexport function MemoryValuePreview({ value }: { value: unknown }) {\n const [expanded, setExpanded] = useState(false);\n\n // ── String / primitive / null ──────────────────────────────────────\n if (value === null) {\n return <p className=\"text-xs text-fg-subtle italic\">null</p>;\n }\n if (typeof value === \"string\") {\n // Multi-line strings deserve a real <pre>; one-liners stay inline.\n if (value.includes(\"\\n\")) {\n return (\n <pre className=\"text-xs text-fg-subtle whitespace-pre-wrap font-mono leading-snug max-h-32 overflow-y-auto\">\n {value}\n </pre>\n );\n }\n return <p className=\"text-xs text-fg-subtle truncate\">{value}</p>;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return <p className=\"text-xs text-fg-subtle font-mono\">{String(value)}</p>;\n }\n\n // ── Array ───────────────────────────────────────────────────────────\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return <p className=\"text-xs text-fg-faint italic\">empty list</p>;\n }\n const preview = value.slice(0, MAX_INLINE_FIELDS).map((v) => formatLeaf(v));\n return (\n <ExpandableBlock\n expanded={expanded}\n onToggle={() => setExpanded((e) => !e)}\n summary={\n <span className=\"text-xs text-fg-subtle truncate\">\n <span className=\"text-fg-faint\">[{value.length}]</span>{\" \"}\n {preview.join(\", \")}\n {value.length > MAX_INLINE_FIELDS && (\n <span className=\"text-fg-faint\"> · +{value.length - MAX_INLINE_FIELDS} more</span>\n )}\n </span>\n }\n full={value}\n />\n );\n }\n\n // ── Object ──────────────────────────────────────────────────────────\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) {\n return <p className=\"text-xs text-fg-faint italic\">empty object</p>;\n }\n const head = entries.slice(0, MAX_INLINE_FIELDS);\n const extra = entries.length - head.length;\n return (\n <ExpandableBlock\n expanded={expanded}\n onToggle={() => setExpanded((e) => !e)}\n summary={\n <div className=\"flex flex-wrap gap-x-2 gap-y-0.5 text-xs\">\n {head.map(([k, v]) => (\n <span key={k} className=\"text-fg-subtle truncate max-w-full\">\n <span className=\"text-fg-faint\">{k}:</span>{\" \"}\n <span className=\"font-mono\">{formatLeaf(v, k)}</span>\n </span>\n ))}\n {extra > 0 && (\n <span className=\"text-fg-faint\">+{extra} more</span>\n )}\n </div>\n }\n full={value}\n />\n );\n }\n\n // Fallback — shouldn't happen for JSON-decoded input, but keep the\n // component total so callers never have to special-case undefined.\n return <p className=\"text-xs text-fg-subtle truncate\">{String(value)}</p>;\n}\n\nfunction ExpandableBlock({\n expanded,\n onToggle,\n summary,\n full,\n}: {\n expanded: boolean;\n onToggle: () => void;\n summary: React.ReactNode;\n full: unknown;\n}) {\n return (\n <div>\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={expanded}\n className=\"w-full text-left flex items-start gap-1 group/expand\"\n title={expanded ? \"Collapse\" : \"Show full value\"}\n >\n <ChevronRight\n size={11}\n className={`mt-0.5 shrink-0 text-fg-faint transition-transform ${expanded ? \"rotate-90\" : \"\"}`}\n />\n <span className=\"flex-1 min-w-0\">{summary}</span>\n </button>\n {expanded && (\n <pre className=\"mt-1 ml-3.5 text-[11px] text-fg-subtle whitespace-pre-wrap font-mono leading-snug bg-surface-3/60 border border-border rounded p-2 max-h-64 overflow-y-auto\">\n {JSON.stringify(full, maskedReplacer(), 2)}\n </pre>\n )}\n </div>\n );\n}\n","import React from \"react\";\n\ntype SelectSize = \"sm\" | \"md\";\n\nconst SIZE_CLASSES: Record<SelectSize, string> = {\n sm: \"text-xs px-2 py-1\",\n md: \"text-sm px-2 py-1.5\",\n};\n\nconst BASE_CLASSES =\n \"rounded border border-border bg-surface-3 text-fg \" +\n \"focus:outline-none focus:ring-1 focus:ring-accent \" +\n \"disabled:opacity-50 disabled:cursor-not-allowed \" +\n // Force a contrast-safe palette for the OS-rendered <option> menu\n // (Firefox + some Chromium themes inherit the page bg, which lands on\n // surface-2 cards and reads as low-contrast).\n \"[&>option]:bg-surface-3 [&>option]:text-fg\";\n\nexport type SelectProps = Omit<React.SelectHTMLAttributes<HTMLSelectElement>, \"size\"> & {\n size?: SelectSize;\n full?: boolean;\n};\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n function Select({ size = \"md\", full = true, className = \"\", children, ...rest }, ref) {\n return (\n <select\n ref={ref}\n className={`${full ? \"w-full \" : \"\"}${BASE_CLASSES} ${SIZE_CLASSES[size]} ${className}`.trim()}\n {...rest}\n >\n {children}\n </select>\n );\n },\n);\n","\"use client\";\nimport { Pencil, Plus, Search, Trash2 } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { MemoryItem } from \"@/api/types\";\nimport { useMemory } from \"@/hooks/useMemory\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { MemoryEditor } from \"./MemoryEditor\";\nimport { MemoryValuePreview } from \"./MemoryValuePreview\";\nimport { Select } from \"@/components/ui/Select\";\n\nfunction useDebounce<T>(value: T, ms: number): T {\n const [d, setD] = useState(value);\n useEffect(() => { const id = setTimeout(() => setD(value), ms); return () => clearTimeout(id); }, [value, ms]);\n return d;\n}\n\nexport function MemoryPanel() {\n const [nsFilter, setNsFilter] = useState(\"\");\n const [searchInput, setSearchInput] = useState(\"\");\n const search = useDebounce(searchInput, 300);\n const { items, loading, create, update, remove, refresh } = useMemory(nsFilter || undefined, search || undefined);\n const [editing, setEditing] = useState<MemoryItem | null | \"new\">(null);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"memory\", \"memory\", containerRef);\n\n const handleSave = useCallback(async (namespace: string, key: string, value: unknown) => {\n if (editing === \"new\") await create(namespace, key, value);\n else if (editing) await update(namespace, key, value);\n }, [editing, create, update]);\n\n const namespaces = [...new Set(items.map((i) => i.namespace))].sort();\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Memory Store</h2>\n <button onClick={() => setEditing(\"new\")} className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\">\n <Plus size={14} /> New\n </button>\n </div>\n <div className=\"px-4 py-2 space-y-2 border-b border-border\">\n <div className=\"flex gap-2\">\n <div className=\"relative flex-1\">\n <Search size={13} className=\"absolute left-2 top-1/2 -translate-y-1/2 text-fg-faint pointer-events-none\" />\n <input className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 pl-7 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n placeholder=\"Search…\" value={searchInput} onChange={(e) => setSearchInput(e.target.value)} />\n </div>\n <Select full={false} value={nsFilter} onChange={(e) => setNsFilter(e.target.value)}>\n <option value=\"\">All namespaces</option>\n {namespaces.map((ns) => <option key={ns} value={ns}>{ns}</option>)}\n </Select>\n </div>\n </div>\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-2\">\n {loading && items.length === 0 && <p className=\"text-fg-faint text-sm text-center py-8\">Loading…</p>}\n {!loading && items.length === 0 && <p className=\"text-fg-faint text-sm text-center py-8\">No memory items yet</p>}\n {items.map((item) => (\n <div key={`${item.namespace}/${item.key}`} data-deep-link-id={`${item.namespace}/${item.key}`} className=\"flex items-start gap-2 py-2.5 border-b border-border/60 group\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5 mb-1\">\n <span className=\"text-[10px] uppercase tracking-wide text-fg-faint\">{item.namespace}</span>\n <span className=\"text-fg-faint\">/</span>\n <span className=\"text-xs font-medium text-fg truncate\">{item.key}</span>\n </div>\n <MemoryValuePreview value={item.value} />\n </div>\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n <button onClick={() => setEditing(item)} className=\"p-1 text-fg-subtle hover:text-fg transition-colors\" title=\"Edit\"><Pencil size={13} /></button>\n <button onClick={() => remove(item.namespace, item.key)} className=\"p-1 text-fg-subtle hover:text-red-700 dark:hover:text-red-400 transition-colors\" title=\"Delete\"><Trash2 size={13} /></button>\n </div>\n </div>\n ))}\n </div>\n {editing !== null && (\n <MemoryEditor item={editing === \"new\" ? undefined : editing} onSave={handleSave} onClose={() => { setEditing(null); refresh(); }} />\n )}\n </div>\n );\n}\n","\"use client\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { ModelConfig, ModelConfigIn, TaskAssignment, ToolPolicy } from \"@/api/types\";\n\nexport function useModels() {\n const [models, setModels] = useState<ModelConfig[]>([]);\n const [assignments, setAssignments] = useState<TaskAssignment[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [m, a] = await Promise.all([api.models.list(), api.tasks.list()]);\n setModels(m);\n setAssignments(a);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const create = useCallback(async (name: string, data: ModelConfigIn) => {\n const m = await api.models.create(name, data);\n setModels((p) => [...p, m]);\n return m;\n }, []);\n\n const update = useCallback(async (name: string, data: ModelConfigIn) => {\n const m = await api.models.update(name, data);\n setModels((p) => p.map((x) => (x.name === name ? m : x)));\n return m;\n }, []);\n\n const remove = useCallback(async (name: string): Promise<void> => {\n await api.models.delete(name);\n setModels((p) => p.filter((x) => x.name !== name));\n setAssignments((p) => p.filter((x) => x.model_config_name !== name));\n }, []);\n\n const assign = useCallback(async (agent_id: string, model_config_name: string, tool_policy?: ToolPolicy) => {\n const a = await api.tasks.assign(agent_id, model_config_name, tool_policy);\n setAssignments((p) => {\n const exists = p.find((x) => x.agent_id === agent_id);\n return exists ? p.map((x) => (x.agent_id === agent_id ? a : x)) : [...p, a];\n });\n return a;\n }, []);\n\n const unassign = useCallback(async (agent_id: string) => {\n await api.tasks.unassign(agent_id);\n setAssignments((p) => p.filter((x) => x.agent_id !== agent_id));\n }, []);\n\n return { models, assignments, loading, refresh, create, update, remove, assign, unassign };\n}\n","// Maps a built-in provider name (anthropic, openai, gemini, …) to its\n// matching integration credential name in the INTEGRATIONS manifest.\n// Pure data — safe to import from both client and server code.\n//\n// Most providers use their own name as the integration name. Gemini is\n// the exception: its credential lives under \"google\" because the same\n// API key powers both Gemini chat models and the Imagen generate_image\n// tool.\n\nexport const PROVIDER_TO_INTEGRATION: Record<string, string> = {\n anthropic: \"anthropic\",\n openai: \"openai\",\n gemini: \"google\",\n deepseek: \"deepseek\",\n cohere: \"cohere\",\n \"github-copilot\": \"github-copilot\",\n};\n\nexport function integrationNameForProvider(provider: string): string {\n return PROVIDER_TO_INTEGRATION[provider] ?? provider;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { CatalogModel, Credential, IntegrationStatus, ModelConfig } from \"@/api/types\";\nimport { integrationNameForProvider } from \"@/lib/providers/provider-integration-map\";\nimport type { ProbeResult, ShrinkPending } from \"./useModelEditorForm\";\n\nconst FALLBACK_PROVIDERS = [\"anthropic\", \"openai\", \"github-copilot\", \"deepseek\", \"gemini\", \"langchain\"];\n\nexport function useIdentityState(model: ModelConfig | undefined) {\n const isEdit = !!model;\n const [name, setName] = useState(model?.name ?? \"\");\n const [nameTouched, setNameTouched] = useState(isEdit);\n const [provider, setProvider] = useState(model?.provider ?? \"anthropic\");\n const [providers, setProviders] = useState<string[]>(FALLBACK_PROVIDERS);\n const [modelId, setModelId] = useState(model?.model_id ?? \"\");\n useProviderList(setProviders);\n return { isEdit, model, name, setName, nameTouched, setNameTouched, provider, setProvider, providers, modelId, setModelId };\n}\n\nexport function useCredentialState(\n model: ModelConfig | undefined, provider: string, isEdit: boolean,\n) {\n const [credentialId, setCredentialId] = useState<string | null>(model?.credential_id ?? null);\n const [credentials, setCredentials] = useState<Credential[]>([]);\n const [credentialDialogOpen, setCredentialDialogOpen] = useState(false);\n const refreshCredentials = useCredentialList(setCredentials);\n const integrationName = integrationNameForProvider(provider);\n const providerCredentials = useMemo(\n () => credentials.filter((c) => c.provider === integrationName),\n [credentials, integrationName],\n );\n // Default to first matching credential on new configs; drop binding when\n // provider switch invalidates the current pick.\n useEffect(() => {\n if (isEdit || credentialId || providerCredentials.length === 0) return;\n setCredentialId(providerCredentials[0].id);\n }, [isEdit, credentialId, providerCredentials]);\n useEffect(() => {\n if (!credentialId) return;\n const stillValid = credentials.some((c) => c.id === credentialId && c.provider === integrationName);\n if (!stillValid) setCredentialId(null);\n }, [integrationName, credentialId, credentials]);\n return {\n credentialId, setCredentialId, credentials, setCredentials,\n credentialDialogOpen, setCredentialDialogOpen,\n integrationName, providerCredentials, refreshCredentials,\n };\n}\n\nexport function useParamsState(model: ModelConfig | undefined) {\n const [apiKey, setApiKey] = useState(model?.params.api_key === \"***\" ? \"\" : (model?.params.api_key ?? \"\"));\n const [baseUrl, setBaseUrl] = useState(model?.params.base_url ?? \"\");\n const [extraHeaders, setExtraHeaders] = useState(\n model?.params.extra_headers ? JSON.stringify(model.params.extra_headers, null, 2) : \"\",\n );\n const [temperature, setTemperature] = useState(String(model?.params.temperature ?? \"\"));\n const [maxTokens, setMaxTokens] = useState(String(model?.params.max_tokens ?? \"\"));\n const [contextWindowTokens, setContextWindowTokens] = useState(String(model?.params.context_window_tokens ?? \"\"));\n const [autoMaxTokens, setAutoMaxTokens] = useState<string | null>(null);\n const [autoContextWindowTokens, setAutoContextWindowTokens] = useState<string | null>(null);\n const [isDefault, setIsDefault] = useState(model?.is_default ?? false);\n return {\n apiKey, setApiKey, baseUrl, setBaseUrl, extraHeaders, setExtraHeaders,\n temperature, setTemperature, maxTokens, setMaxTokens,\n contextWindowTokens, setContextWindowTokens,\n autoMaxTokens, setAutoMaxTokens, autoContextWindowTokens, setAutoContextWindowTokens,\n isDefault, setIsDefault,\n };\n}\n\nexport function useStatusState() {\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const [probing, setProbing] = useState(false);\n const [probeResult, setProbeResult] = useState<ProbeResult>(null);\n const [allowSaveAnyway, setAllowSaveAnyway] = useState(false);\n const [compacting, setCompacting] = useState(false);\n const [pendingShrinkConfirm, setPendingShrinkConfirm] = useState<ShrinkPending>(null);\n return {\n error, setError, saving, setSaving, probing, setProbing,\n probeResult, setProbeResult, allowSaveAnyway, setAllowSaveAnyway,\n compacting, setCompacting, pendingShrinkConfirm, setPendingShrinkConfirm,\n };\n}\n\nexport function useCatalogState(provider: string) {\n const [showCatalog, setShowCatalog] = useState(false);\n const [catalog, setCatalog] = useState<CatalogModel[] | null>(null);\n const [catalogLoading, setCatalogLoading] = useState(false);\n const [catalogError, setCatalogError] = useState<string | null>(null);\n const [catalogSearch, setCatalogSearch] = useState(\"\");\n // Reset catalog when provider changes — different provider = different list.\n useEffect(() => { setCatalog(null); setCatalogError(null); setShowCatalog(false); }, [provider]);\n return {\n showCatalog, setShowCatalog, catalog, setCatalog,\n catalogLoading, setCatalogLoading, catalogError, setCatalogError,\n catalogSearch, setCatalogSearch,\n };\n}\n\nexport function useIntegrationsState() {\n const [integrations, setIntegrations] = useState<IntegrationStatus[]>([]);\n useIntegrationList(setIntegrations);\n return { integrations };\n}\n\nfunction useProviderList(setProviders: (v: string[]) => void) {\n useEffect(() => {\n let mounted = true;\n api.models.providers()\n .then((names) => {\n if (!mounted || !Array.isArray(names) || names.length === 0) return;\n setProviders(names);\n })\n .catch(() => { /* Keep fallback provider list if endpoint fails. */ });\n return () => { mounted = false; };\n }, [setProviders]);\n}\n\nfunction useIntegrationList(setIntegrations: (v: IntegrationStatus[]) => void) {\n useEffect(() => {\n let mounted = true;\n api.integrations.list()\n .then((res) => { if (mounted) setIntegrations(res.statuses); })\n .catch(() => { if (mounted) setIntegrations([]); });\n return () => { mounted = false; };\n }, [setIntegrations]);\n}\n\nfunction useCredentialList(setCredentials: (v: Credential[]) => void) {\n const refresh = async () => {\n try { setCredentials(await api.credentials.list({ type: \"integration\" })); }\n catch { setCredentials([]); }\n };\n useEffect(() => {\n refresh();\n const onChange = () => { refresh(); };\n if (typeof window !== \"undefined\") window.addEventListener(\"jarela:credentials-changed\", onChange);\n return () => {\n if (typeof window !== \"undefined\") window.removeEventListener(\"jarela:credentials-changed\", onChange);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return refresh;\n}\n","import type { ModelConfig } from \"@/api/types\";\nimport {\n useCatalogState, useCredentialState, useIdentityState,\n useIntegrationsState, useParamsState, useStatusState,\n} from \"./form-state\";\n\nexport type ShrinkPending =\n | null\n | {\n oldSnapshot: { provider: string; model_id: string; params: Record<string, unknown> };\n payloadName: string;\n payload: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">;\n };\n\nexport type ProbeResult = { ok: boolean; error?: string } | null;\n\nexport type ModelEditorForm = ReturnType<typeof useModelEditorForm>;\n\nexport function useModelEditorForm(model: ModelConfig | undefined) {\n const id = useIdentityState(model);\n const cred = useCredentialState(model, id.provider, id.isEdit);\n const params = useParamsState(model);\n const status = useStatusState();\n const catalog = useCatalogState(id.provider);\n const integ = useIntegrationsState();\n return { ...id, ...cred, ...params, ...status, ...catalog, ...integ };\n}\n","import type { ModelConfig } from \"@/api/types\";\n\n// Pure helper that turns the model editor's raw form fields (all strings,\n// as React state) into the validated payload that ModelsPanel hands off\n// to `api.models.create` / `api.models.update`. Lifted out of the\n// component so it can be unit-tested without spinning up a React/jsdom\n// environment.\n\nexport interface ModelEditorFormInput {\n name: string;\n provider: string;\n model_id: string;\n api_key: string;\n base_url: string;\n extra_headers: string; // JSON text or empty\n temperature: string; // numeric text or empty\n max_tokens: string; // numeric text or empty\n context_window_tokens: string; // numeric text or empty\n is_default: boolean;\n // Reference to a row in the typed credentials store. The credential\n // carries api_key / base_url / extra_headers; inline values on the\n // model (above) act as per-model overrides only and are typically\n // empty when a credential is bound.\n credential_id?: string | null;\n}\n\nexport type ModelEditorPayload = Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">;\n\nexport type BuildResult =\n | { ok: true; name: string; payload: ModelEditorPayload }\n | { ok: false; error: string };\n\nfunction toNumberOrUndefined(s: string): number | undefined {\n const t = s.trim();\n if (!t) return undefined;\n const n = Number(t);\n return Number.isFinite(n) ? n : undefined;\n}\n\nexport function buildModelEditorPayload(input: ModelEditorFormInput): BuildResult {\n const name = input.name.trim();\n const model_id = input.model_id.trim();\n if (!name || !model_id) return { ok: false, error: \"Name and model ID are required\" };\n\n let parsed_headers: Record<string, string> | undefined;\n if (input.extra_headers.trim()) {\n try {\n const parsed = JSON.parse(input.extra_headers);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return { ok: false, error: \"Extra headers must be a JSON object\" };\n }\n parsed_headers = parsed as Record<string, string>;\n } catch {\n return { ok: false, error: \"Extra headers must be valid JSON\" };\n }\n }\n\n const params: ModelConfig[\"params\"] = {};\n if (input.api_key) params.api_key = input.api_key;\n if (input.base_url) params.base_url = input.base_url;\n if (parsed_headers) params.extra_headers = parsed_headers;\n\n const temp = toNumberOrUndefined(input.temperature);\n if (temp !== undefined) params.temperature = temp;\n\n const maxT = toNumberOrUndefined(input.max_tokens);\n if (maxT !== undefined) params.max_tokens = maxT;\n\n const win = toNumberOrUndefined(input.context_window_tokens);\n if (win !== undefined && win > 0) params.context_window_tokens = Math.floor(win);\n\n return {\n ok: true,\n name,\n payload: {\n provider: input.provider,\n model_id,\n params,\n is_default: input.is_default,\n credential_id: input.credential_id ?? null,\n },\n };\n}\n","import { api } from \"@/api/client\";\nimport type { ModelConfig } from \"@/api/types\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport { buildModelEditorPayload } from \"@/lib/models/editor-payload\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function collectInlineOverrides(form: ModelEditorForm): Record<string, unknown> | undefined {\n const overrides: Record<string, unknown> = {};\n if (form.apiKey.trim()) overrides.api_key = form.apiKey.trim();\n if (form.baseUrl.trim()) overrides.base_url = form.baseUrl.trim();\n if (form.extraHeaders.trim()) {\n try { overrides.extra_headers = JSON.parse(form.extraHeaders); }\n catch { /* invalid JSON — ignore */ }\n }\n return Object.keys(overrides).length > 0 ? overrides : undefined;\n}\n\nexport function buildPayload(form: ModelEditorForm) {\n return buildModelEditorPayload({\n name: form.name,\n provider: form.provider,\n model_id: form.modelId,\n api_key: form.apiKey,\n base_url: form.baseUrl,\n extra_headers: form.extraHeaders,\n temperature: form.temperature,\n max_tokens: form.maxTokens,\n context_window_tokens: form.contextWindowTokens,\n is_default: form.isDefault,\n credential_id: form.credentialId,\n });\n}\n\nexport async function runProbeStep(\n form: ModelEditorForm,\n payload: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">,\n): Promise<boolean> {\n const probe = await api.models\n .probe(form.provider, payload.model_id, payload.params as Record<string, unknown>, undefined, form.credentialId ?? undefined)\n .catch((e) => ({ ok: false, error: String(e instanceof Error ? e.message : e) }));\n form.setProbeResult(probe);\n if (!probe.ok) {\n form.setError(`Model probe failed: ${probe.error || \"unknown error\"}. Use \"Save anyway\" if this is intentional.`);\n form.setAllowSaveAnyway(true);\n form.setSaving(false);\n return false;\n }\n return true;\n}\n\nexport function shouldStageShrinkConfirm(\n form: ModelEditorForm,\n result: { name: string; payload: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\"> },\n): boolean {\n if (!form.model) return false;\n const oldCtx = Number(form.model.params.context_window_tokens) || 0;\n const newCtx = Number(result.payload.params.context_window_tokens) || 0;\n const ctxShrunk = oldCtx > 0 && newCtx > 0 && newCtx < oldCtx;\n const modelIdChanged = form.model.model_id !== result.payload.model_id;\n if (!ctxShrunk && !modelIdChanged) return false;\n form.setPendingShrinkConfirm({\n oldSnapshot: {\n provider: form.model.provider,\n model_id: form.model.model_id,\n params: form.model.params as Record<string, unknown>,\n },\n payloadName: result.name,\n payload: result.payload,\n });\n form.setSaving(false);\n return true;\n}\n\nexport function toastSaveFail(e: unknown, form: ModelEditorForm, name: string, modelIdResolved: string) {\n pushErrorToast({\n title: \"Couldn't save model\",\n error: e,\n context: { panel: \"models\", action: \"model.save\", name, provider: form.provider, model_id: modelIdResolved },\n });\n}\n","import { api } from \"@/api/client\";\nimport type { ModelConfig } from \"@/api/types\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\nimport {\n buildPayload,\n collectInlineOverrides,\n runProbeStep,\n shouldStageShrinkConfirm,\n toastSaveFail,\n} from \"./save-helpers\";\n\ninterface Args {\n form: ModelEditorForm;\n onSave: (name: string, data: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">) => Promise<void>;\n onClose: () => void;\n}\n\nexport function useModelSaveHandlers({ form, onSave, onClose }: Args) {\n const loadCatalog = () => loadCatalogAction(form);\n const handleTestConnection = () => testConnectionAction(form);\n const handleSave = () => saveAction(form, onSave, onClose);\n const confirmShrinkAndSave = () => confirmShrinkAction(form, onSave, onClose);\n const skipCompactAndSave = () => skipCompactAction(form, onSave, onClose);\n return { loadCatalog, handleSave, handleTestConnection, confirmShrinkAndSave, skipCompactAndSave };\n}\n\nasync function loadCatalogAction(form: ModelEditorForm) {\n form.setCatalogLoading(true);\n form.setCatalogError(null);\n try {\n const models = await api.models.catalog(form.provider, collectInlineOverrides(form));\n form.setCatalog(models);\n form.setShowCatalog(true);\n } catch (e) {\n form.setCatalogError(String(e));\n pushErrorToast({\n title: \"Couldn't load model catalog\",\n error: e,\n context: { panel: \"models\", action: \"catalog.load\", provider: form.provider },\n });\n } finally {\n form.setCatalogLoading(false);\n }\n}\n\nasync function testConnectionAction(form: ModelEditorForm) {\n form.setProbeResult(null);\n if (!form.modelId.trim()) { form.setProbeResult({ ok: false, error: \"model_id required\" }); return; }\n form.setProbing(true);\n try {\n const res = await api.models.probe(\n form.provider, form.modelId.trim(), collectInlineOverrides(form),\n form.isEdit ? form.model?.name : undefined,\n form.credentialId ?? undefined,\n );\n form.setProbeResult(res);\n if (res.ok) form.setAllowSaveAnyway(false);\n } catch (e) {\n form.setProbeResult({ ok: false, error: String(e instanceof Error ? e.message : e) });\n } finally {\n form.setProbing(false);\n }\n}\n\nasync function saveAction(form: ModelEditorForm, onSave: Args[\"onSave\"], onClose: Args[\"onClose\"]) {\n form.setError(null);\n const result = buildPayload(form);\n if (!result.ok) { form.setError(result.error); return; }\n form.setSaving(true);\n try {\n if (!form.allowSaveAnyway && !(await runProbeStep(form, result.payload))) return;\n if (form.isEdit && form.model && shouldStageShrinkConfirm(form, result)) return;\n await onSave(result.name, result.payload);\n onClose();\n } catch (e) { toastSaveFail(e, form, result.name, result.payload.model_id); }\n finally { form.setSaving(false); }\n}\n\nasync function confirmShrinkAction(form: ModelEditorForm, onSave: Args[\"onSave\"], onClose: Args[\"onClose\"]) {\n if (!form.pendingShrinkConfirm) return;\n const { oldSnapshot, payloadName, payload } = form.pendingShrinkConfirm;\n form.setCompacting(true);\n try {\n await api.models.compactThreads(payloadName, oldSnapshot);\n await onSave(payloadName, payload);\n form.setPendingShrinkConfirm(null);\n onClose();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't compact threads before model swap\",\n error: e,\n context: { panel: \"models\", action: \"model.compact\", name: payloadName },\n });\n } finally { form.setCompacting(false); }\n}\n\nasync function skipCompactAction(form: ModelEditorForm, onSave: Args[\"onSave\"], onClose: Args[\"onClose\"]) {\n if (!form.pendingShrinkConfirm) return;\n const { payloadName, payload } = form.pendingShrinkConfirm;\n form.setSaving(true);\n try {\n await onSave(payloadName, payload);\n form.setPendingShrinkConfirm(null);\n onClose();\n } catch (e) { toastSaveFail(e, form, payloadName, payload.model_id); }\n finally { form.setSaving(false); }\n}\n","import { X } from \"lucide-react\";\nimport type React from \"react\";\n\ninterface Props {\n title: string;\n wide: boolean;\n onClose: () => void;\n expertToggle: React.ReactNode | null;\n children: React.ReactNode;\n footer: React.ReactNode;\n overlays?: React.ReactNode;\n}\n\nexport function EditorChrome({ title, wide, onClose, expertToggle, children, footer, overlays }: Props) {\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-start justify-center z-50 p-2 sm:p-4 overflow-y-auto\">\n <div className={`bg-surface-2 border border-border rounded-2xl w-full shadow-xl my-2 sm:my-4 ${wide ? \"max-w-2xl\" : \"max-w-xl\"}`}>\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h3 className=\"text-sm font-semibold text-fg\">{title}</h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\"><X size={16} /></button>\n </div>\n <div className=\"p-4 space-y-3.5\">\n {expertToggle}\n {children}\n </div>\n {footer}\n </div>\n {overlays}\n </div>\n );\n}\n\ninterface ExpertToggleProps {\n showExpert: boolean;\n onToggle: () => void;\n}\n\nexport function ExpertToggle({ showExpert, onToggle }: ExpertToggleProps) {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={showExpert}\n className=\"text-[11px] text-fg-faint hover:text-fg-muted transition-colors inline-flex items-center gap-1\"\n >\n {showExpert ? \"Hide advanced fields\" : \"Show advanced fields (context tuning, base URL, headers)\"}\n </button>\n );\n}\n","import { CheckCircle2, Loader2, XCircle } from \"lucide-react\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function ProbeBanner({ result }: { result: ModelEditorForm[\"probeResult\"] }) {\n if (!result) return null;\n const ok = result.ok;\n return (\n <div className={`text-xs flex items-start gap-1.5 px-2 py-1.5 rounded border ${\n ok\n ? \"bg-green-50 dark:bg-green-900/20 border-green-300 dark:border-green-800 text-green-700 dark:text-green-300\"\n : \"bg-red-50 dark:bg-red-900/20 border-red-300 dark:border-red-800 text-red-700 dark:text-red-300\"\n }`}>\n {ok ? <CheckCircle2 size={13} className=\"shrink-0 mt-0.5\" /> : <XCircle size={13} className=\"shrink-0 mt-0.5\" />}\n <span className=\"min-w-0 break-words\">\n {ok ? \"Connection OK — the model responded to a probe.\" : `Probe failed: ${result.error || \"unknown error\"}`}\n </span>\n </div>\n );\n}\n\ninterface FooterProps {\n form: ModelEditorForm;\n onTest: () => void;\n onSave: () => void;\n onClose: () => void;\n}\n\nexport function EditorFooter({ form, onTest, onSave, onClose }: FooterProps) {\n return (\n <div className=\"flex flex-wrap justify-end gap-2 px-4 pb-4 pt-1 border-t border-border/60\">\n <button\n onClick={onTest}\n disabled={form.probing || !form.modelId.trim()}\n className=\"px-3 py-1.5 text-sm text-fg-muted hover:text-fg transition-colors inline-flex items-center gap-1.5 disabled:opacity-40\"\n >\n {form.probing && <Loader2 size={13} className=\"animate-spin\" />}\n {form.probing ? \"Testing…\" : \"Test connection\"}\n </button>\n <div className=\"flex-1\" />\n <button onClick={onClose} className=\"px-3 py-1.5 text-sm text-fg-subtle hover:text-fg transition-colors\">Cancel</button>\n <button\n onClick={onSave}\n disabled={form.saving}\n className=\"px-4 py-1.5 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-xl shadow-sm transition-colors disabled:opacity-50\"\n >\n {form.saving ? \"Saving…\" : form.allowSaveAnyway ? \"Save anyway\" : \"Save\"}\n </button>\n </div>\n );\n}\n","\"use client\";\nimport { CheckCircle2, ExternalLink, Link as LinkIcon, Loader2, Terminal, Trash2, XCircle } from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { IntegrationDefinition, IntegrationStatus } from \"@/api/types\";\n\nconst SECRET_MASK = \"********\";\n\n// Per-integration editor with inline OAuth Connect, Save, Test, Clear, and\n// (for Gmail/Outlook) a collapsible setup guide. Extracted from the old\n// `components/integrations/IntegrationsPanel.tsx` so the unified credentials\n// panel can render one card per known integration — keeping OAuth and key\n// editing in the same surface that handles model API keys.\n\nexport function IntegrationCard({\n definition: def,\n status,\n onChanged,\n}: {\n definition: IntegrationDefinition;\n status?: IntegrationStatus;\n onChanged: () => void;\n}) {\n // Form values are seeded from status (with secrets masked) so the user sees\n // their saved config and can edit only what they want.\n const [values, setValues] = useState<Record<string, string>>(() => ({ ...(status?.values ?? {}) }));\n const [saving, setSaving] = useState(false);\n const [testing, setTesting] = useState(false);\n const [testResult, setTestResult] = useState<{ ok: boolean; message: string } | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [connecting, setConnecting] = useState(false);\n const popupRef = useRef<Window | null>(null);\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Stop any in-flight OAuth polling on unmount.\n useEffect(() => () => { if (pollRef.current) clearInterval(pollRef.current); }, []);\n\n async function connectOAuth(provider: \"gmail\" | \"outlook\") {\n setError(null);\n setTestResult(null);\n const clientId = values.client_id?.trim();\n const clientSecret = values.client_secret?.trim();\n // Allow empty when the user has already saved creds (backend falls back).\n if (!status?.configured && (!clientId || !clientSecret)) {\n setError(\"Enter the OAuth client ID and client secret first.\");\n return;\n }\n setConnecting(true);\n try {\n const startFn = provider === \"gmail\"\n ? api.integrations.gmailOauthStart\n : api.integrations.outlookOauthStart;\n const statusFn = provider === \"gmail\"\n ? api.integrations.gmailOauthStatus\n : api.integrations.outlookOauthStatus;\n const label = provider === \"gmail\" ? \"Gmail\" : \"Outlook\";\n\n const r = await startFn({ client_id: clientId, client_secret: clientSecret });\n popupRef.current = window.open(r.authorize_url, `jarela-${provider}-oauth`, \"width=560,height=720\");\n if (!popupRef.current) {\n setError(\"Browser blocked the OAuth popup. Allow popups for this site and retry.\");\n setConnecting(false);\n return;\n }\n const startedAt = Date.now();\n if (pollRef.current) clearInterval(pollRef.current);\n pollRef.current = setInterval(async () => {\n if (Date.now() - startedAt > 10 * 60_000) {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(false);\n setError(\"Timed out waiting for authorization.\");\n return;\n }\n try {\n const s = await statusFn(r.state);\n if (s.status === \"done\") {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(false);\n setTestResult({ ok: true, message: `Connected to ${label}. Refresh token saved.` });\n try { popupRef.current?.close(); } catch { /* ignore */ }\n onChanged();\n } else if (s.status === \"error\") {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(false);\n setError(s.error ?? \"Authorization failed.\");\n } else if (s.status === \"unknown\") {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(false);\n setError(\"Authorization session expired.\");\n }\n } catch (e) {\n if (pollRef.current) clearInterval(pollRef.current);\n setConnecting(false);\n setError(e instanceof Error ? e.message : String(e));\n }\n }, 1500);\n } catch (e) {\n setConnecting(false);\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n // Re-seed when the status changes (e.g. after save returns updated mask).\n useEffect(() => {\n setValues({ ...(status?.values ?? {}) });\n // status?.values intentionally omitted — only re-seed on a real save\n // (signalled by updated_at). Including .values would clobber user edits.\n }, [status?.updated_at]); // eslint-disable-line react-hooks/exhaustive-deps\n\n async function save() {\n setError(null);\n setSaving(true);\n try {\n const result = await api.integrations.save(def.name, values);\n setTestResult(null);\n setValues({ ...result.values });\n onChanged();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setSaving(false);\n }\n }\n\n async function test() {\n setTesting(true);\n setTestResult(null);\n try {\n const r = await api.integrations.test(def.name);\n if (r.ok) {\n const detail = r.detail as { displayName?: string; email?: string } | undefined;\n setTestResult({\n ok: true,\n message: detail?.displayName ? `Connected as ${detail.displayName}` : \"Connection ok\",\n });\n } else {\n setTestResult({ ok: false, message: r.error ?? \"Test failed\" });\n }\n } catch (e) {\n setTestResult({ ok: false, message: e instanceof Error ? e.message : String(e) });\n } finally {\n setTesting(false);\n }\n }\n\n async function clear() {\n if (!confirm(`Remove saved credentials for ${def.label}?`)) return;\n await api.integrations.delete(def.name);\n setValues({});\n setTestResult(null);\n onChanged();\n }\n\n const configured = status?.configured;\n\n return (\n <div data-deep-link-id={def.name} className=\"mb-3 rounded-lg border border-border bg-surface-2 overflow-hidden\">\n <div className=\"px-3 py-2.5 border-b border-border/60 flex items-start gap-2\">\n <div className={`w-1.5 h-1.5 rounded-full mt-1.5 ${configured ? \"bg-emerald-500\" : \"bg-fg-faint\"}`} />\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-medium text-fg\">{def.label}</h3>\n <p className=\"text-[11px] text-fg-faint mt-0.5 leading-snug\">{def.description}</p>\n </div>\n </div>\n\n <div className=\"px-3 py-3 space-y-2\">\n {def.name === \"gmail\" && <GmailSetupGuide />}\n {def.name === \"outlook\" && <OutlookSetupGuide />}\n {def.fields.map((f) => {\n const fieldSource = status?.source?.[f.key];\n return (\n <label key={f.key} className=\"block text-xs text-fg-subtle\">\n <span className=\"flex items-center gap-1.5\">\n {f.label}{f.required && <span className=\"text-rose-700 dark:text-rose-400 ml-0.5\">*</span>}\n {fieldSource === \"rc\" && (\n <span\n title=\"Value pulled from your shell rc / Windows User env. Editing here will switch this field to manual mode.\"\n className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[9px] font-medium uppercase tracking-wide bg-sky-500/10 text-sky-700 dark:text-sky-300 border border-sky-500/30\"\n >\n <Terminal size={9} /> from shell\n </span>\n )}\n </span>\n <input\n type={f.secret ? \"password\" : \"text\"}\n value={values[f.key] ?? \"\"}\n onChange={(e) => setValues((p) => ({ ...p, [f.key]: e.target.value }))}\n onFocus={(e) => {\n // Clicking a masked secret field clears it so the user can type a new value\n // without manually selecting and replacing the dots.\n if (f.secret && e.target.value === SECRET_MASK) {\n setValues((p) => ({ ...p, [f.key]: \"\" }));\n }\n }}\n placeholder={f.placeholder}\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n );\n })}\n\n {error && (\n <div className=\"px-2 py-1.5 rounded bg-rose-950/40 border border-rose-800 text-xs text-rose-700 dark:text-rose-300\">\n {error}\n </div>\n )}\n {testResult && (\n <div className={`px-2 py-1.5 rounded border text-xs flex items-center gap-1.5 ${\n testResult.ok\n ? \"bg-emerald-950/30 border-emerald-800 text-emerald-700 dark:text-emerald-300\"\n : \"bg-rose-950/30 border-rose-800 text-rose-700 dark:text-rose-300\"\n }`}>\n {testResult.ok ? <CheckCircle2 size={12} /> : <XCircle size={12} />}\n <span className=\"truncate\">{testResult.message}</span>\n </div>\n )}\n\n <div className=\"flex items-center gap-2 pt-1\">\n <button\n onClick={save}\n disabled={saving}\n className=\"px-3 py-1.5 text-xs rounded bg-accent text-white hover:bg-accent-hover disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n <button\n onClick={test}\n disabled={testing || !configured}\n title={!configured ? \"Save credentials first\" : \"Test the connection\"}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-xs rounded border border-border text-fg-muted hover:bg-surface-3 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {testing ? <Loader2 size={11} className=\"animate-spin\" /> : <ExternalLink size={11} />}\n Test\n </button>\n {def.name === \"gmail\" && (\n <button\n onClick={() => connectOAuth(\"gmail\")}\n disabled={connecting}\n title=\"Authorize Gmail + Calendar via Google OAuth — opens a browser window\"\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-xs rounded border border-border text-fg-muted hover:bg-surface-3 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {connecting ? <Loader2 size={11} className=\"animate-spin\" /> : <LinkIcon size={11} />}\n {connecting ? \"Waiting…\" : \"Connect Gmail\"}\n </button>\n )}\n {def.name === \"outlook\" && (\n <button\n onClick={() => connectOAuth(\"outlook\")}\n disabled={connecting}\n title=\"Authorize Outlook + Calendar via Microsoft OAuth — opens a browser window\"\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-xs rounded border border-border text-fg-muted hover:bg-surface-3 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {connecting ? <Loader2 size={11} className=\"animate-spin\" /> : <LinkIcon size={11} />}\n {connecting ? \"Waiting…\" : \"Connect Outlook\"}\n </button>\n )}\n {configured && (\n <button\n onClick={clear}\n className=\"ml-auto inline-flex items-center gap-1 px-2 py-1.5 text-xs text-fg-faint hover:text-rose-700 dark:hover:text-rose-400\"\n title=\"Remove saved credentials\"\n >\n <Trash2 size={11} /> Clear\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// Inline walkthrough rendered inside the Gmail integration card. Google's GCP\n// console UI changes often; keep this in sync with reality and prefer linking\n// directly to the right page over screenshots.\nfunction GmailSetupGuide() {\n return (\n <details className=\"rounded border border-border/60 bg-surface-3/40 text-xs text-fg-muted\">\n <summary className=\"cursor-pointer select-none px-2.5 py-1.5 text-fg hover:bg-surface-3\">\n Setup guide (first-time only)\n </summary>\n <div className=\"px-3 py-2.5 space-y-3 border-t border-border/60 leading-relaxed\">\n <p className=\"text-amber-700 dark:text-amber-300/90 text-[11px] border border-amber-400/30 bg-amber-400/5 rounded px-2 py-1.5\">\n <strong>Upgrading from an earlier version?</strong> Click <strong>Connect Gmail</strong> again so\n Google can grant the new Calendar scope — otherwise calendar tools will fail with a 403.\n </p>\n <p className=\"text-fg-subtle\">\n You only need to do this once per Google account. The end result is a <code className=\"text-fg\">client_id</code>,\n {\" \"}<code className=\"text-fg\">client_secret</code> pair you paste below. Then click\n {\" \"}<strong className=\"text-fg\">Connect Gmail</strong> to authorize Gmail + Calendar access.\n </p>\n\n <Step n={1} title=\"Create or pick a Google Cloud project\">\n Open <Ext href=\"https://console.cloud.google.com/projectcreate\">console.cloud.google.com/projectcreate</Ext>{\" \"}\n and create a project (any name). If you already have one, just select it in the top bar.\n </Step>\n\n <Step n={2} title=\"Enable the Gmail and Calendar APIs\">\n Enable <Ext href=\"https://console.cloud.google.com/apis/library/gmail.googleapis.com\">Gmail API</Ext>{\" \"}\n <strong>and</strong> <Ext href=\"https://console.cloud.google.com/apis/library/calendar-json.googleapis.com\">Google Calendar API</Ext>.\n Click <strong>Enable</strong> on each and wait a few seconds for them to activate.\n </Step>\n\n <Step n={3} title=\"Configure the OAuth consent screen\">\n Go to <Ext href=\"https://console.cloud.google.com/auth/branding\">Auth Platform → Branding</Ext>.\n Set <strong>User type: External</strong>, fill in an app name and your email, save.\n Then in <Ext href=\"https://console.cloud.google.com/auth/scopes\">Data Access → Scopes</Ext>{\" \"}\n click <strong>Add or remove scopes</strong> and add all three:\n <ul className=\"list-disc ml-5 mt-1 text-fg-subtle\">\n <li><code className=\"text-fg\">.../auth/gmail.modify</code></li>\n <li><code className=\"text-fg\">.../auth/gmail.compose</code></li>\n <li><code className=\"text-fg\">.../auth/calendar.events</code></li>\n <li><code className=\"text-fg\">.../auth/calendar.readonly</code></li>\n </ul>\n Finally, in <Ext href=\"https://console.cloud.google.com/auth/audience\">Audience</Ext>{\" \"}\n add your own Gmail address as a <strong>Test user</strong>. (Leaving the app in Testing\n mode is fine — you don't need to publish or verify it for personal use.)\n </Step>\n\n <Step n={4} title=\"Create the OAuth client (Desktop type)\">\n Go to <Ext href=\"https://console.cloud.google.com/auth/clients\">Clients</Ext> →{\" \"}\n <strong>Create client</strong>.\n <ul className=\"list-disc ml-5 mt-1 text-fg-subtle\">\n <li><strong>Application type:</strong> <span className=\"text-fg\">Desktop app</span>{\" \"}\n (this matters — Web app types require pre-registering redirect URIs and will fail with\n <code className=\"text-fg\"> redirect_uri_mismatch</code>).</li>\n <li><strong>Name:</strong> anything, e.g. <code className=\"text-fg\">Jarela</code>.</li>\n </ul>\n After it's created, copy the <strong>Client ID</strong> and <strong>Client secret</strong>{\" \"}\n shown in the popup (or click the download icon to get the JSON — the values are under{\" \"}\n <code className=\"text-fg\">installed.client_id</code> /{\" \"}\n <code className=\"text-fg\">installed.client_secret</code>).\n </Step>\n\n <Step n={5} title=\"Paste and connect\">\n Paste them into the two fields below, click <strong>Save</strong>, then{\" \"}\n <strong>Connect Gmail</strong>. A Google consent window opens — approve it and the tab\n will close itself. Hit <strong>Test</strong> to confirm.\n </Step>\n\n <div className=\"mt-2 pt-2 border-t border-border/60 text-[11px] text-fg-faint\">\n <strong className=\"text-fg-subtle\">Troubleshooting:</strong>\n <ul className=\"list-disc ml-5 mt-1 space-y-0.5\">\n <li><code>redirect_uri_mismatch</code> → your client is a <em>Web</em> app. Create a fresh\n one as <em>Desktop app</em> instead, or add{\" \"}\n <code className=\"text-fg-muted\">http://localhost:4312/api/v1/integrations/gmail/oauth/callback</code>{\" \"}\n to its Authorized redirect URIs.</li>\n <li><code>access_denied</code> → your Gmail address isn't in the Test users list\n (step 3, last paragraph).</li>\n <li>"Google did not return a refresh_token" → you previously authorized this\n client. Revoke it at{\" \"}\n <Ext href=\"https://myaccount.google.com/permissions\">myaccount.google.com/permissions</Ext>{\" \"}\n and click Connect Gmail again.</li>\n <li>Token works for ~6 months of inactivity, then Google may revoke it. Just click\n Connect Gmail again to refresh.</li>\n </ul>\n </div>\n </div>\n </details>\n );\n}\n\nfunction Step({ n, title, children }: { n: number; title: string; children: React.ReactNode }) {\n return (\n <div className=\"flex gap-2\">\n <div className=\"flex-none w-5 h-5 rounded-full bg-surface-3 border border-border text-[10px] text-fg-muted flex items-center justify-center font-mono\">\n {n}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-fg font-medium\">{title}</div>\n <div className=\"text-fg-subtle mt-0.5\">{children}</div>\n </div>\n </div>\n );\n}\n\nfunction Ext({ href, children }: { href: string; children: React.ReactNode }) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sky-700 dark:text-sky-400 hover:text-sky-700 dark:hover:text-sky-300 underline decoration-dotted underline-offset-2\"\n >\n {children}\n </a>\n );\n}\n\n// Inline walkthrough for the Outlook integration card. The Azure portal UI\n// shifts less than GCP's but still drifts; keep instructions concrete and\n// link to the exact blade rather than describing breadcrumbs.\nfunction OutlookSetupGuide() {\n return (\n <details className=\"rounded border border-border/60 bg-surface-3/40 text-xs text-fg-muted\">\n <summary className=\"cursor-pointer select-none px-2.5 py-1.5 text-fg hover:bg-surface-3\">\n Setup guide (first-time only)\n </summary>\n <div className=\"px-3 py-2.5 space-y-3 border-t border-border/60 leading-relaxed\">\n <p className=\"text-fg-subtle\">\n You only need to do this once per Microsoft account. The end result is an{\" \"}\n <code className=\"text-fg\">Application (client) ID</code> +{\" \"}\n <code className=\"text-fg\">client secret value</code> pair you paste below. Then click{\" \"}\n <strong className=\"text-fg\">Connect Outlook</strong> to authorize Mail + Calendar access.\n Free — no Azure subscription required.\n </p>\n\n <Step n={1} title=\"Sign in to the Azure portal\">\n Open <Ext href=\"https://portal.azure.com\">portal.azure.com</Ext> with the Microsoft account\n whose Outlook data you want to access. If a banner asks you to start a free Azure\n subscription, <strong>skip it</strong> — app registrations live under the free\n identity tier.\n </Step>\n\n <Step n={2} title=\"Create the app registration\">\n Open <Ext href=\"https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\">Microsoft Entra → App registrations</Ext>\n {\" \"}(or the same blade in the <Ext href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\">Azure portal</Ext>),\n then click <strong>+ New registration</strong> in the toolbar.\n <ul className=\"list-disc ml-5 mt-1 text-fg-subtle\">\n <li><strong>Name:</strong> anything, e.g. <code className=\"text-fg\">Jarela</code>.</li>\n <li><strong>Supported account types:</strong>{\" \"}\n <span className=\"text-fg\">\n Accounts in any organizational directory (Any Microsoft Entra ID tenant -\n Multitenant) and personal Microsoft accounts\n </span>{\" \"}\n — this is the broadest option and works for both <code>@outlook.com</code> and\n work/school accounts.</li>\n <li><strong>Redirect URI:</strong> select <strong>Web</strong> and paste{\" \"}\n <code className=\"text-fg\">{typeof window !== \"undefined\" ? window.location.origin : \"http://localhost:4312\"}/api/v1/integrations/outlook/oauth/callback</code>.{\" \"}\n Microsoft will reject the auth flow with <code>redirect_uri_mismatch</code> if this\n doesn't match exactly.</li>\n </ul>\n Click <strong>Register</strong>. Copy the <strong>Application (client) ID</strong> from\n the overview page.\n </Step>\n\n <Step n={3} title=\"Create a client secret\">\n On the app's page, open <strong>Certificates & secrets</strong> →{\" \"}\n <strong>Client secrets</strong> → <strong>New client secret</strong>. Pick a\n description and expiration (24 months is reasonable). Click <strong>Add</strong>.\n {\" \"}<strong className=\"text-fg\">Immediately copy the "Value" column</strong>\n {\" \"}— it's only shown once. (The "Secret ID" column is NOT the secret;\n ignore it.)\n </Step>\n\n <Step n={4} title=\"Add API permissions\">\n Open <strong>API permissions</strong> → <strong>Add a permission</strong> →{\" \"}\n <strong>Microsoft Graph</strong> → <strong>Delegated permissions</strong>. Tick all four:\n <ul className=\"list-disc ml-5 mt-1 text-fg-subtle\">\n <li><code className=\"text-fg\">offline_access</code> — required for refresh tokens.</li>\n <li><code className=\"text-fg\">User.Read</code> — basic profile for the Test button.</li>\n <li><code className=\"text-fg\">Mail.ReadWrite</code> — search/read/draft/move mail.</li>\n <li><code className=\"text-fg\">Calendars.ReadWrite</code> — manage calendar events.</li>\n </ul>\n Click <strong>Add permissions</strong>. Personal accounts grant these themselves at the\n consent screen. Work/school accounts may require admin consent — if you're not\n the tenant admin, ask IT.\n </Step>\n\n <Step n={5} title=\"Paste and connect\">\n Paste the <strong>Application (client) ID</strong> and the secret <strong>Value</strong>\n {\" \"}from step 3 into the two fields below, click <strong>Save</strong>, then{\" \"}\n <strong>Connect Outlook</strong>. A Microsoft consent window opens — approve it and\n the tab will close itself. Hit <strong>Test</strong> to confirm.\n </Step>\n\n <div className=\"mt-2 pt-2 border-t border-border/60 text-[11px] text-fg-faint\">\n <strong className=\"text-fg-subtle\">Troubleshooting:</strong>\n <ul className=\"list-disc ml-5 mt-1 space-y-0.5\">\n <li><code>redirect_uri_mismatch</code> / <code>AADSTS50011</code> → the redirect\n URI on your Azure app doesn't exactly match the one Jarela sent. Compare\n character-for-character (trailing slash, http vs https, port).</li>\n <li><code>invalid_client</code> / <code>AADSTS7000215</code> → you pasted the\n Secret ID instead of the Secret Value. Regenerate the secret and copy the Value\n column.</li>\n <li><code>AADSTS65001</code> → admin consent required. For work/school accounts\n ask your IT admin to grant tenant consent on your app.</li>\n <li><code>AADSTS900144</code> → missing scope on the token call. Update Jarela.</li>\n <li>Tokens are tied to the client secret's expiration. When the secret expires,\n create a new one in Azure and reconnect.</li>\n </ul>\n </div>\n </div>\n </details>\n );\n}\n","\"use client\";\nimport { ChevronLeft, X } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { IntegrationDefinition, IntegrationStatus } from \"@/api/types\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport { IntegrationCard } from \"./IntegrationCard\";\n\ntype Category = NonNullable<IntegrationDefinition[\"category\"]>;\n\nconst CATEGORY_ORDER: Category[] = [\n \"llm\",\n \"mail\",\n \"calendar\",\n \"issue-tracker\",\n \"infrastructure\",\n \"chat\",\n \"other\",\n];\n\nconst CATEGORY_LABELS: Record<Category, string> = {\n llm: \"Model providers (LLM)\",\n mail: \"Mail\",\n calendar: \"Calendar\",\n \"issue-tracker\": \"Issue trackers\",\n infrastructure: \"Infrastructure\",\n chat: \"Chat\",\n other: \"Other\",\n};\n\ninterface Props {\n // When set, the picker opens directly on a specific category (e.g.\n // \"llm\" when launched from the ModelEditor's \"+ New credential\" button).\n initialCategory?: Category;\n // When set, skip the picker entirely and open the form for this exact\n // integration name (e.g. \"anthropic\"). Used by the Credentials panel's\n // edit affordance so the user lands straight on the right form.\n directProviderName?: string;\n // When set, lock the category step — the user can't navigate back to\n // pick a different bucket. Used when the host already constrained the\n // category (e.g. ModelEditor only wants LLM credentials).\n lockCategory?: boolean;\n onClose: () => void;\n // Called after a successful save with the integration name that was\n // configured. Hosts can use this to refresh their views.\n onSaved?: (integrationName: string) => void;\n}\n\n// Unified picker for adding/editing any credential. Shows manifest\n// providers grouped by category, then drops the user into the same\n// IntegrationCard editor the Credentials panel renders inline — so\n// OAuth Connect, Test, and the setup guides are all in one place.\nexport function AddCredentialDialog({ initialCategory, directProviderName, lockCategory, onClose, onSaved }: Props) {\n const [defs, setDefs] = useState<IntegrationDefinition[]>([]);\n const [statuses, setStatuses] = useState<Record<string, IntegrationStatus>>({});\n const [loading, setLoading] = useState(true);\n const [step, setStep] = useState<\"pick\" | \"form\">(directProviderName ? \"form\" : \"pick\");\n const [category] = useState<Category | null>(initialCategory ?? null);\n const [activeName, setActiveName] = useState<string | null>(directProviderName ?? null);\n\n useEscapeKey(onClose);\n\n const reload = useCallback(async () => {\n try {\n const res = await api.integrations.list();\n setDefs(res.definitions);\n setStatuses(Object.fromEntries(res.statuses.map((s) => [s.name, s])));\n } catch (e) {\n pushErrorToast({ title: \"Couldn't load credentials catalog\", error: e, context: { panel: \"credentials\", action: \"catalog.load\" } });\n }\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const res = await api.integrations.list();\n if (cancelled) return;\n setDefs(res.definitions);\n setStatuses(Object.fromEntries(res.statuses.map((s) => [s.name, s])));\n } catch (e) {\n if (cancelled) return;\n pushErrorToast({ title: \"Couldn't load credentials catalog\", error: e, context: { panel: \"credentials\", action: \"catalog.load\" } });\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => { cancelled = true; };\n }, []);\n\n const grouped = useMemo(() => {\n const out = new Map<Category, IntegrationDefinition[]>();\n for (const def of defs) {\n const cat = (def.category ?? \"other\") as Category;\n const arr = out.get(cat) ?? [];\n arr.push(def);\n out.set(cat, arr);\n }\n for (const [, arr] of out) arr.sort((a, b) => a.label.localeCompare(b.label));\n return out;\n }, [defs]);\n\n const visibleCategories = useMemo(() => {\n if (category) return [category];\n return CATEGORY_ORDER.filter((c) => grouped.has(c));\n }, [category, grouped]);\n\n function openProvider(name: string) {\n setActiveName(name);\n setStep(\"form\");\n }\n\n function backToPicker() {\n setActiveName(null);\n setStep(\"pick\");\n }\n\n const activeDef = activeName ? defs.find((d) => d.name === activeName) ?? null : null;\n const activeStatus = activeName ? statuses[activeName] ?? null : null;\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-start justify-center z-[70] p-2 sm:p-4 overflow-y-auto\">\n <div className=\"bg-surface-2 border border-border rounded-2xl w-full max-w-lg shadow-xl my-2 sm:my-4\">\n <div className=\"flex items-center gap-2 px-4 py-3 border-b border-border\">\n {step === \"form\" && !lockCategory && !directProviderName && (\n <button onClick={backToPicker} className=\"text-fg-subtle hover:text-fg\" title=\"Back to picker\">\n <ChevronLeft size={16} />\n </button>\n )}\n <h3 className=\"text-sm font-semibold text-fg flex-1 truncate\">\n {step === \"form\" && activeDef\n ? `${activeStatus?.configured ? \"Edit\" : \"Connect\"} ${activeDef.label}`\n : \"Add credential\"}\n </h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\">\n <X size={16} />\n </button>\n </div>\n\n {step === \"pick\" && (\n <div className=\"p-4 space-y-4 max-h-[70vh] overflow-y-auto\">\n {loading && <p className=\"text-fg-faint text-sm text-center py-6\">Loading…</p>}\n {!loading && defs.length === 0 && (\n <p className=\"text-fg-faint text-sm text-center py-6\">No credential providers available.</p>\n )}\n {!loading && visibleCategories.map((cat) => {\n const entries = grouped.get(cat) ?? [];\n if (entries.length === 0) return null;\n return (\n <section key={cat}>\n <h4 className=\"text-[11px] uppercase tracking-wide text-fg-faint mb-1.5 px-1\">{CATEGORY_LABELS[cat]}</h4>\n <div className=\"divide-y divide-border/60 border border-border/60 rounded-xl overflow-hidden bg-surface-3/40\">\n {entries.map((def) => {\n const configured = statuses[def.name]?.configured;\n return (\n <button\n key={def.name}\n type=\"button\"\n onClick={() => openProvider(def.name)}\n className=\"w-full text-left px-3 py-2.5 hover:bg-surface-2 transition-colors flex items-start gap-3\"\n >\n <div className={`w-1.5 h-1.5 rounded-full mt-1.5 ${configured ? \"bg-emerald-500\" : \"bg-fg-faint\"}`} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-fg flex items-center gap-2\">\n <span className=\"font-medium\">{def.label}</span>\n {configured && (\n <span className=\"text-[10px] px-1.5 py-0.5 rounded border border-emerald-700 bg-emerald-900/20 text-emerald-700 dark:text-emerald-300\">\n configured\n </span>\n )}\n </div>\n <p className=\"text-[11px] text-fg-faint mt-0.5 leading-snug\">{def.description}</p>\n </div>\n </button>\n );\n })}\n </div>\n </section>\n );\n })}\n </div>\n )}\n\n {step === \"form\" && activeDef && (\n <div className=\"p-4 max-h-[70vh] overflow-y-auto\">\n <IntegrationCard\n definition={activeDef}\n status={activeStatus ?? undefined}\n onChanged={() => {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"jarela:credentials-changed\"));\n }\n onSaved?.(activeDef.name);\n void reload();\n }}\n />\n </div>\n )}\n {step === \"form\" && !activeDef && (\n <p className=\"text-fg-faint text-sm text-center py-8\">Loading…</p>\n )}\n </div>\n </div>\n );\n}\n","import type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function IdentitySection({ form }: { form: ModelEditorForm }) {\n return (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Config name</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent disabled:opacity-50\"\n value={form.name}\n onChange={(e) => { form.setName(e.target.value); form.setNameTouched(true); }}\n placeholder={form.modelId || \"e.g. work-claude\"}\n disabled={form.isEdit}\n />\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Provider</span>\n <select\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.provider}\n onChange={(e) => form.setProvider(e.target.value)}\n >\n {form.providers.map((p) => <option key={p} value={p}>{p}</option>)}\n </select>\n </label>\n </div>\n );\n}\n","import { BookOpen } from \"lucide-react\";\nimport type { CatalogModel } from \"@/api/types\";\nimport { CapBadges } from \"../CapBadges\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\n\ninterface Props {\n form: ModelEditorForm;\n onLoadCatalog: () => Promise<void>;\n}\n\nexport function ModelIdSection({ form, onLoadCatalog }: Props) {\n return (\n <div className=\"space-y-1.5\">\n <ModelIdHeader form={form} onLoadCatalog={onLoadCatalog} />\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.modelId}\n onChange={(e) => {\n const next = e.target.value;\n form.setModelId(next);\n if (!form.nameTouched && !form.isEdit) form.setName(next);\n }}\n placeholder=\"e.g. claude-sonnet-4-6\"\n />\n {form.catalogError && <p className=\"text-red-700 dark:text-red-400 text-xs\">{form.catalogError}</p>}\n {form.showCatalog && form.catalog && <CatalogPanel form={form} />}\n </div>\n );\n}\n\nfunction ModelIdHeader({ form, onLoadCatalog }: Props) {\n return (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-fg-subtle\">Model ID</span>\n <button\n onClick={() => form.showCatalog ? form.setShowCatalog(false) : onLoadCatalog()}\n disabled={form.catalogLoading}\n className=\"flex items-center gap-1 text-[11px] text-accent hover:text-accent/80 transition-colors disabled:opacity-50\"\n >\n <BookOpen size={11} />\n {form.catalogLoading ? \"Loading…\" : form.showCatalog ? \"Hide catalog\" : \"Browse catalog\"}\n </button>\n </div>\n );\n}\n\nfunction CatalogPanel({ form }: { form: ModelEditorForm }) {\n const filtered = form.catalog?.filter((m) =>\n !form.catalogSearch || m.id.toLowerCase().includes(form.catalogSearch.toLowerCase()),\n ) ?? [];\n return (\n <div className=\"border border-border rounded-xl overflow-hidden bg-surface-3 shadow-sm\">\n <div className=\"px-2 py-1.5 border-b border-border bg-surface-2/50\">\n <input\n className=\"w-full bg-surface text-fg text-xs rounded px-2 py-1 border border-border focus:outline-none focus:ring-1 focus:ring-accent placeholder-fg-faint\"\n placeholder=\"Filter models…\"\n value={form.catalogSearch}\n onChange={(e) => form.setCatalogSearch(e.target.value)}\n />\n </div>\n <div className=\"max-h-52 overflow-y-auto divide-y divide-border\">\n {filtered.length === 0 && (\n <p className=\"text-xs text-fg-faint text-center py-3\">No models match</p>\n )}\n {filtered.map((m) => (\n <CatalogRow key={m.id} model={m} form={form} />\n ))}\n </div>\n </div>\n );\n}\n\nfunction CatalogRow({ model, form }: { model: CatalogModel; form: ModelEditorForm }) {\n return (\n <button\n onClick={() => applyCatalogPick(model, form)}\n className={`w-full text-left px-3 py-2 hover:bg-surface-2 transition-colors ${model.id === form.modelId ? \"bg-accent/10 border-l-2 border-accent\" : \"\"}`}\n >\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-xs font-mono text-fg truncate\">{model.id}</span>\n {model.context_length && (\n <span className=\"text-[10px] text-fg-faint shrink-0\">{fmtCtx(model.context_length)} ctx</span>\n )}\n {model.hosted_on && (\n <span className=\"text-[10px] text-fg-faint shrink-0 truncate\">{model.hosted_on}</span>\n )}\n </div>\n <CapBadges caps={model.capabilities} />\n </button>\n );\n}\n\nfunction applyCatalogPick(model: CatalogModel, form: ModelEditorForm) {\n form.setModelId(model.id);\n if (!form.nameTouched && !form.isEdit) form.setName(model.id);\n // Auto-apply the catalog's known sizing as the default so the agent doesn't\n // fall back to the global 8K window. Only fills when the field is currently\n // empty — never clobbers a value the user explicitly typed.\n if (model.context_length && !form.contextWindowTokens.trim()) {\n const v = String(model.context_length);\n form.setContextWindowTokens(v);\n form.setAutoContextWindowTokens(v);\n }\n if (model.max_output_tokens && !form.maxTokens.trim()) {\n const v = String(model.max_output_tokens);\n form.setMaxTokens(v);\n form.setAutoMaxTokens(v);\n }\n form.setShowCatalog(false);\n}\n\nfunction fmtCtx(n: number | null) {\n if (!n) return null;\n return n >= 1000000 ? `${n / 1000000}M` : n >= 1000 ? `${Math.round(n / 1000)}k` : String(n);\n}\n","import { api } from \"@/api/client\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function CredentialSection({ form }: { form: ModelEditorForm }) {\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-fg-subtle\">Credential</span>\n <button\n type=\"button\"\n onClick={() => form.setCredentialDialogOpen(true)}\n className=\"text-[11px] text-accent hover:text-accent/80 transition-colors inline-flex items-center gap-1\"\n >\n + New credential\n </button>\n </div>\n <CredentialDropdown form={form} />\n {form.credentialId && (\n <button\n type=\"button\"\n onClick={() => form.setCredentialDialogOpen(true)}\n className=\"text-[11px] text-fg-faint hover:text-fg-muted transition-colors\"\n >\n Edit selected credential\n </button>\n )}\n </div>\n );\n}\n\nfunction CredentialDropdown({ form }: { form: ModelEditorForm }) {\n const emptyLabel = form.providerCredentials.length === 0\n ? `— No credentials for ${form.provider} —`\n : \"— Inline / env fallback —\";\n return (\n <select\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.credentialId ?? \"\"}\n onChange={(e) => form.setCredentialId(e.target.value || null)}\n >\n <option value=\"\">{emptyLabel}</option>\n {form.providerCredentials.map((c) => (\n <option key={c.id} value={c.id}>{c.id} ({c.auth_method})</option>\n ))}\n {form.credentialId && !form.providerCredentials.some((c) => c.id === form.credentialId) && (\n <option value={form.credentialId}>{form.credentialId} (other provider)</option>\n )}\n </select>\n );\n}\n\n// Auto-bind a freshly-created credential so the user's next \"Save model\"\n// uses it without re-picking. Look it up by integration name + first match.\nexport async function rebindCredentialAfterCreate(form: ModelEditorForm) {\n try {\n const rows = await api.credentials.list({ type: \"integration\", provider: form.integrationName });\n form.setCredentials((prev) => {\n const merged = [...prev.filter((c) => !rows.some((r) => r.id === c.id)), ...rows];\n return merged;\n });\n if (rows.length > 0 && !form.credentialId) form.setCredentialId(rows[0].id);\n } catch { /* refresh-only failure is non-fatal */ }\n}\n","import type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function ConnectionFields({ form, expertVisible }: { form: ModelEditorForm; expertVisible: boolean }) {\n return (\n <>\n {!form.credentialId && <InlineApiKeyField form={form} placeholder=\"••••••••\" />}\n {expertVisible && form.credentialId && (\n <InlineApiKeyField\n form={form}\n label=\"API Key override (advanced)\"\n placeholder=\"leave blank — credential value used\"\n />\n )}\n {expertVisible && (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Base URL (optional override)</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.baseUrl}\n onChange={(e) => form.setBaseUrl(e.target.value)}\n placeholder=\"https://custom-endpoint\"\n />\n </label>\n )}\n </>\n );\n}\n\nfunction InlineApiKeyField({\n form, label, placeholder,\n}: { form: ModelEditorForm; label?: string; placeholder: string }) {\n return (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">\n {label ?? <>API Key<span className=\"ml-1 text-fg-faint\">(optional — env fallback used if blank)</span></>}\n </span>\n <input\n type=\"password\"\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.apiKey}\n onChange={(e) => form.setApiKey(e.target.value)}\n placeholder={placeholder}\n />\n </label>\n );\n}\n","import type { ModelEditorForm } from \"./useModelEditorForm\";\n\nexport function TemperatureMaxTokensRow({ form }: { form: ModelEditorForm }) {\n return (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Temperature</span>\n <input\n type=\"number\" min=\"0\" max=\"2\" step=\"0.1\"\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.temperature}\n onChange={(e) => form.setTemperature(e.target.value)}\n placeholder=\"0.7\"\n />\n </label>\n <MaxTokensField form={form} />\n </div>\n );\n}\n\nfunction MaxTokensField({ form }: { form: ModelEditorForm }) {\n const showCatalog = form.autoMaxTokens !== null && form.autoMaxTokens === form.maxTokens;\n return (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">\n Max tokens{showCatalog && <span className=\"ml-1 text-fg-faint\">(catalog default)</span>}\n </span>\n <input\n type=\"number\"\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.maxTokens}\n onChange={(e) => {\n form.setMaxTokens(e.target.value);\n if (e.target.value !== form.autoMaxTokens) form.setAutoMaxTokens(null);\n }}\n placeholder=\"4096\"\n />\n </label>\n );\n}\n\nexport function ContextWindowField({ form }: { form: ModelEditorForm }) {\n const showCatalog = form.autoContextWindowTokens !== null && form.autoContextWindowTokens === form.contextWindowTokens;\n return (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">\n Context window tokens{showCatalog && <span className=\"ml-1 text-fg-faint\">(catalog default)</span>}\n </span>\n <input\n type=\"number\" min=\"1\"\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.contextWindowTokens}\n onChange={(e) => {\n form.setContextWindowTokens(e.target.value);\n if (e.target.value !== form.autoContextWindowTokens) form.setAutoContextWindowTokens(null);\n }}\n placeholder=\"8192\"\n />\n </label>\n );\n}\n\nexport function ExtraHeadersField({ form }: { form: ModelEditorForm }) {\n return (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Extra headers (JSON, optional)</span>\n <textarea\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent font-mono h-20 resize-none\"\n value={form.extraHeaders}\n onChange={(e) => form.setExtraHeaders(e.target.value)}\n placeholder='{\"X-Custom\": \"value\"}'\n />\n </label>\n );\n}\n","import { api } from \"@/api/client\";\nimport type { DeviceFlow, GhCopilotState } from \"./useGitHubCopilotAuth\";\n\nexport type PollResult = \"continue\" | \"slow_down\" | \"done\";\n\nexport interface AuthSetters {\n setStatus: (s: GhCopilotState | null) => void;\n setFlow: (f: DeviceFlow | null) => void;\n setPolling: (b: boolean) => void;\n setMessage: (m: string | null) => void;\n setError: (e: string | null) => void;\n}\n\nexport function makeStartSignIn(setters: AuthSetters) {\n return async function startSignIn() {\n setters.setError(null); setters.setMessage(null);\n try {\n const f = await api.githubCopilotAuth.start();\n const interval = f.interval || 5;\n setters.setFlow({ user_code: f.user_code, verification_uri: f.verification_uri, device_code: f.device_code, interval });\n setters.setPolling(true);\n void pollLoop(setters, f.device_code, interval, f.expires_in || 900);\n } catch (e) { setters.setError(e instanceof Error ? e.message : String(e)); }\n };\n}\n\nexport function makeSignOut(setters: AuthSetters) {\n return async function signOut() {\n setters.setError(null); setters.setMessage(null);\n try {\n await api.githubCopilotAuth.signOut();\n setters.setStatus(await api.githubCopilotAuth.status());\n setters.setMessage(\"Signed out.\");\n } catch (e) { setters.setError(e instanceof Error ? e.message : String(e)); }\n };\n}\n\nasync function pollLoop(setters: AuthSetters, deviceCode: string, intervalSec: number, expiresInSec: number) {\n const deadline = Date.now() + expiresInSec * 1000;\n let interval = intervalSec;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, interval * 1000));\n const result = await pollOnce(setters, deviceCode);\n if (result === \"continue\") continue;\n if (result === \"slow_down\") { interval += 5; continue; }\n return;\n }\n setters.setError(\"Sign-in timed out. Try again.\");\n setters.setFlow(null); setters.setPolling(false);\n}\n\nasync function pollOnce(setters: AuthSetters, deviceCode: string): Promise<PollResult> {\n try {\n const res = await api.githubCopilotAuth.poll(deviceCode);\n if (res.status === \"success\") {\n setters.setMessage(\"Signed in to GitHub Copilot.\");\n setters.setFlow(null); setters.setPolling(false);\n setters.setStatus(await api.githubCopilotAuth.status());\n return \"done\";\n }\n if (res.status === \"slow_down\") return \"slow_down\";\n if (res.status === \"pending\") return \"continue\";\n setters.setError(`Sign-in failed: ${res.status}${res.error ? ` (${res.error})` : \"\"}`);\n setters.setFlow(null); setters.setPolling(false);\n return \"done\";\n } catch (e) {\n setters.setError(e instanceof Error ? e.message : String(e));\n setters.setPolling(false);\n return \"done\";\n }\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport { makeSignOut, makeStartSignIn } from \"./github-copilot-auth-actions\";\n\nexport interface DeviceFlow {\n user_code: string;\n verification_uri: string;\n device_code: string;\n interval: number;\n}\n\nexport interface GhCopilotState {\n signed_in: boolean;\n stored_at: string | null;\n}\n\nexport function useGitHubCopilotAuth() {\n const [status, setStatus] = useState<GhCopilotState | null>(null);\n const [flow, setFlow] = useState<DeviceFlow | null>(null);\n const [polling, setPolling] = useState(false);\n const [message, setMessage] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n api.githubCopilotAuth.status().then(setStatus).catch(() => setStatus({ signed_in: false, stored_at: null }));\n }, []);\n\n const actions = useMemo(() => {\n const setters = { setStatus, setFlow, setPolling, setMessage, setError };\n return { startSignIn: makeStartSignIn(setters), signOut: makeSignOut(setters) };\n }, []);\n\n return { status, flow, polling, message, error, ...actions };\n}\n","import { useGitHubCopilotAuth, type DeviceFlow, type GhCopilotState } from \"./useGitHubCopilotAuth\";\n\nexport function GitHubCopilotAuth() {\n const auth = useGitHubCopilotAuth();\n return (\n <div className=\"p-2.5 rounded-lg bg-surface-3 border border-border text-xs space-y-2\">\n <AuthHeader status={auth.status} polling={auth.polling} onSignIn={auth.startSignIn} onSignOut={auth.signOut} />\n {auth.status?.signed_in && !auth.flow && <ConnectedLine status={auth.status} />}\n {auth.flow && <DeviceFlowBlock flow={auth.flow} />}\n {auth.message && <p className=\"text-emerald-700 dark:text-emerald-400\">{auth.message}</p>}\n {auth.error && <p className=\"text-red-700 dark:text-red-400\">{auth.error}</p>}\n </div>\n );\n}\n\ninterface HeaderProps {\n status: GhCopilotState | null;\n polling: boolean;\n onSignIn: () => void;\n onSignOut: () => void;\n}\n\nfunction AuthHeader({ status, polling, onSignIn, onSignOut }: HeaderProps) {\n return (\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-fg-muted\">\n <strong>GitHub Copilot sign-in</strong>\n <p className=\"text-fg-faint mt-0.5\">\n Unlocks full model context windows (vs. the 8k cap on raw PATs via GitHub Models).\n </p>\n </div>\n {status?.signed_in ? (\n <button onClick={onSignOut} className=\"px-2 py-1 text-[11px] bg-surface text-fg-muted hover:text-red-700 dark:hover:text-red-300 rounded border border-border whitespace-nowrap\">\n Sign out\n </button>\n ) : (\n <button\n onClick={onSignIn}\n disabled={polling}\n className=\"px-2 py-1 text-[11px] bg-accent hover:bg-accent-hover text-white rounded whitespace-nowrap disabled:opacity-50\"\n >\n {polling ? \"Waiting…\" : \"Sign in\"}\n </button>\n )}\n </div>\n );\n}\n\nfunction ConnectedLine({ status }: { status: GhCopilotState }) {\n return (\n <p className=\"text-emerald-700 dark:text-emerald-400\">\n Connected{status.stored_at ? ` · ${new Date(status.stored_at).toLocaleString()}` : \"\"}\n </p>\n );\n}\n\nfunction DeviceFlowBlock({ flow }: { flow: DeviceFlow }) {\n return (\n <div className=\"rounded bg-surface p-2 border border-border space-y-1.5\">\n <p className=\"text-fg-subtle\">\n 1. Open{\" \"}\n <a href={flow.verification_uri} target=\"_blank\" rel=\"noreferrer\" className=\"text-accent underline\">\n {flow.verification_uri}\n </a>\n </p>\n <p className=\"text-fg-subtle\">2. Enter this code:</p>\n <div className=\"flex items-center gap-2\">\n <code className=\"px-2 py-1 bg-surface-2 rounded font-mono text-fg text-sm tracking-wider\">\n {flow.user_code}\n </code>\n <button\n onClick={() => { void navigator.clipboard.writeText(flow.user_code).catch(() => {}); }}\n className=\"text-[10px] text-fg-subtle hover:text-fg\"\n >\n Copy\n </button>\n </div>\n </div>\n );\n}\n","import { Loader2 } from \"lucide-react\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\n\ninterface Props {\n form: ModelEditorForm;\n onConfirm: () => void;\n onSkip: () => void;\n}\n\nexport function ShrinkConfirmDialog({ form, onConfirm, onSkip }: Props) {\n const pending = form.pendingShrinkConfirm;\n if (!pending) return null;\n return (\n <div className=\"fixed inset-0 bg-black/70 flex items-center justify-center z-[60] p-4\">\n <div className=\"bg-surface-2 border border-border rounded-2xl w-full max-w-md shadow-2xl p-5 space-y-3\">\n <h4 className=\"text-sm font-semibold text-fg\">Compact threads first?</h4>\n <p className=\"text-xs text-fg-muted leading-relaxed\">\n You're switching <span className=\"font-mono\">{pending.payloadName}</span> from{\" \"}\n <span className=\"font-mono\">{pending.oldSnapshot.model_id}</span> to{\" \"}\n <span className=\"font-mono\">{pending.payload.model_id}</span>. The new model may have a smaller\n context window. To avoid the next turn failing, Jarela can summarize older messages now using the\n previous model, then complete the swap.\n </p>\n <p className=\"text-[11px] text-fg-faint\">Other actions are blocked while compaction runs.</p>\n <DialogActions form={form} onConfirm={onConfirm} onSkip={onSkip} />\n </div>\n </div>\n );\n}\n\nfunction DialogActions({ form, onConfirm, onSkip }: Props) {\n return (\n <div className=\"flex justify-end gap-2 pt-1\">\n <button\n onClick={() => form.setPendingShrinkConfirm(null)}\n disabled={form.compacting}\n className=\"px-3 py-1.5 text-xs text-fg-subtle hover:text-fg transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={onSkip}\n disabled={form.compacting || form.saving}\n className=\"px-3 py-1.5 text-xs text-fg-muted hover:text-fg transition-colors\"\n >\n Skip & save anyway\n </button>\n <button\n onClick={onConfirm}\n disabled={form.compacting}\n className=\"px-4 py-1.5 text-xs font-medium bg-accent hover:bg-accent-hover text-white rounded-xl shadow-sm transition-colors disabled:opacity-50 inline-flex items-center gap-1.5\"\n >\n {form.compacting && <Loader2 size={12} className=\"animate-spin\" />}\n {form.compacting ? \"Compacting…\" : \"Compact & save\"}\n </button>\n </div>\n );\n}\n","\"use client\";\nimport { AddCredentialDialog } from \"@/components/credentials/AddCredentialDialog\";\nimport { ModelFeatureGuide } from \"../ModelFeatureGuide\";\nimport type { ModelEditorForm } from \"./useModelEditorForm\";\nimport { IdentitySection } from \"./IdentitySection\";\nimport { ModelIdSection } from \"./ModelIdSection\";\nimport { CredentialSection, rebindCredentialAfterCreate } from \"./CredentialSection\";\nimport { ConnectionFields } from \"./ConnectionFields\";\nimport { ContextWindowField, ExtraHeadersField, TemperatureMaxTokensRow } from \"./TuningFields\";\nimport { GitHubCopilotAuth } from \"./GitHubCopilotAuth\";\nimport { ProbeBanner } from \"./ProbeAndFooter\";\nimport { ShrinkConfirmDialog } from \"./ShrinkConfirmDialog\";\n\ninterface BodyProps {\n form: ModelEditorForm;\n expertVisible: boolean;\n onLoadCatalog: () => Promise<void>;\n}\n\nexport function ModelEditorBody({ form, expertVisible, onLoadCatalog }: BodyProps) {\n return (\n <>\n <IdentitySection form={form} />\n <ModelIdSection form={form} onLoadCatalog={onLoadCatalog} />\n <ModelFeatureGuide\n provider={form.provider}\n modelId={form.modelId}\n models={form.model ? [form.model] : []}\n integrations={form.integrations}\n />\n {form.provider === \"github-copilot\" && <GitHubCopilotAuth />}\n <CredentialSection form={form} />\n <ConnectionFields form={form} expertVisible={expertVisible} />\n <TemperatureMaxTokensRow form={form} />\n {expertVisible && <ContextWindowField form={form} />}\n {expertVisible && <ExtraHeadersField form={form} />}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\" className=\"rounded border-border\"\n checked={form.isDefault}\n onChange={(e) => form.setIsDefault(e.target.checked)}\n />\n <span className=\"text-xs text-fg-muted\">Set as default model</span>\n </label>\n {form.error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{form.error}</p>}\n <ProbeBanner result={form.probeResult} />\n </>\n );\n}\n\ninterface OverlayProps {\n form: ModelEditorForm;\n onConfirmShrink: () => void;\n onSkipShrink: () => void;\n}\n\nexport function ModelEditorOverlays({ form, onConfirmShrink, onSkipShrink }: OverlayProps) {\n return (\n <>\n <ShrinkConfirmDialog form={form} onConfirm={onConfirmShrink} onSkip={onSkipShrink} />\n {form.credentialDialogOpen && (\n <AddCredentialDialog\n initialCategory=\"llm\"\n directProviderName={form.integrationName}\n lockCategory\n onClose={() => { form.setCredentialDialogOpen(false); form.refreshCredentials(); }}\n onSaved={() => rebindCredentialAfterCreate(form)}\n />\n )}\n </>\n );\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport type { ModelConfig } from \"@/api/types\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { useModelEditorForm } from \"./model-editor/useModelEditorForm\";\nimport { useModelSaveHandlers } from \"./model-editor/useModelSaveHandlers\";\nimport { EditorChrome, ExpertToggle } from \"./model-editor/EditorChrome\";\nimport { EditorFooter } from \"./model-editor/ProbeAndFooter\";\nimport { ModelEditorBody, ModelEditorOverlays } from \"./model-editor/ModelEditorBody\";\n\ninterface Props {\n model?: ModelConfig;\n onSave: (name: string, data: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">) => Promise<void>;\n onClose: () => void;\n}\n\nexport function ModelEditor({ model, onSave, onClose }: Props) {\n const isFullMode = useAppContext().state.experienceMode === \"full\";\n // Per-editor opt-in so a normal-mode user can reveal the engine-room\n // fields for one model without flipping the global workspace mode.\n const [showExpert, setShowExpert] = useState(false);\n const expertVisible = isFullMode || showExpert;\n const form = useModelEditorForm(model);\n const h = useModelSaveHandlers({ form, onSave, onClose });\n useEscapeKey(onClose);\n\n return (\n <EditorChrome\n title={form.isEdit ? \"Edit model config\" : \"New model config\"}\n wide={expertVisible}\n onClose={onClose}\n expertToggle={!isFullMode ? <ExpertToggle showExpert={showExpert} onToggle={() => setShowExpert((v) => !v)} /> : null}\n footer={<EditorFooter form={form} onTest={h.handleTestConnection} onSave={h.handleSave} onClose={onClose} />}\n overlays={<ModelEditorOverlays form={form} onConfirmShrink={h.confirmShrinkAndSave} onSkipShrink={h.skipCompactAndSave} />}\n >\n <ModelEditorBody form={form} expertVisible={expertVisible} onLoadCatalog={h.loadCatalog} />\n </EditorChrome>\n );\n}\n","\"use client\";\nimport { Cpu, Pencil, Plus, Star, Trash2 } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport type { ModelConfig } from \"@/api/types\";\nimport { useModels } from \"@/hooks/useModels\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { ModelEditor } from \"./ModelEditor\";\nimport { CapBadges } from \"./CapBadges\";\n\nconst PROVIDER_COLORS: Record<string, string> = {\n anthropic: \"bg-orange-900/40 text-orange-700 dark:text-orange-300 border-orange-700\",\n openai: \"bg-green-900/40 text-green-700 dark:text-green-300 border-green-700\",\n \"github-copilot\": \"bg-purple-900/40 text-purple-300 border-purple-700\",\n};\n\nexport function ModelsPanel() {\n const { models, assignments, loading, create, update, remove, refresh } = useModels();\n const [editing, setEditing] = useState<ModelConfig | null | \"new\">(null);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"models\", \"model\", containerRef);\n\n async function handleSave(name: string, data: Omit<ModelConfig, \"name\" | \"created_at\" | \"updated_at\">) {\n if (editing === \"new\") await create(name, data);\n else if (editing) await update(name, data);\n refresh();\n }\n\n async function handleSetDefault(m: ModelConfig) {\n await update(m.name, { provider: m.provider, model_id: m.model_id, params: m.params, is_default: true });\n }\n\n async function handleRemove(name: string) {\n setDeleteError(null);\n try {\n await remove(name);\n } catch (e) {\n setDeleteError(`Could not delete \"${name}\": ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Cpu size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Model Configs</h2>\n <button onClick={() => setEditing(\"new\")} className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\">\n <Plus size={14} /> New\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto\">\n {/* Model list */}\n <div className=\"px-4 py-2\">\n {loading && models.length === 0 && <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>}\n {!loading && models.length === 0 && <p className=\"text-fg-faint text-sm py-6 text-center\">No model configs yet</p>}\n {deleteError && (\n <p className=\"text-red-700 dark:text-red-400 text-xs mb-2 px-1\">{deleteError}</p>\n )}\n {models.map((m) => {\n const inUse = assignments.some((a) => a.model_config_name === m.name);\n return (\n <div key={m.name} data-deep-link-id={m.name} className=\"flex items-center gap-3 py-2.5 border-b border-border/60 group\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-sm font-medium text-fg\">{m.name}</span>\n {m.is_default && <Star size={11} className=\"text-yellow-700 dark:text-yellow-400 fill-yellow-400 shrink-0\" />}\n <span className={`text-xs px-1.5 py-0.5 rounded border ${PROVIDER_COLORS[m.provider] ?? \"bg-surface-2 text-fg-muted border-border\"}`}>\n {m.provider}\n </span>\n </div>\n <p className=\"text-xs text-fg-subtle truncate\">{m.model_id}</p>\n <div className=\"mt-1\">\n <CapBadges provider={m.provider} modelId={m.model_id} />\n </div>\n </div>\n <div className=\"flex gap-1 opacity-40 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n {!m.is_default && (\n <button onClick={() => handleSetDefault(m)} className=\"p-1 text-fg-subtle hover:text-yellow-700 dark:hover:text-yellow-400 transition-colors\" title=\"Set as default\">\n <Star size={13} />\n </button>\n )}\n <button onClick={() => setEditing(m)} className=\"p-1 text-fg-subtle hover:text-fg transition-colors\" title=\"Edit\">\n <Pencil size={13} />\n </button>\n <button\n onClick={() => handleRemove(m.name)}\n disabled={inUse}\n className=\"p-1 text-fg-subtle hover:text-red-700 dark:hover:text-red-400 transition-colors disabled:opacity-30 disabled:cursor-not-allowed\"\n title={inUse ? \"Unassign from agents first\" : \"Delete\"}\n >\n <Trash2 size={13} />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n\n </div>\n\n {editing !== null && (\n <ModelEditor\n model={editing === \"new\" ? undefined : editing}\n onSave={handleSave}\n onClose={() => { setEditing(null); refresh(); }}\n />\n )}\n </div>\n );\n}\n","\"use client\";\nimport { Globe, Loader2, RefreshCw, Save, ShieldCheck, Trash2 } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { ProxyApplyResult, ProxyConfigEnvelope, ProxyMode, ProxyScheme } from \"@/api/types\";\n\nconst SECRET_MASK = \"********\";\n\n// Network / proxy configuration card (ADR-0009, ADR-0012). Lives inside\n// the Integrations tab so all credential-bearing config sits in one place\n// rather than getting its own top-level menu entry.\nexport function NetworkSection() {\n const [env, setEnv] = useState<ProxyConfigEnvelope | null>(null);\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<ProxyApplyResult | null>(null);\n\n // Editable form state. Re-seeded from server on load and after save.\n const [mode, setMode] = useState<ProxyMode>(\"off\");\n const [scheme, setScheme] = useState<ProxyScheme>(\"http\");\n const [host, setHost] = useState(\"\");\n const [port, setPort] = useState(\"\");\n const [username, setUsername] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [noProxy, setNoProxy] = useState(\"\");\n // CA bundle: caBundle holds the PEM text (in-memory only between\n // save/load); caLabel describes its origin so the user can see\n // \"Loaded: corp-ca.pem\" or \"Saved CA bundle (1.2 KB)\" after a reload.\n const [caBundle, setCaBundle] = useState<string | null>(null);\n const [caLabel, setCaLabel] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n\n const seed = useCallback((r: ProxyConfigEnvelope) => {\n const c = r.config;\n setMode(c.mode);\n setScheme(c.scheme);\n setHost(c.host ?? \"\");\n setPort(c.port != null ? String(c.port) : \"\");\n setUsername(c.username ?? \"\");\n setPassword(c.password ?? \"\");\n setNoProxy(c.no_proxy ?? \"\");\n setCaBundle(c.ca_bundle ?? null);\n setCaLabel(c.ca_bundle ? `Saved CA bundle (${humanBytes(c.ca_bundle.length)})` : null);\n }, []);\n\n const load = useCallback(async () => {\n setLoading(true);\n try {\n const r = await api.proxy.get();\n setEnv(r);\n seed(r);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [seed]);\n\n useEffect(() => { void load(); }, [load]);\n\n async function save() {\n setError(null);\n setSaving(true);\n try {\n const r = await api.proxy.save({\n mode,\n scheme,\n host: host.trim() || null,\n port: port.trim() ? Number.parseInt(port, 10) : null,\n username: username.trim() || null,\n password: password.length > 0 ? password : null,\n no_proxy: noProxy.trim() || null,\n ca_bundle: caBundle && caBundle.length > 0 ? caBundle : null,\n });\n setEnv(r);\n seed(r);\n setResult(r.applied ?? null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setSaving(false);\n }\n }\n\n async function clear() {\n if (!confirm(\"Clear saved proxy configuration?\")) return;\n setError(null);\n try {\n const r = await api.proxy.clear();\n setEnv(r);\n seed(r);\n setResult(r.applied ?? null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function onCaFile(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0];\n if (!file) return;\n try {\n const text = await file.text();\n if (!text.includes(\"-----BEGIN CERTIFICATE-----\")) {\n setError(`${file.name} does not contain a PEM certificate (no BEGIN CERTIFICATE block).`);\n return;\n }\n setCaBundle(text);\n setCaLabel(`Loaded: ${file.name}`);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n // Reset the input so the same file can be picked again after removal.\n if (fileInputRef.current) fileInputRef.current.value = \"\";\n }\n }\n\n function removeCa() {\n setCaBundle(null);\n setCaLabel(null);\n if (fileInputRef.current) fileInputRef.current.value = \"\";\n }\n\n const envOverride = env?.env_override ?? false;\n const configured = env?.config.mode !== \"off\" && env?.config.updated_at != null;\n\n return (\n <div className=\"mb-3 rounded-lg border border-border bg-surface-2 overflow-hidden\">\n <div className=\"px-3 py-2.5 border-b border-border/60 flex items-start gap-2\">\n <Globe size={14} className=\"text-fg-subtle mt-0.5\" />\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-medium text-fg\">Network proxy</h3>\n <p className=\"text-[11px] text-fg-faint mt-0.5 leading-snug\">\n HTTP proxy for outbound calls (LLM providers, MCP servers, integrations). Stored encrypted.\n Changes apply to new requests immediately; in-flight streams finish on the previous proxy.\n </p>\n </div>\n </div>\n\n <div className=\"px-3 py-3 space-y-2\">\n {loading && <p className=\"text-fg-faint text-xs py-2\">Loading…</p>}\n\n {envOverride && (\n <div className=\"px-2 py-1.5 rounded bg-amber-950/30 border border-amber-800 text-[11px] text-amber-700 dark:text-amber-300\">\n <code>HTTPS_PROXY</code> is set in the process environment. The in-app config is saved but not applied\n while the env var is present.\n </div>\n )}\n\n {!loading && (\n <>\n <label className=\"block text-xs text-fg-subtle\">\n Mode\n <select\n value={mode}\n onChange={(e) => setMode(e.target.value as ProxyMode)}\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg\"\n >\n <option value=\"off\">Off — direct connection</option>\n <option value=\"manual\">Manual — host / port below</option>\n <option value=\"system\">System (macOS) — import from scutil --proxy</option>\n </select>\n </label>\n\n {mode === \"manual\" && (\n <>\n <div className=\"grid grid-cols-4 gap-2\">\n <label className=\"col-span-2 block text-xs text-fg-subtle\">\n Host\n <input\n type=\"text\"\n value={host}\n onChange={(e) => setHost(e.target.value)}\n placeholder=\"proxy.corp.example\"\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n <label className=\"block text-xs text-fg-subtle\">\n Port\n <input\n type=\"number\"\n value={port}\n onChange={(e) => setPort(e.target.value)}\n placeholder=\"8080\"\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n <label className=\"block text-xs text-fg-subtle\">\n Scheme\n <select\n value={scheme}\n onChange={(e) => setScheme(e.target.value as ProxyScheme)}\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg\"\n >\n <option value=\"http\">http</option>\n <option value=\"https\">https</option>\n </select>\n </label>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <label className=\"block text-xs text-fg-subtle\">\n Username (optional)\n <input\n type=\"text\"\n value={username}\n onChange={(e) => setUsername(e.target.value)}\n placeholder=\"\"\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n <label className=\"block text-xs text-fg-subtle\">\n Password (optional)\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onFocus={(e) => {\n // Clicking the masked sentinel clears the field so the\n // user can type a new password without manually erasing\n // the dots.\n if (e.target.value === SECRET_MASK) setPassword(\"\");\n }}\n placeholder=\"\"\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n </div>\n </>\n )}\n\n {mode !== \"off\" && (\n <>\n <label className=\"block text-xs text-fg-subtle\">\n No proxy (comma-separated, optional)\n <input\n type=\"text\"\n value={noProxy}\n onChange={(e) => setNoProxy(e.target.value)}\n placeholder=\"localhost,127.0.0.1,.internal\"\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n\n {/* In system mode the keychain extraction is the trust source — the\n user-paste textarea would conflict with it (ADR-0020). Hide it. */}\n {mode !== \"system\" && (\n <div className=\"block text-xs text-fg-subtle\">\n CA bundle (optional — for proxies that intercept TLS with an internal CA)\n <div className=\"mt-1 flex items-center gap-2 flex-wrap\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".pem,.crt,.cer,.cert,application/x-x509-ca-cert,application/x-pem-file\"\n onChange={onCaFile}\n className=\"text-[11px] text-fg-faint file:mr-2 file:px-2 file:py-1 file:rounded file:border-0 file:bg-surface-3 file:text-fg file:text-[11px] file:cursor-pointer\"\n />\n {caLabel && (\n <span className=\"inline-flex items-center gap-2 text-[11px] text-fg-muted\">\n <code className=\"text-fg\">{caLabel}</code>\n <button\n onClick={removeCa}\n className=\"text-rose-700 dark:text-rose-400 hover:underline\"\n >\n remove\n </button>\n </span>\n )}\n </div>\n </div>\n )}\n\n {mode === \"system\" && (\n <p className=\"text-[11px] text-fg-faint leading-snug\">\n Trust store comes from the macOS keychain (System + login). MDM-pushed\n corporate roots are picked up automatically. Use “Refresh trust store”\n after a cert rotation.\n </p>\n )}\n </>\n )}\n\n {error && (\n <div className=\"px-2 py-1.5 rounded bg-rose-950/40 border border-rose-800 text-xs text-rose-700 dark:text-rose-300\">\n {error}\n </div>\n )}\n\n {result && (\n <div className=\"px-2 py-1.5 rounded bg-surface-3 border border-border text-[11px] text-fg-muted\">\n Applied: <code className=\"text-fg\">{result.source}</code>\n {result.proxyUrl && <> → <code className=\"text-fg\">{result.proxyUrl}</code></>}\n {result.note && <span className=\"text-fg-faint\"> — {result.note}</span>}\n </div>\n )}\n\n {result?.caBundlePath && (\n <div className=\"px-2 py-1.5 rounded bg-emerald-950/30 border border-emerald-800 text-[11px] text-emerald-700 dark:text-emerald-300 inline-flex items-start gap-1.5\">\n <ShieldCheck size={12} className=\"mt-0.5 shrink-0\" />\n <span>\n System trust: <strong>{result.caBundleCertCount}</strong> certs from the macOS\n keychain →{\" \"}\n <code className=\"text-emerald-700 dark:text-emerald-200\">{result.caBundlePath}</code>\n </span>\n </div>\n )}\n\n <div className=\"flex items-center gap-2 pt-1\">\n <button\n onClick={save}\n disabled={saving}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-xs rounded bg-accent text-white hover:bg-accent-hover disabled:opacity-50\"\n >\n {saving ? <Loader2 size={11} className=\"animate-spin\" /> : <Save size={11} />}\n {saving ? \"Saving…\" : \"Save & apply\"}\n </button>\n {mode === \"system\" && (\n <button\n onClick={save}\n disabled={saving}\n className=\"inline-flex items-center gap-1 px-2 py-1.5 text-xs rounded border border-border text-fg-muted hover:text-fg disabled:opacity-50\"\n title=\"Re-extract the macOS keychain trust store\"\n >\n <RefreshCw size={11} /> Refresh trust store\n </button>\n )}\n {configured && (\n <button\n onClick={clear}\n className=\"ml-auto inline-flex items-center gap-1 px-2 py-1.5 text-xs text-fg-faint hover:text-rose-700 dark:hover:text-rose-400\"\n title=\"Clear saved proxy configuration\"\n >\n <Trash2 size={11} /> Clear\n </button>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction humanBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(1)} MB`;\n}\n","\"use client\";\nimport { Globe, Loader2, Plus, ShieldAlert, Trash2 } from \"lucide-react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AllowedSiteStatus } from \"@/api/types\";\n\n// Settings card for the allowed-sites list. A host on this list grants\n// the agent two paired capabilities: (1) the browser extension may drive\n// a tab on this host on the agent's behalf (browser RPC), and (2) cookies\n// the extension scrapes for this host get attached to web_fetch requests.\n// The two capabilities live on a single user approval — there is no way\n// to enable one without the other.\n//\n// SSRF bypass is per-host opt-in: required to let web_fetch reach\n// intranet/private-IP allow-listed hosts (e.g. an internal Confluence\n// behind the corp VPN). Without it, the SSRF guard refuses the fetch\n// even for an allow-listed host.\nexport function AllowedSitesSection() {\n const [sites, setSites] = useState<AllowedSiteStatus[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [adding, setAdding] = useState(false);\n const [newHost, setNewHost] = useState(\"\");\n const [newBypass, setNewBypass] = useState(false);\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const r = await api.allowedSites.list();\n setSites(r.sites);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => { void load(); }, [load]);\n\n async function add() {\n const host = newHost.trim();\n if (!host) return;\n setAdding(true);\n setError(null);\n try {\n await api.allowedSites.add({ hostname: host, ssrf_bypass: newBypass });\n setNewHost(\"\");\n setNewBypass(false);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setAdding(false);\n }\n }\n\n async function toggleBypass(s: AllowedSiteStatus) {\n setError(null);\n try {\n await api.allowedSites.setSsrfBypass(s.hostname, !s.ssrf_bypass);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function remove(s: AllowedSiteStatus) {\n if (!confirm(`Remove ${s.hostname}? The agent will lose browser-RPC and cookie access for this host.`)) return;\n setError(null);\n try {\n await api.allowedSites.remove(s.hostname);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n return (\n <div className=\"mb-3 rounded-lg border border-border bg-surface-2 overflow-hidden\">\n <div className=\"px-3 py-2.5 border-b border-border/60 flex items-start gap-2\">\n <Globe size={14} className=\"text-fg-subtle mt-0.5\" />\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-medium text-fg\">Sites the agent can use as you</h3>\n <p className=\"text-[11px] text-fg-faint mt-0.5 leading-snug\">\n On these sites, the Jarela browser extension may drive a tab on the agent's behalf, and the\n agent's <code>web_fetch</code> tool gets your browser's cookies for direct requests.\n One approval enables both. Cookies are stored encrypted and never shown in this UI.\n </p>\n </div>\n </div>\n\n <div className=\"px-3 py-3 space-y-2\">\n {loading && <p className=\"text-fg-faint text-xs py-2\">Loading…</p>}\n\n {error && (\n <div className=\"px-2 py-1.5 rounded bg-rose-950/40 border border-rose-800 text-xs text-rose-700 dark:text-rose-300\">\n {error}\n </div>\n )}\n\n {!loading && sites.length === 0 && (\n <p className=\"text-fg-faint text-xs py-2\">No approved sites yet. Add one below, or approve a host\n from the in-browser dialog when the agent first asks to use a site.</p>\n )}\n\n {sites.length > 0 && (\n <ul className=\"divide-y divide-border/60 rounded border border-border/60 bg-surface-3\">\n {sites.map((s) => (\n <li key={s.hostname} className=\"px-2.5 py-2 flex items-center gap-3\">\n <code className=\"text-xs text-fg font-mono flex-1 min-w-0 truncate\">{s.hostname}</code>\n <span className=\"text-[10px] text-fg-faint shrink-0\">\n {s.has_cookies\n ? `cookies updated ${formatRelative(s.cookies_updated_at)}`\n : \"no cookies yet\"}\n </span>\n <label\n className=\"text-[10px] inline-flex items-center gap-1 text-fg-muted cursor-pointer shrink-0\"\n title=\"Allow web_fetch to reach private/loopback addresses for this host (intranet)\"\n >\n <input\n type=\"checkbox\"\n checked={s.ssrf_bypass}\n onChange={() => toggleBypass(s)}\n className=\"accent-amber-500\"\n />\n intranet\n </label>\n <button\n onClick={() => remove(s)}\n className=\"text-fg-faint hover:text-rose-700 dark:hover:text-rose-400 shrink-0\"\n title=\"Remove this host\"\n >\n <Trash2 size={12} />\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <div className=\"flex items-center gap-2 pt-1\">\n <input\n type=\"text\"\n value={newHost}\n onChange={(e) => setNewHost(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") void add(); }}\n placeholder=\"jira.example.com\"\n spellCheck={false}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n className=\"flex-1 px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n <label\n className=\"text-[11px] inline-flex items-center gap-1 text-fg-muted cursor-pointer\"\n title=\"Allow web_fetch to reach private/loopback addresses for this host (intranet)\"\n >\n <input\n type=\"checkbox\"\n checked={newBypass}\n onChange={(e) => setNewBypass(e.target.checked)}\n className=\"accent-amber-500\"\n />\n intranet\n </label>\n <button\n onClick={() => { void add(); }}\n disabled={adding || !newHost.trim()}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-xs rounded bg-accent text-white hover:bg-accent-hover disabled:opacity-50\"\n >\n {adding ? <Loader2 size={11} className=\"animate-spin\" /> : <Plus size={11} />}\n Approve\n </button>\n </div>\n\n {newBypass && (\n <div className=\"px-2 py-1.5 rounded bg-amber-950/30 border border-amber-800 text-[11px] text-amber-700 dark:text-amber-300 inline-flex items-start gap-1.5\">\n <ShieldAlert size={12} className=\"mt-0.5 shrink-0\" />\n <span>\n Intranet bypass lets the agent reach private/loopback addresses for this host. Only enable for\n hosts you actually run on the corp network.\n </span>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction formatRelative(iso: string | null): string {\n if (!iso) return \"never\";\n const t = new Date(iso).getTime();\n if (Number.isNaN(t)) return \"never\";\n const sec = Math.max(0, Math.floor((Date.now() - t) / 1000));\n if (sec < 60) return \"just now\";\n if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;\n if (sec < 86400) return `${Math.floor(sec / 3600)}h ago`;\n return `${Math.floor(sec / 86400)}d ago`;\n}\n","\"use client\";\n\n// Editor for the env-sync allowlist overrides. Users see the default\n// env-var aliases (read-only chips) and can add their own additional\n// aliases per (integration, field) — lets a dotfile that names tokens\n// `MY_ANT_KEY` still feed `anthropic.api_key`. Save calls\n// /api/v1/env-sync/allowlist (PUT). The integration + field side is\n// fixed by the schema in INTEGRATIONS; this UI never lets users invent\n// new targets.\n\nimport { useEffect, useState } from \"react\";\nimport { Loader2, Save, X } from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport type { EnvAllowlistConfig, EnvAllowlistMapping } from \"@/api/types\";\n\nconst ROW_KEY = (integration: string, field: string) => `${integration}:${field}`;\n\nexport function EnvAliasEditor({ onClose, onSaved }: { onClose: () => void; onSaved: () => void }) {\n const [config, setConfig] = useState<EnvAllowlistConfig | null>(null);\n const [drafts, setDrafts] = useState<Record<string, string>>({});\n const [savingKey, setSavingKey] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n void api.envSync.allowlist.get().then((c) => {\n setConfig(c);\n const initial: Record<string, string> = {};\n for (const m of c.defaults) {\n initial[ROW_KEY(m.integration, m.field)] = (c.overrides[ROW_KEY(m.integration, m.field)] ?? []).join(\", \");\n }\n setDrafts(initial);\n }).catch((e) => setError(e instanceof Error ? e.message : String(e)));\n }, []);\n\n async function saveRow(m: EnvAllowlistMapping) {\n const key = ROW_KEY(m.integration, m.field);\n const envVars = drafts[key]\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n setSavingKey(key);\n setError(null);\n try {\n const next = await api.envSync.allowlist.set(m.integration, m.field, envVars);\n setConfig(next);\n setDrafts((d) => ({ ...d, [key]: (next.overrides[key] ?? []).join(\", \") }));\n onSaved();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setSavingKey(null);\n }\n }\n\n return (\n <div className=\"mb-3 px-3 py-3 rounded border border-border bg-surface-2 text-[11px]\">\n <div className=\"flex items-start gap-2 mb-2\">\n <span className=\"font-semibold text-fg flex-1\">Env-sync aliases</span>\n <button onClick={onClose} className=\"text-fg-faint hover:text-fg\" aria-label=\"Close alias editor\">\n <X size={12} />\n </button>\n </div>\n <p className=\"text-fg-faint mb-3\">\n Default names are always checked. Add your own aliases (comma-separated) per row when your dotfile uses a different name.\n </p>\n {error && (\n <div className=\"mb-2 px-2 py-1 rounded border border-border bg-surface-3 text-fg\">{error}</div>\n )}\n {config === null ? (\n <p className=\"text-fg-faint\">Loading…</p>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {config.defaults.map((m) => {\n const key = ROW_KEY(m.integration, m.field);\n return (\n <div key={key} className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-fg-muted min-w-[120px]\">\n {m.integration}.{m.field}\n </span>\n <span className=\"flex flex-wrap gap-1\">\n {m.envVars.map((v) => (\n <span key={v} className=\"px-1.5 py-0.5 rounded bg-surface-3 text-fg-faint border border-border\">\n {v}\n </span>\n ))}\n </span>\n <input\n type=\"text\"\n value={drafts[key] ?? \"\"}\n onChange={(e) => setDrafts((d) => ({ ...d, [key]: e.target.value }))}\n placeholder=\"MY_OTHER_NAME, SOMETHING_ELSE\"\n className=\"flex-1 min-w-[160px] px-2 py-1 rounded border border-border bg-surface text-fg\"\n />\n <button\n onClick={() => saveRow(m)}\n disabled={savingKey === key}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded border border-border text-fg-muted hover:bg-surface-3 disabled:opacity-50\"\n >\n {savingKey === key ? <Loader2 size={11} className=\"animate-spin\" /> : <Save size={11} />}\n Save\n </button>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { Globe, Loader2, RefreshCw, Settings2, Terminal, XCircle } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { NetworkSection } from \"./NetworkSection\";\nimport { AllowedSitesSection } from \"./AllowedSitesSection\";\nimport { EnvAliasEditor } from \"./EnvAliasEditor\";\n\n// \"Network & environment\" hosts everything that's NOT a credential: HTTP\n// proxy, allowed sites, env-var aliases, and the env-sync button that\n// pulls credential env vars (GITHUB_TOKEN, ATLASSIAN_API_TOKEN, …) from\n// the user's shell rc / Windows User env into the unified credentials\n// store. Per-integration auth (keys + OAuth) lives in the sibling\n// Credentials sub-tab.\n\nexport function NetworkPanel() {\n const [syncing, setSyncing] = useState(false);\n const [syncMsg, setSyncMsg] = useState<string | null>(null);\n const [aliasEditorOpen, setAliasEditorOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"credentials\", \"network\", containerRef);\n\n async function syncFromEnv() {\n setSyncing(true);\n setSyncMsg(null);\n try {\n const r = await api.envSync.apply();\n const sourceLabel = r.discovered.source === \"shell-rc\"\n ? `your ${r.discovered.shell ?? \"shell\"} rc`\n : r.discovered.source === \"windows-registry\"\n ? \"your Windows User env\"\n : \"the process env\";\n if (r.applied_count > 0) {\n setSyncMsg(`Synced ${r.applied_count} field(s) from ${sourceLabel}.`);\n } else {\n const userSkipped = r.candidates.filter((c) => c.action === \"skipped-user\").length;\n const equal = r.candidates.filter((c) => c.action === \"skipped-equal\").length;\n const absent = r.candidates.filter((c) => c.action === \"absent\").length;\n if (userSkipped > 0) {\n setSyncMsg(`Nothing to write — ${userSkipped} field(s) were edited here and won't be overwritten.`);\n } else if (equal > 0 && absent === r.candidates.length - equal) {\n setSyncMsg(`Already up to date with ${sourceLabel}.`);\n } else {\n setSyncMsg(`No matching env vars set in ${sourceLabel}.`);\n }\n }\n // Notify the Credentials list so it re-loads any newly-synced rows.\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"jarela:credentials-changed\"));\n }\n } catch (e) {\n setSyncMsg(e instanceof Error ? e.message : String(e));\n } finally {\n setSyncing(false);\n }\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Globe size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Network & environment</h2>\n <button\n onClick={() => setAliasEditorOpen((v) => !v)}\n title=\"Add additional env-var name aliases that env-sync should look for, per integration field.\"\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:bg-surface-3\"\n >\n <Settings2 size={11} />\n Aliases\n </button>\n <button\n onClick={syncFromEnv}\n disabled={syncing}\n title=\"Pull standard credential env vars (GITHUB_TOKEN, ATLASSIAN_API_TOKEN, …) from your shell rc / Windows User env into the Credentials list. Fields you've edited there are never overwritten.\"\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:bg-surface-3 disabled:opacity-50\"\n >\n {syncing ? <Loader2 size={11} className=\"animate-spin\" /> : <RefreshCw size={11} />}\n Sync from environment\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-3\">\n {syncMsg && (\n <div className=\"mb-3 px-3 py-2 rounded border border-border bg-surface-2 text-[11px] text-fg-muted flex items-start gap-2\">\n <Terminal size={12} className=\"mt-0.5 text-fg-subtle shrink-0\" />\n <span className=\"flex-1\">{syncMsg}</span>\n <button onClick={() => setSyncMsg(null)} className=\"text-fg-faint hover:text-fg\">\n <XCircle size={12} />\n </button>\n </div>\n )}\n {aliasEditorOpen && (\n <EnvAliasEditor\n onClose={() => setAliasEditorOpen(false)}\n onSaved={() => { /* re-sync happens on next click of Sync button; nothing to refresh here */ }}\n />\n )}\n <NetworkSection />\n <AllowedSitesSection />\n </div>\n </div>\n );\n}\n","// Persona → integration-category filter.\n//\n// The Credentials panel is overwhelming on first boot because *every*\n// integration is shown to every user. Most home users do not need Jira,\n// most work users do not need a personal LLM key separate from the\n// chat-bot keys, and a casual chat user does not want to see GitHub /\n// infrastructure tokens at all.\n//\n// We let the user pick a single \"preset\" in the Profile editor and use\n// it to filter the Credentials list. Picking \"custom\" (or leaving it\n// unset → null) shows everything — exactly today's behaviour.\n//\n// This mapping is intentionally small and conservative: a \"home\" user\n// still gets LLM keys (otherwise nothing works), and a \"work\" user\n// still gets mail/calendar/issue-tracker/infrastructure (today's\n// office toolbelt). \"dev\" sees everything, same as \"custom\".\n\nimport type { IntegrationCategory } from \"@/lib/stores/integrations\";\nimport type { UserPreset } from \"@/lib/stores/user-profile\";\n\nexport const PRESET_CATEGORIES: Record<UserPreset, ReadonlySet<IntegrationCategory> | null> = {\n home: new Set<IntegrationCategory>([\"llm\", \"mail\", \"calendar\", \"chat\", \"other\"]),\n work: new Set<IntegrationCategory>([\"llm\", \"mail\", \"calendar\", \"issue-tracker\", \"infrastructure\", \"other\"]),\n dev: null, // null = show all\n custom: null, // null = show all\n};\n\n/** Returns true when the given integration category should be visible for the given preset. */\nexport function isCategoryVisible(\n preset: UserPreset | null | undefined,\n category: IntegrationCategory | undefined,\n): boolean {\n if (!preset) return true; // unset → show all\n const allowed = PRESET_CATEGORIES[preset];\n if (allowed === null) return true; // dev / custom → show all\n if (!category) return true; // legacy entries without category → show\n return allowed.has(category);\n}\n","\"use client\";\nimport { Filter, Key, Pencil, Plus, Trash2 } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { Credential, IntegrationDefinition, IntegrationStatus, UserProfile } from \"@/api/types\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { NetworkPanel } from \"@/components/integrations/NetworkPanel\";\nimport { PRESET_CATEGORIES } from \"@/lib/integrations/categories\";\nimport { AddCredentialDialog } from \"./AddCredentialDialog\";\nimport { IntegrationCard } from \"./IntegrationCard\";\n\n// \"Credentials\" is the single home for every auth surface. The default\n// sub-tab is the unified list: model API keys, integration keys, and\n// OAuth (Gmail/Outlook/etc.) all live here, grouped by category, with\n// each known integration rendered as an inline editor (save / test /\n// Connect). The sibling \"Network & environment\" sub-tab hosts the\n// non-auth bits — HTTP proxy, allowed sites, env-var aliases, and the\n// env-sync button.\n//\n// MCP servers (a capability, not an auth) live under Tools. Result: one\n// mental model — *Credentials* answers \"what accounts has this agent\n// been given access to\".\n\ntype Sub = \"list\" | \"network\";\n\nconst SUB_TITLES: Record<Sub, string> = {\n list: \"Credentials\",\n network: \"Network & environment\",\n};\n\ntype Category = NonNullable<IntegrationDefinition[\"category\"]>;\n\nconst CATEGORY_ORDER: Category[] = [\n \"llm\",\n \"mail\",\n \"calendar\",\n \"issue-tracker\",\n \"infrastructure\",\n \"chat\",\n \"other\",\n];\n\nconst CATEGORY_LABELS: Record<Category, string> = {\n llm: \"Model providers (LLM)\",\n mail: \"Mail\",\n calendar: \"Calendar\",\n \"issue-tracker\": \"Issue trackers\",\n infrastructure: \"Infrastructure\",\n chat: \"Chat\",\n other: \"Other\",\n};\n\nconst PRESET_LABELS: Record<NonNullable<UserProfile[\"preset\"]>, string> = {\n home: \"Home\",\n work: \"Work\",\n dev: \"Developer\",\n custom: \"Everything\",\n};\n\nfunction describeCredential(c: Credential): string {\n const keys = Object.keys(c.params).filter((k) => k !== \"base_url\" && k !== \"extra_headers\");\n if (keys.length === 0) return \"Not configured\";\n if (c.auth_method === \"oauth\") {\n return c.params.refresh_token ? \"Refresh token stored\" : \"OAuth pending\";\n }\n return `Fields: ${keys.join(\", \")}`;\n}\n\nexport function CredentialsPanel() {\n const { state, dispatch } = useAppContext();\n const raw = state.selectedItem.credentials;\n // Backward compatibility: the second sub-tab used to be keyed\n // \"integrations\" (when it was called \"Built-in integrations\"). Honour\n // older deep links and saved selections by routing them to the new\n // \"network\" key.\n const active: Sub = raw === \"network\" || raw === \"integrations\" ? \"network\" : \"list\";\n\n const setSub = (s: Sub) =>\n dispatch({ type: \"SET_SELECTION\", tab: \"credentials\", itemId: s });\n\n return (\n <div className=\"flex flex-col h-full min-h-0\">\n <div\n role=\"tablist\"\n aria-label=\"Credentials sub-section\"\n className=\"flex gap-1 border-b border-[var(--border)] bg-[var(--bg-secondary)] px-3 pt-2\"\n >\n {([\"list\", \"network\"] as Sub[]).map((s) => {\n const selected = s === active;\n return (\n <button\n key={s}\n role=\"tab\"\n type=\"button\"\n aria-selected={selected}\n onClick={() => setSub(s)}\n className={\n \"px-3 py-1.5 text-sm rounded-t-md border-b-2 -mb-px transition-colors \" +\n (selected\n ? \"border-[var(--accent)] text-[var(--text-primary)] bg-[var(--bg-primary)]\"\n : \"border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]\")\n }\n >\n {SUB_TITLES[s]}\n </button>\n );\n })}\n </div>\n <div className=\"flex-1 min-h-0 overflow-auto\">\n {active === \"list\" ? <CredentialsListPanel /> : <NetworkPanel />}\n </div>\n </div>\n );\n}\n\nfunction CredentialsListPanel() {\n const { dispatch } = useAppContext();\n const [credentials, setCredentials] = useState<Credential[]>([]);\n const [defs, setDefs] = useState<IntegrationDefinition[]>([]);\n const [statuses, setStatuses] = useState<Record<string, IntegrationStatus>>({});\n const [preset, setPreset] = useState<UserProfile[\"preset\"]>(null);\n const [loading, setLoading] = useState(true);\n const [addOpen, setAddOpen] = useState(false);\n const [editingProvider, setEditingProvider] = useState<string | null>(null);\n const [expandedProvider, setExpandedProvider] = useState<string | null>(null);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"credentials\", \"credential\", containerRef);\n useDeepLinkScroll(\"credentials\", \"integration\", containerRef);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [rows, ints, profile] = await Promise.all([\n api.credentials.list(),\n api.integrations.list().catch(() => ({ definitions: [] as IntegrationDefinition[], statuses: [] as IntegrationStatus[] })),\n api.profile.get().catch(() => null),\n ]);\n setCredentials(rows);\n setDefs(ints.definitions);\n setStatuses(Object.fromEntries(ints.statuses.map((s) => [s.name, s])));\n setPreset(profile?.preset ?? null);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n refresh();\n const onChange = () => refresh();\n if (typeof window !== \"undefined\") window.addEventListener(\"jarela:credentials-changed\", onChange);\n return () => {\n if (typeof window !== \"undefined\") window.removeEventListener(\"jarela:credentials-changed\", onChange);\n };\n }, [refresh]);\n\n const defByName = useMemo(() => {\n const m = new Map<string, IntegrationDefinition>();\n for (const d of defs) m.set(d.name, d);\n return m;\n }, [defs]);\n\n async function handleDelete(c: Credential) {\n setDeleteError(null);\n try {\n if (c.type === \"integration\") {\n await api.integrations.delete(c.provider);\n } else {\n await api.credentials.delete(c.id);\n }\n refresh();\n } catch (e) {\n setDeleteError(`Could not delete \"${c.id}\": ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n // Persona filter: if the user has chosen a preset, hide unconfigured\n // integrations outside that bucket. Configured-but-out-of-bucket\n // entries stay visible so a saved credential never silently vanishes.\n const visibleDefs = useMemo(() => {\n if (!preset) return defs;\n const allowed = PRESET_CATEGORIES[preset];\n if (allowed === null) return defs;\n return defs.filter((def) => {\n if (!def.category) return true;\n if (allowed.has(def.category)) return true;\n return statuses[def.name]?.configured === true;\n });\n }, [defs, preset, statuses]);\n\n const hiddenCount = defs.length - visibleDefs.length;\n\n // Group: every visible definition belongs in its category bucket\n // (renders as IntegrationCard); credentials WITHOUT a matching\n // definition (legacy model rows etc.) also fall into the right\n // bucket so the user sees a single grouped list.\n const grouped = useMemo(() => {\n type Row =\n | { kind: \"def\"; def: IntegrationDefinition }\n | { kind: \"credential\"; credential: Credential };\n const byCat = new Map<Category, Row[]>();\n const defNames = new Set(visibleDefs.map((d) => d.name));\n\n for (const def of visibleDefs) {\n const cat = (def.category ?? \"other\") as Category;\n const arr = byCat.get(cat) ?? [];\n arr.push({ kind: \"def\", def });\n byCat.set(cat, arr);\n }\n for (const c of credentials) {\n if (defNames.has(c.provider)) continue; // covered by the integration card\n const cat = (defByName.get(c.provider)?.category ?? \"other\") as Category;\n const arr = byCat.get(cat) ?? [];\n arr.push({ kind: \"credential\", credential: c });\n byCat.set(cat, arr);\n }\n return CATEGORY_ORDER\n .filter((c) => byCat.has(c))\n .map((c) => [c, byCat.get(c)!] as const);\n }, [visibleDefs, credentials, defByName]);\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Key size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Credentials</h2>\n {preset && preset !== \"custom\" && (\n <button\n type=\"button\"\n onClick={() => dispatch({ type: \"SET_TAB\", tab: \"profile\" })}\n title={`Filtered to \"${PRESET_LABELS[preset]}\" preset. Click to change in Profile.`}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded-full border border-border bg-surface-2 text-fg-muted hover:bg-surface-3\"\n >\n <Filter size={11} />\n <span>{PRESET_LABELS[preset]}</span>\n {hiddenCount > 0 && (\n <span className=\"text-fg-faint\">· {hiddenCount} hidden</span>\n )}\n </button>\n )}\n <button\n onClick={() => setAddOpen(true)}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\"\n title=\"Pick a provider and connect it. Same editors are available inline below.\"\n >\n <Plus size={14} /> Add credential\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto\">\n <div className=\"px-4 py-2 space-y-4\">\n {loading && credentials.length === 0 && defs.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && grouped.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">\n No credentials yet. Click <span className=\"font-medium\">+ Add credential</span> to connect a model provider (OpenAI, Anthropic, Gemini…) or an integration (Gmail, GitHub, Atlassian…).\n </p>\n )}\n {deleteError && (\n <p className=\"text-red-700 dark:text-red-400 text-xs mb-2 px-1\">{deleteError}</p>\n )}\n {grouped.map(([cat, rows]) => (\n <section key={cat}>\n <h3 className=\"text-[11px] uppercase tracking-wide text-fg-faint mb-1 px-1\">{CATEGORY_LABELS[cat]}</h3>\n <div className=\"space-y-2\">\n {rows.map((row) => {\n if (row.kind === \"def\") {\n const def = row.def;\n const status = statuses[def.name];\n const isOpen = expandedProvider === def.name || !!status?.configured;\n if (!isOpen) {\n // Collapse unconfigured integrations into a compact row.\n return (\n <div\n key={def.name}\n data-deep-link-id={def.name}\n className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg border border-border/60 bg-surface-2/40\"\n >\n <div className=\"w-1.5 h-1.5 rounded-full bg-fg-faint\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-sm font-medium text-fg truncate\">{def.label}</span>\n <span className=\"text-[10px] px-1.5 py-0.5 rounded border bg-surface-3 text-fg-muted border-border font-mono\">{def.name}</span>\n </div>\n <p className=\"text-[11px] text-fg-subtle truncate\">{def.description}</p>\n </div>\n <button\n onClick={() => setExpandedProvider(def.name)}\n className=\"text-[11px] text-accent hover:text-accent-hover shrink-0\"\n title=\"Open editor\"\n >\n Connect\n </button>\n </div>\n );\n }\n return (\n <IntegrationCard\n key={def.name}\n definition={def}\n status={status}\n onChanged={refresh}\n />\n );\n }\n // Legacy credential row (no matching integration definition).\n const c = row.credential;\n return (\n <div key={c.id} data-deep-link-id={c.id} className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg border border-border/60 bg-surface-2/40 group\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-sm font-medium text-fg truncate\">{c.provider}</span>\n <span className=\"text-[10px] px-1.5 py-0.5 rounded border bg-surface-3 text-fg-muted border-border font-mono\">{c.provider}</span>\n <span className=\"text-[10px] text-fg-faint\">{c.auth_method}</span>\n </div>\n <p className=\"text-[11px] text-fg-subtle\">{describeCredential(c)}</p>\n </div>\n <div className=\"flex gap-1 opacity-40 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n <button\n onClick={() => setEditingProvider(c.provider)}\n className=\"p-1 text-fg-subtle hover:text-fg transition-colors\"\n title=\"Edit credential\"\n >\n <Pencil size={13} />\n </button>\n <button\n onClick={() => handleDelete(c)}\n className=\"p-1 text-fg-subtle hover:text-red-700 dark:hover:text-red-400 transition-colors\"\n title=\"Delete\"\n >\n <Trash2 size={13} />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </section>\n ))}\n </div>\n </div>\n\n {addOpen && (\n <AddCredentialDialog\n onClose={() => { setAddOpen(false); refresh(); }}\n onSaved={() => refresh()}\n />\n )}\n {editingProvider && (\n <AddCredentialDialog\n directProviderName={editingProvider}\n onClose={() => { setEditingProvider(null); refresh(); }}\n onSaved={() => refresh()}\n />\n )}\n </div>\n );\n}\n","\"use client\";\nimport { ArrowUp, Check, Folder, FolderOpen, Home, X } from \"lucide-react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport { api } from \"@/api/client\";\n\ninterface Props {\n initialPath?: string;\n onSelect: (path: string) => void;\n onClose: () => void;\n}\n\n// FolderPickerDialog — modal browser over the local filesystem via\n// /api/v1/fs/browse. Used by DocumentsPanel to add an indexed folder\n// without making the user type an absolute path. Hidden dotfiles are\n// filtered server-side; users can paste a path into the text input\n// at the top to jump anywhere they have read access to.\nexport function FolderPickerDialog({ initialPath, onSelect, onClose }: Props) {\n const [cwd, setCwd] = useState<string>(initialPath ?? \"\");\n const [parent, setParent] = useState<string | null>(null);\n const [home, setHome] = useState<string>(\"\");\n const [entries, setEntries] = useState<{ name: string; path: string }[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pathInput, setPathInput] = useState<string>(initialPath ?? \"\");\n\n const navigate = useCallback(async (target?: string) => {\n setLoading(true);\n setError(null);\n try {\n const res = await api.fs.browse(target);\n setCwd(res.path);\n setParent(res.parent);\n setHome(res.home);\n setEntries(res.entries);\n setPathInput(res.path);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => { void navigate(initialPath); }, [initialPath, navigate]);\n\n useEscapeKey(onClose);\n\n function jumpToPath(e: React.FormEvent) {\n e.preventDefault();\n if (!pathInput.trim()) return;\n void navigate(pathInput.trim());\n }\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4\">\n <div className=\"bg-surface-2 border border-border rounded-2xl w-full max-w-lg shadow-xl flex flex-col\" style={{ maxHeight: \"80vh\" }}>\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h3 className=\"text-sm font-semibold text-fg flex items-center gap-2\">\n <FolderOpen size={14} /> Pick a folder\n </h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\"><X size={16} /></button>\n </div>\n\n <div className=\"px-4 py-3 border-b border-border space-y-2\">\n <form onSubmit={jumpToPath} className=\"flex items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={() => void navigate(home)}\n title=\"Go to home\"\n className=\"p-1.5 rounded-md text-fg-subtle hover:text-fg hover:bg-surface-3\"\n >\n <Home size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => parent && void navigate(parent)}\n disabled={!parent}\n title=\"Go up\"\n className=\"p-1.5 rounded-md text-fg-subtle hover:text-fg hover:bg-surface-3 disabled:opacity-30 disabled:hover:bg-transparent\"\n >\n <ArrowUp size={14} />\n </button>\n <input\n type=\"text\"\n value={pathInput}\n onChange={(e) => setPathInput(e.target.value)}\n className=\"flex-1 min-w-0 px-2 py-1 rounded-md bg-surface-3 border border-border text-xs text-fg font-mono focus:outline-none focus:ring-1 focus:ring-accent\"\n />\n </form>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-2 py-1.5\">\n {loading && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && error && (\n <p className=\"text-red-600 dark:text-red-400 text-xs px-2 py-3\">{error}</p>\n )}\n {!loading && !error && entries.length === 0 && (\n <p className=\"text-fg-faint text-xs italic px-2 py-3\">No subfolders here.</p>\n )}\n {!loading && !error && entries.map((e) => (\n <button\n key={e.path}\n type=\"button\"\n onDoubleClick={() => void navigate(e.path)}\n onClick={() => void navigate(e.path)}\n className=\"flex items-center gap-2 w-full px-2 py-1.5 rounded-md text-left text-xs text-fg hover:bg-surface-3\"\n title={e.path}\n >\n <Folder size={13} className=\"text-accent shrink-0\" />\n <span className=\"truncate\">{e.name}</span>\n </button>\n ))}\n </div>\n\n <div className=\"flex justify-between items-center gap-2 px-4 py-3 border-t border-border\">\n <span className=\"text-[11px] text-fg-faint font-mono truncate flex-1\" title={cwd}>{cwd}</span>\n <button\n onClick={onClose}\n className=\"px-3 py-1.5 text-sm text-fg-subtle hover:text-fg transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={() => onSelect(cwd)}\n disabled={!cwd || loading}\n className=\"flex items-center gap-1.5 px-4 py-1.5 text-sm bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors disabled:opacity-50\"\n >\n <Check size={13} /> Use this folder\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import type { DocumentSource, DocumentSourceKind } from \"@/api/types\";\n\nexport const KIND_OPTIONS: Array<{ value: DocumentSourceKind; label: string }> = [\n { value: \"local_folder\", label: \"Local folder\" },\n { value: \"jira_project\", label: \"Jira project\" },\n { value: \"jira_jql\", label: \"Jira JQL\" },\n { value: \"confluence_space\", label: \"Confluence space\" },\n { value: \"confluence_cql\", label: \"Confluence CQL\" },\n { value: \"github_pulls\", label: \"GitHub pull requests\" },\n { value: \"github_repo\", label: \"GitHub repo files\" },\n { value: \"gmail_mail\", label: \"Gmail mail\" },\n { value: \"outlook_mail\", label: \"Outlook mail\" },\n];\n\nexport function isGithubKind(k: DocumentSourceKind): boolean {\n return k === \"github_pulls\" || k === \"github_repo\";\n}\n\nexport function isMailKind(k: DocumentSourceKind): boolean {\n return k === \"gmail_mail\" || k === \"outlook_mail\";\n}\n\nexport function summarizeRemote(s: DocumentSource): string {\n const c = s.config ?? {};\n switch (s.kind) {\n case \"jira_project\": return `Jira project: ${String(c.project_key ?? \"?\")}`;\n case \"jira_jql\": return `Jira JQL: ${String(c.jql ?? \"?\")}`;\n case \"confluence_space\": return `Confluence space: ${String(c.space_key ?? \"?\")}`;\n case \"confluence_cql\": return `Confluence CQL: ${String(c.cql ?? \"?\")}`;\n case \"github_pulls\": {\n const slug = `${String(c.owner ?? \"?\")}/${String(c.repo ?? \"?\")}`;\n return `GitHub PRs: ${slug}`;\n }\n case \"github_repo\": {\n const slug = `${String(c.owner ?? \"?\")}/${String(c.repo ?? \"?\")}`;\n const ref = c.ref ? `@${String(c.ref)}` : \"\";\n const prefix = c.path_prefix ? ` /${String(c.path_prefix).replace(/^\\/+|\\/+$/g, \"\")}` : \"\";\n return `GitHub repo: ${slug}${ref}${prefix}`;\n }\n case \"gmail_mail\": return `Gmail: ${String(c.query ?? \"?\")}`;\n case \"outlook_mail\": return `Outlook: ${String(c.query ?? \"?\")}`;\n default: return s.path;\n }\n}\n","\"use client\";\nimport { FolderOpen, Plus } from \"lucide-react\";\nimport type { Dispatch, SetStateAction } from \"react\";\nimport type { DocumentSourceKind } from \"@/api/types\";\nimport { isGithubKind, isMailKind } from \"./helpers\";\n\nexport interface FormState {\n addKind: DocumentSourceKind;\n addPath: string;\n addLabel: string;\n addProjectKey: string;\n addSpaceKey: string;\n addQuery: string;\n addMailQuery: string;\n addMailMaxResults: string;\n addMailPageSize: string;\n addRecencyDays: string;\n addGhOwner: string;\n addGhRepo: string;\n addGhRef: string;\n addGhPathPrefix: string;\n addGhState: \"all\" | \"open\" | \"closed\";\n}\n\nexport type SetField = <K extends keyof FormState>(k: K, v: FormState[K]) => void;\n\ninterface FieldsProps {\n state: FormState;\n set: SetField;\n disabled: boolean;\n canSubmit: boolean;\n onSubmit: () => void;\n onOpenPicker?: () => void;\n}\n\nexport function LocalFolderFields(props: FieldsProps) {\n const { state, set, disabled, canSubmit, onSubmit, onOpenPicker } = props;\n return (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <div className=\"flex flex-1 min-w-0 gap-1\">\n <input\n type=\"text\"\n value={state.addPath}\n onChange={(e) => set(\"addPath\", e.target.value)}\n placeholder=\"Pick or paste an absolute path\"\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n <button\n type=\"button\"\n onClick={onOpenPicker}\n title=\"Browse for a folder\"\n className=\"flex items-center gap-1 px-2 py-1.5 rounded-md bg-surface-3 border border-border text-xs text-fg hover:bg-surface-2 transition-colors\"\n >\n <FolderOpen size={13} /> Browse\n </button>\n </div>\n <input\n type=\"text\"\n value={state.addLabel}\n onChange={(e) => set(\"addLabel\", e.target.value)}\n placeholder=\"Label (optional)\"\n className=\"sm:w-40 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n <SubmitButton disabled={disabled || !canSubmit} onClick={onSubmit} />\n </div>\n );\n}\n\nexport function RemoteSourceFields(props: FieldsProps) {\n return (\n <div className=\"space-y-2\">\n <RemoteKindInputs state={props.state} set={props.set} />\n <RemoteLabelRow {...props} />\n </div>\n );\n}\n\nfunction RemoteKindInputs({ state, set }: { state: FormState; set: SetField }) {\n return (\n <>\n {state.addKind === \"jira_project\" && (\n <input\n type=\"text\"\n value={state.addProjectKey}\n onChange={(e) => set(\"addProjectKey\", e.target.value)}\n placeholder='Project key (e.g. \"ACME\")'\n className=\"w-full px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n )}\n {state.addKind === \"confluence_space\" && (\n <input\n type=\"text\"\n value={state.addSpaceKey}\n onChange={(e) => set(\"addSpaceKey\", e.target.value)}\n placeholder='Space key (e.g. \"ENG\")'\n className=\"w-full px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n )}\n {(state.addKind === \"jira_jql\" || state.addKind === \"confluence_cql\") && (\n <textarea\n value={state.addQuery}\n onChange={(e) => set(\"addQuery\", e.target.value)}\n placeholder={\n state.addKind === \"jira_jql\"\n ? 'JQL — e.g. assignee = currentUser() AND resolution = Unresolved'\n : 'CQL — e.g. label = onboarding'\n }\n rows={2}\n className=\"w-full px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono resize-y\"\n />\n )}\n {isMailKind(state.addKind) && (\n <textarea\n value={state.addMailQuery}\n onChange={(e) => set(\"addMailQuery\", e.target.value)}\n placeholder={\n state.addKind === \"gmail_mail\"\n ? 'Gmail query — e.g. is:unread newer_than:7d'\n : 'KQL — e.g. isRead:false received>=2026-05-01'\n }\n rows={2}\n className=\"w-full px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono resize-y\"\n />\n )}\n {isGithubKind(state.addKind) && <GithubOwnerRepoInputs state={state} set={set} />}\n {state.addKind === \"github_pulls\" && (\n <select\n value={state.addGhState}\n onChange={(e) => set(\"addGhState\", e.target.value as FormState[\"addGhState\"])}\n className=\"w-full sm:w-44 px-2 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n title=\"Which PRs to index\"\n >\n <option value=\"all\">All PRs</option>\n <option value=\"open\">Open PRs only</option>\n <option value=\"closed\">Closed PRs only</option>\n </select>\n )}\n {state.addKind === \"github_repo\" && <GithubRepoExtras state={state} set={set} />}\n </>\n );\n}\n\nfunction GithubOwnerRepoInputs({ state, set }: { state: FormState; set: SetField }) {\n return (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n value={state.addGhOwner}\n onChange={(e) => set(\"addGhOwner\", e.target.value)}\n placeholder='Owner (e.g. \"octocat\")'\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n <input\n type=\"text\"\n value={state.addGhRepo}\n onChange={(e) => set(\"addGhRepo\", e.target.value)}\n placeholder='Repo (e.g. \"hello-world\")'\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n </div>\n );\n}\n\nfunction GithubRepoExtras({ state, set }: { state: FormState; set: SetField }) {\n return (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n value={state.addGhRef}\n onChange={(e) => set(\"addGhRef\", e.target.value)}\n placeholder=\"Ref (optional, default branch)\"\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n <input\n type=\"text\"\n value={state.addGhPathPrefix}\n onChange={(e) => set(\"addGhPathPrefix\", e.target.value)}\n placeholder=\"Path prefix (optional, e.g. docs)\"\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg font-mono\"\n />\n </div>\n );\n}\n\nfunction RemoteLabelRow({ state, set, disabled, canSubmit, onSubmit }: FieldsProps) {\n return (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n value={state.addLabel}\n onChange={(e) => set(\"addLabel\", e.target.value)}\n placeholder=\"Label (required)\"\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n {isMailKind(state.addKind) ? (\n <>\n <input\n type=\"number\"\n min={1}\n value={state.addMailMaxResults}\n onChange={(e) => set(\"addMailMaxResults\", e.target.value)}\n placeholder=\"Max results (optional)\"\n className=\"sm:w-44 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n <input\n type=\"number\"\n min={1}\n value={state.addMailPageSize}\n onChange={(e) => set(\"addMailPageSize\", e.target.value)}\n placeholder=\"Page size (optional)\"\n className=\"sm:w-40 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n </>\n ) : (\n <input\n type=\"number\"\n min={1}\n value={state.addRecencyDays}\n onChange={(e) => set(\"addRecencyDays\", e.target.value)}\n placeholder=\"Recency days (optional)\"\n className=\"sm:w-44 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n )}\n <SubmitButton disabled={disabled || !canSubmit} onClick={onSubmit} />\n </div>\n );\n}\n\nfunction SubmitButton({ disabled, onClick }: { disabled: boolean; onClick: () => void }) {\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className=\"flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-accent text-white text-xs font-medium disabled:opacity-50 hover:bg-accent-hover transition-colors\"\n >\n <Plus size={13} /> Add\n </button>\n );\n}\n\n// Hook helper so the form parent doesn't need to remember the SetState shape.\nexport function makeSetField(setState: Dispatch<SetStateAction<FormState>>): SetField {\n return (k, v) => setState((prev) => ({ ...prev, [k]: v }));\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport type { api } from \"@/api/client\";\nimport type { DocumentSourceKind } from \"@/api/types\";\nimport { FolderPickerDialog } from \"./FolderPickerDialog\";\nimport { KIND_OPTIONS, isGithubKind, isMailKind } from \"./helpers\";\nimport {\n LocalFolderFields,\n RemoteSourceFields,\n makeSetField,\n type FormState,\n} from \"./AddSourceFields\";\n\ntype CreatePayload = Parameters<typeof api.documents.createSource>[0];\n\ninterface Props {\n disabled: boolean;\n onSubmit: (payload: CreatePayload) => Promise<void>;\n}\n\nconst INITIAL: FormState = {\n addKind: \"local_folder\",\n addPath: \"\",\n addLabel: \"\",\n addProjectKey: \"\",\n addSpaceKey: \"\",\n addQuery: \"\",\n addMailQuery: \"\",\n addMailMaxResults: \"\",\n addMailPageSize: \"\",\n addRecencyDays: \"\",\n addGhOwner: \"\",\n addGhRepo: \"\",\n addGhRef: \"\",\n addGhPathPrefix: \"\",\n addGhState: \"all\",\n};\n\nfunction buildPayload(s: FormState): CreatePayload | null {\n const label = s.addLabel.trim();\n if (s.addKind === \"local_folder\") {\n const trimmedPath = s.addPath.trim();\n if (!trimmedPath) return null;\n return { path: trimmedPath, label: label || null };\n }\n const config: Record<string, unknown> = {};\n if (s.addKind === \"jira_project\") {\n if (!s.addProjectKey.trim()) return null;\n config.project_key = s.addProjectKey.trim();\n } else if (s.addKind === \"confluence_space\") {\n if (!s.addSpaceKey.trim()) return null;\n config.space_key = s.addSpaceKey.trim();\n } else if (s.addKind === \"jira_jql\") {\n if (!s.addQuery.trim()) return null;\n config.jql = s.addQuery.trim();\n } else if (s.addKind === \"confluence_cql\") {\n if (!s.addQuery.trim()) return null;\n config.cql = s.addQuery.trim();\n } else if (isGithubKind(s.addKind)) {\n const owner = s.addGhOwner.trim();\n const repo = s.addGhRepo.trim();\n if (!owner || !repo) return null;\n config.owner = owner;\n config.repo = repo;\n if (s.addKind === \"github_pulls\") {\n config.state = s.addGhState;\n } else {\n const ref = s.addGhRef.trim();\n if (ref) config.ref = ref;\n const prefix = s.addGhPathPrefix.trim().replace(/^\\/+|\\/+$/g, \"\");\n if (prefix) config.path_prefix = prefix;\n }\n } else if (isMailKind(s.addKind)) {\n const v = s.addMailQuery.trim();\n if (!v) return null;\n config.query = v;\n const maxResults = parseInt(s.addMailMaxResults, 10);\n if (Number.isFinite(maxResults) && maxResults > 0) config.max_results = maxResults;\n const pageSize = parseInt(s.addMailPageSize, 10);\n if (Number.isFinite(pageSize) && pageSize > 0) config.page_size = pageSize;\n }\n const recency = parseInt(s.addRecencyDays, 10);\n if (Number.isFinite(recency) && recency > 0) config.recency_days = recency;\n if (!label) return null;\n return { kind: s.addKind, label, config };\n}\n\nfunction kindHint(kind: DocumentSourceKind): string {\n if (kind === \"local_folder\") return \"Pick a folder on this machine.\";\n if (kind === \"gmail_mail\") return \"Requires Gmail credentials (Credentials → Gmail).\";\n if (kind === \"outlook_mail\") return \"Requires Outlook credentials (Credentials → Outlook).\";\n if (isGithubKind(kind)) return \"Requires GitHub credentials (Credentials → GitHub).\";\n return \"Requires Atlassian credentials (Credentials → Atlassian).\";\n}\n\nexport function AddSourceForm({ disabled, onSubmit }: Props) {\n const [state, setState] = useState<FormState>(INITIAL);\n const [pickerOpen, setPickerOpen] = useState(false);\n const set = makeSetField(setState);\n const payload = buildPayload(state);\n\n async function handleSubmit() {\n if (!payload) return;\n try {\n await onSubmit(payload);\n setState({ ...INITIAL, addKind: state.addKind });\n } catch {\n // parent surfaces the error; keep form state for retry.\n }\n }\n\n const fieldProps = {\n state,\n set,\n disabled,\n canSubmit: payload !== null,\n onSubmit: () => void handleSubmit(),\n };\n\n return (\n <section className=\"space-y-2\">\n <label className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">Add a source</label>\n <div className=\"flex items-center gap-2\">\n <select\n value={state.addKind}\n onChange={(e) => setState({ ...INITIAL, addKind: e.target.value as DocumentSourceKind })}\n className=\"px-2 py-1.5 rounded-md bg-surface-2 border border-border text-xs text-fg\"\n >\n {KIND_OPTIONS.map((o) => (\n <option key={o.value} value={o.value}>{o.label}</option>\n ))}\n </select>\n <span className=\"text-[11px] text-fg-faint\">{kindHint(state.addKind)}</span>\n </div>\n\n {state.addKind === \"local_folder\"\n ? <LocalFolderFields {...fieldProps} onOpenPicker={() => setPickerOpen(true)} />\n : <RemoteSourceFields {...fieldProps} />}\n\n {pickerOpen && (\n <FolderPickerDialog\n initialPath={state.addPath.trim() || undefined}\n onClose={() => setPickerOpen(false)}\n onSelect={(picked) => {\n set(\"addPath\", picked);\n setPickerOpen(false);\n }}\n />\n )}\n </section>\n );\n}\n","\"use client\";\nimport type { ModelConfig } from \"@/api/types\";\nimport type { EmbeddingProbe } from \"./useDocumentsPanel\";\nimport type { computeFeatureReadiness } from \"@/lib/ui/feature-readiness\";\n\ninterface Props {\n models: ModelConfig[];\n embeddingModel: string;\n savingEmbeddingModel: boolean;\n embeddingProbe: EmbeddingProbe | null;\n readiness: ReturnType<typeof computeFeatureReadiness>;\n hasWorkingEmbeddingModel: boolean;\n onSave: (value: string) => void;\n onOpenModels: () => void;\n}\n\nexport function EmbeddingModelSection(props: Props) {\n const {\n models, embeddingModel, savingEmbeddingModel, embeddingProbe,\n readiness, hasWorkingEmbeddingModel, onSave, onOpenModels,\n } = props;\n\n return (\n <section className=\"space-y-2\">\n <label className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">Embedding model</label>\n {!readiness.documentsReady && (\n <div className=\"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-800 dark:text-amber-200 leading-snug\">\n <p>\n Documents need an embeddings-capable model that this installation can already use. Add one in Models if semantic recall is important.\n </p>\n <p className=\"mt-1 text-amber-900/90 dark:text-amber-100/90\">\n Compatible setup: OpenAI, Gemini, and GitHub Copilot-backed setups are the main built-in paths here. If none is available, Documents falls back to substring search only.\n </p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={onOpenModels}\n className=\"rounded-md border border-amber-600/30 bg-white/50 px-2 py-1 text-[11px] font-medium text-amber-900 dark:bg-black/10 dark:text-amber-100\"\n >\n Open Models\n </button>\n </div>\n </div>\n )}\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <select\n value={embeddingModel}\n onChange={(e) => onSave(e.target.value)}\n disabled={savingEmbeddingModel}\n className=\"px-2 py-1.5 rounded-md bg-surface-2 border border-border text-xs text-fg disabled:opacity-60\"\n >\n <option value=\"__auto__\">Auto (best available)</option>\n {models.map((m) => (\n <option key={m.name} value={m.name}>{m.name} ({m.provider})</option>\n ))}\n </select>\n <span className=\"text-[11px] text-fg-faint\">\n Used for document chunk embeddings. Rescan applies this to all eligible chunks.\n </span>\n </div>\n {savingEmbeddingModel && (\n <p className=\"text-[11px] text-fg-faint\">Testing embedding model...</p>\n )}\n {!savingEmbeddingModel && embeddingProbe && (\n <p className={`text-[11px] ${embeddingProbe.ok ? \"text-emerald-500\" : \"text-red-400\"}`}>\n {embeddingProbe.ok\n ? `Usable: ${embeddingProbe.provider}/${embeddingProbe.model_id}` +\n (embeddingProbe.dimension ? ` (${embeddingProbe.dimension} dims)` : \"\")\n : `Not usable: ${embeddingProbe.error ?? \"embedding probe failed\"}`}\n </p>\n )}\n {!savingEmbeddingModel && models.length > 0 && !hasWorkingEmbeddingModel && (\n <div className=\"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-800 dark:text-amber-200 leading-snug\">\n <p>\n Current model setup does not appear ready for semantic document search yet. Add or switch to a model/provider with embeddings support in Models, then rescan your sources.\n </p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={onOpenModels}\n className=\"rounded-md border border-amber-600/30 bg-white/50 px-2 py-1 text-[11px] font-medium text-amber-900 dark:bg-black/10 dark:text-amber-100\"\n >\n Fix in Models\n </button>\n </div>\n </div>\n )}\n </section>\n );\n}\n","\"use client\";\nimport { Search } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { DocumentHit } from \"@/api/types\";\n\ninterface Props {\n onSearch: (query: string) => Promise<DocumentHit[]>;\n}\n\nexport function SearchProbe({ onSearch }: Props) {\n const [query, setQuery] = useState(\"\");\n const [hits, setHits] = useState<DocumentHit[]>([]);\n const [searching, setSearching] = useState(false);\n\n async function runSearch() {\n const q = query.trim();\n if (!q) { setHits([]); return; }\n setSearching(true);\n try {\n setHits(await onSearch(q));\n } finally {\n setSearching(false);\n }\n }\n\n return (\n <section className=\"space-y-2\">\n <label className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">Try a search</label>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") void runSearch(); }}\n placeholder=\"Ask something the docs would know…\"\n className=\"flex-1 min-w-0 px-2.5 py-1.5 rounded-md bg-surface-2 border border-border text-sm text-fg\"\n />\n <button\n onClick={() => void runSearch()}\n disabled={searching || !query.trim()}\n className=\"flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-accent text-white text-xs font-medium disabled:opacity-50 hover:bg-accent-hover transition-colors\"\n >\n <Search size={13} /> Search\n </button>\n </div>\n {hits.length > 0 && (\n <div className=\"space-y-2\">\n {hits.map((h) => (\n <div key={`${h.document_id}-${h.chunk_index}`} className=\"rounded-md border border-border bg-surface px-3 py-2 text-xs\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className=\"font-mono text-fg-muted truncate flex-1\">\n {h.source_label ? `${h.source_label} / ` : \"\"}{h.rel_path}\n </span>\n <span className=\"text-[10px] uppercase tracking-wide text-fg-faint shrink-0\">\n {h.match} · {h.score.toFixed(2)}\n </span>\n </div>\n <pre className=\"whitespace-pre-wrap text-fg-muted text-[11px] leading-relaxed font-sans line-clamp-6\">\n {h.text}\n </pre>\n </div>\n ))}\n </div>\n )}\n {!searching && query.trim() && hits.length === 0 && (\n <p className=\"text-fg-faint text-xs italic\">No hits — try different terms or add more folders above.</p>\n )}\n </section>\n );\n}\n","\"use client\";\nimport { Cloud, FolderOpen, RefreshCw, Trash2 } from \"lucide-react\";\nimport type { DocumentSource, DocumentSourceKind } from \"@/api/types\";\nimport { summarizeRemote } from \"./helpers\";\n\ninterface Props {\n sources: DocumentSource[];\n loading: boolean;\n busy: Record<string, boolean>;\n onReindex: (id: string) => void;\n onRemove: (id: string, summary: string, kind: DocumentSourceKind) => void;\n onToggle: (s: DocumentSource) => void;\n}\n\nexport function SourceList({ sources, loading, busy, onReindex, onRemove, onToggle }: Props) {\n return (\n <section className=\"space-y-2\">\n <label className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">Indexed sources</label>\n {loading && sources.length === 0 && (\n <p className=\"text-fg-faint text-sm py-3 text-center\">Loading…</p>\n )}\n {!loading && sources.length === 0 && (\n <p className=\"text-fg-faint text-xs italic\">\n No sources yet. Add one above to start indexing.\n </p>\n )}\n {sources.map((s) => (\n <SourceRow\n key={s.id}\n source={s}\n busy={!!busy[s.id]}\n onReindex={onReindex}\n onRemove={onRemove}\n onToggle={onToggle}\n />\n ))}\n </section>\n );\n}\n\ninterface RowProps {\n source: DocumentSource;\n busy: boolean;\n onReindex: (id: string) => void;\n onRemove: (id: string, summary: string, kind: DocumentSourceKind) => void;\n onToggle: (s: DocumentSource) => void;\n}\n\nfunction SourceRow({ source: s, busy, onReindex, onRemove, onToggle }: RowProps) {\n const summary = s.kind === \"local_folder\" ? s.path : summarizeRemote(s);\n return (\n <div className=\"rounded-lg border border-border bg-surface-2 px-3 py-2.5 space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n {s.kind === \"local_folder\"\n ? <FolderOpen size={13} className=\"text-fg-subtle shrink-0\" />\n : <Cloud size={13} className=\"text-fg-subtle shrink-0\" />}\n <span className=\"font-mono text-xs text-fg break-all flex-1\">\n {s.label ? <strong>{s.label}</strong> : null}\n {s.label ? <span className=\"text-fg-faint\"> — </span> : null}\n {summary}\n </span>\n <label className=\"text-[11px] text-fg-faint flex items-center gap-1 select-none\">\n <input\n type=\"checkbox\"\n checked={s.enabled}\n onChange={() => onToggle(s)}\n />\n enabled\n </label>\n <button\n onClick={() => onReindex(s.id)}\n disabled={busy}\n title=\"Re-scan now\"\n className=\"p-1 text-fg-subtle hover:text-fg disabled:opacity-40\"\n >\n <RefreshCw size={13} className={busy ? \"animate-spin\" : \"\"} />\n </button>\n <button\n onClick={() => onRemove(s.id, summary, s.kind)}\n title=\"Remove source\"\n className=\"p-1 text-fg-faint hover:text-red-600 dark:hover:text-red-400\"\n >\n <Trash2 size={13} />\n </button>\n </div>\n <div className=\"text-[11px] text-fg-faint flex flex-wrap gap-x-3 gap-y-0.5\">\n <span>{s.stats.document_count} files</span>\n <span>{s.stats.chunk_count} chunks</span>\n <span>{s.stats.embedded_chunk_count} embedded</span>\n {s.last_scan_at && <span>last scan: {new Date(s.last_scan_at).toLocaleString()}</span>}\n </div>\n {!s.last_error && s.stats.chunk_count > 0 && s.stats.embedded_chunk_count === 0 && (\n <div className=\"text-[11px] text-amber-700 dark:text-amber-400 break-words\">\n Warning: this source has chunks but zero embeddings. Semantic recall is degraded; check default model/provider embedding support.\n </div>\n )}\n {s.last_error && (\n <div className=\"text-[11px] text-red-600 dark:text-red-400 break-words\">\n Last error: {s.last_error}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { DocumentHit, DocumentSource, DocumentSourceKind, ModelConfig } from \"@/api/types\";\nimport { computeFeatureReadiness } from \"@/lib/ui/feature-readiness\";\nimport { isMailKind, summarizeRemote } from \"./helpers\";\n\nexport interface EmbeddingProbe {\n ok: boolean;\n provider: string;\n model_id: string;\n dimension?: number;\n error?: string;\n}\n\nexport interface UseDocumentsPanelResult {\n sources: DocumentSource[];\n loading: boolean;\n error: string | null;\n models: ModelConfig[];\n embeddingModel: string;\n savingEmbeddingModel: boolean;\n embeddingProbe: EmbeddingProbe | null;\n busy: Record<string, boolean>;\n readiness: ReturnType<typeof computeFeatureReadiness>;\n hasWorkingEmbeddingModel: boolean;\n load: () => Promise<void>;\n saveEmbeddingModel: (value: string) => Promise<void>;\n addSource: (payload: Parameters<typeof api.documents.createSource>[0]) => Promise<void>;\n reindex: (id: string) => Promise<void>;\n removeSource: (id: string, summary: string, kind: DocumentSourceKind) => Promise<void>;\n toggleSource: (s: DocumentSource) => Promise<void>;\n search: (q: string) => Promise<DocumentHit[]>;\n}\n\nexport function useDocumentsPanel(): UseDocumentsPanelResult {\n const [sources, setSources] = useState<DocumentSource[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [models, setModels] = useState<ModelConfig[]>([]);\n const [embeddingModel, setEmbeddingModel] = useState<string>(\"__auto__\");\n const [savingEmbeddingModel, setSavingEmbeddingModel] = useState(false);\n const [embeddingProbe, setEmbeddingProbe] = useState<EmbeddingProbe | null>(null);\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n\n async function load() {\n setLoading(true);\n setError(null);\n try {\n const [sourceRows, modelRows, settings] = await Promise.all([\n api.documents.listSources(),\n api.models.list(),\n api.documents.getSettings(),\n ]);\n setSources(sourceRows);\n setModels(modelRows);\n setEmbeddingModel(settings.embedding_model_config ?? \"__auto__\");\n setEmbeddingProbe(settings.embedding_probe ?? null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }\n\n useEffect(() => { void load(); }, []);\n\n async function saveEmbeddingModel(value: string) {\n const next = value === \"__auto__\" ? null : value;\n setEmbeddingModel(value);\n setSavingEmbeddingModel(true);\n setEmbeddingProbe(null);\n try {\n const updated = await api.documents.setSettings({ embedding_model_config: next });\n setEmbeddingModel(updated.embedding_model_config ?? \"__auto__\");\n setEmbeddingProbe(updated.embedding_probe ?? null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setSavingEmbeddingModel(false);\n }\n }\n\n async function addSource(payload: Parameters<typeof api.documents.createSource>[0]) {\n setError(null);\n try {\n await api.documents.createSource(payload);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n throw e;\n }\n }\n\n async function reindex(id: string) {\n setBusy((b) => ({ ...b, [id]: true }));\n try {\n const result = await api.documents.reindex(id);\n if ((result.stats.embed_failed ?? 0) > 0) {\n setError(\n `Embedding degraded: ${result.stats.embed_failed} chunk${result.stats.embed_failed === 1 ? \"\" : \"s\"} failed to embed` +\n (result.stats.embed_error ? ` (${result.stats.embed_error})` : \"\"),\n );\n }\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy((b) => ({ ...b, [id]: false }));\n }\n }\n\n async function removeSource(id: string, summary: string, kind: DocumentSourceKind) {\n const tail = kind === \"local_folder\"\n ? \"Files on disk are untouched.\"\n : isMailKind(kind)\n ? \"The upstream mailbox is untouched.\"\n : \"The upstream content is untouched.\";\n if (!confirm(`Stop indexing ${summary}? This deletes all chunks for this source. ${tail}`)) return;\n try {\n await api.documents.deleteSource(id);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function toggleSource(s: DocumentSource) {\n try {\n await api.documents.updateSource(s.id, { enabled: !s.enabled });\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function search(q: string): Promise<DocumentHit[]> {\n try {\n const res = await api.documents.search(q, { limit: 8 });\n return res.hits;\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n return [];\n }\n }\n\n const readiness = computeFeatureReadiness({ models, selectedProvider: undefined, selectedModelId: undefined });\n const hasWorkingEmbeddingModel = embeddingProbe?.ok ?? false;\n\n return {\n sources, loading, error, models, embeddingModel, savingEmbeddingModel, embeddingProbe,\n busy, readiness, hasWorkingEmbeddingModel,\n load, saveEmbeddingModel, addSource, reindex, removeSource, toggleSource, search,\n };\n}\n\n// Re-export so subcomponents can import in one place.\nexport { summarizeRemote };\n","\"use client\";\nimport { AlertCircle, FolderSearch, RefreshCw } from \"lucide-react\";\nimport { useRef } from \"react\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { AddSourceForm } from \"./AddSourceForm\";\nimport { EmbeddingModelSection } from \"./EmbeddingModelSection\";\nimport { SearchProbe } from \"./SearchProbe\";\nimport { SourceList } from \"./SourceList\";\nimport { useDocumentsPanel } from \"./useDocumentsPanel\";\n\nexport function DocumentsPanel() {\n const { dispatch } = useAppContext();\n const containerRef = useRef<HTMLDivElement>(null);\n const panel = useDocumentsPanel();\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <FolderSearch size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Documents</h2>\n <button\n onClick={() => void panel.load()}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\"\n title=\"Refresh source list\"\n >\n <RefreshCw size={13} /> Refresh\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-3 space-y-5\">\n <p className=\"text-xs text-fg-faint leading-relaxed\">\n Sources listed here are indexed in the background. Text files in folders are chunked, embedded, and\n made available to agents via the <code className=\"font-mono text-fg-muted\">documents_search</code> tool.\n Remote sources reuse credentials configured in <em>Credentials</em>:\n {\" \"}Jira/Confluence under <em>Atlassian</em>, GitHub PRs/repos under <em>GitHub</em>, and mail under <em>Gmail</em>/<em>Outlook</em>.\n Embedding uses your default model provider; without one, search falls back to substring match.\n </p>\n\n <EmbeddingModelSection\n models={panel.models}\n embeddingModel={panel.embeddingModel}\n savingEmbeddingModel={panel.savingEmbeddingModel}\n embeddingProbe={panel.embeddingProbe}\n readiness={panel.readiness}\n hasWorkingEmbeddingModel={panel.hasWorkingEmbeddingModel}\n onSave={(v) => { void panel.saveEmbeddingModel(v); }}\n onOpenModels={() => dispatch({ type: \"SET_TAB\", tab: \"models\" })}\n />\n\n <AddSourceForm\n disabled={panel.loading}\n onSubmit={panel.addSource}\n />\n\n {panel.error && (\n <div className=\"flex items-start gap-2 text-xs text-red-600 dark:text-red-400 px-2 py-1.5 rounded-md bg-red-500/10 border border-red-500/20\">\n <AlertCircle size={13} className=\"mt-0.5 shrink-0\" />\n <span className=\"break-words\">{panel.error}</span>\n </div>\n )}\n\n <SourceList\n sources={panel.sources}\n loading={panel.loading}\n busy={panel.busy}\n onReindex={(id) => { void panel.reindex(id); }}\n onRemove={(id, summary, kind) => { void panel.removeSource(id, summary, kind); }}\n onToggle={(s) => { void panel.toggleSource(s); }}\n />\n\n <SearchProbe onSearch={panel.search} />\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, AgentConfigIn } from \"@/api/types\";\n\nexport function useAgents() {\n const [agents, setAgents] = useState<AgentConfig[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n setAgents(await api.agents.list());\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void refresh();\n function onAgentsChanged() { void refresh(); }\n window.addEventListener(\"jarela:agents-changed\", onAgentsChanged);\n return () => window.removeEventListener(\"jarela:agents-changed\", onAgentsChanged);\n }, [refresh]);\n\n const create = useCallback(async (data: AgentConfigIn) => {\n const a = await api.agents.create(data);\n setAgents((p) => [...p, a]);\n return a;\n }, []);\n\n const update = useCallback(async (id: string, data: AgentConfigIn) => {\n const a = await api.agents.update(id, data);\n setAgents((p) => p.map((x) => (x.id === id ? a : x)));\n return a;\n }, []);\n\n const remove = useCallback(async (id: string) => {\n await api.agents.delete(id);\n setAgents((p) => p.filter((x) => x.id !== id));\n }, []);\n\n return { agents, loading, refresh, create, update, remove };\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { ToolInfo } from \"@/api/types\";\n\nexport function useTools() {\n const [tools, setTools] = useState<ToolInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n api.tools\n .list()\n .then(setTools)\n .catch((err: unknown) => setError(String(err)))\n .finally(() => setLoading(false));\n }, []);\n\n return { tools, loading, error };\n}\n","export type MbtiType =\n | \"INTJ\" | \"INTP\" | \"ENTJ\" | \"ENTP\"\n | \"INFJ\" | \"INFP\" | \"ENFJ\" | \"ENFP\"\n | \"ISTJ\" | \"ISFJ\" | \"ESTJ\" | \"ESFJ\"\n | \"ISTP\" | \"ISFP\" | \"ESTP\" | \"ESFP\";\n\nexport interface MbtiPreset {\n label: string;\n strength: number;\n empathy: number;\n expressiveness: number;\n verbosity: number;\n}\n\n// Presets are intentionally conservative: they shape tone while leaving\n// truthfulness and execution behavior to core agent policies.\nexport const MBTI_PRESETS: Record<MbtiType, MbtiPreset> = {\n INTJ: { label: \"Architect\", strength: 55, empathy: 35, expressiveness: 30, verbosity: 45 },\n INTP: { label: \"Logician\", strength: 50, empathy: 35, expressiveness: 30, verbosity: 55 },\n ENTJ: { label: \"Commander\", strength: 65, empathy: 30, expressiveness: 45, verbosity: 40 },\n ENTP: { label: \"Debater\", strength: 60, empathy: 40, expressiveness: 60, verbosity: 50 },\n\n INFJ: { label: \"Advocate\", strength: 55, empathy: 75, expressiveness: 50, verbosity: 55 },\n INFP: { label: \"Mediator\", strength: 50, empathy: 80, expressiveness: 55, verbosity: 60 },\n ENFJ: { label: \"Protagonist\", strength: 65, empathy: 80, expressiveness: 70, verbosity: 55 },\n ENFP: { label: \"Campaigner\", strength: 60, empathy: 75, expressiveness: 75, verbosity: 60 },\n\n ISTJ: { label: \"Logistician\", strength: 50, empathy: 30, expressiveness: 25, verbosity: 40 },\n ISFJ: { label: \"Defender\", strength: 50, empathy: 70, expressiveness: 40, verbosity: 50 },\n ESTJ: { label: \"Executive\", strength: 60, empathy: 35, expressiveness: 45, verbosity: 40 },\n ESFJ: { label: \"Consul\", strength: 60, empathy: 80, expressiveness: 65, verbosity: 50 },\n\n ISTP: { label: \"Virtuoso\", strength: 50, empathy: 30, expressiveness: 30, verbosity: 35 },\n ISFP: { label: \"Adventurer\", strength: 50, empathy: 65, expressiveness: 55, verbosity: 45 },\n ESTP: { label: \"Entrepreneur\", strength: 60, empathy: 40, expressiveness: 70, verbosity: 40 },\n ESFP: { label: \"Entertainer\", strength: 60, empathy: 70, expressiveness: 80, verbosity: 50 },\n};\n\nexport const MBTI_TYPES: MbtiType[] = Object.keys(MBTI_PRESETS) as MbtiType[];\n","import { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, Harness, IntegrationStatus } from \"@/api/types\";\n\nexport interface ExternalAgentData {\n harnesses: Harness[];\n defaultHarnessId: string;\n integrations: IntegrationStatus[];\n otherAgents: AgentConfig[];\n}\n\nexport function useAgentExternalData(agentId: string | undefined): ExternalAgentData {\n const [harnesses, setHarnesses] = useState<Harness[]>([]);\n const [defaultHarnessId, setDefaultHarnessId] = useState<string>(\"builtin:default\");\n const [integrations, setIntegrations] = useState<IntegrationStatus[]>([]);\n const [otherAgents, setOtherAgents] = useState<AgentConfig[]>([]);\n\n useEffect(() => {\n let cancelled = false;\n api.harnesses.list()\n .then((res) => { if (!cancelled) { setHarnesses(res.harnesses); setDefaultHarnessId(res.default_harness_id); } })\n .catch(() => { /* picker stays empty if fetch fails */ });\n return () => { cancelled = true; };\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n api.integrations.list()\n .then((res) => { if (!cancelled) setIntegrations(res.statuses); })\n .catch(() => { if (!cancelled) setIntegrations([]); });\n return () => { cancelled = true; };\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n api.agents.list()\n .then((list) => { if (!cancelled) setOtherAgents(list.filter((a) => a.id !== agentId)); })\n .catch(() => { /* delegate picker stays empty if fetch fails */ });\n return () => { cancelled = true; };\n }, [agentId]);\n\n return { harnesses, defaultHarnessId, integrations, otherAgents };\n}\n","import type { ToolInfo } from \"@/api/types\";\n\nexport type ToolPermissionKind = \"read\" | \"write\" | \"execute\";\n\nconst READ_PREFIXES = [\"get_\", \"list_\", \"search_\", \"read_\", \"fetch_\", \"check_\", \"status_\"];\nconst WRITE_PREFIXES = [\n \"create_\", \"update_\", \"delete_\", \"write_\", \"edit_\", \"modify_\", \"move_\", \"copy_\", \"mkdir_\",\n \"set_\", \"add_\", \"remove_\", \"trash_\", \"cancel_\", \"upsert_\", \"transition_\", \"upload_\",\n];\nconst EXECUTE_PREFIXES = [\"run_\", \"exec_\", \"execute_\", \"shell_\", \"script_\", \"schedule_\", \"generate_\", \"trigger_\", \"propose_\"];\n\nexport function permissionKindForTool(name: string, category?: string): ToolPermissionKind {\n const n = name.toLowerCase();\n if (READ_PREFIXES.some((p) => n.startsWith(p))) return \"read\";\n if (WRITE_PREFIXES.some((p) => n.startsWith(p))) return \"write\";\n if (category === \"Shell\") return \"execute\";\n if (EXECUTE_PREFIXES.some((p) => n.startsWith(p))) return \"execute\";\n return \"execute\";\n}\n\nexport function toolScoreClass(score: number): string {\n if (score >= 0.75) {\n return \"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300\";\n }\n if (score >= 0.5) {\n return \"border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\";\n }\n return \"border-rose-500/30 bg-rose-500/10 text-rose-700 dark:text-rose-300\";\n}\n\nexport type ToolInfoLike = ToolInfo;\n","import { useMemo } from \"react\";\nimport type { ToolInfo } from \"@/api/types\";\nimport { permissionKindForTool, type ToolPermissionKind } from \"./permissions\";\n\nexport interface GroupedTools {\n groupedTools: Array<{ group: string | null; categories: Array<[string, ToolInfo[]]> }>;\n toggleTool: (name: string) => void;\n toggleAllTools: () => void;\n toggleCategory: (category: string, enable: boolean) => void;\n toggleCategoryPermission: (category: string, kind: ToolPermissionKind, enable: boolean) => void;\n toggleGroup: (group: string, enable: boolean) => void;\n}\n\nexport function useAgentToolHandlers(\n tools: ToolInfo[],\n setSelectedTools: React.Dispatch<React.SetStateAction<string[]>>,\n): GroupedTools {\n const groupedTools = useMemo(() => buildGroupedTools(tools), [tools]);\n const allCategories = useMemo(() => groupedTools.flatMap((g) => g.categories), [groupedTools]);\n\n const toggleTool = (toolName: string) =>\n setSelectedTools((p) => p.includes(toolName) ? p.filter((n) => n !== toolName) : [...p, toolName]);\n\n const toggleAllTools = () =>\n setSelectedTools((p) => p.length === tools.length ? [] : tools.map((t) => t.name));\n\n const toggleCategory = (category: string, enable: boolean) => {\n const names = allCategories.find(([c]) => c === category)?.[1].map((t) => t.name) ?? [];\n applyBulkSelection(names, enable, setSelectedTools);\n };\n\n const toggleCategoryPermission = (category: string, kind: ToolPermissionKind, enable: boolean) => {\n const cat = allCategories.find(([c]) => c === category)?.[1] ?? [];\n const names = cat.filter((t) => permissionKindForTool(t.name, category) === kind).map((t) => t.name);\n applyBulkSelection(names, enable, setSelectedTools);\n };\n\n const toggleGroup = (group: string, enable: boolean) => {\n const names = (groupedTools.find((g) => g.group === group)?.categories ?? [])\n .flatMap(([, ts]) => ts.map((t) => t.name));\n applyBulkSelection(names, enable, setSelectedTools);\n };\n\n return { groupedTools, toggleTool, toggleAllTools, toggleCategory, toggleCategoryPermission, toggleGroup };\n}\n\nfunction applyBulkSelection(\n names: string[],\n enable: boolean,\n setSelectedTools: React.Dispatch<React.SetStateAction<string[]>>,\n) {\n if (names.length === 0) return;\n setSelectedTools((prev) => {\n if (enable) {\n const set = new Set(prev);\n for (const n of names) set.add(n);\n return [...set];\n }\n const remove = new Set(names);\n return prev.filter((n) => !remove.has(n));\n });\n}\n\nconst CATEGORY_ORDER = [\n \"Memory\", \"Documents\", \"Files\", \"Shell\", \"Web\", \"Images\", \"Voice\",\n \"Schedule\", \"Atlassian\", \"GitHub\", \"Mail\", \"Calendar\", \"Config\", \"Other\", \"MCP\",\n];\n\nfunction buildGroupedTools(tools: ToolInfo[]) {\n const byCat = new Map<string, ToolInfo[]>();\n const catGroup = new Map<string, string | null>();\n for (const t of tools) {\n const cat = t.category ?? \"Other\";\n const arr = byCat.get(cat) ?? [];\n arr.push(t);\n byCat.set(cat, arr);\n if (!catGroup.has(cat)) catGroup.set(cat, t.group ?? null);\n }\n const orderOf = (c: string) => {\n const i = CATEGORY_ORDER.indexOf(c);\n return i === -1 ? 999 : i;\n };\n const buckets = new Map<string | null, Array<[string, ToolInfo[]]>>();\n const groupOrder = new Map<string | null, number>();\n for (const [cat, ts] of byCat) {\n const g = catGroup.get(cat) ?? null;\n const arr = buckets.get(g) ?? [];\n arr.push([cat, ts]);\n buckets.set(g, arr);\n const prev = groupOrder.get(g);\n const here = orderOf(cat);\n if (prev === undefined || here < prev) groupOrder.set(g, here);\n }\n for (const arr of buckets.values()) arr.sort((a, b) => orderOf(a[0]) - orderOf(b[0]));\n for (const arr of buckets.values()) {\n for (const entry of arr) {\n entry[1].sort((a, b) => {\n const scoreDiff = (b.stats?.score ?? 0) - (a.stats?.score ?? 0);\n if (scoreDiff !== 0) return scoreDiff;\n return a.name.localeCompare(b.name);\n });\n }\n }\n return [...buckets.entries()]\n .sort((a, b) => (groupOrder.get(a[0]) ?? 999) - (groupOrder.get(b[0]) ?? 999))\n .map(([group, categories]) => ({ group, categories }));\n}\n","import { useRef, useState } from \"react\";\nimport type { AgentConfig, AgentConfigIn } from \"@/api/types\";\nimport { useTools } from \"@/hooks/useTools\";\nimport { MBTI_PRESETS, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\nimport { useAgentExternalData } from \"./useAgentExternalData\";\nimport { useAgentToolHandlers } from \"./useAgentToolHandlers\";\n\ntype TierOverride = { hot: number; warm: number; facts: number } | null;\ntype AntiHallucMode = \"\" | \"off\" | \"regex\" | \"model\";\ntype CitationStrictness = \"off\" | \"informational\" | \"standard\" | \"strict\";\n\nexport type AgentEditorForm = ReturnType<typeof useAgentEditorForm>;\n\n// Flat composition hook. Each useState is an orthogonal form field —\n// splitting further would add seams without simplifying anything.\nexport function useAgentEditorForm(agent: AgentConfig | undefined) {\n const { tools } = useTools();\n const iconInputRef = useRef<HTMLInputElement>(null);\n const [name, setName] = useState(agent?.name ?? \"\");\n const [icon, setIcon] = useState<string | null>(agent?.icon ?? null);\n const [identity, setIdentity] = useState(agent?.identity ?? \"\");\n const [instructions, setInstructions] = useState(agent?.instructions ?? \"\");\n const [isDefault, setIsDefault] = useState<boolean>(agent?.is_default ?? false);\n const [modelConfigName, setModelConfigName] = useState<string>(agent?.model_config_name ?? \"\");\n const [selectedTools, setSelectedTools] = useState<string[]>(agent?.tools ?? []);\n const [delegateTargets, setDelegateTargets] = useState<string[]>(agent?.delegate_targets ?? []);\n const [harnessId, setHarnessId] = useState<string>(agent?.harness_id ?? \"\");\n const [antiHallucMode, setAntiHallucMode] = useState<AntiHallucMode>(agent?.anti_hallucination_mode ?? \"\");\n const [antiHallucModel, setAntiHallucModel] = useState<string>(agent?.anti_hallucination_model_config ?? \"\");\n const [citationStrictness, setCitationStrictness] = useState<CitationStrictness>(agent?.citation_strictness ?? \"off\");\n // ADR-0043. `null` = inherit from the model; only flips to non-null when\n // the user drags a handle, so saving an unmodified agent keeps inherit.\n const [tierOverride, setTierOverride] = useState<TierOverride>(agent?.context_tier_proportions ?? null);\n const [adaptivePersonaEnabled, setAdaptivePersonaEnabled] = useState<boolean>(agent?.adaptive_persona_enabled ?? false);\n const [adaptiveMbti, setAdaptiveMbti] = useState<MbtiType>(initialMbti(agent?.adaptive_mbti));\n const [voiceEnabled, setVoiceEnabled] = useState<boolean>(agent?.voice_enabled ?? false);\n const [voiceModel, setVoiceModel] = useState<string>(agent?.voice_model ?? \"gemini-2.5-flash-preview-tts\");\n const [voiceName, setVoiceName] = useState<string>(agent?.voice_name ?? \"Kore\");\n const [voiceSttModel, setVoiceSttModel] = useState<string>(agent?.voice_stt_model ?? \"gemini-2.5-flash\");\n const [voiceAutoSpeak, setVoiceAutoSpeak] = useState<boolean>(agent?.voice_auto_speak ?? true);\n const external = useAgentExternalData(agent?.id);\n const handlers = useAgentToolHandlers(tools, setSelectedTools);\n const fields = {\n name, setName, icon, setIcon, identity, setIdentity, instructions, setInstructions,\n isDefault, setIsDefault, iconInputRef, handleIconFile: handleIconFileFor(setIcon),\n modelConfigName, setModelConfigName, tools, selectedTools,\n delegateTargets, setDelegateTargets, harnessId, setHarnessId,\n antiHallucMode, setAntiHallucMode, antiHallucModel, setAntiHallucModel,\n citationStrictness, setCitationStrictness, tierOverride, setTierOverride,\n adaptivePersonaEnabled, setAdaptivePersonaEnabled, adaptiveMbti, setAdaptiveMbti,\n voiceEnabled, setVoiceEnabled, voiceModel, setVoiceModel,\n voiceName, setVoiceName, voiceSttModel, setVoiceSttModel,\n voiceAutoSpeak, setVoiceAutoSpeak,\n };\n return { ...fields, ...external, ...handlers, buildPayload: () => buildAgentPayload(fields) };\n}\n\nfunction initialMbti(value: string | null | undefined): MbtiType {\n const v = value ?? \"INTJ\";\n return (v in MBTI_PRESETS ? v : \"INTJ\") as MbtiType;\n}\n\nfunction handleIconFileFor(setIcon: (v: string | null) => void) {\n return (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => setIcon(reader.result as string);\n reader.readAsDataURL(file);\n };\n}\n\ninterface PayloadFields {\n name: string; icon: string | null; identity: string; instructions: string;\n isDefault: boolean; modelConfigName: string; selectedTools: string[];\n delegateTargets: string[]; harnessId: string; tierOverride: TierOverride;\n antiHallucMode: AntiHallucMode; antiHallucModel: string;\n citationStrictness: CitationStrictness;\n adaptivePersonaEnabled: boolean; adaptiveMbti: MbtiType;\n voiceEnabled: boolean; voiceModel: string; voiceName: string;\n voiceSttModel: string; voiceAutoSpeak: boolean;\n}\n\nfunction buildAgentPayload(f: PayloadFields): AgentConfigIn {\n return {\n name: f.name.trim(),\n icon: f.icon ?? null,\n identity: f.identity.trim(),\n instructions: f.instructions.trim(),\n tools: f.selectedTools,\n model_config_name: f.modelConfigName || null,\n is_default: f.isDefault,\n adaptive_persona_enabled: f.adaptivePersonaEnabled,\n adaptive_mbti: f.adaptiveMbti,\n voice_enabled: f.voiceEnabled,\n voice_model: f.voiceModel,\n voice_name: f.voiceName,\n voice_stt_model: f.voiceSttModel,\n voice_auto_speak: f.voiceAutoSpeak,\n harness_id: f.harnessId || null,\n delegate_targets: f.delegateTargets,\n context_tier_proportions: f.tierOverride,\n anti_hallucination_mode: f.antiHallucMode === \"\" ? null : f.antiHallucMode,\n anti_hallucination_model_config: f.antiHallucModel.trim() === \"\" ? null : f.antiHallucModel.trim(),\n citation_strictness: f.citationStrictness,\n };\n}\n","import { useState } from \"react\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport type { AgentConfigIn } from \"@/api/types\";\n\ninterface Args {\n buildPayload: () => AgentConfigIn;\n getName: () => string;\n onSave: (data: AgentConfigIn) => Promise<void>;\n onClose: () => void;\n}\n\nexport function useAgentSaveHandler({ buildPayload, getName, onSave, onClose }: Args) {\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function handleSave() {\n setError(null);\n const trimmed = getName().trim();\n if (!trimmed) { setError(\"Name is required\"); return; }\n setSaving(true);\n try {\n await onSave(buildPayload());\n onClose();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't save agent\",\n error: e,\n context: { panel: \"agents\", action: \"agent.save\", agent_name: trimmed },\n });\n } finally {\n setSaving(false);\n }\n }\n\n return { saving, error, handleSave };\n}\n","import type React from \"react\";\n\ninterface Props {\n step: number;\n title: string;\n children: React.ReactNode;\n}\n\nexport function Section({ step, title, children }: Props) {\n return (\n <div className=\"space-y-2.5 rounded-xl border border-border bg-surface-1/30 p-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"w-5 h-5 rounded-full bg-accent text-white text-[10px] font-bold flex items-center justify-center shrink-0\">\n {step}\n </span>\n <span className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">{title}</span>\n </div>\n <div className=\"ml-7 space-y-2\">{children}</div>\n </div>\n );\n}\n","import { Upload } from \"lucide-react\";\nimport { MarkdownTextarea } from \"@/components/ui/MarkdownTextarea\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\nimport { Section } from \"./Section\";\n\nexport function IdentitySection({ form }: { form: AgentEditorForm }) {\n return (\n <Section step={1} title=\"Identity\">\n <div className=\"flex items-end gap-3\">\n <IconPicker form={form} />\n <label className=\"flex-1 block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Name</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={form.name}\n onChange={(e) => form.setName(e.target.value)}\n placeholder=\"e.g. Code Reviewer\"\n autoFocus\n />\n </label>\n </div>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Persona</span>\n <MarkdownTextarea\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent min-h-[4rem] resize-y\"\n value={form.identity}\n onChange={form.setIdentity}\n rows={3}\n placeholder=\"You are a senior TypeScript engineer with deep expertise in React and Next.js…\"\n />\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Instructions</span>\n <MarkdownTextarea\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent min-h-[4rem] resize-y\"\n value={form.instructions}\n onChange={form.setInstructions}\n rows={3}\n placeholder=\"Focus on code review, suggest best practices, and explain your reasoning…\"\n />\n </label>\n </Section>\n );\n}\n\nfunction IconPicker({ form }: { form: AgentEditorForm }) {\n return (\n <div className=\"shrink-0\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Icon</span>\n <button\n onClick={() => form.iconInputRef.current?.click()}\n className=\"w-12 h-12 rounded-lg border-2 border-dashed border-border bg-surface-3 flex items-center justify-center hover:border-accent transition-colors overflow-hidden group\"\n title=\"Upload image\"\n >\n {form.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={form.icon} alt=\"icon\" className=\"w-full h-full object-cover\" />\n ) : (\n <Upload size={14} className=\"text-fg-faint group-hover:text-accent transition-colors\" />\n )}\n </button>\n <input ref={form.iconInputRef} type=\"file\" accept=\"image/*\" className=\"hidden\" onChange={form.handleIconFile} />\n {form.icon && (\n <button onClick={() => form.setIcon(null)} className=\"text-[10px] text-fg-faint hover:text-red-700 dark:hover:text-red-400 mt-0.5 block\">\n Remove\n </button>\n )}\n </div>\n );\n}\n","import type { ModelConfig } from \"@/api/types\";\nimport { isProviderClassified, modelSupportsImages } from \"@/lib/providers/capabilities\";\nimport { CapBadges } from \"@/components/models/CapBadges\";\nimport { Select } from \"@/components/ui/Select\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { computeFeatureReadiness } from \"@/lib/ui/feature-readiness\";\nimport type { IntegrationStatus } from \"@/api/types\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\nimport { Section } from \"./Section\";\n\ninterface Props {\n form: AgentEditorForm;\n models: ModelConfig[];\n integrations: IntegrationStatus[];\n onClose: () => void;\n}\n\nexport function ModelSection({ form, models, integrations, onClose }: Props) {\n const { dispatch } = useAppContext();\n const selectedModel = models.find((m) => m.name === form.modelConfigName);\n const defaultModel = models.find((m) => m.is_default);\n const readiness = computeFeatureReadiness({\n models,\n integrations,\n selectedProvider: selectedModel?.provider,\n selectedModelId: selectedModel?.model_id,\n });\n\n return (\n <Section step={2} title=\"Model\">\n {!readiness.documentsReady && (\n <DocumentsReadinessNotice onOpenModels={() => { onClose(); dispatch({ type: \"SET_TAB\", tab: \"models\" }); }} />\n )}\n <Select value={form.modelConfigName} onChange={(e) => form.setModelConfigName(e.target.value)}>\n <option value=\"\">\n {defaultModel\n ? `Default (${defaultModel.name} · ${defaultModel.model_id})${modelSupportsImages(defaultModel.provider, defaultModel.model_id) ? \" 📷\" : \"\"}`\n : \"(no default configured)\"}\n </option>\n {models.map((m) => {\n // Prefix with a camera glyph when the model is known to accept\n // image inputs — surfaces \"this agent can read images\" without\n // a separate column. Plain <option> can't hold an SVG.\n const vision = modelSupportsImages(m.provider, m.model_id);\n return (\n <option key={m.name} value={m.name}>\n {vision ? \"📷 \" : \"\"}{m.name} · {m.provider} / {m.model_id}\n </option>\n );\n })}\n </Select>\n {selectedModel && <SelectedModelDescription model={selectedModel} />}\n {models.length === 0 && (\n <p className=\"text-[11px] text-amber-700 dark:text-amber-400\">No model configs yet — go to the Models panel to add one first.</p>\n )}\n </Section>\n );\n}\n\nfunction DocumentsReadinessNotice({ onOpenModels }: { onOpenModels: () => void }) {\n return (\n <div className=\"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-800 dark:text-amber-200 leading-snug\">\n <p>Add a model config that the current installation can use for Documents embeddings if you want semantic document recall.</p>\n <p className=\"mt-1 text-amber-900/90 dark:text-amber-100/90\">\n Compatible setup: OpenAI, Gemini, and GitHub Copilot-backed setups are the main built-in paths for embeddings without introducing another billing surface.\n </p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={onOpenModels}\n className=\"rounded-md border border-amber-600/30 bg-white/50 px-2 py-1 text-[11px] font-medium text-amber-900 dark:bg-black/10 dark:text-amber-100\"\n >\n Open Models\n </button>\n </div>\n </div>\n );\n}\n\nfunction SelectedModelDescription({ model }: { model: ModelConfig }) {\n return (\n <div className=\"space-y-1\">\n <p className=\"text-[11px] text-fg-faint\">\n Using <span className=\"text-fg-subtle\">{model.provider}</span> / <span className=\"font-mono text-fg-muted\">{model.model_id}</span>\n {!modelSupportsImages(model.provider, model.model_id) && (\n isProviderClassified(model.provider)\n ? <span className=\"ml-1 text-amber-700 dark:text-amber-300\">· no image input</span>\n : <span className=\"ml-1 text-fg-faint\">· capabilities unknown</span>\n )}\n </p>\n <CapBadges provider={model.provider} modelId={model.model_id} />\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport type { ToolInfo } from \"@/api/types\";\nimport { permissionKindForTool, toolScoreClass, type ToolPermissionKind } from \"./permissions\";\n\ninterface ToolGroupBlockProps {\n group: string;\n categories: Array<[string, ToolInfo[]]>;\n advancedMode: boolean;\n selected: string[];\n onToggleTool: (name: string) => void;\n onToggleCategory: (category: string, enable: boolean) => void;\n onToggleCategoryPermission: (category: string, kind: ToolPermissionKind, enable: boolean) => void;\n onToggleGroup: (group: string, enable: boolean) => void;\n}\n\n// Collapsible parent group wrapping multiple ToolCategoryBlocks. Used today\n// for the \"Work\" header that gathers vendor-native tool categories (Atlassian,\n// GitHub) under one collapsible. Header tri-state flips every tool in every\n// child category on/off; the per-category blocks remain individually toggleable.\nexport function ToolGroupBlock({\n group, categories, advancedMode, selected,\n onToggleTool, onToggleCategory, onToggleCategoryPermission, onToggleGroup,\n}: ToolGroupBlockProps) {\n const allTools = categories.flatMap(([, ts]) => ts);\n const selectedInGroup = allTools.filter((t) => selected.includes(t.name)).length;\n const allOn = selectedInGroup === allTools.length;\n const someOn = selectedInGroup > 0 && !allOn;\n const [open, setOpen] = useState(false);\n const headerRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (headerRef.current) headerRef.current.indeterminate = someOn;\n }, [someOn]);\n\n return (\n <ToolSelectionSection\n label={group}\n open={open}\n setOpen={setOpen}\n selectedCount={selectedInGroup}\n totalCount={allTools.length}\n allOn={allOn}\n onToggleAll={(enable) => onToggleGroup(group, enable)}\n headerRef={headerRef}\n bodyClassName=\"space-y-1.5 px-2 pb-2 pt-0.5 border-t border-border/60\"\n >\n {categories.map(([category, catTools]) => (\n <ToolCategoryBlock\n key={category}\n category={category}\n tools={catTools}\n advancedMode={advancedMode}\n selected={selected}\n onToggleTool={onToggleTool}\n onToggleCategory={onToggleCategory}\n onToggleCategoryPermission={onToggleCategoryPermission}\n />\n ))}\n </ToolSelectionSection>\n );\n}\n\ninterface ToolCategoryBlockProps {\n category: string;\n tools: ToolInfo[];\n advancedMode: boolean;\n selected: string[];\n onToggleTool: (name: string) => void;\n onToggleCategory: (category: string, enable: boolean) => void;\n onToggleCategoryPermission: (category: string, kind: ToolPermissionKind, enable: boolean) => void;\n}\n\n// Collapsible per-category block with a tri-state header checkbox. The\n// header toggle flips the entire category on/off; individual tool checkboxes\n// stay available for fine-grained control.\nexport function ToolCategoryBlock({\n category, tools, advancedMode, selected,\n onToggleTool, onToggleCategory, onToggleCategoryPermission,\n}: ToolCategoryBlockProps) {\n const selectedInCat = tools.filter((t) => selected.includes(t.name)).length;\n const allOn = selectedInCat === tools.length;\n const someOn = selectedInCat > 0 && !allOn;\n const [open, setOpen] = useState(false);\n const headerRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (headerRef.current) headerRef.current.indeterminate = someOn;\n }, [someOn]);\n\n return (\n <ToolSelectionSection\n label={category}\n open={open}\n setOpen={setOpen}\n selectedCount={selectedInCat}\n totalCount={tools.length}\n allOn={allOn}\n onToggleAll={(enable) => onToggleCategory(category, enable)}\n headerRef={headerRef}\n bodyClassName=\"grid grid-cols-1 sm:grid-cols-2 gap-1.5 px-3 pb-2 pt-0.5 border-t border-border/60\"\n >\n {advancedMode\n ? tools.map((t) => <ToolCheckbox key={t.name} tool={t} selected={selected} onToggle={onToggleTool} />)\n : <NormalPermissionControls\n category={category}\n tools={tools}\n selected={selected}\n onToggle={(kind, enable) => onToggleCategoryPermission(category, kind, enable)}\n />\n }\n </ToolSelectionSection>\n );\n}\n\nfunction ToolCheckbox({ tool, selected, onToggle }: { tool: ToolInfo; selected: string[]; onToggle: (name: string) => void }) {\n const isOn = selected.includes(tool.name);\n return (\n <label\n className={`flex items-center gap-2 cursor-pointer rounded-lg border px-2 py-1.5 transition-colors ${\n isOn ? \"border-accent/40 bg-accent/10\" : \"border-border bg-surface-2/80 hover:bg-surface-3/70\"\n }`}\n title={tool.description}\n >\n <input type=\"checkbox\" className=\"rounded border-border\" checked={isOn} onChange={() => onToggle(tool.name)} />\n <span className=\"min-w-0 flex-1 flex items-center gap-1.5\">\n <span className=\"font-mono text-[11px] text-fg-muted truncate\">{tool.name}</span>\n <span className={`shrink-0 rounded px-1.5 py-0.5 text-[10px] border ${toolScoreClass(tool.stats?.score ?? 1)}`}>\n {Math.round((tool.stats?.score ?? 1) * 100)}%\n </span>\n </span>\n </label>\n );\n}\n\ninterface NormalPermissionControlsProps {\n category: string;\n tools: ToolInfo[];\n selected: string[];\n onToggle: (kind: ToolPermissionKind, enable: boolean) => void;\n}\n\nfunction NormalPermissionControls({ category, tools, selected, onToggle }: NormalPermissionControlsProps) {\n const kinds: ToolPermissionKind[] = [\"read\", \"write\", \"execute\"];\n return (\n <div className=\"col-span-2 rounded-lg border border-border bg-surface-2/40 p-2.5 space-y-2.5\">\n <p className=\"text-[11px] text-fg-faint leading-snug\">\n Quick permissions for {category}. Advanced mode exposes individual functions.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-2\">\n {kinds.map((kind) => (\n <PermissionTile\n key={kind}\n kind={kind}\n tools={tools}\n category={category}\n selected={selected}\n onToggle={onToggle}\n />\n ))}\n </div>\n </div>\n );\n}\n\ninterface PermissionTileProps {\n kind: ToolPermissionKind;\n tools: ToolInfo[];\n category: string;\n selected: string[];\n onToggle: (kind: ToolPermissionKind, enable: boolean) => void;\n}\n\nfunction PermissionTile({ kind, tools, category, selected, onToggle }: PermissionTileProps) {\n const names = tools.filter((t) => permissionKindForTool(t.name, category) === kind).map((t) => t.name);\n const selectedCount = names.filter((n) => selected.includes(n)).length;\n const checked = names.length > 0 && selectedCount === names.length;\n return (\n <label className={`flex items-center gap-2 cursor-pointer rounded-xl border px-2.5 py-2 transition-colors ${\n checked ? \"border-accent/50 bg-accent/10\" : \"border-border bg-surface-2 hover:bg-surface-3/70\"\n }`}>\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={checked}\n disabled={names.length === 0}\n onChange={(e) => onToggle(kind, e.target.checked)}\n />\n <span className=\"text-[11px] text-fg-subtle capitalize leading-tight\">\n <span className=\"font-medium\">{kind}</span>{\" \"}\n <span className=\"text-fg-faint\">{selectedCount}/{names.length}</span>\n </span>\n </label>\n );\n}\n\ninterface ToolSelectionSectionProps {\n label: string;\n open: boolean;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n selectedCount: number;\n totalCount: number;\n allOn: boolean;\n onToggleAll: (enable: boolean) => void;\n headerRef: React.RefObject<HTMLInputElement | null>;\n bodyClassName: string;\n children: React.ReactNode;\n}\n\nfunction ToolSelectionSection({\n label, open, setOpen, selectedCount, totalCount, allOn,\n onToggleAll, headerRef, bodyClassName, children,\n}: ToolSelectionSectionProps) {\n return (\n <div className=\"rounded-xl border border-border bg-surface-1/40 overflow-hidden\">\n <div className=\"flex items-center gap-2 px-2.5 py-2 bg-surface-2/50\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"text-fg-subtle hover:text-fg transition-colors\"\n aria-label={open ? \"Collapse\" : \"Expand\"}\n >\n {open ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </button>\n <label className=\"flex items-center gap-1.5 cursor-pointer flex-1 min-w-0\">\n <input\n ref={headerRef}\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={allOn}\n onChange={(e) => onToggleAll(e.target.checked)}\n />\n <span className=\"text-[12px] font-semibold text-fg truncate\">{label}</span>\n </label>\n <span className=\"text-[10px] text-fg-faint shrink-0\">{selectedCount}/{totalCount}</span>\n </div>\n {open && <div className={bodyClassName}>{children}</div>}\n </div>\n );\n}\n","import type { AgentEditorForm } from \"./useAgentEditorForm\";\nimport { Section } from \"./Section\";\nimport { ToolCategoryBlock, ToolGroupBlock } from \"./ToolSelection\";\n\nexport function ToolsSection({ form, advancedMode }: { form: AgentEditorForm; advancedMode: boolean }) {\n return (\n <Section step={3} title=\"Tools\">\n {form.tools.length === 0\n ? <p className=\"text-xs text-fg-faint\">No tools available.</p>\n : <ToolsBody form={form} advancedMode={advancedMode} />}\n </Section>\n );\n}\n\nfunction ToolsBody({ form, advancedMode }: { form: AgentEditorForm; advancedMode: boolean }) {\n return (\n <>\n <ToolsHeader form={form} />\n <div className=\"space-y-1.5\">\n {form.groupedTools.map(({ group, categories }) =>\n group\n ? <ToolGroupBlock\n key={group}\n group={group}\n categories={categories}\n advancedMode={advancedMode}\n selected={form.selectedTools}\n onToggleTool={form.toggleTool}\n onToggleCategory={form.toggleCategory}\n onToggleCategoryPermission={form.toggleCategoryPermission}\n onToggleGroup={form.toggleGroup}\n />\n : categories.map(([category, catTools]) => (\n <ToolCategoryBlock\n key={category}\n category={category}\n tools={catTools}\n advancedMode={advancedMode}\n selected={form.selectedTools}\n onToggleTool={form.toggleTool}\n onToggleCategory={form.toggleCategory}\n onToggleCategoryPermission={form.toggleCategoryPermission}\n />\n )),\n )}\n </div>\n </>\n );\n}\n\nfunction ToolsHeader({ form }: { form: AgentEditorForm }) {\n const allOn = form.selectedTools.length === form.tools.length;\n return (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[11px] text-fg-faint\">{form.selectedTools.length} of {form.tools.length} enabled</span>\n <button onClick={form.toggleAllTools} className=\"text-[11px] text-fg-faint hover:text-fg-muted transition-colors\">\n {allOn ? \"Deselect all\" : \"Select all\"}\n </button>\n </div>\n );\n}\n","import type { AgentConfig } from \"@/api/types\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\nimport { Section } from \"./Section\";\n\nexport function DelegatesSection({ form }: { form: AgentEditorForm }) {\n // Only meaningful when delegate_to_agent is enabled.\n const canDelegate = form.selectedTools.includes(\"delegate_to_agent\");\n if (!canDelegate && form.delegateTargets.length === 0) return null;\n\n return (\n <>\n <hr className=\"border-border\" />\n <Section step={4} title=\"Delegates\">\n <p className=\"text-[11px] text-fg-faint\">\n Other agents this one may hand subtasks to via <code>delegate_to_agent</code>.\n {!canDelegate && (\n <span className=\"text-amber-700 dark:text-amber-400\">\n {\" \"}Enable the <code>delegate_to_agent</code> tool above for these to take effect.\n </span>\n )}\n </p>\n {form.otherAgents.length === 0 ? (\n <p className=\"text-xs text-fg-faint\">No other agents to delegate to yet.</p>\n ) : (\n <div className=\"space-y-1\">\n {form.otherAgents.map((a) => (\n <DelegateRow\n key={a.id}\n agent={a}\n checked={form.delegateTargets.includes(a.id)}\n onToggle={() =>\n form.setDelegateTargets((prev) =>\n prev.includes(a.id) ? prev.filter((x) => x !== a.id) : [...prev, a.id],\n )\n }\n />\n ))}\n </div>\n )}\n </Section>\n </>\n );\n}\n\nfunction DelegateRow({ agent, checked, onToggle }: { agent: AgentConfig; checked: boolean; onToggle: () => void }) {\n return (\n <label className=\"flex items-start gap-2 p-1.5 rounded hover:bg-surface-3/50 cursor-pointer\">\n <input type=\"checkbox\" checked={checked} onChange={onToggle} className=\"mt-0.5\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-xs font-medium text-fg\">{agent.name}</div>\n {agent.identity && (\n <div className=\"text-[11px] text-fg-faint truncate\">\n {agent.identity.split(\"\\n\")[0]}\n </div>\n )}\n </div>\n </label>\n );\n}\n","import { Select } from \"@/components/ui/Select\";\nimport type { Harness } from \"@/api/types\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\n\nexport function HarnessField({ form }: { form: AgentEditorForm }) {\n return (\n <>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Harness</span>\n <Select value={form.harnessId} onChange={(e) => form.setHarnessId(e.target.value)}>\n <option value=\"\">\n Use global default{defaultHarnessLabel(form.harnesses, form.defaultHarnessId)}\n </option>\n {form.harnesses.map((h) => (\n <option key={h.id} value={h.id}>\n {h.name}{h.builtin ? \" (built-in)\" : \"\"}\n </option>\n ))}\n </Select>\n </label>\n <p className=\"text-[11px] text-fg-faint\">\n Behavioral scaffolding (output formatting, citation rules, anti-fabrication, self-config) injected into this agent's system prompt.\n </p>\n </>\n );\n}\n\nfunction defaultHarnessLabel(harnesses: Harness[], defaultHarnessId: string): string {\n const def = harnesses.find((h) => h.id === defaultHarnessId);\n return def ? ` (${def.name})` : \"\";\n}\n","import type { ModelConfig } from \"@/api/types\";\nimport { Select } from \"@/components/ui/Select\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\n\nexport function AntiHallucinationFields({ form, models }: { form: AgentEditorForm; models: ModelConfig[] }) {\n return (\n <>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Anti-hallucination detector</span>\n <Select\n value={form.antiHallucMode}\n onChange={(e) => form.setAntiHallucMode(e.target.value as typeof form.antiHallucMode)}\n >\n <option value=\"\">Inherit global default</option>\n <option value=\"off\">Off — no detection</option>\n <option value=\"regex\">Regex — fast, free, brittle</option>\n <option value=\"model\">Model — LLM classifier (more accurate, +1 call/turn)</option>\n </Select>\n </label>\n {form.antiHallucMode === \"model\" && (\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">\n Classifier model\n {form.antiHallucModel === \"\" && (\n <span className=\"ml-1 text-fg-faint\">(inherits global)</span>\n )}\n </span>\n <Select value={form.antiHallucModel} onChange={(e) => form.setAntiHallucModel(e.target.value)}>\n <option value=\"\">Inherit global JARELA_HALLUCINATION_DETECTOR_MODEL</option>\n {models.map((m) => (\n <option key={m.name} value={m.name}>\n {m.name} — {m.provider}/{m.model_id}\n </option>\n ))}\n </Select>\n </label>\n )}\n <p className=\"text-[11px] text-fg-faint\">\n When set to <em>model</em>, every assistant turn for this agent runs through an LLM classifier that judges whether the agent stalled (narrated future work without invoking a write tool). Pick a fast/cheap config (e.g. Haiku, gpt-4o-mini, gemini-flash). If no model is configured here or globally, falls back to <em>regex</em>.\n </p>\n </>\n );\n}\n\nexport function CitationStrictnessField({ form }: { form: AgentEditorForm }) {\n return (\n <>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-semibold text-fg-subtle\">Citation strictness</span>\n <Select\n value={form.citationStrictness}\n onChange={(e) => form.setCitationStrictness(e.target.value as typeof form.citationStrictness)}\n >\n <option value=\"off\">Off — no checker, no nudge to cite</option>\n <option value=\"informational\">Informational — checker surfaces references; agent NOT asked to cite</option>\n <option value=\"standard\">Standard — nudge agent to cite KEY (load-bearing) claims</option>\n <option value=\"strict\">Strict — cite EVERY claim; force model-based stall detector</option>\n </Select>\n <span className=\"text-[11px] text-fg-faint mt-1\">\n The audit (a second-pass LLM that ranks each factual claim by impact) runs whenever strictness is not <em>off</em>. References may be tool-visited files/URLs, memory items, or prior assistant turns. The chat UI renders each <code>[N]</code> marker as a clickable link/anchor.\n </span>\n </label>\n {form.citationStrictness !== \"off\" && form.antiHallucModel.trim() === \"\" && (\n <p className=\"text-[11px] text-warn\">\n Pick a classifier model above (or set <em>Anti-hallucination detector</em> to <em>model</em>) so the citation audit has somewhere to run. Without it, the system-prompt directive is added but no verification happens.\n </p>\n )}\n </>\n );\n}\n","\"use client\";\n// ADR-0043. Stacked-bar slider for the hot / warm / facts context split.\n// Two drag handles divide a single 100%-wide bar into three coloured\n// segments — hot on the left, warm in the middle, facts on the right.\n// Dragging a handle redistributes the percentage between the segment to\n// its left and the one to its right; the third segment is unaffected.\n//\n// The user never has to reconcile to 100: the bar IS 100 by construction.\n// Backend `normalizeTierProportions` divides by sum, so we send the raw\n// percentages and they round-trip cleanly.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ninterface TierValue {\n hot: number;\n warm: number;\n facts: number;\n}\n\ninterface Props {\n value: TierValue;\n onChange: (next: TierValue) => void;\n /** Disables drag and dims the bar. Useful when the parent shows it as a\n * read-only preview (e.g. while inheriting from the model). */\n readOnly?: boolean;\n}\n\nconst MIN_SEGMENT = 5; // %; below this a segment becomes unhittable\nconst MAX_SEGMENT_END = 100 - MIN_SEGMENT;\n\nexport function TierProportionBar({ value, onChange, readOnly = false }: Props) {\n const barRef = useRef<HTMLDivElement>(null);\n\n // Normalise to integer percentages summing to 100. The bar wants exact\n // arithmetic — fractional values create gaps and accumulate drift on drag.\n const normalised = useMemo(() => normaliseToHundred(value), [value]);\n const hotEnd = normalised.hot;\n const warmEnd = normalised.hot + normalised.warm;\n\n const [activeHandle, setActiveHandle] = useState<null | \"hot-warm\" | \"warm-facts\">(null);\n\n const onPointerDown = useCallback(\n (handle: \"hot-warm\" | \"warm-facts\") => (e: React.PointerEvent) => {\n if (readOnly) return;\n e.preventDefault();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n setActiveHandle(handle);\n },\n [readOnly],\n );\n\n useEffect(() => {\n if (!activeHandle) return;\n const bar = barRef.current;\n if (!bar) return;\n\n const handleMove = (e: PointerEvent) => {\n const rect = bar.getBoundingClientRect();\n const xPct = clamp(((e.clientX - rect.left) / rect.width) * 100, 0, 100);\n onChange(updateAt(activeHandle, xPct, normalised));\n };\n const handleUp = () => setActiveHandle(null);\n\n document.addEventListener(\"pointermove\", handleMove);\n document.addEventListener(\"pointerup\", handleUp);\n document.addEventListener(\"pointercancel\", handleUp);\n return () => {\n document.removeEventListener(\"pointermove\", handleMove);\n document.removeEventListener(\"pointerup\", handleUp);\n document.removeEventListener(\"pointercancel\", handleUp);\n };\n }, [activeHandle, normalised, onChange]);\n\n // Keyboard arrow support on each handle: 1% nudges, Shift+arrow = 5%.\n const onKeyDown = useCallback(\n (handle: \"hot-warm\" | \"warm-facts\") => (e: React.KeyboardEvent) => {\n if (readOnly) return;\n const step = e.shiftKey ? 5 : 1;\n let delta = 0;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") delta = step;\n else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") delta = -step;\n else return;\n e.preventDefault();\n const target = handle === \"hot-warm\" ? hotEnd + delta : warmEnd + delta;\n onChange(updateAt(handle, target, normalised));\n },\n [readOnly, hotEnd, warmEnd, normalised, onChange],\n );\n\n const dim = readOnly ? \"opacity-60\" : \"\";\n\n return (\n <div className={`space-y-2 ${dim}`}>\n {/* Tier label chips above the bar — live as the user drags */}\n <div className=\"grid grid-cols-3 gap-1 text-[10px] font-medium uppercase tracking-wider\">\n <Chip color=\"accent\" label=\"Hot\" pct={normalised.hot} />\n <Chip color=\"amber\" label=\"Warm\" pct={normalised.warm} centered />\n <Chip color=\"teal\" label=\"Facts\" pct={normalised.facts} right />\n </div>\n\n {/* The bar itself */}\n <div\n ref={barRef}\n className=\"relative h-6 rounded-full bg-surface-3 border border-border overflow-hidden select-none\"\n role=\"group\"\n aria-label=\"Context tier proportions\"\n >\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/70\"\n style={{ width: `${hotEnd}%` }}\n aria-hidden\n />\n <div\n className=\"absolute inset-y-0 bg-amber-500/70\"\n style={{ left: `${hotEnd}%`, width: `${normalised.warm}%` }}\n aria-hidden\n />\n <div\n className=\"absolute inset-y-0 bg-teal-500/70\"\n style={{ left: `${warmEnd}%`, right: 0 }}\n aria-hidden\n />\n\n <Handle\n left={hotEnd}\n active={activeHandle === \"hot-warm\"}\n readOnly={readOnly}\n onPointerDown={onPointerDown(\"hot-warm\")}\n onKeyDown={onKeyDown(\"hot-warm\")}\n ariaLabel=\"Hot ↔ Warm split\"\n ariaValueNow={hotEnd}\n ariaValueMin={MIN_SEGMENT}\n ariaValueMax={warmEnd - MIN_SEGMENT}\n />\n <Handle\n left={warmEnd}\n active={activeHandle === \"warm-facts\"}\n readOnly={readOnly}\n onPointerDown={onPointerDown(\"warm-facts\")}\n onKeyDown={onKeyDown(\"warm-facts\")}\n ariaLabel=\"Warm ↔ Facts split\"\n ariaValueNow={warmEnd}\n ariaValueMin={hotEnd + MIN_SEGMENT}\n ariaValueMax={MAX_SEGMENT_END}\n />\n </div>\n\n {/* Explainer — surfaces what each tier means to the agent so the user\n isn't dragging blind. The bar represents the share of the input\n context budget; growing one tier shrinks the others. */}\n <div className=\"rounded-lg border border-border bg-surface-3/50 p-2.5 space-y-1.5\">\n <p className=\"text-[11px] font-semibold text-fg-subtle\">\n What changes when you drag\n </p>\n <ul className=\"text-[11px] text-fg-muted space-y-1\">\n <li>\n <span className=\"inline-block w-12 font-medium text-accent\">Hot</span>\n Verbatim recent messages. More hot = the agent has more of this\n exact conversation in front of it.\n </li>\n <li>\n <span className=\"inline-block w-12 font-medium text-amber-500\">Warm</span>\n A summary of older messages outside the hot window. More warm =\n better long-term recall of how we got here, less raw detail.\n </li>\n <li>\n <span className=\"inline-block w-12 font-medium text-teal-500\">Facts</span>\n Hits from saved memory (preferences, domain notes). More facts =\n the agent draws on what you've taught it across threads.\n </li>\n </ul>\n <p className=\"text-[10px] text-fg-faint pt-0.5\">\n The bar is always 100% of the agent's input budget, so growing\n one tier shrinks the others. Arrow keys nudge by 1% (Shift+arrow\n by 5%).\n </p>\n </div>\n </div>\n );\n}\n\nfunction Chip({\n color,\n label,\n pct,\n centered,\n right,\n}: {\n color: \"accent\" | \"amber\" | \"teal\";\n label: string;\n pct: number;\n centered?: boolean;\n right?: boolean;\n}) {\n const colorMap = {\n accent: \"text-accent bg-accent/10 border-accent/30\",\n amber: \"text-amber-500 bg-amber-500/10 border-amber-500/30\",\n teal: \"text-teal-500 bg-teal-500/10 border-teal-500/30\",\n } as const;\n const align = centered ? \"justify-center\" : right ? \"justify-end\" : \"justify-start\";\n return (\n <div className={`flex ${align}`}>\n <span className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded border ${colorMap[color]}`}>\n <span>{label}</span>\n <span className=\"font-mono normal-case tracking-normal\">{Math.round(pct)}%</span>\n </span>\n </div>\n );\n}\n\nfunction Handle({\n left,\n active,\n readOnly,\n ariaLabel,\n ariaValueNow,\n ariaValueMin,\n ariaValueMax,\n onPointerDown,\n onKeyDown,\n}: {\n left: number;\n active: boolean;\n readOnly: boolean;\n ariaLabel: string;\n ariaValueNow: number;\n ariaValueMin: number;\n ariaValueMax: number;\n onPointerDown: (e: React.PointerEvent) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n}) {\n return (\n <div\n role=\"slider\"\n tabIndex={readOnly ? -1 : 0}\n aria-orientation=\"horizontal\"\n aria-label={ariaLabel}\n aria-valuenow={ariaValueNow}\n aria-valuemin={ariaValueMin}\n aria-valuemax={ariaValueMax}\n onPointerDown={onPointerDown}\n onKeyDown={onKeyDown}\n style={{ left: `calc(${left}% - 9px)` }}\n className={[\n \"absolute top-1/2 -translate-y-1/2 w-[18px] h-[18px] rounded-full\",\n \"bg-surface border-2 shadow-md transition-colors\",\n readOnly ? \"border-border cursor-default\" : \"border-fg-muted hover:border-accent cursor-ew-resize\",\n active ? \"border-accent ring-2 ring-accent/30\" : \"\",\n \"focus:outline-none focus:border-accent focus:ring-2 focus:ring-accent/40\",\n ].join(\" \")}\n />\n );\n}\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, n));\n}\n\n// Move the chosen handle to `endPct`, clamped so each segment keeps at least\n// MIN_SEGMENT %. The third tier (the one neither side of the moved handle)\n// is left untouched — only the two adjacent tiers redistribute.\nfunction updateAt(\n handle: \"hot-warm\" | \"warm-facts\",\n endPct: number,\n current: TierValue,\n): TierValue {\n const hot = current.hot;\n const warm = current.warm;\n const facts = current.facts;\n if (handle === \"hot-warm\") {\n const minHot = MIN_SEGMENT;\n const maxHot = 100 - facts - MIN_SEGMENT;\n const newHot = Math.round(clamp(endPct, minHot, maxHot));\n return { hot: newHot, warm: 100 - newHot - facts, facts };\n } else {\n // endPct is the position of the warm-facts boundary, i.e. hot + warm.\n const minBoundary = hot + MIN_SEGMENT;\n const maxBoundary = MAX_SEGMENT_END;\n const newBoundary = Math.round(clamp(endPct, minBoundary, maxBoundary));\n return { hot, warm: newBoundary - hot, facts: 100 - newBoundary };\n }\n}\n\n// Map any positive numbers to integer percents summing to exactly 100. Falls\n// back to defaults on a zero/negative sum so the UI never displays an empty\n// bar. Drift from rounding is absorbed by `facts` (the residual).\nfunction normaliseToHundred(v: TierValue): TierValue {\n const sum = (Number(v.hot) || 0) + (Number(v.warm) || 0) + (Number(v.facts) || 0);\n if (sum <= 0) return { hot: 60, warm: 25, facts: 15 };\n const hot = Math.round((Number(v.hot) / sum) * 100);\n const warm = Math.round((Number(v.warm) / sum) * 100);\n return { hot, warm, facts: 100 - hot - warm };\n}\n","import type { ModelConfig } from \"@/api/types\";\nimport { TierProportionBar } from \"../TierProportionBar\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\n\ninterface Props {\n form: AgentEditorForm;\n selectedModel: ModelConfig | undefined;\n}\n\n// ADR-0043. Per-agent override of the hot / warm / facts split.\n// Bar shows the effective value (override or model fallback);\n// \"Inherit from model\" link clears the override.\nexport function TierOverrideField({ form, selectedModel }: Props) {\n const fallback = {\n hot: selectedModel?.params?.context_tier_proportions?.hot ?? 60,\n warm: selectedModel?.params?.context_tier_proportions?.warm ?? 25,\n facts: selectedModel?.params?.context_tier_proportions?.facts ?? 15,\n };\n const value = form.tierOverride ?? fallback;\n const isOverriding = form.tierOverride !== null;\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-fg-subtle\">Context tier split</span>\n {isOverriding ? (\n <button\n type=\"button\"\n onClick={() => form.setTierOverride(null)}\n className=\"text-[11px] text-fg-faint hover:text-accent transition-colors\"\n >\n Inherit from model\n </button>\n ) : (\n <span className=\"text-[11px] text-fg-faint italic\">\n {selectedModel ? `inheriting from ${selectedModel.name}` : \"using built-in defaults\"}\n </span>\n )}\n </div>\n <TierProportionBar value={value} onChange={(next) => form.setTierOverride(next)} />\n </div>\n );\n}\n","import { Select } from \"@/components/ui/Select\";\nimport { MBTI_PRESETS, MBTI_TYPES, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\n\nexport function AdaptivePersonaFields({ form }: { form: AgentEditorForm }) {\n const preset = MBTI_PRESETS[form.adaptiveMbti];\n return (\n <>\n <label className=\"flex items-center gap-2 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={form.adaptivePersonaEnabled}\n onChange={(e) => form.setAdaptivePersonaEnabled(e.target.checked)}\n />\n <span className=\"text-xs text-fg-subtle\">Enable adaptive personality and emotion mirroring</span>\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">MBTI preset</span>\n <Select\n value={form.adaptiveMbti}\n onChange={(e) => form.setAdaptiveMbti(e.target.value as MbtiType)}\n disabled={!form.adaptivePersonaEnabled}\n >\n {MBTI_TYPES.map((t) => (\n <option key={t} value={t}>\n {t} - {MBTI_PRESETS[t].label}\n </option>\n ))}\n </Select>\n </label>\n <p className=\"text-[11px] text-fg-faint\">\n Hidden preset values: strength {preset.strength}, empathy {preset.empathy}, expressiveness {preset.expressiveness}, verbosity {preset.verbosity}.\n </p>\n </>\n );\n}\n","// Client-safe constants for the voice picker UI. Kept in a standalone\n// module so client components can import them without dragging server-only\n// modules (lib/db, undici, node:child_process) through the import graph.\n\nexport const GEMINI_VOICES: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"Zephyr\", label: \"Zephyr · bright\" },\n { id: \"Puck\", label: \"Puck · upbeat\" },\n { id: \"Charon\", label: \"Charon · informative\" },\n { id: \"Kore\", label: \"Kore · firm\" },\n { id: \"Fenrir\", label: \"Fenrir · excitable\" },\n { id: \"Leda\", label: \"Leda · youthful\" },\n { id: \"Orus\", label: \"Orus · firm\" },\n { id: \"Aoede\", label: \"Aoede · breezy\" },\n { id: \"Callirrhoe\", label: \"Callirrhoe · easy-going\" },\n { id: \"Autonoe\", label: \"Autonoe · bright\" },\n { id: \"Enceladus\", label: \"Enceladus · breathy\" },\n { id: \"Iapetus\", label: \"Iapetus · clear\" },\n { id: \"Umbriel\", label: \"Umbriel · easy-going\" },\n { id: \"Algieba\", label: \"Algieba · smooth\" },\n { id: \"Despina\", label: \"Despina · smooth\" },\n { id: \"Erinome\", label: \"Erinome · clear\" },\n { id: \"Algenib\", label: \"Algenib · gravelly\" },\n { id: \"Rasalgethi\", label: \"Rasalgethi · informative\" },\n { id: \"Laomedeia\", label: \"Laomedeia · upbeat\" },\n { id: \"Achernar\", label: \"Achernar · soft\" },\n { id: \"Alnilam\", label: \"Alnilam · firm\" },\n { id: \"Schedar\", label: \"Schedar · even\" },\n { id: \"Gacrux\", label: \"Gacrux · mature\" },\n { id: \"Pulcherrima\", label: \"Pulcherrima · forward\" },\n { id: \"Achird\", label: \"Achird · friendly\" },\n { id: \"Zubenelgenubi\", label: \"Zubenelgenubi · casual\" },\n { id: \"Vindemiatrix\", label: \"Vindemiatrix · gentle\" },\n { id: \"Sadachbia\", label: \"Sadachbia · lively\" },\n { id: \"Sadaltager\", label: \"Sadaltager · knowledgeable\" },\n { id: \"Sulafat\", label: \"Sulafat · warm\" },\n];\n\nexport const GEMINI_TTS_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash-preview-tts\", label: \"Flash TTS (fast, cheap)\" },\n { id: \"gemini-2.5-pro-preview-tts\", label: \"Pro TTS (higher quality)\" },\n];\n\nexport const GEMINI_STT_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash\", label: \"Flash (fast, multilingual)\" },\n { id: \"gemini-2.5-pro\", label: \"Pro (slower, more accurate)\" },\n];\n","import { Select } from \"@/components/ui/Select\";\nimport { GEMINI_STT_MODELS, GEMINI_TTS_MODELS, GEMINI_VOICES } from \"@/lib/voice/constants\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { computeFeatureReadiness } from \"@/lib/ui/feature-readiness\";\nimport type { IntegrationStatus, ModelConfig } from \"@/api/types\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\n\ninterface Props {\n form: AgentEditorForm;\n models: ModelConfig[];\n integrations: IntegrationStatus[];\n selectedModel: ModelConfig | undefined;\n onClose: () => void;\n}\n\nexport function VoiceFields({ form, models, integrations, selectedModel, onClose }: Props) {\n const { dispatch } = useAppContext();\n const readiness = computeFeatureReadiness({\n models,\n integrations,\n selectedProvider: selectedModel?.provider,\n selectedModelId: selectedModel?.model_id,\n });\n return (\n <>\n <label className=\"flex items-center gap-2 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={form.voiceEnabled}\n onChange={(e) => form.setVoiceEnabled(e.target.checked)}\n />\n <span className=\"text-xs text-fg-subtle\">Enable voice (Gemini TTS + STT)</span>\n </label>\n <p className=\"text-[11px] text-fg-faint\">\n When on, the chat input shows a microphone and assistant replies show a play button.\n Requires the Google integration api_key.\n </p>\n {!readiness.voiceReady && (\n <VoiceReadinessNotice\n hasGoogleIntegration={readiness.hasGoogleIntegration}\n onOpenModels={() => { onClose(); dispatch({ type: \"SET_TAB\", tab: \"models\" }); }}\n onOpenCredentials={() => {\n onClose();\n dispatch({ type: \"SET_TAB\", tab: \"credentials\" });\n dispatch({ type: \"SET_SELECTION\", tab: \"credentials\", itemId: \"list\" });\n }}\n />\n )}\n <VoicePickers form={form} />\n </>\n );\n}\n\nfunction VoicePickers({ form }: { form: AgentEditorForm }) {\n return (\n <>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">TTS model</span>\n <Select value={form.voiceModel} onChange={(e) => form.setVoiceModel(e.target.value)} disabled={!form.voiceEnabled}>\n {GEMINI_TTS_MODELS.map((m) => (<option key={m.id} value={m.id}>{m.id} — {m.label}</option>))}\n </Select>\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Voice</span>\n <Select value={form.voiceName} onChange={(e) => form.setVoiceName(e.target.value)} disabled={!form.voiceEnabled}>\n {GEMINI_VOICES.map((v) => (<option key={v.id} value={v.id}>{v.label}</option>))}\n </Select>\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Transcription model</span>\n <Select value={form.voiceSttModel} onChange={(e) => form.setVoiceSttModel(e.target.value)} disabled={!form.voiceEnabled}>\n {GEMINI_STT_MODELS.map((m) => (<option key={m.id} value={m.id}>{m.id} — {m.label}</option>))}\n </Select>\n </label>\n <label className=\"flex items-center gap-2 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={form.voiceAutoSpeak}\n onChange={(e) => form.setVoiceAutoSpeak(e.target.checked)}\n disabled={!form.voiceEnabled}\n />\n <span className=\"text-xs text-fg-subtle\">Auto-speak reply when I send a voice message</span>\n </label>\n </>\n );\n}\n\nfunction VoiceReadinessNotice({\n hasGoogleIntegration,\n onOpenModels,\n onOpenCredentials,\n}: {\n hasGoogleIntegration: boolean;\n onOpenModels: () => void;\n onOpenCredentials: () => void;\n}) {\n return (\n <div className=\"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-800 dark:text-amber-200 leading-snug\">\n <p>Voice is not fully ready at the system level yet.</p>\n <p className=\"mt-1 text-amber-900/90 dark:text-amber-100/90\">\n Compatible setup: a Gemini model plus the existing Google AI integration. Without both, enabling voice would require extra setup.\n </p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={onOpenModels}\n className=\"rounded-md border border-amber-600/30 bg-white/50 px-2 py-1 text-[11px] font-medium text-amber-900 dark:bg-black/10 dark:text-amber-100\"\n >\n Open Models\n </button>\n {!hasGoogleIntegration && (\n <button\n type=\"button\"\n onClick={onOpenCredentials}\n className=\"rounded-md border border-amber-600/30 bg-white/50 px-2 py-1 text-[11px] font-medium text-amber-900 dark:bg-black/10 dark:text-amber-100\"\n >\n Open Credentials\n </button>\n )}\n </div>\n </div>\n );\n}\n","import type { IntegrationStatus, ModelConfig } from \"@/api/types\";\nimport type { AgentEditorForm } from \"./useAgentEditorForm\";\nimport { Section } from \"./Section\";\nimport { HarnessField } from \"./HarnessField\";\nimport { AntiHallucinationFields, CitationStrictnessField } from \"./HallucinationFields\";\nimport { TierOverrideField } from \"./TierOverrideField\";\nimport { AdaptivePersonaFields } from \"./AdaptivePersonaFields\";\nimport { VoiceFields } from \"./VoiceFields\";\n\ninterface Props {\n form: AgentEditorForm;\n models: ModelConfig[];\n integrations: IntegrationStatus[];\n isFullMode: boolean;\n onClose: () => void;\n}\n\nconst Divider = () => <hr className=\"border-border/60 my-2\" />;\n\nexport function AdvancedSection({ form, models, integrations, isFullMode, onClose }: Props) {\n const selectedModel = models.find((m) => m.name === form.modelConfigName);\n return (\n <Section step={4} title=\"Advanced settings\">\n {isFullMode && (\n <>\n <HarnessField form={form} />\n <Divider />\n <AntiHallucinationFields form={form} models={models} />\n <Divider />\n <CitationStrictnessField form={form} />\n <Divider />\n </>\n )}\n <TierOverrideField form={form} selectedModel={selectedModel} />\n <Divider />\n <AdaptivePersonaFields form={form} />\n <Divider />\n <VoiceFields\n form={form}\n models={models}\n integrations={integrations}\n selectedModel={selectedModel}\n onClose={onClose}\n />\n </Section>\n );\n}\n","import { X } from \"lucide-react\";\nimport type React from \"react\";\n\ninterface ChromeProps {\n title: string;\n variant: \"compact\" | \"full\";\n onClose: () => void;\n children: React.ReactNode;\n footer: React.ReactNode;\n}\n\nexport function EditorChrome({ title, variant, onClose, children, footer }: ChromeProps) {\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-start justify-center z-50 p-2 sm:p-4 overflow-y-auto\">\n <div className={`bg-surface-2 border border-border rounded-2xl w-full shadow-xl my-2 sm:my-4 ${variant === \"full\" ? \"max-w-2xl\" : \"max-w-xl\"}`}>\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h3 className=\"text-sm font-semibold text-fg\">{title}</h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\">\n <X size={16} />\n </button>\n </div>\n <div className=\"p-4 space-y-5\">{children}</div>\n {footer}\n </div>\n </div>\n );\n}\n\ninterface FooterProps {\n isDefault: boolean;\n onIsDefaultChange: (v: boolean) => void;\n saving: boolean;\n onSave: () => void;\n onClose: () => void;\n}\n\nexport function EditorFooter({ isDefault, onIsDefaultChange, saving, onSave, onClose }: FooterProps) {\n return (\n <div className=\"flex items-center justify-between px-4 pb-4\">\n <label className=\"flex items-center gap-2 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={isDefault}\n onChange={(e) => onIsDefaultChange(e.target.checked)}\n />\n <span className=\"text-xs text-fg-subtle\">Set as default agent</span>\n </label>\n <div className=\"flex gap-2\">\n <button onClick={onClose} className=\"px-3 py-1.5 text-sm text-fg-subtle hover:text-fg transition-colors\">\n Cancel\n </button>\n <button\n onClick={onSave}\n disabled={saving}\n className=\"px-4 py-1.5 text-sm bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport type { AgentConfig, AgentConfigIn, ModelConfig } from \"@/api/types\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { useAgentEditorForm } from \"./agent-editor/useAgentEditorForm\";\nimport { useAgentSaveHandler } from \"./agent-editor/useAgentSaveHandler\";\nimport { IdentitySection } from \"./agent-editor/IdentitySection\";\nimport { ModelSection } from \"./agent-editor/ModelSection\";\nimport { ToolsSection } from \"./agent-editor/ToolsSection\";\nimport { DelegatesSection } from \"./agent-editor/DelegatesSection\";\nimport { AdvancedSection } from \"./agent-editor/AdvancedSection\";\nimport { EditorChrome, EditorFooter } from \"./agent-editor/EditorChrome\";\n\ninterface Props {\n agent?: AgentConfig;\n models: ModelConfig[];\n onSave: (data: AgentConfigIn) => Promise<void>;\n onClose: () => void;\n}\n\nexport function AgentEditor({ agent, models, onSave, onClose }: Props) {\n const isFullMode = useAppContext().state.experienceMode === \"full\";\n const form = useAgentEditorForm(agent);\n const { saving, error, handleSave } = useAgentSaveHandler({\n buildPayload: form.buildPayload, getName: () => form.name, onSave, onClose,\n });\n useEscapeKey(onClose);\n return (\n <EditorChrome\n title={agent ? \"Edit agent\" : \"New agent\"}\n variant={isFullMode ? \"full\" : \"compact\"}\n onClose={onClose}\n footer={<EditorFooter isDefault={form.isDefault} onIsDefaultChange={form.setIsDefault} saving={saving} onSave={handleSave} onClose={onClose} />}\n >\n <IdentitySection form={form} />\n <hr className=\"border-border\" />\n <ModelSection form={form} models={models} integrations={form.integrations} onClose={onClose} />\n <hr className=\"border-border\" />\n <ToolsSection form={form} advancedMode={isFullMode} />\n <DelegatesSection form={form} />\n <hr className=\"border-border\" />\n <AdvancedSection form={form} models={models} integrations={form.integrations} isFullMode={isFullMode} onClose={onClose} />\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{error}</p>}\n </EditorChrome>\n );\n}\n","\"use client\";\nimport { useRef, useState } from \"react\";\nimport { Pencil, Plus, Trash2 } from \"lucide-react\";\nimport type { AgentConfig, AgentConfigIn } from \"@/api/types\";\nimport { useAgents } from \"@/hooks/useAgents\";\nimport { useModels } from \"@/hooks/useModels\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { AgentEditor } from \"./AgentEditor\";\n\nconst AVATAR_GRADIENTS = [\n \"from-violet-500 to-indigo-600\",\n \"from-blue-500 to-cyan-600\",\n \"from-emerald-500 to-teal-600\",\n \"from-orange-500 to-amber-600\",\n \"from-rose-500 to-pink-600\",\n \"from-fuchsia-500 to-purple-600\",\n];\n\nfunction agentGradient(id: string): string {\n let hash = 0;\n for (let i = 0; i < id.length; i++) hash = (hash * 31 + id.charCodeAt(i)) | 0;\n return AVATAR_GRADIENTS[Math.abs(hash) % AVATAR_GRADIENTS.length];\n}\n\nfunction AgentAvatar({ icon, name, id }: { icon: string | null; name: string; id: string }) {\n if (icon) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={icon}\n alt={name}\n className=\"w-8 h-8 rounded-lg object-cover shrink-0\"\n />\n );\n }\n return (\n <div\n className={`w-8 h-8 rounded-lg bg-gradient-to-br ${agentGradient(id)} flex items-center justify-center text-white text-sm font-bold shrink-0 select-none shadow-sm`}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n );\n}\n\nexport function AgentsPanel() {\n const { agents, loading, create, update, remove } = useAgents();\n const { models } = useModels();\n const [editing, setEditing] = useState<AgentConfig | null | \"new\">(null);\n const [deleting, setDeleting] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"agents\", \"agent\", containerRef);\n\n async function handleSave(data: AgentConfigIn) {\n if (editing === \"new\") {\n await create(data);\n } else if (editing) {\n await update(editing.id, data);\n }\n }\n\n async function handleDelete(agent: AgentConfig) {\n if (!confirm(`Delete agent \"${agent.name}\"? This cannot be undone.`)) return;\n setDeleting(agent.id);\n try {\n await remove(agent.id);\n } finally {\n setDeleting(null);\n }\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-3 pt-3 pb-2 shrink-0\">\n <span className=\"text-[11px] text-fg-faint font-medium uppercase tracking-wide\">Agents</span>\n <button\n onClick={() => setEditing(\"new\")}\n className=\"flex items-center gap-1 px-2 py-1 text-xs bg-accent hover:bg-accent-hover text-white rounded-md transition-colors\"\n >\n <Plus size={11} /> New\n </button>\n </div>\n\n {/* List */}\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-2 pb-2\">\n {loading && (\n <p className=\"text-fg-faint text-xs text-center py-4\">Loading…</p>\n )}\n {!loading && agents.length === 0 && (\n <p className=\"text-fg-faint text-xs text-center py-4 select-none\">\n No agents yet. Create one to start chatting.\n </p>\n )}\n {agents.map((a) => (\n <div\n key={a.id}\n data-deep-link-id={a.id}\n className=\"group flex items-center gap-2.5 px-2 py-2 rounded-lg hover:bg-surface-3 transition-colors\"\n >\n <AgentAvatar icon={a.icon} name={a.name} id={a.id} />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-fg font-medium truncate\">{a.name}</p>\n {a.identity && (\n <p className=\"text-[11px] text-fg-faint truncate\">{a.identity}</p>\n )}\n </div>\n <div className=\"flex items-center gap-0.5 opacity-40 group-hover:opacity-100 focus-within:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n <button\n onClick={() => setEditing(a)}\n className=\"p-1 text-fg-muted hover:text-fg transition-colors\"\n title=\"Edit\"\n >\n <Pencil size={12} />\n </button>\n <button\n onClick={() => void handleDelete(a)}\n disabled={deleting === a.id}\n className=\"p-1 text-fg-muted hover:text-red-700 dark:hover:text-red-400 transition-colors disabled:opacity-50\"\n title=\"Delete\"\n >\n <Trash2 size={12} />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {/* Editor modal */}\n {editing !== null && (\n <AgentEditor\n agent={editing === \"new\" ? undefined : editing}\n models={models}\n onSave={handleSave}\n onClose={() => setEditing(null)}\n />\n )}\n </div>\n );\n}\n","\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { api } from \"@/api/client\";\n\n// When the user has opted in to location sharing, this hook acquires a\n// browser geolocation fix and posts it to the server. It also watches for\n// movement while the tab is open (watchPosition), so the agent's view of\n// the user's location stays roughly fresh without manual refresh.\n//\n// Privacy:\n// - Nothing is requested or sent unless `consent` is true.\n// - Disabling consent clears stored coordinates server-side.\n// - We avoid high-accuracy mode by default — saves battery and is plenty\n// for \"what's nearby\" / weather use-cases. Caller can opt in.\nexport function useLocationSharing(consent: boolean, opts?: { highAccuracy?: boolean }) {\n const lastPostedAt = useRef(0);\n\n useEffect(() => {\n if (!consent) return;\n if (typeof navigator === \"undefined\" || !navigator.geolocation) return;\n\n const post = async (pos: GeolocationPosition) => {\n // Throttle: don't hammer the server faster than once every 30s.\n const t = Date.now();\n if (t - lastPostedAt.current < 30_000) return;\n lastPostedAt.current = t;\n try {\n await api.profile.updateLocation({\n lat: pos.coords.latitude,\n lng: pos.coords.longitude,\n accuracy_m: pos.coords.accuracy,\n });\n } catch (err) {\n console.warn(\"[location] post failed:\", err);\n }\n };\n\n const onError = (err: GeolocationPositionError) => {\n console.warn(\"[location] geolocation error:\", err.code, err.message);\n };\n\n // One-shot first fix (fast), then a watcher for updates.\n navigator.geolocation.getCurrentPosition(post, onError, {\n enableHighAccuracy: opts?.highAccuracy ?? false,\n maximumAge: 60_000,\n timeout: 15_000,\n });\n const watchId = navigator.geolocation.watchPosition(post, onError, {\n enableHighAccuracy: opts?.highAccuracy ?? false,\n maximumAge: 60_000,\n });\n return () => navigator.geolocation.clearWatch(watchId);\n }, [consent, opts?.highAccuracy]);\n}\n","/**\n * Time-formatting helpers shared by UI components.\n *\n * The codebase had three near-identical \"X ago\" implementations across\n * BridgeEditor, ScheduledTasksPanel, and ProfileEditor. They all reduce to:\n * convert a timestamp to a delta, pick a unit, label it.\n *\n * Conventions:\n * - Past timestamps are suffixed \" ago\" (unless `signed` is false).\n * - Future timestamps are prefixed \"in \".\n * - Unit thresholds: <60s → \"Ns\", <60m → \"Nm\", <48h → \"Nh\", else \"Nd\".\n * - For deltas older than ~7 days, callers that prefer an absolute date\n * should use `formatRelativeOrDate()`.\n */\n\nexport type TimeInput = number | string | Date;\n\nfunction toMs(input: TimeInput): number {\n if (typeof input === \"number\") return input;\n if (input instanceof Date) return input.getTime();\n return Date.parse(input);\n}\n\ninterface Options {\n /** Append \" ago\" / prefix \"in \" for past / future. Default true. */\n signed?: boolean;\n /** Use \"<1m\" rather than \"Ns\" for sub-minute deltas. Default false. */\n collapseSeconds?: boolean;\n}\n\n/**\n * Format a timestamp as a relative \"X ago\" / \"in X\" string.\n */\nexport function formatRelative(input: TimeInput, opts: Options = {}): string {\n const { signed = true, collapseSeconds = false } = opts;\n const ms = toMs(input);\n const delta = ms - Date.now();\n const past = delta <= 0;\n const abs = Math.abs(delta);\n\n let txt: string;\n if (abs < 60_000) {\n txt = collapseSeconds ? \"<1m\" : `${Math.max(1, Math.round(abs / 1000))}s`;\n } else if (abs < 3_600_000) {\n txt = `${Math.round(abs / 60_000)}m`;\n } else if (abs < 172_800_000) {\n txt = `${Math.round(abs / 3_600_000)}h`;\n } else {\n txt = `${Math.round(abs / 86_400_000)}d`;\n }\n\n if (!signed) return txt;\n return past ? `${txt} ago` : `in ${txt}`;\n}\n\n/**\n * Like `formatRelative`, but falls back to an absolute locale date once the\n * delta exceeds `maxDays` (default 7).\n */\nexport function formatRelativeOrDate(input: TimeInput, maxDays = 7): string {\n const ms = toMs(input);\n const abs = Math.abs(ms - Date.now());\n if (abs > maxDays * 86_400_000) return new Date(ms).toLocaleDateString();\n return formatRelative(input);\n}\n","\"use client\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { Upload, Plus, Trash2, Shield, MapPin, Globe, Check, Copy } from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport type { UserProfile, AccessWhitelistEntry, TailscaleStatus } from \"@/api/types\";\nimport { useLocationSharing } from \"@/hooks/useLocationSharing\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { formatRelative } from \"@/lib/utils/time\";\nimport { MarkdownTextarea } from \"@/components/ui/MarkdownTextarea\";\n\nexport function ProfileEditor() {\n const { state, dispatch } = useAppContext();\n const mode = state.experienceMode;\n const fileRef = useRef<HTMLInputElement>(null);\n const [profile, setProfile] = useState<UserProfile | null>(null);\n const [name, setName] = useState(\"\");\n const [icon, setIcon] = useState<string | null>(null);\n const [about, setAbout] = useState(\"\");\n const [preset, setPreset] = useState<UserProfile[\"preset\"]>(null);\n const [saving, setSaving] = useState(false);\n const [saved, setSaved] = useState(false);\n\n useEffect(() => {\n api.profile.get().then((p) => {\n setProfile(p);\n setName(p.name);\n setIcon(p.icon);\n setAbout(p.about);\n setPreset(p.preset ?? null);\n }).catch(console.error);\n }, []);\n\n function handleIconFile(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => setIcon(reader.result as string);\n reader.readAsDataURL(file);\n }\n\n async function handleSave() {\n setSaving(true);\n setSaved(false);\n try {\n const updated = await api.profile.update({ name, icon, about, preset });\n setProfile(updated);\n setSaved(true);\n setTimeout(() => setSaved(false), 2000);\n } catch (err) {\n console.error(err);\n } finally {\n setSaving(false);\n }\n }\n\n const isDirty = profile\n ? name !== profile.name\n || icon !== profile.icon\n || about !== profile.about\n || (preset ?? null) !== (profile.preset ?? null)\n : false;\n\n return (\n <div className=\"p-4 space-y-4\">\n {/* Icon + name row */}\n <div className=\"flex items-end gap-3\">\n <div className=\"shrink-0\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Icon</span>\n <button\n onClick={() => fileRef.current?.click()}\n className=\"w-14 h-14 rounded-xl border-2 border-dashed border-border bg-surface-3 flex items-center justify-center hover:border-accent transition-colors overflow-hidden group\"\n title=\"Upload avatar\"\n >\n {icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={icon} alt=\"avatar\" className=\"w-full h-full object-cover\" />\n ) : (\n <Upload size={14} className=\"text-fg-faint group-hover:text-accent transition-colors\" />\n )}\n </button>\n <input ref={fileRef} type=\"file\" accept=\"image/*\" className=\"hidden\" onChange={handleIconFile} />\n {icon && (\n <button onClick={() => setIcon(null)} className=\"text-[10px] text-fg-faint hover:text-red-700 dark:hover:text-red-400 mt-0.5 block\">\n Remove\n </button>\n )}\n </div>\n <label className=\"flex-1 block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Name</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Your name\"\n />\n </label>\n </div>\n\n {/* About */}\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">About me</span>\n <MarkdownTextarea\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent min-h-[7rem] resize-y\"\n value={about}\n onChange={setAbout}\n rows={5}\n placeholder=\"Senior engineer at Acme Corp. Prefers concise answers. Working on a payments platform…\"\n />\n </label>\n\n <p className=\"text-[11px] text-fg-faint\">\n This information is appended to every agent's context so they know who they're talking to.\n </p>\n\n <PresetPicker value={preset} onChange={setPreset} />\n\n <div className=\"pt-4 border-t border-border\">\n <div className=\"rounded-xl border border-border bg-surface-1/40 p-3 space-y-2.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold text-fg\">Experience mode</h3>\n <span className=\"text-[10px] uppercase tracking-wide px-2 py-0.5 rounded-full border border-border bg-surface-3 text-fg-faint\">\n {mode}\n </span>\n </div>\n <p className=\"text-[11px] text-fg-faint leading-snug\">\n Choose how much configuration detail is shown in the app.\n Essential hides technical panels and advanced model controls.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n <button\n type=\"button\"\n onClick={() => dispatch({ type: \"SET_EXPERIENCE_MODE\", mode: \"essential\" })}\n aria-pressed={mode === \"essential\"}\n className={`text-left px-3 py-2.5 rounded-xl border transition-colors ${\n mode === \"essential\"\n ? \"border-accent/60 bg-accent/15 text-fg shadow-sm\"\n : \"border-border bg-surface-3 text-fg-muted hover:text-fg hover:border-border-strong\"\n }`}\n >\n <div className=\"text-xs font-medium\">Essential</div>\n <div className=\"text-[10px] text-fg-faint leading-tight mt-0.5\">Cleaner layout, fewer technical controls</div>\n </button>\n <button\n type=\"button\"\n onClick={() => dispatch({ type: \"SET_EXPERIENCE_MODE\", mode: \"full\" })}\n aria-pressed={mode === \"full\"}\n className={`text-left px-3 py-2.5 rounded-xl border transition-colors ${\n mode === \"full\"\n ? \"border-accent/60 bg-accent/15 text-fg shadow-sm\"\n : \"border-border bg-surface-3 text-fg-muted hover:text-fg hover:border-border-strong\"\n }`}\n >\n <div className=\"text-xs font-medium\">Full</div>\n <div className=\"text-[10px] text-fg-faint leading-tight mt-0.5\">Per-function controls and full tuning</div>\n </button>\n </div>\n </div>\n </div>\n\n <button\n onClick={handleSave}\n disabled={saving || !isDirty}\n className=\"w-full py-2 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-xl shadow-sm transition-colors disabled:opacity-40\"\n >\n {saving ? \"Saving…\" : saved ? \"Saved\" : \"Save profile\"}\n </button>\n\n <LocationSharing profile={profile} onChange={setProfile} />\n\n <TailscaleServe />\n\n <AccessWhitelist />\n </div>\n );\n}\n\n// ─── Persona preset ──────────────────────────────────────────────────────\n// Drives the Credentials panel's category filter. Strictly a UX shortcut:\n// each preset just hides categories that aren't useful for the chosen\n// persona. \"Everything\" (== custom in the DB) means no filtering — same as\n// having no preset at all, which is what fresh installs get.\n//\n// Storing the literal string keeps the column trivially extensible: a\n// future \"education\" preset is a one-line tweak to PRESET_CATEGORIES.\n\ntype Preset = NonNullable<UserProfile[\"preset\"]>;\n\nconst PRESET_OPTIONS: Array<{ value: Preset; label: string; hint: string }> = [\n { value: \"home\", label: \"Home\", hint: \"LLMs, mail, calendar, chat\" },\n { value: \"work\", label: \"Work\", hint: \"Office toolbelt + issue trackers\" },\n { value: \"dev\", label: \"Developer\", hint: \"Everything, incl. infrastructure\" },\n { value: \"custom\", label: \"Everything\", hint: \"No filter — show every integration\" },\n];\n\nfunction PresetPicker({\n value,\n onChange,\n}: {\n value: UserProfile[\"preset\"];\n onChange: (v: Preset) => void;\n}) {\n return (\n <div className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Persona</span>\n <p className=\"text-[11px] text-fg-faint mb-2\">\n Filters the Credentials list so you only see integrations relevant\n to how you use Jarela. Pick "Everything" to see them all.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n {PRESET_OPTIONS.map((o) => {\n const selected = (value ?? \"custom\") === o.value;\n return (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => onChange(o.value)}\n aria-pressed={selected}\n className={`text-left px-3 py-2.5 rounded-xl border transition-colors ${\n selected\n ? \"border-accent/60 bg-accent/15 text-fg shadow-sm\"\n : \"border-border bg-surface-3 text-fg-muted hover:text-fg hover:border-border-strong\"\n }`}\n >\n <div className=\"text-xs font-medium\">{o.label}</div>\n <div className=\"text-[10px] text-fg-faint leading-tight mt-0.5\">{o.hint}</div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ─── Location sharing ───────────────────────────────────────────────────────\n// User-facing toggle backed by user_profile.location_consent. When enabled,\n// the useLocationSharing hook acquires a browser geolocation fix and POSTs\n// it to /api/v1/profile/location. The agent sees the latest position in\n// every system prompt and can also call the get_user_location tool.\n\nfunction LocationSharing({\n profile,\n onChange,\n}: {\n profile: UserProfile | null;\n onChange: (p: UserProfile) => void;\n}) {\n const consent = profile?.location_consent === 1;\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Drives the browser geolocation request + watcher whenever consent is on.\n useLocationSharing(consent);\n\n // Pick up server-side updates (timestamps, accuracy) after the hook POSTs.\n useEffect(() => {\n if (!consent) return;\n const t = setInterval(() => {\n api.profile.get().then(onChange).catch(() => { /* ignore */ });\n }, 5000);\n return () => clearInterval(t);\n }, [consent, onChange]);\n\n async function toggle() {\n if (busy) return;\n setBusy(true);\n setError(null);\n try {\n if (!consent && typeof navigator !== \"undefined\" && !navigator.geolocation) {\n throw new Error(\"Geolocation is not supported in this browser.\");\n }\n const updated = await api.profile.setLocationConsent(!consent);\n onChange(updated);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n }\n\n const hasFix = consent && typeof profile?.location_lat === \"number\" && typeof profile?.location_lng === \"number\";\n const updatedAt = profile?.location_updated_at;\n\n return (\n <div className=\"pt-4 border-t border-border space-y-2\">\n <div className=\"flex items-center gap-2\">\n <MapPin size={14} className=\"text-fg-subtle\" />\n <h3 className=\"text-sm font-semibold text-fg mr-auto\">Share my location</h3>\n <button\n onClick={toggle}\n disabled={busy}\n className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${\n consent ? \"bg-accent\" : \"bg-surface-3 border border-border\"\n } disabled:opacity-40`}\n title={consent ? \"Stop sharing\" : \"Start sharing\"}\n aria-pressed={consent}\n >\n <span\n className={`inline-block h-3.5 w-3.5 transform rounded-full bg-white transition-transform ${\n consent ? \"translate-x-5\" : \"translate-x-1\"\n }`}\n />\n </button>\n </div>\n <p className=\"text-[11px] text-fg-faint\">\n When enabled, your browser sends your current coordinates to Jarela so the agent can answer\n location-aware questions (weather, nearby places, directions). Stored locally only; never sent\n to any third party other than the LLM/MCP services you've configured.\n </p>\n\n {consent && (\n <div className=\"text-[11px] text-fg-subtle px-2 py-1.5 rounded bg-surface-3/40 border border-border\">\n {hasFix ? (\n <>\n <span className=\"font-mono\">\n {profile!.location_lat!.toFixed(5)}, {profile!.location_lng!.toFixed(5)}\n </span>\n {profile?.location_accuracy_m != null && (\n <span className=\"text-fg-faint\"> · ±{Math.round(profile.location_accuracy_m)}m</span>\n )}\n {updatedAt && (\n <span className=\"text-fg-faint\"> · {formatRelative(updatedAt)}</span>\n )}\n </>\n ) : (\n <span className=\"text-fg-faint\">Waiting for browser fix… (allow location when prompted)</span>\n )}\n </div>\n )}\n\n {error && <p className=\"text-rose-700 dark:text-rose-400 text-[11px]\">{error}</p>}\n </div>\n );\n}\n\nfunction AccessWhitelist() {\n const [entries, setEntries] = useState<AccessWhitelistEntry[] | null>(null);\n const [identity, setIdentity] = useState(\"\");\n const [displayName, setDisplayName] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function refresh() {\n try { setEntries(await api.access.list()); }\n catch (e) { setError(e instanceof Error ? e.message : String(e)); }\n }\n useEffect(() => { void refresh(); }, []);\n\n async function add() {\n setError(null);\n if (!identity.trim()) return;\n setBusy(true);\n try {\n await api.access.add(identity.trim(), displayName.trim() || null);\n setIdentity(\"\"); setDisplayName(\"\");\n await refresh();\n } catch (e) { setError(e instanceof Error ? e.message : String(e)); }\n finally { setBusy(false); }\n }\n\n async function remove(id: string) {\n setError(null);\n setBusy(true);\n try { await api.access.remove(id); await refresh(); }\n catch (e) { setError(e instanceof Error ? e.message : String(e)); }\n finally { setBusy(false); }\n }\n\n return (\n <div className=\"pt-4 border-t border-border space-y-2\">\n <div className=\"flex items-center gap-2\">\n <Shield size={14} className=\"text-fg-subtle\" />\n <h3 className=\"text-sm font-semibold text-fg\">Tailscale access whitelist</h3>\n </div>\n <p className=\"text-[11px] text-fg-faint\">\n Identities allowed to reach Jarela through <code className=\"text-fg-subtle\">tailscale serve</code>.\n Local access (<code className=\"text-fg-subtle\">localhost</code>) is always allowed.\n Tailscale passes the identity via the <code className=\"text-fg-subtle\">Tailscale-User-Login</code> header.\n </p>\n\n <div className=\"flex gap-2 items-end\">\n <label className=\"flex-1 block\">\n <span className=\"text-[10px] text-fg-faint mb-0.5 block\">Identity (email)</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={identity}\n onChange={(e) => setIdentity(e.target.value)}\n placeholder=\"you@example.com\"\n onKeyDown={(e) => { if (e.key === \"Enter\") void add(); }}\n />\n </label>\n <label className=\"w-32 block\">\n <span className=\"text-[10px] text-fg-faint mb-0.5 block\">Label (optional)</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n placeholder=\"iPhone\"\n onKeyDown={(e) => { if (e.key === \"Enter\") void add(); }}\n />\n </label>\n <button\n onClick={add}\n disabled={busy || !identity.trim()}\n className=\"px-3 py-1.5 text-xs bg-accent hover:bg-accent-hover text-white rounded transition-colors disabled:opacity-40 flex items-center gap-1\"\n >\n <Plus size={12} /> Add\n </button>\n </div>\n\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{error}</p>}\n\n <ul className=\"divide-y divide-border border border-border rounded\">\n {entries === null && (\n <li className=\"px-3 py-2 text-xs text-fg-faint\">Loading…</li>\n )}\n {entries && entries.length === 0 && (\n <li className=\"px-3 py-2 text-xs text-fg-faint\">No remote identities allowed yet.</li>\n )}\n {entries?.map((e) => (\n <li key={e.identity} className=\"px-3 py-2 flex items-center gap-2 text-xs\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-mono text-fg truncate\">{e.identity}</div>\n <div className=\"text-[10px] text-fg-faint\">\n {e.display_name ? `${e.display_name} · ` : \"\"}\n added {new Date(e.added_at).toLocaleString()}\n {e.last_seen_at ? ` · last seen ${new Date(e.last_seen_at).toLocaleString()}` : \" · never seen\"}\n </div>\n </div>\n <button\n onClick={() => remove(e.identity)}\n disabled={busy}\n className=\"p-1 text-fg-faint hover:text-red-700 dark:hover:text-red-400 disabled:opacity-40\"\n title=\"Remove\"\n >\n <Trash2 size={12} />\n </button>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\n// ─── Tailscale serve status ─────────────────────────────────────────────────\n// Companion to the access whitelist: surfaces whether `tailscale serve` is\n// currently forwarding to this node, the tailnet FQDN, and a one-click\n// copy of the configuration recipe. See ADR-0008 for the recipe rationale.\n\nfunction TailscaleServe() {\n const [status, setStatus] = useState<TailscaleStatus | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n api.tailscale.status()\n .then(setStatus)\n .catch((e) => setError(e instanceof Error ? e.message : String(e)));\n }, []);\n\n async function copyRecipe() {\n if (!status) return;\n try {\n await navigator.clipboard.writeText(status.serve_recipe);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch { /* ignore */ }\n }\n\n const reachableUrl = status?.fqdn ? `https://${status.fqdn}/` : null;\n\n return (\n <div className=\"pt-4 border-t border-border space-y-2\">\n <div className=\"flex items-center gap-2\">\n <Globe size={14} className=\"text-fg-subtle\" />\n <h3 className=\"text-sm font-semibold text-fg mr-auto\">Tailscale serve</h3>\n {status && (\n <span\n className={`text-[10px] uppercase tracking-wide font-semibold px-1.5 py-0.5 rounded ${\n status.serving\n ? \"bg-emerald-500/15 text-emerald-700 dark:text-emerald-400\"\n : status.installed\n ? \"bg-amber-500/15 text-amber-700 dark:text-amber-400\"\n : \"bg-surface-3 text-fg-faint\"\n }`}\n >\n {!status.installed ? \"not installed\" : status.serving ? \"serving\" : status.logged_in ? \"idle\" : \"logged out\"}\n </span>\n )}\n </div>\n\n <p className=\"text-[11px] text-fg-faint\">\n Expose this Jarela on your tailnet so phones (iOS PWA included) can reach it over a\n trusted HTTPS path. Run the recipe once, then add identities to the whitelist below.\n </p>\n\n {status?.serving && reachableUrl && (\n <div className=\"text-[11px] px-2 py-1.5 rounded bg-surface-3/40 border border-border\">\n <span className=\"text-fg-faint\">Reachable at </span>\n <a\n href={reachableUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-mono text-accent hover:underline break-all\"\n >\n {reachableUrl}\n </a>\n </div>\n )}\n\n {status && (\n <div className=\"flex items-stretch gap-1.5\">\n <code className=\"flex-1 text-[11px] font-mono bg-surface-3 text-fg-muted px-2 py-1.5 rounded border border-border break-all leading-snug\">\n {status.serve_recipe}\n </code>\n <button\n onClick={copyRecipe}\n className=\"px-2 text-xs bg-surface-3 hover:bg-surface text-fg-muted border border-border rounded transition-colors flex items-center gap-1\"\n title=\"Copy recipe\"\n >\n {copied ? <Check size={12} className=\"text-emerald-600\" /> : <Copy size={12} />}\n </button>\n </div>\n )}\n\n {status && !status.installed && (\n <p className=\"text-[11px] text-fg-faint\">\n Tailscale isn't installed on this host. Install from{\" \"}\n <a href=\"https://tailscale.com/download/windows\" target=\"_blank\" rel=\"noreferrer\" className=\"text-accent hover:underline\">\n tailscale.com\n </a>{\" \"}\n and run <code className=\"text-fg-subtle\">tailscale up</code> first.\n </p>\n )}\n\n {status?.installed && !status.logged_in && (\n <p className=\"text-[11px] text-fg-faint\">\n Tailscale is installed but not logged in. Run <code className=\"text-fg-subtle\">tailscale up</code> in a terminal.\n </p>\n )}\n\n {status && (\n <p className=\"text-[11px] text-fg-faint\">\n Or run the helper script:{\" \"}\n <code className=\"text-fg-subtle\">{status.install_script}</code>\n {\" — \"}\n <code className=\"text-fg-subtle\">{status.uninstall_script}</code> to reverse.\n </p>\n )}\n\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{error}</p>}\n </div>\n );\n}\n// ─── Tailscale serve status ─────────────────────────────────────────────────\n// Companion to the access whitelist: surfaces whether `tailscale serve` is\n// currently forwarding to this node, the tailnet FQDN, and a one-click\n// copy of the configuration recipe. See ADR-0008 for the recipe rationale.\n\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Lock, Shield } from \"lucide-react\";\n\n// SecurityPanel — UI for enabling, changing, or disabling the at-rest\n// PIN (ADR-0063). Talks to /api/v1/security/{state,pin}. The unlock\n// route is exercised by the splash screen, not here.\n\ntype State = {\n state: \"locked\" | \"unlocked\" | null;\n source: \"keychain\" | \"keyfile\" | \"pin-wrapped-keyfile\" | null;\n pin_enabled: boolean;\n};\n\ntype Mode = \"idle\" | \"enable\" | \"change\" | \"disable\";\n\nexport function SecurityPanel() {\n const [state, setState] = useState<State | null>(null);\n const [mode, setMode] = useState<Mode>(\"idle\");\n const [currentPin, setCurrentPin] = useState(\"\");\n const [newPin, setNewPin] = useState(\"\");\n const [confirmPin, setConfirmPin] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n const [okMsg, setOkMsg] = useState<string | null>(null);\n\n useEffect(() => {\n refresh();\n }, []);\n\n async function refresh() {\n try {\n const res = await fetch(\"/api/v1/security/state\");\n if (res.ok) setState(await res.json());\n } catch { /* ignore */ }\n }\n\n function reset() {\n setMode(\"idle\");\n setCurrentPin(\"\");\n setNewPin(\"\");\n setConfirmPin(\"\");\n setError(null);\n }\n\n async function submit() {\n setError(null);\n setOkMsg(null);\n\n if (mode === \"enable\" || mode === \"change\") {\n if (!/^\\d{6}$/.test(newPin)) {\n setError(\"PIN must be exactly 6 digits.\");\n return;\n }\n if (newPin !== confirmPin) {\n setError(\"PIN entries don't match.\");\n return;\n }\n }\n if ((mode === \"change\" || mode === \"disable\") && !/^\\d{6}$/.test(currentPin)) {\n setError(\"Current PIN must be exactly 6 digits.\");\n return;\n }\n\n const body: Record<string, string> = { action: mode };\n if (mode === \"enable\") body.newPin = newPin;\n if (mode === \"change\") { body.currentPin = currentPin; body.newPin = newPin; }\n if (mode === \"disable\") body.currentPin = currentPin;\n\n setSubmitting(true);\n try {\n const res = await fetch(\"/api/v1/security/pin\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n if (res.ok) {\n const successMsg = mode === \"enable\"\n ? \"PIN enabled. You'll be asked for it on next launch.\"\n : mode === \"change\"\n ? \"PIN changed.\"\n : \"PIN disabled.\";\n setOkMsg(successMsg);\n reset();\n await refresh();\n } else {\n const data = (await res.json().catch(() => ({}))) as { error?: string };\n if (res.status === 401) setError(\"Current PIN is incorrect.\");\n else if (res.status === 429) setError(\"Too many attempts. Try again later.\");\n else setError(data.error ?? `Error (${res.status})`);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setSubmitting(false);\n }\n }\n\n if (!state) {\n return (\n <div className=\"rounded-xl border border-border bg-surface-2/70 p-4 text-sm text-fg-muted\">\n Loading security state…\n </div>\n );\n }\n\n return (\n <div className=\"rounded-xl border border-border bg-surface-2/70 p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Shield size={14} className=\"text-accent\" />\n <h3 className=\"text-sm font-semibold text-fg\">At-rest PIN</h3>\n </div>\n <p className=\"text-xs text-fg-muted mb-3\">\n {state.pin_enabled\n ? \"A 6-digit PIN is required to unlock encrypted data on every launch.\"\n : \"Your data is encrypted at rest with a key from the OS keychain or a local keyfile. Add a 6-digit PIN to require unlock on every launch.\"}\n </p>\n\n {okMsg && (\n <p className=\"text-xs text-emerald-500 mb-2\" role=\"status\">{okMsg}</p>\n )}\n\n {mode === \"idle\" && (\n <div className=\"flex flex-wrap gap-2\">\n {!state.pin_enabled && (\n <button\n type=\"button\"\n onClick={() => { reset(); setMode(\"enable\"); setOkMsg(null); }}\n className=\"text-xs px-3 py-1.5 rounded-lg border border-border bg-surface-3 hover:bg-surface-2 text-fg flex items-center gap-1.5\"\n >\n <Lock size={12} /> Enable PIN\n </button>\n )}\n {state.pin_enabled && (\n <>\n <button\n type=\"button\"\n onClick={() => { reset(); setMode(\"change\"); setOkMsg(null); }}\n className=\"text-xs px-3 py-1.5 rounded-lg border border-border bg-surface-3 hover:bg-surface-2 text-fg\"\n >\n Change PIN\n </button>\n <button\n type=\"button\"\n onClick={() => { reset(); setMode(\"disable\"); setOkMsg(null); }}\n className=\"text-xs px-3 py-1.5 rounded-lg border border-red-500/30 bg-red-500/10 hover:bg-red-500/20 text-red-400\"\n >\n Disable PIN\n </button>\n </>\n )}\n </div>\n )}\n\n {mode !== \"idle\" && (\n <div className=\"space-y-2\">\n {(mode === \"change\" || mode === \"disable\") && (\n <PinInput label=\"Current PIN\" value={currentPin} onChange={setCurrentPin} disabled={submitting} />\n )}\n {(mode === \"enable\" || mode === \"change\") && (\n <>\n <PinInput label=\"New PIN\" value={newPin} onChange={setNewPin} disabled={submitting} />\n <PinInput label=\"Confirm new PIN\" value={confirmPin} onChange={setConfirmPin} disabled={submitting} />\n </>\n )}\n {error && <p className=\"text-xs text-red-400\">{error}</p>}\n <div className=\"flex gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={submit}\n disabled={submitting}\n className=\"text-xs px-3 py-1.5 rounded-lg bg-accent text-bg hover:opacity-90 disabled:opacity-50\"\n >\n {submitting ? \"Saving…\" : \"Confirm\"}\n </button>\n <button\n type=\"button\"\n onClick={reset}\n disabled={submitting}\n className=\"text-xs px-3 py-1.5 rounded-lg border border-border bg-surface-3 hover:bg-surface-2 text-fg-muted\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction PinInput({\n label,\n value,\n onChange,\n disabled,\n}: {\n label: string;\n value: string;\n onChange: (v: string) => void;\n disabled: boolean;\n}) {\n return (\n <label className=\"block\">\n <span className=\"block text-xs text-fg-muted mb-1\">{label}</span>\n <input\n type=\"password\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n maxLength={6}\n value={value}\n onChange={(e) => onChange(e.target.value.replace(/\\D/g, \"\").slice(0, 6))}\n disabled={disabled}\n className=\"w-32 px-2 py-1.5 rounded-lg border border-border bg-surface-3 text-fg text-sm tracking-[0.4em] font-mono\"\n />\n </label>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { ChevronRight, ShieldCheck } from \"lucide-react\";\n\n// RedactionPanel — settings UI for ADR-0064 outbound redaction.\n// Surfaces the global on/off toggle, the path of the user's pattern\n// file, and a read-only view of the patterns the app is currently\n// using (defaults until the user materializes their own file).\n\ninterface PatternConfig {\n name: string;\n type_hint: string;\n validator?: string;\n enabled: boolean;\n}\n\ninterface ActiveConfig {\n patterns: PatternConfig[];\n heuristics: {\n high_entropy: {\n enabled: boolean;\n min_length: number;\n min_entropy: number;\n };\n };\n field_name_allowlist: string[];\n}\n\ninterface RedactionState {\n enabled: boolean;\n config_path: string;\n config_exists: boolean;\n active: ActiveConfig;\n}\n\nexport function RedactionPanel() {\n const [state, setState] = useState<RedactionState | null>(null);\n const [showPatterns, setShowPatterns] = useState(false);\n const [showAllowlist, setShowAllowlist] = useState(false);\n const [busy, setBusy] = useState(false);\n const [msg, setMsg] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n try {\n const res = await fetch(\"/api/v1/redaction\");\n if (res.ok) setState(await res.json());\n } catch { /* ignore */ }\n }, []);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const toggle = useCallback(async (enabled: boolean) => {\n setBusy(true);\n setMsg(null);\n try {\n const res = await fetch(\"/api/v1/redaction\", {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ enabled }),\n });\n if (res.ok) {\n await refresh();\n } else {\n setMsg(\"Could not save toggle.\");\n }\n } finally {\n setBusy(false);\n }\n }, [refresh]);\n\n const materialize = useCallback(async () => {\n setBusy(true);\n setMsg(null);\n try {\n const res = await fetch(\"/api/v1/redaction/init\", { method: \"POST\" });\n if (res.ok) {\n const { created, path } = (await res.json()) as { created: boolean; path: string };\n setMsg(created ? `Created ${path}` : `Already exists at ${path}`);\n await refresh();\n } else {\n setMsg(\"Could not create pattern file.\");\n }\n } finally {\n setBusy(false);\n }\n }, [refresh]);\n\n if (!state) {\n return (\n <div className=\"rounded-xl border border-border bg-surface-2/70 p-4 text-sm text-fg-muted\">\n Loading redaction settings…\n </div>\n );\n }\n\n const enabledPatterns = state.active.patterns.filter((p) => p.enabled);\n\n return (\n <div className=\"rounded-xl border border-border bg-surface-2/70 p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <ShieldCheck size={14} className=\"text-emerald-500\" />\n <h3 className=\"text-sm font-semibold text-fg\">Outbound redaction</h3>\n </div>\n <p className=\"text-xs text-fg-muted mb-3\">\n Sensitive values (API keys, JWTs, SSN, Swedish personnummer, IBAN, plus a\n high-entropy heuristic) are replaced with stable placeholders before being\n sent to the LLM, then rehydrated on the way back. Real values stay on this\n device.\n </p>\n\n <label className=\"flex items-center justify-between gap-2 py-2\">\n <div className=\"flex flex-col\">\n <span className=\"text-xs font-medium text-fg\">Enable redaction</span>\n <span className=\"text-[11px] text-fg-faint\">\n When off, message content reaches the LLM provider untouched.\n </span>\n </div>\n <input\n type=\"checkbox\"\n checked={state.enabled}\n disabled={busy}\n onChange={(e) => void toggle(e.target.checked)}\n className=\"h-4 w-4 cursor-pointer accent-emerald-500\"\n />\n </label>\n\n <div className=\"mt-2 pt-2 border-t border-border/50 flex items-center justify-between gap-2\">\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-xs font-medium text-fg\">Pattern file</span>\n <span className=\"text-[11px] text-fg-faint font-mono truncate\" title={state.config_path}>\n {state.config_path}\n </span>\n </div>\n {state.config_exists ? (\n <span className=\"text-[11px] text-emerald-600 dark:text-emerald-400 shrink-0\">\n user-edited\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={() => void materialize()}\n disabled={busy}\n className=\"text-[11px] px-2 py-1 rounded border border-border bg-surface-3 hover:bg-surface-2 text-fg disabled:opacity-50\"\n title=\"Write the default pattern set to disk so you can edit it\"\n >\n Create default file\n </button>\n )}\n </div>\n\n {msg && <div className=\"mt-2 text-[11px] text-fg-muted\">{msg}</div>}\n\n <div className=\"mt-3 pt-2 border-t border-border/50\">\n <button\n type=\"button\"\n onClick={() => setShowPatterns((v) => !v)}\n className=\"inline-flex items-center gap-1 text-xs text-fg-muted hover:text-fg\"\n aria-expanded={showPatterns}\n >\n <ChevronRight size={11} className={`transition-transform ${showPatterns ? \"rotate-90\" : \"\"}`} />\n <span>{enabledPatterns.length} active patterns</span>\n {state.active.heuristics.high_entropy.enabled && (\n <span className=\"text-fg-faint\">\n {\" \"}+ entropy heuristic (≥ {state.active.heuristics.high_entropy.min_length} chars,\n ≥ {state.active.heuristics.high_entropy.min_entropy} bits/char)\n </span>\n )}\n </button>\n {showPatterns && (\n <ul className=\"mt-1 pl-4 space-y-0.5\">\n {enabledPatterns.map((p) => (\n <li key={p.name} className=\"text-[11px] text-fg-muted\">\n <span className=\"font-mono opacity-90\">{p.name}</span>\n {\" → \"}\n <span className=\"font-mono opacity-75\">{p.type_hint}</span>\n {p.validator && (\n <span className=\"ml-1 text-fg-faint\">[{p.validator}]</span>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n\n <div className=\"mt-2\">\n <button\n type=\"button\"\n onClick={() => setShowAllowlist((v) => !v)}\n className=\"inline-flex items-center gap-1 text-xs text-fg-muted hover:text-fg\"\n aria-expanded={showAllowlist}\n >\n <ChevronRight size={11} className={`transition-transform ${showAllowlist ? \"rotate-90\" : \"\"}`} />\n <span>{state.active.field_name_allowlist.length} allowlisted JSON field names</span>\n </button>\n {showAllowlist && (\n <div className=\"mt-1 pl-4 flex flex-wrap gap-1\">\n {state.active.field_name_allowlist.map((f) => (\n <span\n key={f}\n className=\"text-[10px] font-mono px-1.5 py-0.5 rounded bg-surface-3 text-fg-muted\"\n >\n {f}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Edit3, Network, RotateCcw, Save, ServerCog } from \"lucide-react\";\nimport { refreshRuntimeConfig } from \"@/api/runtime-config\";\n\ninterface EnvRow {\n name: string;\n type: \"int\" | \"string\" | \"bool\" | \"enum\";\n default: number | string | boolean;\n current: string;\n overridden: boolean;\n description: string;\n category: string;\n tier: \"A\" | \"B\" | \"C\";\n requiresRestart: boolean;\n agentWritable: boolean;\n enumValues?: readonly string[];\n min?: number;\n max?: number;\n}\n\n// Embedded network/proxy settings for the Profile page. Shows the\n// `category === \"network\"` slice of /api/v1/env (bind host, port,\n// HTTP/SSE timeouts, retry count) inline so the user doesn't need to\n// open the full Environment panel to tune them. The same vars no\n// longer appear in EnvVarsPanel.\nexport function NetworkPanel() {\n const [rows, setRows] = useState<EnvRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [editing, setEditing] = useState<{ name: string; value: string } | null>(null);\n const [saving, setSaving] = useState(false);\n const [restartNeeded, setRestartNeeded] = useState(false);\n const [restarting, setRestarting] = useState(false);\n\n const load = useCallback(async () => {\n try {\n const r = await fetch(\"/api/v1/env\", { cache: \"no-store\" });\n if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);\n const body = (await r.json()) as { entries: EnvRow[] };\n setRows(body.entries.filter((row) => row.category === \"network\"));\n setError(null);\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const persist = useCallback(async (name: string, value: string | null, requiresRestart: boolean) => {\n setSaving(true);\n try {\n const r = await fetch(\"/api/v1/env\", {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name, value }),\n });\n if (!r.ok) {\n const body = (await r.json().catch(() => ({}))) as { error?: string };\n throw new Error(body.error ?? `${r.status} ${r.statusText}`);\n }\n if (requiresRestart) setRestartNeeded(true);\n refreshRuntimeConfig();\n await load();\n setEditing(null);\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setSaving(false);\n }\n }, [load]);\n\n const onSave = useCallback(() => {\n if (!editing) return;\n const row = rows.find((r) => r.name === editing.name);\n if (!row) return;\n void persist(editing.name, editing.value, row.requiresRestart);\n }, [editing, rows, persist]);\n\n const onReset = useCallback((row: EnvRow) => {\n void persist(row.name, null, row.requiresRestart);\n }, [persist]);\n\n const onRestart = useCallback(async () => {\n if (!confirm(\"Restart the server? In-flight runs will be aborted; the supervisor (launchd / systemd / Task Scheduler) will relaunch the process.\")) {\n return;\n }\n setRestarting(true);\n try {\n await fetch(\"/api/v1/system/restart\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ reason: \"user clicked Restart in NetworkPanel\" }),\n });\n pollUntilUp().then(() => {\n setRestarting(false);\n setRestartNeeded(false);\n void load();\n }).catch(() => {\n setRestarting(false);\n setError(\"Server didn't come back within 30s — check it manually.\");\n });\n } catch (e) {\n setRestarting(false);\n setError((e as Error).message);\n }\n }, [load]);\n\n return (\n <div className=\"rounded-xl border border-border bg-surface-2/70 p-4 mt-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Network size={14} className=\"text-accent\" />\n <h3 className=\"text-sm font-semibold text-fg\">Network</h3>\n <span className=\"ml-auto text-[10px] text-fg-faint\">{rows.length} vars</span>\n </div>\n <p className=\"text-xs text-fg-muted mb-3\">\n Bind address, port, and HTTP timeouts. Changes to bind-time\n values require a server restart.\n </p>\n\n {restartNeeded && (\n <div className=\"mb-3 px-3 py-2 rounded-lg border border-amber-700/50 bg-amber-900/20 text-amber-700 dark:text-amber-300 text-xs flex items-center gap-2\">\n <ServerCog size={14} aria-hidden />\n <span className=\"flex-1\">A change you made requires a server restart to take effect.</span>\n <button\n type=\"button\"\n disabled={restarting}\n onClick={onRestart}\n className=\"px-2 py-0.5 rounded bg-amber-600/80 text-white hover:bg-amber-600 disabled:opacity-50 text-[11px]\"\n >\n {restarting ? \"Restarting…\" : \"Restart server\"}\n </button>\n </div>\n )}\n\n {error && (\n <p className=\"text-xs text-red-400 mb-2\">{error}</p>\n )}\n\n {loading ? (\n <p className=\"text-xs text-fg-muted\">Loading…</p>\n ) : rows.length === 0 ? (\n <p className=\"text-xs text-fg-muted\">No network vars surfaced by the server.</p>\n ) : (\n <ul className=\"divide-y divide-border/30 rounded-lg border border-border/40 bg-surface\">\n {rows.map((row) => (\n <li key={row.name} className=\"px-3 py-2\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n <code className=\"text-[12px] font-mono text-fg\">{row.name}</code>\n {row.overridden && (\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-emerald-500/20 text-emerald-700 dark:text-emerald-300\">\n overridden\n </span>\n )}\n {row.requiresRestart && (\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-amber-500/20 text-amber-700 dark:text-amber-300\">\n restart\n </span>\n )}\n </div>\n <div className=\"mt-0.5 text-[11px] text-fg-muted\">{row.description}</div>\n {editing?.name === row.name ? (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <input\n type={row.type === \"int\" ? \"number\" : \"text\"}\n value={editing.value}\n onChange={(e) => setEditing({ name: row.name, value: e.target.value })}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onSave();\n if (e.key === \"Escape\") setEditing(null);\n }}\n min={row.min}\n max={row.max}\n autoFocus\n className=\"px-2 py-1 rounded border border-border bg-surface text-fg text-[11px] font-mono w-48\"\n />\n <button\n type=\"button\"\n onClick={onSave}\n disabled={saving}\n className=\"px-2 py-1 rounded bg-accent text-white hover:bg-accent/90 disabled:opacity-50 text-[11px] inline-flex items-center gap-1\"\n >\n <Save size={11} /> Save\n </button>\n <button\n type=\"button\"\n onClick={() => setEditing(null)}\n className=\"px-2 py-1 rounded border border-border text-fg-faint hover:bg-surface-2 text-[11px]\"\n >\n Cancel\n </button>\n </div>\n ) : (\n <div className=\"mt-0.5 flex items-center gap-2 flex-wrap\">\n <code className=\"text-[11px] font-mono text-fg-muted\">{row.current}</code>\n {row.overridden && (\n <span className=\"text-[10px] text-fg-faint\">\n (default: <code className=\"font-mono\">{String(row.default)}</code>)\n </span>\n )}\n </div>\n )}\n </div>\n {editing?.name !== row.name && (\n <div className=\"flex items-center gap-1 shrink-0\">\n <button\n type=\"button\"\n onClick={() => setEditing({ name: row.name, value: row.current })}\n className=\"p-1.5 rounded border border-border text-fg-faint hover:bg-surface-2 hover:text-fg\"\n title=\"Edit\"\n >\n <Edit3 size={12} />\n </button>\n <button\n type=\"button\"\n onClick={() => onReset(row)}\n disabled={!row.overridden}\n className=\"p-1.5 rounded border border-border text-fg-faint hover:bg-surface-2 hover:text-fg disabled:opacity-30 disabled:hover:bg-transparent\"\n title={row.overridden ? \"Reset to default\" : \"No override to reset\"}\n >\n <RotateCcw size={12} />\n </button>\n </div>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nasync function pollUntilUp(timeoutMs = 30_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let delay = 500;\n while (Date.now() < deadline) {\n await new Promise<void>((r) => setTimeout(r, delay));\n delay = Math.min(2000, Math.floor(delay * 1.4));\n try {\n const r = await fetch(\"/api/v1/health\", { cache: \"no-store\" });\n if (r.ok) return;\n } catch { /* still down */ }\n }\n throw new Error(\"server did not return\");\n}\n","\"use client\";\nimport { Sparkles, User } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { OnboardingWizard } from \"@/components/setup/OnboardingWizard\";\nimport { ProfileEditor } from \"./ProfileEditor\";\nimport { SecurityPanel } from \"./SecurityPanel\";\nimport { RedactionPanel } from \"./RedactionPanel\";\nimport { NetworkPanel } from \"./NetworkPanel\";\n\nexport function ProfilePanel() {\n const { state } = useAppContext();\n const isEssential = state.experienceMode === \"essential\";\n const containerRef = useRef<HTMLDivElement>(null);\n const [showWizard, setShowWizard] = useState(false);\n useDeepLinkScroll(\"profile\", \"profile\", containerRef);\n\n if (isEssential && showWizard) {\n return (\n <div className=\"h-full overflow-y-auto profile-scrollbar panel-scrollbar\">\n <div className=\"max-w-3xl mx-auto w-full px-4 pt-4\">\n <div className=\"rounded-xl border border-border bg-surface-2/70 px-3 py-2 flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2 text-xs text-fg-muted\">\n <Sparkles size={14} className=\"text-accent\" />\n <span>\n Setup wizard is open. You can return to profile anytime.\n </span>\n </div>\n <button\n type=\"button\"\n onClick={() => {\n setShowWizard(false);\n }}\n className=\"text-xs px-2.5 py-1.5 rounded-lg border border-border bg-surface-3 hover:bg-surface-2 text-fg\"\n >\n Back to profile\n </button>\n </div>\n </div>\n <OnboardingWizard context=\"profile\" />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <User size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg\">User Profile</h2>\n {isEssential && (\n <button\n type=\"button\"\n onClick={() => {\n setShowWizard(true);\n }}\n className=\"ml-auto text-xs px-2.5 py-1 rounded-lg border border-border bg-surface-3 hover:bg-surface-2 text-fg-muted hover:text-fg\"\n >\n Run setup wizard again\n </button>\n )}\n </div>\n <div ref={containerRef} className=\"flex-1 overflow-y-auto profile-scrollbar panel-scrollbar max-w-lg mx-auto w-full\">\n <ProfileEditor />\n <div className=\"px-4 pb-6\">\n <SecurityPanel />\n <RedactionPanel />\n <NetworkPanel />\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { AlertCircle, CheckCircle2, ChevronLeft, ExternalLink, Plug, Plus, Sparkles, Trash2, X } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { McpRegistryEntry, McpServer } from \"@/api/types\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\n\n// `editing` value when the user clicked New: starts on the picker step;\n// once they pick a registry entry (or click \"custom\") it transitions to a form.\ntype EditState =\n | null\n | { mode: \"picker\" }\n | { mode: \"form\"; existing: McpServer | null; registryEntry?: McpRegistryEntry };\n\nexport function MCPPanel() {\n const [servers, setServers] = useState<McpServer[]>([]);\n const [loading, setLoading] = useState(true);\n const [editing, setEditing] = useState<EditState>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"mcp\", \"mcp\", containerRef);\n\n async function load() {\n setLoading(true);\n try { setServers(await api.mcp.list()); } catch (e) { console.error(e); }\n finally { setLoading(false); }\n }\n\n useEffect(() => { void load(); }, []);\n\n async function toggle(s: McpServer) {\n await api.mcp.update(s.name, { enabled: !s.enabled });\n void load();\n }\n\n async function remove(name: string) {\n if (!confirm(`Remove MCP server \"${name}\"?`)) return;\n await api.mcp.delete(name);\n void load();\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Plug size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">MCP Servers</h2>\n <button\n onClick={() => setEditing({ mode: \"picker\" })}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\"\n >\n <Plus size={14} /> New\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto\">\n <div className=\"px-4 py-2\">\n {loading && servers.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && servers.length === 0 && (\n <div className=\"text-fg-faint text-sm py-8 text-center space-y-2\">\n <p>No MCP servers configured.</p>\n <p className=\"text-xs text-fg-faint\">\n MCP servers expose tools (filesystem, GitHub, Postgres, …) that the agent can call alongside built-ins.\n </p>\n </div>\n )}\n {servers.map((s) => (\n <div key={s.name} data-deep-link-id={s.name} className=\"flex items-center gap-3 py-2.5 border-b border-border/60 group\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <button\n onClick={() => toggle(s)}\n className={s.enabled ? \"text-emerald-700 dark:text-emerald-400\" : \"text-fg-faint hover:text-fg-subtle\"}\n title={s.enabled ? \"Disable\" : \"Enable\"}\n >\n {s.enabled ? <CheckCircle2 size={13} /> : <AlertCircle size={13} />}\n </button>\n <span className=\"text-sm font-medium text-fg\">{s.name}</span>\n <span className=\"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded border bg-surface-2 text-fg-subtle border-border\">\n {s.transport}\n </span>\n </div>\n <p className=\"text-xs text-fg-faint truncate font-mono\">\n {s.transport === \"stdio\"\n ? `${(s.spec as { command?: string }).command ?? \"?\"} ${((s.spec as { args?: string[] }).args ?? []).join(\" \")}`\n : `${(s.spec as { url?: string }).url ?? \"?\"}`}\n </p>\n {s.last_error && (\n <p className=\"text-xs text-rose-700 dark:text-rose-400 mt-0.5 truncate\" title={s.last_error}>\n error: {s.last_error}\n </p>\n )}\n </div>\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n <button onClick={() => setEditing({ mode: \"form\", existing: s })} className=\"p-1 text-fg-subtle hover:text-fg transition-colors\" title=\"Edit\">\n <span className=\"text-xs\">edit</span>\n </button>\n <button onClick={() => remove(s.name)} className=\"p-1 text-fg-subtle hover:text-red-700 dark:hover:text-red-400 transition-colors\" title=\"Delete\">\n <Trash2 size={13} />\n </button>\n </div>\n </div>\n ))}\n </div>\n </div>\n\n {editing?.mode === \"picker\" && (\n <RegistryPicker\n existingNames={new Set(servers.map((s) => s.name))}\n onPick={(entry) => setEditing({ mode: \"form\", existing: null, registryEntry: entry })}\n onCustom={() => setEditing({ mode: \"form\", existing: null })}\n onClose={() => setEditing(null)}\n />\n )}\n {editing?.mode === \"form\" && (\n <MCPEditor\n server={editing.existing}\n registryEntry={editing.registryEntry}\n onBack={editing.existing ? undefined : () => setEditing({ mode: \"picker\" })}\n onClose={() => { setEditing(null); void load(); }}\n />\n )}\n </div>\n );\n}\n\nfunction MCPEditor({\n server, registryEntry, onClose, onBack,\n}: {\n server: McpServer | null;\n registryEntry?: McpRegistryEntry;\n onClose: () => void;\n onBack?: () => void;\n}) {\n // If we came from the registry picker, pre-fill name + transport + spec.\n // The user fills in `${VAR}` values via the variables form below; we render\n // the spec with substitutions applied at save time.\n const [name, setName] = useState(server?.name ?? registryEntry?.id ?? \"\");\n const [transport, setTransport] = useState<\"stdio\" | \"http\">(server?.transport ?? registryEntry?.transport ?? \"stdio\");\n const [varValues, setVarValues] = useState<Record<string, string>>(() => {\n const init: Record<string, string> = {};\n for (const v of registryEntry?.variables ?? []) init[v.key] = v.default ?? \"\";\n return init;\n });\n\n const initialSpecJSON = useMemo(() => {\n if (server) return JSON.stringify(server.spec, null, 2);\n if (registryEntry) return JSON.stringify(registryEntry.spec, null, 2);\n return JSON.stringify(\n transport === \"stdio\"\n ? { command: \"npx\", args: [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"] }\n : { url: \"https://example.com/mcp\", headers: {} },\n null, 2,\n );\n // initialSpecJSON should only compute once per editor instance.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n const [specJSON, setSpecJSON] = useState(initialSpecJSON);\n const [enabled, setEnabled] = useState(server?.enabled ?? true);\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n\n // When transport switches, suggest a fresh spec template if user hasn't customized.\n function switchTransport(t: \"stdio\" | \"http\") {\n setTransport(t);\n const template = t === \"stdio\"\n ? { command: \"npx\", args: [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"] }\n : { url: \"https://example.com/mcp\", headers: {} };\n setSpecJSON(JSON.stringify(template, null, 2));\n }\n\n async function save() {\n setError(null);\n if (!name.trim()) { setError(\"name is required\"); return; }\n let spec: Record<string, unknown>;\n try { spec = JSON.parse(specJSON); }\n catch (e) { setError(`spec is not valid JSON: ${e instanceof Error ? e.message : String(e)}`); return; }\n // Apply registry variable substitutions if any are declared.\n if (registryEntry?.variables?.length) {\n const missing = registryEntry.variables.filter((v) => !varValues[v.key]?.trim());\n if (missing.length > 0) {\n setError(`Fill in: ${missing.map((m) => m.label).join(\", \")}`);\n return;\n }\n spec = substituteVars(spec, varValues);\n }\n setSaving(true);\n try {\n if (server) {\n await api.mcp.update(server.name, { transport, spec, enabled });\n } else {\n await api.mcp.create({ name: name.trim(), transport, spec, enabled });\n }\n onClose();\n } catch (e) {\n pushErrorToast({\n title: server ? \"Couldn't update MCP server\" : \"Couldn't create MCP server\",\n error: e,\n context: { panel: \"mcp\", action: server ? \"mcp.update\" : \"mcp.create\", name: name.trim(), transport },\n });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div className=\"absolute inset-0 bg-black/60 z-30 flex items-center justify-center p-4\" onClick={onClose}>\n <div className=\"bg-surface-2 border border-border rounded-xl w-full max-w-md shadow-2xl max-h-[90vh] flex flex-col\" onClick={(e) => e.stopPropagation()}>\n <div className=\"px-4 py-3 border-b border-border flex items-center gap-1\">\n {onBack && (\n <button onClick={onBack} className=\"p-1 text-fg-subtle hover:text-fg\" title=\"Back to picker\">\n <ChevronLeft size={14} />\n </button>\n )}\n <h3 className=\"text-sm font-semibold text-fg mr-auto\">\n {server ? `Edit ${server.name}` : registryEntry ? `Install ${registryEntry.name}` : \"New MCP server\"}\n </h3>\n <button onClick={onClose} className=\"p-1 text-fg-subtle hover:text-fg\">\n <X size={14} />\n </button>\n </div>\n\n <div className=\"p-4 space-y-3 overflow-y-auto\">\n {registryEntry && (\n <div className=\"px-3 py-2 rounded bg-surface-3/40 border border-border text-[11px] text-fg-subtle\">\n {registryEntry.description}\n {registryEntry.url && (\n <a href={registryEntry.url} target=\"_blank\" rel=\"noreferrer\" className=\"ml-1 inline-flex items-center gap-0.5 text-sky-700 dark:text-sky-400 hover:text-sky-700 dark:hover:text-sky-300\">\n docs <ExternalLink size={10} />\n </a>\n )}\n </div>\n )}\n\n {registryEntry?.variables?.length ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-fg-subtle font-medium\">Configure</p>\n {registryEntry.variables.map((v) => (\n <label key={v.key} className=\"block text-xs text-fg-subtle\">\n {v.label}\n <input\n type={v.secret ? \"password\" : \"text\"}\n value={varValues[v.key] ?? \"\"}\n onChange={(e) => setVarValues((prev) => ({ ...prev, [v.key]: e.target.value }))}\n placeholder={v.placeholder}\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono\"\n />\n </label>\n ))}\n </div>\n ) : null}\n\n <label className=\"block text-xs text-fg-subtle\">\n Name\n <input\n value={name}\n onChange={(e) => setName(e.target.value)}\n disabled={!!server}\n className=\"mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg disabled:opacity-50\"\n placeholder=\"filesystem\"\n />\n </label>\n\n <div>\n <p className=\"text-xs text-fg-subtle mb-1\">Transport</p>\n <div className=\"flex gap-1\">\n {([\"stdio\", \"http\"] as const).map((t) => (\n <button\n key={t}\n onClick={() => switchTransport(t)}\n className={`px-3 py-1 text-xs rounded border ${\n transport === t\n ? \"bg-accent/20 border-accent text-accent\"\n : \"bg-surface-3 border-border text-fg-subtle hover:text-fg\"\n }`}\n >\n {t}\n </button>\n ))}\n </div>\n </div>\n\n <label className=\"block text-xs text-fg-subtle\">\n Spec (JSON)\n <p className=\"mt-0.5 mb-1 text-[11px] text-fg-faint\">\n {transport === \"stdio\"\n ? <>Keys: <code>command</code>, <code>args[]</code>, <code>env{}</code></>\n : <>Keys: <code>url</code>, <code>headers{}</code></>}\n </p>\n <textarea\n value={specJSON}\n onChange={(e) => setSpecJSON(e.target.value)}\n rows={8}\n className=\"w-full px-2 py-1.5 text-xs font-mono rounded border border-border bg-surface-3 text-fg\"\n />\n </label>\n\n <label className=\"inline-flex items-center gap-2 text-xs text-fg-muted\">\n <input type=\"checkbox\" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />\n Enabled\n </label>\n\n {error && (\n <div className=\"px-2 py-1.5 rounded bg-rose-950/40 border border-rose-800 text-xs text-rose-700 dark:text-rose-300\">\n {error}\n </div>\n )}\n </div>\n\n <div className=\"px-4 py-3 border-t border-border flex justify-end gap-2\">\n <button onClick={onClose} className=\"px-3 py-1.5 text-xs text-fg-subtle hover:text-fg\">\n Cancel\n </button>\n <button\n onClick={save}\n disabled={saving}\n className=\"px-3 py-1.5 text-xs rounded bg-accent text-white hover:bg-accent-hover disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// Recursively substitutes ${VAR} placeholders in spec strings using user input.\nfunction substituteVars(node: unknown, values: Record<string, string>): Record<string, unknown> {\n return walk(node) as Record<string, unknown>;\n function walk(n: unknown): unknown {\n if (typeof n === \"string\") return n.replace(/\\$\\{(\\w+)\\}/g, (_, k) => values[k] ?? `\\${${k}}`);\n if (Array.isArray(n)) return n.map(walk);\n if (n && typeof n === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(n as Record<string, unknown>)) out[k] = walk(v);\n return out;\n }\n return n;\n }\n}\n\n// Browse-and-install picker backed by the official MCP registry. Search\n// queries hit registry.modelcontextprotocol.io via /api/v1/mcp-servers/registry;\n// results are paginated with a cursor.\nfunction RegistryPicker({\n existingNames, onPick, onCustom, onClose,\n}: {\n existingNames: Set<string>;\n onPick: (entry: McpRegistryEntry) => void;\n onCustom: () => void;\n onClose: () => void;\n}) {\n const [query, setQuery] = useState(\"\");\n const [debouncedQuery, setDebouncedQuery] = useState(\"\");\n const [entries, setEntries] = useState<McpRegistryEntry[]>([]);\n const [nextCursor, setNextCursor] = useState<string | undefined>(undefined);\n const [loading, setLoading] = useState(true);\n const [loadingMore, setLoadingMore] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const t = setTimeout(() => setDebouncedQuery(query.trim()), 250);\n return () => clearTimeout(t);\n }, [query]);\n\n const runSearch = useCallback(async (q: string, fresh = false) => {\n setLoading(true); setError(null);\n try {\n const res = await api.mcp.registry({ q: q || undefined, fresh });\n setEntries(res.entries);\n setNextCursor(res.nextCursor);\n } catch (e) {\n setEntries([]); setNextCursor(undefined);\n // Inline error preserves the Retry button at the picker; the toast\n // gives the user a one-click path to report the failure.\n setError(e instanceof Error ? e.message : String(e));\n pushErrorToast({\n title: \"Couldn't search MCP registry\",\n error: e,\n context: { panel: \"mcp\", action: \"registry.search\", query: q || null },\n });\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => { void runSearch(debouncedQuery); }, [debouncedQuery, runSearch]);\n\n async function loadMore() {\n if (!nextCursor || loadingMore) return;\n setLoadingMore(true);\n try {\n const res = await api.mcp.registry({ q: debouncedQuery || undefined, cursor: nextCursor });\n setEntries((prev) => [...prev, ...res.entries]);\n setNextCursor(res.nextCursor);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n pushErrorToast({\n title: \"Couldn't load more registry entries\",\n error: e,\n context: { panel: \"mcp\", action: \"registry.loadMore\", cursor: nextCursor ?? null },\n });\n } finally {\n setLoadingMore(false);\n }\n }\n\n return (\n <div className=\"absolute inset-0 bg-black/60 z-30 flex items-center justify-center p-4\" onClick={onClose}>\n <div\n className=\"bg-surface-2 border border-border rounded-xl w-full max-w-lg shadow-2xl max-h-[85vh] flex flex-col\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"px-4 py-3 border-b border-border flex items-center gap-2\">\n <Sparkles size={14} className=\"text-amber-700 dark:text-amber-400\" />\n <h3 className=\"text-sm font-semibold text-fg mr-auto\">Add MCP server</h3>\n <button onClick={onClose} className=\"p-1 text-fg-subtle hover:text-fg\">\n <X size={14} />\n </button>\n </div>\n\n <div className=\"px-4 py-2 border-b border-border\">\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search the MCP registry…\"\n className=\"w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg\"\n autoFocus\n />\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-2\">\n {loading && entries.length === 0 && <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>}\n {error && (\n <div className=\"my-3 px-3 py-2 rounded border border-rose-800 bg-rose-950/40 text-xs text-rose-700 dark:text-rose-300\">\n <p className=\"mb-1\">Couldn’t reach registry.modelcontextprotocol.io.</p>\n <button\n onClick={() => void runSearch(debouncedQuery, true)}\n className=\"underline hover:text-rose-200\"\n >\n Retry\n </button>\n </div>\n )}\n {!loading && !error && entries.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">No matches.</p>\n )}\n <div className=\"space-y-1\">\n {entries.map((e) => {\n const installed = existingNames.has(e.id);\n return (\n <button\n key={`${e.id}-${e.name}`}\n onClick={() => onPick(e)}\n disabled={installed}\n className={`w-full text-left px-3 py-2 rounded-lg border transition-colors group ${\n installed\n ? \"bg-surface-3/30 border-border/40 cursor-not-allowed\"\n : \"bg-surface-3/60 hover:bg-surface-3 border-border hover:border-border\"\n }`}\n >\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className={`text-sm font-medium ${installed ? \"text-fg-faint\" : \"text-fg\"}`}>{e.name}</span>\n <span className=\"text-[9px] uppercase tracking-wider px-1 py-px rounded border border-border text-fg-faint\">\n {e.transport}\n </span>\n <span className={`text-[9px] uppercase tracking-wider px-1 py-px rounded border ${\n e.source === \"Official\"\n ? \"border-emerald-700/60 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10\"\n : e.source === \"Vendor\"\n ? \"border-sky-700/60 text-sky-600 dark:text-sky-400 bg-sky-500/10\"\n : \"border-border text-fg-faint\"\n }`}>\n {e.source}\n </span>\n {installed && (\n <span className=\"text-[10px] text-emerald-500 ml-auto\">installed</span>\n )}\n </div>\n <p className={`text-xs ${installed ? \"text-fg-faint\" : \"text-fg-subtle\"}`}>{e.description}</p>\n </button>\n );\n })}\n </div>\n {nextCursor && !error && (\n <div className=\"text-center my-3\">\n <button\n onClick={loadMore}\n disabled={loadingMore}\n className=\"text-xs text-fg-subtle hover:text-fg disabled:opacity-50\"\n >\n {loadingMore ? \"Loading…\" : \"Load more\"}\n </button>\n </div>\n )}\n </div>\n\n <div className=\"px-4 py-3 border-t border-border flex items-center justify-between\">\n <button\n onClick={onCustom}\n className=\"text-xs text-fg-subtle hover:text-fg\"\n >\n …or set up a custom server\n </button>\n <button\n onClick={onClose}\n className=\"px-3 py-1.5 text-xs text-fg-subtle hover:text-fg\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { AlertCircle, Puzzle, RefreshCw, KeyRound } from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { ExtensionsListResponse, ToolSecretSlotInfo, ExternalToolInfo } from \"@/api/types\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\n\nconst SECRET_MASK = \"********\";\n\nexport function ExtensionsPanel() {\n const [data, setData] = useState<ExtensionsListResponse | null>(null);\n const [loading, setLoading] = useState(true);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"extensions\", \"extension\", containerRef);\n\n async function load() {\n setLoading(true);\n try {\n setData(await api.extensions.list());\n } catch (e) {\n console.error(e);\n } finally {\n setLoading(false);\n }\n }\n\n useEffect(() => {\n void load();\n }, []);\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Puzzle size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Extensions</h2>\n <button\n onClick={() => void load()}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\"\n title=\"Re-scan extension directories\"\n >\n <RefreshCw size={13} /> Refresh\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-3 space-y-5\">\n {loading && !data && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n\n {data && (\n <>\n <Section title=\"External providers\" dir={data.directories.providers}>\n {data.providers.length === 0 ? (\n <EmptyHint\n dir={data.directories.providers}\n what=\"provider\"\n template=\"lib/providers/template-external.cjs.example\"\n />\n ) : (\n data.providers.map((p) => (\n <Row key={p.name} name={p.name} file={p.file} />\n ))\n )}\n </Section>\n\n <Section title=\"External tools\" dir={data.directories.tools}>\n {data.tools.length === 0 ? (\n <EmptyHint\n dir={data.directories.tools}\n what=\"tool\"\n template=\"lib/tools/template-external.cjs.example\"\n />\n ) : (\n data.tools.map((t) => (\n <ToolRow key={t.name} tool={t} onSaved={() => void load()} />\n ))\n )}\n </Section>\n\n {data.errors.length > 0 && (\n <Section title=\"Validation errors\">\n {data.errors.map((e, i) => (\n <div\n key={`${e.kind}-${e.file}-${i}`}\n className=\"flex gap-2 py-2 border-b border-border/60\"\n >\n <AlertCircle\n size={13}\n className=\"text-rose-700 dark:text-rose-400 mt-0.5 shrink-0\"\n />\n <div className=\"min-w-0\">\n <p className=\"text-xs text-fg\">\n <span className=\"text-fg-subtle uppercase tracking-wide\">\n {e.kind}\n </span>{\" \"}\n <span className=\"font-mono\">{e.file}</span>\n </p>\n <p className=\"text-xs text-rose-700 dark:text-rose-400 break-words\">\n {e.error}\n </p>\n </div>\n </div>\n ))}\n </Section>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction Section({\n title,\n dir,\n children,\n}: {\n title: string;\n dir?: string;\n children: React.ReactNode;\n}) {\n return (\n <section>\n <div className=\"flex items-baseline justify-between mb-1.5\">\n <h3 className=\"text-[11px] uppercase tracking-wide text-fg-faint font-semibold\">\n {title}\n </h3>\n {dir && (\n <span\n className=\"text-[10px] text-fg-faint font-mono truncate max-w-[60%]\"\n title={dir}\n >\n {dir}\n </span>\n )}\n </div>\n <div>{children}</div>\n </section>\n );\n}\n\nfunction Row({\n name,\n file,\n badge,\n sub,\n}: {\n name: string;\n file: string | null;\n badge?: string;\n sub?: string;\n}) {\n return (\n <div data-deep-link-id={name} className=\"flex items-center gap-3 py-2 border-b border-border/60\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-fg\">{name}</span>\n {badge && (\n <span className=\"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded border bg-surface-2 text-fg-subtle border-border\">\n {badge}\n </span>\n )}\n </div>\n {sub && (\n <p className=\"text-xs text-fg-faint mt-0.5 line-clamp-2\">{sub}</p>\n )}\n {file && (\n <p className=\"text-[11px] text-fg-faint mt-0.5 font-mono truncate\">\n {file}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nfunction ToolRow({\n tool,\n onSaved,\n}: {\n tool: ExternalToolInfo;\n onSaved: () => void;\n}) {\n const [open, setOpen] = useState(false);\n const [values, setValues] = useState<Record<string, string>>(() =>\n Object.fromEntries(tool.secrets.map((s) => [s.key, s.is_set ? SECRET_MASK : \"\"])),\n );\n const [saving, setSaving] = useState(false);\n const [err, setErr] = useState<string | null>(null);\n\n // If the panel re-fetches and the slot set changes, reset the editor.\n useEffect(() => {\n setValues(\n Object.fromEntries(tool.secrets.map((s) => [s.key, s.is_set ? SECRET_MASK : \"\"])),\n );\n }, [tool.name, tool.secrets]);\n\n const hasSecrets = tool.secrets.length > 0;\n const setCount = tool.secrets.filter((s) => s.is_set).length;\n const requiredMissing = tool.secrets.some((s) => s.required && !s.is_set);\n\n async function save() {\n setSaving(true);\n setErr(null);\n try {\n const payload: Record<string, string> = {};\n for (const s of tool.secrets) {\n const v = values[s.key];\n if (v === undefined) continue;\n if (v === SECRET_MASK) continue; // leave untouched\n payload[s.key] = v;\n }\n await api.extensions.saveToolSecrets(tool.name, payload);\n onSaved();\n } catch (e) {\n setErr(e instanceof Error ? e.message : String(e));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div data-deep-link-id={tool.name} className=\"py-2 border-b border-border/60\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-fg\">{tool.name}</span>\n {tool.category && (\n <span className=\"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded border bg-surface-2 text-fg-subtle border-border\">\n {tool.category}\n </span>\n )}\n {hasSecrets && (\n <span\n className={`text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded border ${\n requiredMissing\n ? \"bg-amber-50 dark:bg-amber-950/40 text-amber-800 dark:text-amber-300 border-amber-200 dark:border-amber-900\"\n : \"bg-emerald-50 dark:bg-emerald-950/40 text-emerald-800 dark:text-emerald-300 border-emerald-200 dark:border-emerald-900\"\n }`}\n title={requiredMissing ? \"Required secrets are missing\" : \"Configured\"}\n >\n {setCount}/{tool.secrets.length} secrets\n </span>\n )}\n </div>\n {tool.description && (\n <p className=\"text-xs text-fg-faint mt-0.5 line-clamp-2\">{tool.description}</p>\n )}\n {tool.file && (\n <p className=\"text-[11px] text-fg-faint mt-0.5 font-mono truncate\">{tool.file}</p>\n )}\n </div>\n {hasSecrets && (\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors shrink-0\"\n title=\"Edit secrets\"\n >\n <KeyRound size={13} /> {open ? \"Hide\" : \"Edit\"}\n </button>\n )}\n </div>\n\n {open && hasSecrets && (\n <div className=\"mt-2 ml-1 pl-3 border-l border-border/60 space-y-2\">\n {tool.secrets.map((s) => (\n <label key={s.key} className=\"block\">\n <span className=\"text-xs text-fg-subtle\">\n {s.label ?? s.key}\n {s.required && <span className=\"text-rose-600 dark:text-rose-400 ml-0.5\">*</span>}\n </span>\n {s.description && (\n <span className=\"block text-[11px] text-fg-faint\">{s.description}</span>\n )}\n <input\n type=\"password\"\n autoComplete=\"off\"\n value={values[s.key] ?? \"\"}\n onChange={(e) =>\n setValues((v) => ({ ...v, [s.key]: e.target.value }))\n }\n onFocus={(e) => {\n if (e.currentTarget.value === SECRET_MASK) {\n e.currentTarget.select();\n }\n }}\n placeholder={s.is_set ? \"\" : \"not configured\"}\n className=\"mt-0.5 w-full px-2 py-1 text-sm bg-surface border border-border rounded font-mono\"\n />\n </label>\n ))}\n {err && <p className=\"text-xs text-rose-700 dark:text-rose-400\">{err}</p>}\n <div className=\"flex items-center gap-2 pt-1\">\n <button\n onClick={() => void save()}\n disabled={saving}\n className=\"text-xs px-2 py-1 rounded bg-accent text-white hover:bg-accent-hover disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n <span className=\"text-[11px] text-fg-faint\">\n Leave a field empty to clear it. Stored encrypted at rest.\n </span>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction EmptyHint({\n dir,\n what,\n template,\n}: {\n dir: string;\n what: \"provider\" | \"tool\";\n template: string;\n}) {\n return (\n <div className=\"text-fg-faint text-xs py-4 space-y-1.5\">\n <p>No external {what}s loaded.</p>\n <p>\n Drop a <code className=\"text-fg-subtle\">.cjs</code> file into{\" \"}\n <span className=\"font-mono text-fg-subtle\">{dir}</span>. Hot-reload is\n automatic on the next request.\n </p>\n <p>\n Template: <span className=\"font-mono text-fg-subtle\">{template}</span>\n </p>\n </div>\n );\n}\n","\"use client\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { Bridge, BridgeIn, BridgePatch, BridgeRoute, BridgeRouteIn, BridgeRoutePatch } from \"@/api/types\";\n\nexport function useBridges() {\n const [bridges, setBridges] = useState<Bridge[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try { setBridges(await api.bridges.list()); }\n finally { setLoading(false); }\n }, []);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const create = useCallback(async (data: BridgeIn) => {\n const b = await api.bridges.create(data);\n setBridges((p) => [...p, b]);\n return b;\n }, []);\n\n const update = useCallback(async (id: string, patch: BridgePatch) => {\n const b = await api.bridges.update(id, patch);\n setBridges((p) => p.map((x) => (x.id === id ? b : x)));\n return b;\n }, []);\n\n const remove = useCallback(async (id: string) => {\n await api.bridges.delete(id);\n setBridges((p) => p.filter((x) => x.id !== id));\n }, []);\n\n const pair = useCallback(async (id: string) => {\n await api.bridges.pair(id);\n }, []);\n\n return { bridges, loading, refresh, create, update, remove, pair };\n}\n\nexport function useBridgeRoutes(bridge_id: string | null) {\n const [routes, setRoutes] = useState<BridgeRoute[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n if (!bridge_id) { setRoutes([]); return; }\n setLoading(true);\n try { setRoutes(await api.bridges.routes.list(bridge_id)); }\n finally { setLoading(false); }\n }, [bridge_id]);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const create = useCallback(async (data: BridgeRouteIn) => {\n if (!bridge_id) throw new Error(\"No bridge selected\");\n const r = await api.bridges.routes.create(bridge_id, data);\n setRoutes((p) => [...p, r]);\n return r;\n }, [bridge_id]);\n\n const update = useCallback(async (route_id: string, patch: BridgeRoutePatch) => {\n if (!bridge_id) throw new Error(\"No bridge selected\");\n const r = await api.bridges.routes.update(bridge_id, route_id, patch);\n setRoutes((p) => p.map((x) => (x.id === route_id ? r : x)));\n return r;\n }, [bridge_id]);\n\n const remove = useCallback(async (route_id: string) => {\n if (!bridge_id) throw new Error(\"No bridge selected\");\n await api.bridges.routes.delete(bridge_id, route_id);\n setRoutes((p) => p.filter((x) => x.id !== route_id));\n }, [bridge_id]);\n\n return { routes, loading, refresh, create, update, remove };\n}\n","\"use client\";\nimport { ArrowLeft, Camera, Plus, QrCode, RefreshCw, Search, Trash2, Users } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, Bridge, BridgeChat, BridgeLiveStatus, BridgeRoute, ModelConfig } from \"@/api/types\";\nimport { useBridgeRoutes } from \"@/hooks/useBridges\";\nimport { modelSupportsImages, isProviderClassified } from \"@/lib/providers/capabilities\";\nimport { resolveAgentModel } from \"@/lib/agents/effective-model\";\nimport { formatRelativeOrDate } from \"@/lib/utils/time\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport { StatusPill } from \"./BridgesPanel\";\n\n/**\n * Single-bridge editor: shows live status (QR while pairing, paired ID once\n * connected), exposes the re-pair button, and embeds the routing table that\n * binds WhatsApp chats (JIDs) to agents.\n *\n * Routes have a `UNIQUE(agent_id)` constraint server-side — each agent is\n * the target of at most one route across all bridges. A route can be a\n * specific chat JID or `*` (catch-all for otherwise-unrouted chats). In both\n * cases inbound text is enqueued into that agent's existing thread.\n */\nexport function BridgeEditor({\n bridge, onBack, onRename, onToggleEnabled,\n}: {\n bridge: Bridge;\n onBack: () => void;\n onRename: (name: string) => Promise<unknown>;\n onToggleEnabled: () => Promise<unknown> | unknown;\n}) {\n const [name, setName] = useState(bridge.name);\n const [savingName, setSavingName] = useState(false);\n const [live, setLive] = useState<BridgeLiveStatus | null>(null);\n const [repairing, setRepairing] = useState(false);\n\n // Poll live status while pairing so the QR shows up quickly, then slow\n // down once we're stable.\n useEffect(() => {\n let alive = true;\n let timer: ReturnType<typeof setTimeout>;\n async function tick() {\n if (!alive) return;\n try {\n const s = await api.bridges.status(bridge.id);\n if (!alive) return;\n setLive(s);\n timer = setTimeout(tick, s.status === \"pairing\" ? 1500 : 5000);\n } catch {\n timer = setTimeout(tick, 5000);\n }\n }\n void tick();\n return () => { alive = false; clearTimeout(timer); };\n }, [bridge.id]);\n\n async function saveName() {\n if (name.trim() === bridge.name || !name.trim()) return;\n setSavingName(true);\n try { await onRename(name.trim()); }\n finally { setSavingName(false); }\n }\n\n async function rePair() {\n if (!confirm(\"Re-pair this bridge? This wipes the current WhatsApp session and shows a new QR code.\")) return;\n setRepairing(true);\n try {\n await api.bridges.pair(bridge.id);\n // Re-pairing also enables the bridge if it was off, so the QR fires.\n if (!bridge.enabled) await onToggleEnabled();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't re-pair bridge\",\n error: e,\n context: { panel: \"bridges\", action: \"bridge.rePair\", bridge_id: bridge.id },\n });\n } finally {\n setRepairing(false);\n }\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <button onClick={onBack} className=\"p-1 rounded hover:bg-surface-3 text-fg-subtle\">\n <ArrowLeft size={14} />\n </button>\n <input\n value={name}\n onChange={(e) => setName(e.target.value)}\n onBlur={saveName}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLInputElement).blur(); }}\n className=\"flex-1 bg-transparent text-sm font-semibold text-fg outline-none border-b border-transparent focus:border-accent\"\n disabled={savingName}\n />\n <StatusPill status={live?.status ?? bridge.status} />\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-3 space-y-4\">\n <section className=\"rounded-lg border border-border bg-surface-2 p-3 space-y-3\">\n <header className=\"flex items-center gap-2\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-fg-subtle\">Connection</h3>\n <span className=\"text-[11px] text-fg-faint ml-auto\">\n {live?.paired_id ?? bridge.paired_id ?? \"Not paired\"}\n </span>\n </header>\n\n {(live?.status === \"pairing\" || (!live && bridge.status === \"pairing\")) && live?.qr_data_url && (\n <div className=\"flex flex-col items-center gap-2 py-2\">\n <div className=\"bg-white p-3 rounded-lg\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={live.qr_data_url} alt=\"WhatsApp pairing QR\" className=\"w-48 h-48 block\" />\n </div>\n <p className=\"text-[11px] text-fg-faint text-center max-w-xs\">\n Open WhatsApp on your phone → Settings → Linked Devices → Link a device → scan this code.\n </p>\n </div>\n )}\n\n {(live?.last_error || bridge.last_error) && (\n <p className=\"text-[11px] text-rose-700 dark:text-rose-300 bg-rose-500/10 border border-rose-500/30 rounded px-2 py-1\">\n {live?.last_error ?? bridge.last_error}\n </p>\n )}\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n <label className=\"flex items-center gap-1.5 text-xs text-fg-muted cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n checked={bridge.enabled}\n onChange={() => void onToggleEnabled()}\n className=\"accent-accent\"\n />\n Enabled\n </label>\n <button\n onClick={rePair}\n disabled={repairing}\n className=\"ml-auto px-2 py-1 text-xs rounded bg-surface-3 hover:bg-surface-3/70 text-fg-muted flex items-center gap-1 disabled:opacity-50\"\n >\n {repairing ? <RefreshCw size={11} className=\"animate-spin\" /> : <QrCode size={11} />}\n Re-pair\n </button>\n </div>\n </section>\n\n <RouteTable bridge_id={bridge.id} />\n\n <section className=\"rounded-lg border border-border bg-surface-2 p-3 text-[11px] text-fg-faint leading-relaxed space-y-2\">\n <p>\n <strong className=\"text-fg-muted\">Unrouted messages are ignored (unless catch-all exists).</strong>{\" \"}\n If a WhatsApp chat isn't mapped to an agent below, incoming messages are silently dropped\n unless you add a <em>catch-all</em> route (`*`). Each agent can still have only one route,\n but a catch-all route can intentionally aggregate many chats into one agent thread.\n </p>\n <p>\n <strong className=\"text-fg-muted\">What gets forwarded.</strong>{\" \"}\n Text, image captions, and image / sticker payloads (as vision input) reach the agent.\n Voice notes, audio, video and documents are forwarded as attachments — agents can see\n their filename and mime type, but only models with native audio / video / PDF support\n interpret the contents. Location and contact-card messages are flattened into the text\n body. The <Camera className=\"inline -mt-0.5\" size={11} /> badge above marks agents whose\n model can read images.\n </p>\n </section>\n </div>\n </div>\n );\n}\n\nfunction RouteTable({ bridge_id }: { bridge_id: string }) {\n const { routes, create, update, remove } = useBridgeRoutes(bridge_id);\n const [agents, setAgents] = useState<AgentConfig[]>([]);\n const [chats, setChats] = useState<BridgeChat[]>([]);\n const [chatsRunning, setChatsRunning] = useState<boolean>(true);\n const [chatsLoading, setChatsLoading] = useState(false);\n const [manualMode, setManualMode] = useState(false);\n const [adding, setAdding] = useState(false);\n const [draft, setDraft] = useState<{ remote_jid: string; agent_id: string; label: string }>({\n remote_jid: \"\", agent_id: \"\", label: \"\",\n });\n const [error, setError] = useState<string | null>(null);\n\n // Inline lookup state — phone number → WhatsApp JID via /lookup.\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [searching, setSearching] = useState(false);\n const [searchMsg, setSearchMsg] = useState<string | null>(null);\n // Locally-resolved chats (from phone lookups) merged into the picker\n // alongside the synced list. Keeps a hit visible even if the bridge's\n // chat cache drops it later.\n const [extraChats, setExtraChats] = useState<BridgeChat[]>([]);\n // Resolved model config per agent — used to badge agents as vision-capable\n // so the user can pick one that will actually interpret WhatsApp images,\n // stickers and image-captioned messages forwarded through this bridge.\n const [models, setModels] = useState<ModelConfig[]>([]);\n\n useEffect(() => { api.agents.list().then(setAgents).catch(() => {}); }, []);\n useEffect(() => { api.models.list().then(setModels).catch(() => {}); }, []);\n\n /** Vision capability of an agent (resolves via its model_config_name, with default fallback). */\n function agentVisionState(a: AgentConfig): { supported: boolean; classified: boolean; modelLabel: string | null } {\n const cfg = resolveAgentModel(a, models);\n if (!cfg) return { supported: false, classified: false, modelLabel: null };\n return {\n supported: modelSupportsImages(cfg.provider, cfg.model_id),\n classified: isProviderClassified(cfg.provider),\n modelLabel: `${cfg.provider} / ${cfg.model_id}`,\n };\n }\n\n // Pull chats whenever the Add form opens, then keep polling every 4s\n // while it stays open so newly-arrived chats appear without the user\n // needing to close+reopen the dialog. Re-pair / first-time pair often\n // takes several seconds before history-sync delivers the chat list.\n useEffect(() => {\n if (!adding) return;\n let alive = true;\n async function load() {\n setChatsLoading(true);\n try {\n const r = await api.bridges.chats(bridge_id);\n if (!alive) return;\n setChats(r.chats);\n setChatsRunning(r.running);\n } catch { /* ignore — UI shows empty state */ }\n finally { if (alive) setChatsLoading(false); }\n }\n void load();\n const t = setInterval(() => void load(), 4000);\n return () => { alive = false; clearInterval(t); };\n }, [adding, bridge_id]);\n\n // Agents already targeted by other routes are unavailable in the picker.\n const usedAgents = new Set(routes.map((r) => r.agent_id));\n const availableAgents = agents.filter((a) => !usedAgents.has(a.id));\n const hasCatchAll = routes.some((r) => r.remote_jid === \"*\");\n const creatingCatchAll = draft.remote_jid === \"*\";\n\n // Hide chats that already have a route — picking them would just throw\n // a UNIQUE violation. Sort: groups & named chats first, then the rest.\n const routedJids = useMemo(\n () => new Set(routes.map((r) => r.remote_jid)),\n [routes],\n );\n const availableChats = useMemo(() => {\n // Merge synced chats with locally-resolved phone-lookup hits; the\n // synced entry wins on collision (it has the better metadata).\n const byJid = new Map<string, BridgeChat>();\n for (const c of extraChats) byJid.set(c.remote_jid, c);\n for (const c of chats) byJid.set(c.remote_jid, c);\n return Array.from(byJid.values()).filter((c) => !routedJids.has(c.remote_jid));\n }, [chats, extraChats, routedJids]);\n\n function selectChat(jid: string) {\n const c = availableChats.find((x) => x.remote_jid === jid);\n setDraft((d) => ({\n remote_jid: jid,\n agent_id: d.agent_id,\n // Auto-fill the label from the chat name when the user hasn't typed\n // anything yet — saves typing on the common case.\n label: d.label.trim() ? d.label : (c?.name ?? d.label),\n }));\n }\n\n async function onSearch() {\n setSearchMsg(null);\n const q = searchQuery.trim();\n if (!q) return;\n setSearching(true);\n try {\n const r = await api.bridges.lookup(bridge_id, q);\n if (!r.chat) {\n setSearchMsg(\"That number isn't on WhatsApp.\");\n return;\n }\n if (routedJids.has(r.chat.remote_jid)) {\n setSearchMsg(\"That chat already has a route.\");\n return;\n }\n // Merge into the picker and auto-select. setExtraChats is async, so\n // we don't rely on availableChats for the selection — set draft\n // directly from the hit.\n setExtraChats((prev) => {\n const exists = prev.some((c) => c.remote_jid === r.chat!.remote_jid);\n return exists ? prev : [...prev, r.chat!];\n });\n setDraft((d) => ({\n remote_jid: r.chat!.remote_jid,\n agent_id: d.agent_id,\n label: d.label.trim() ? d.label : (r.chat!.name ?? d.label),\n }));\n setSearchQuery(\"\");\n } catch (e) {\n setSearchMsg(e instanceof Error ? e.message : String(e));\n } finally {\n setSearching(false);\n }\n }\n\n async function onAdd() {\n setError(null);\n const remote_jid = draft.remote_jid.trim();\n const agent_id = draft.agent_id.trim();\n if (!remote_jid || !agent_id) { setError(\"Pick a chat and an agent\"); return; }\n try {\n await create({ remote_jid, agent_id, label: draft.label.trim() || null });\n setAdding(false);\n setManualMode(false);\n setDraft({ remote_jid: \"\", agent_id: \"\", label: \"\" });\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n return (\n <section className=\"rounded-lg border border-border bg-surface-2 p-3 space-y-2\">\n <header className=\"flex items-center gap-2\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-fg-subtle\">Routes</h3>\n <span className=\"text-[11px] text-fg-faint\">{routes.length}</span>\n <button\n onClick={() => { setAdding(true); setError(null); }}\n className=\"ml-auto px-2 py-0.5 text-[11px] rounded bg-accent/15 hover:bg-accent/25 text-accent flex items-center gap-1\"\n >\n <Plus size={10} /> Add\n </button>\n </header>\n\n {adding && (\n <div className=\"rounded border border-accent/30 bg-surface-3/30 p-2 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <label className=\"text-[11px] text-fg-subtle flex items-center gap-2 cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n checked={creatingCatchAll}\n onChange={(e) => {\n const on = e.target.checked;\n setDraft((d) => ({\n ...d,\n remote_jid: on ? \"*\" : \"\",\n label: on ? (d.label.trim() ? d.label : \"Catch-all\") : d.label,\n }));\n if (on) {\n setManualMode(false);\n setError(null);\n }\n }}\n disabled={hasCatchAll && !creatingCatchAll}\n />\n Catch everything else (fallback route)\n </label>\n {hasCatchAll && !creatingCatchAll && (\n <span className=\"text-[10px] text-fg-faint\">Catch-all already exists</span>\n )}\n </div>\n\n {creatingCatchAll && (\n <p className=\"text-[11px] text-fg-faint leading-snug\">\n This route matches any inbound chat without an explicit route. The agent will receive\n chat metadata (name + JID) in each message so it can distinguish sources.\n </p>\n )}\n\n {!creatingCatchAll && (\n !manualMode ? (\n <>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[10px] uppercase tracking-wide text-fg-faint font-semibold\">Chat</label>\n {chatsLoading && <RefreshCw size={10} className=\"animate-spin text-fg-faint\" />}\n <button\n type=\"button\"\n onClick={() => setManualMode(true)}\n className=\"ml-auto text-[10px] text-fg-faint hover:text-accent underline-offset-2 hover:underline\"\n >\n Enter JID manually\n </button>\n </div>\n {!chatsRunning && (\n <p className=\"text-[11px] text-amber-700 dark:text-amber-300 bg-amber-500/10 border border-amber-500/30 rounded px-2 py-1\">\n Bridge isn't running — enable it to load your WhatsApp chats.\n </p>\n )}\n {chatsRunning && (\n <>\n <div className=\"flex items-center gap-1.5\">\n <div className=\"flex-1 flex items-center gap-1.5 rounded border border-border bg-surface-3/60 px-2 py-1 focus-within:border-accent/60\">\n <Search size={11} className=\"text-fg-faint shrink-0\" />\n <input\n type=\"tel\"\n inputMode=\"tel\"\n placeholder=\"Find by phone (e.g. +1 555 123 4567)\"\n value={searchQuery}\n onChange={(e) => { setSearchQuery(e.target.value); setSearchMsg(null); }}\n onKeyDown={(e) => { if (e.key === \"Enter\") { e.preventDefault(); void onSearch(); } }}\n className=\"flex-1 bg-transparent text-xs outline-none placeholder:text-fg-faint\"\n disabled={searching}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => void onSearch()}\n disabled={searching || !searchQuery.trim()}\n className=\"text-[11px] px-2 py-1 rounded border border-border bg-surface-3 hover:bg-surface-2 disabled:opacity-40\"\n >\n {searching ? \"…\" : \"Find\"}\n </button>\n </div>\n <p className=\"text-[10px] text-fg-faint leading-snug\">\n WhatsApp only auto-syncs your recent chats. Use search to find any contact (including\n yourself) by phone number — country code + digits, no spaces required.\n </p>\n {searchMsg && (\n <p className=\"text-[11px] text-amber-700 dark:text-amber-300\">{searchMsg}</p>\n )}\n </>\n )}\n {chatsRunning && availableChats.length === 0 && !chatsLoading && (\n <p className=\"text-[11px] text-fg-faint px-1 py-2 leading-relaxed\">\n No chats synced yet. WhatsApp delivers your chat list a few seconds after pairing, and any\n chat you receive a message in will also appear here. If you can't wait, you can{\" \"}\n <button\n type=\"button\"\n onClick={() => setManualMode(true)}\n className=\"text-accent hover:underline\"\n >\n enter the JID manually\n </button>.\n </p>\n )}\n {availableChats.length > 0 && (\n <div className=\"max-h-56 overflow-y-auto rounded border border-border bg-surface-3/40 divide-y divide-border\">\n {availableChats.map((c) => (\n <button\n key={c.remote_jid}\n type=\"button\"\n onClick={() => selectChat(c.remote_jid)}\n className={`w-full flex items-center gap-2 px-2 py-1.5 text-left text-xs transition-colors ${\n draft.remote_jid === c.remote_jid\n ? \"bg-accent/20 text-fg\"\n : \"hover:bg-surface-3 text-fg\"\n }`}\n >\n <span className={`w-5 h-5 rounded shrink-0 flex items-center justify-center ${\n c.is_group ? \"bg-violet-500/20 text-violet-700 dark:text-violet-300\" : \"bg-emerald-500/20 text-emerald-700 dark:text-emerald-300\"\n }`}>\n {c.is_group ? <Users size={10} /> : <span className=\"text-[10px] font-bold\">{(c.name ?? \"?\").charAt(0).toUpperCase()}</span>}\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"truncate\">{c.name ?? <span className=\"text-fg-faint italic\">Unnamed</span>}</div>\n <div className=\"text-[10px] text-fg-faint truncate font-mono\">{c.remote_jid}</div>\n </div>\n {c.last_message_at && (\n <span className=\"text-[9px] text-fg-faint shrink-0\">{formatRelative(c.last_message_at)}</span>\n )}\n </button>\n ))}\n </div>\n )}\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[10px] uppercase tracking-wide text-fg-faint font-semibold\">JID</label>\n <button\n type=\"button\"\n onClick={() => setManualMode(false)}\n className=\"ml-auto text-[10px] text-fg-faint hover:text-accent underline-offset-2 hover:underline\"\n >\n Pick from chat list\n </button>\n </div>\n <input\n autoFocus\n value={draft.remote_jid}\n onChange={(e) => setDraft((d) => ({ ...d, remote_jid: e.target.value }))}\n placeholder=\"5511999990000@s.whatsapp.net or <group-id>@g.us\"\n className=\"w-full px-2 py-1 text-xs bg-surface-3 rounded border border-border focus:border-accent outline-none font-mono\"\n />\n </>\n )\n )}\n\n <div className=\"space-y-2\">\n <label className=\"block text-[10px] uppercase tracking-wide text-fg-faint font-semibold\">Agent</label>\n <select\n value={draft.agent_id}\n onChange={(e) => setDraft((d) => ({ ...d, agent_id: e.target.value }))}\n className=\"w-full px-2 py-1 text-xs bg-surface-3 rounded border border-border focus:border-accent outline-none\"\n >\n <option value=\"\">Select agent…</option>\n {availableAgents.map((a) => {\n const v = agentVisionState(a);\n // Prefix the option label with a camera glyph for vision-\n // capable agents so the picker conveys the capability\n // without needing a separate column. Plain <option> can't\n // hold an SVG; the unicode camera is the closest stable\n // glyph that renders across OSes.\n const prefix = v.supported ? \"📷 \" : v.classified ? \" \" : \" \";\n return (\n <option key={a.id} value={a.id}>{prefix}{a.name}</option>\n );\n })}\n </select>\n {(() => {\n const a = availableAgents.find((x) => x.id === draft.agent_id);\n if (!a) return null;\n const v = agentVisionState(a);\n if (v.supported) {\n return (\n <p className=\"text-[10px] text-emerald-700 dark:text-emerald-300 flex items-center gap-1\">\n <Camera size={10} /> Vision-capable — WhatsApp images, stickers and image captions will be read by this agent.\n </p>\n );\n }\n if (!v.classified) {\n return (\n <p className=\"text-[10px] text-fg-faint\">\n Unknown model capabilities ({v.modelLabel ?? \"no model\"}) — images will be forwarded; whether the model can interpret them depends on the upstream provider.\n </p>\n );\n }\n return (\n <p className=\"text-[10px] text-amber-700 dark:text-amber-300\">\n This agent's model ({v.modelLabel ?? \"none\"}) doesn't accept images. Text and image <em>captions</em> still reach it, but the image itself will be ignored. Switch the agent's model to a vision-capable one (e.g. gpt-4o, claude-3.5/4, gemini-1.5+) to enable image understanding.\n </p>\n );\n })()}\n\n <label className=\"block text-[10px] uppercase tracking-wide text-fg-faint font-semibold\">Label (optional)</label>\n <input\n value={draft.label}\n onChange={(e) => setDraft((d) => ({ ...d, label: e.target.value }))}\n placeholder={creatingCatchAll ? \"e.g. Catch-all triage\" : \"e.g. Mom, Support Group\"}\n className=\"w-full px-2 py-1 text-xs bg-surface-3 rounded border border-border focus:border-accent outline-none\"\n />\n </div>\n\n {error && <p className=\"text-[11px] text-rose-700 dark:text-rose-300\">{error}</p>}\n <div className=\"flex gap-2\">\n <button\n onClick={onAdd}\n disabled={!draft.remote_jid || !draft.agent_id}\n className=\"px-3 py-1 text-xs rounded bg-accent text-white hover:bg-accent/90 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n Add route\n </button>\n <button\n onClick={() => { setAdding(false); setManualMode(false); setError(null); setDraft({ remote_jid: \"\", agent_id: \"\", label: \"\" }); }}\n className=\"px-3 py-1 text-xs rounded text-fg-subtle hover:bg-surface-3\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {routes.length === 0 && !adding && (\n <p className=\"text-[11px] text-fg-faint py-2\">No routes. Inbound messages will be ignored unless you add a catch-all route.</p>\n )}\n\n {routes.length > 0 && (\n <p className=\"text-[10px] text-fg-faint pb-1\">\n Route settings: pick which agent receives this chat, choose whether replies are\n sent back to chat (Silent mode off) or kept user-side only (Silent mode on), and\n select who should trigger outbound replies when not silent.\n </p>\n )}\n\n {routes.map((r) => {\n const a = agents.find((x) => x.id === r.agent_id) ?? null;\n return (\n <RouteRow\n key={r.id}\n route={r}\n chatName={chats.find((c) => c.remote_jid === r.remote_jid)?.name ?? null}\n agent={a}\n agentVision={a ? agentVisionState(a) : null}\n onChangeAgent={async (agent_id) => {\n try { await update(r.id, { agent_id }); }\n catch (e) {\n pushErrorToast({\n title: \"Couldn't change route's agent\",\n error: e,\n context: { panel: \"bridges\", action: \"route.changeAgent\", route_id: r.id, agent_id },\n });\n }\n }}\n onToggleSilent={async (silent_mode) => {\n try { await update(r.id, { silent_mode }); }\n catch (e) {\n pushErrorToast({\n title: \"Couldn't toggle silent mode\",\n error: e,\n context: { panel: \"bridges\", action: \"route.toggleSilent\", route_id: r.id, silent_mode },\n });\n }\n }}\n onChangeRespondTo={async (respond_to) => {\n try { await update(r.id, { respond_to }); }\n catch (e) {\n pushErrorToast({\n title: \"Couldn't change reply trigger\",\n error: e,\n context: { panel: \"bridges\", action: \"route.changeRespondTo\", route_id: r.id, respond_to },\n });\n }\n }}\n agents={agents.filter((x) => x.id === r.agent_id || !usedAgents.has(x.id))}\n visionForAgent={(x) => agentVisionState(x)}\n onDelete={async () => {\n if (!confirm(\"Delete this route? Incoming messages from this chat will be ignored.\")) return;\n await remove(r.id);\n }}\n />\n );\n })}\n </section>\n );\n}\n\nfunction RouteRow({\n route, chatName, agent, agentVision, agents, visionForAgent, onChangeAgent, onToggleSilent, onChangeRespondTo, onDelete,\n}: {\n route: BridgeRoute;\n chatName: string | null;\n agent: AgentConfig | null;\n agentVision: { supported: boolean; classified: boolean; modelLabel: string | null } | null;\n agents: AgentConfig[];\n visionForAgent: (a: AgentConfig) => { supported: boolean; classified: boolean; modelLabel: string | null };\n onChangeAgent: (id: string) => Promise<void>;\n onToggleSilent: (silent: boolean) => Promise<void>;\n onChangeRespondTo: (respond_to: \"user\" | \"counterpart\") => Promise<void>;\n onDelete: () => Promise<void> | void;\n}) {\n // Prefer the route's user-set label, fall back to the live chat name from\n // the picker, then the JID itself. Always show the JID as the small\n // monospaced subline so the user can verify the binding.\n const headline = route.label?.trim() || chatName || route.remote_jid;\n const isCatchAll = route.remote_jid === \"*\";\n const showJidSubline = headline !== route.remote_jid;\n const isGroup = route.remote_jid.endsWith(\"@g.us\");\n return (\n <div className=\"py-1.5 border-t border-border first:border-t-0\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-fg truncate\">\n {isCatchAll ? \"Catch-all (everything else)\" : headline}\n </p>\n {showJidSubline && (\n <p className=\"text-[10px] font-mono text-fg-faint truncate\">{route.remote_jid}</p>\n )}\n {isCatchAll && (\n <p className=\"text-[10px] text-fg-faint\">Matches any chat without an explicit route.</p>\n )}\n </div>\n <select\n value={agent?.id ?? \"\"}\n onChange={(e) => void onChangeAgent(e.target.value)}\n className=\"px-1.5 py-0.5 text-[11px] bg-surface-3 rounded border border-border focus:border-accent outline-none max-w-[40%]\"\n >\n {!agent && <option value=\"\">(missing agent)</option>}\n {agents.map((a) => {\n const v = visionForAgent(a);\n const prefix = v.supported ? \"📷 \" : \"\";\n return <option key={a.id} value={a.id}>{prefix}{a.name}</option>;\n })}\n </select>\n {agentVision && (\n <span\n title={\n agentVision.supported\n ? `Vision-capable model (${agentVision.modelLabel}) — reads images & stickers.`\n : agentVision.classified\n ? `Model ${agentVision.modelLabel ?? \"\"} doesn't accept images. Captions still reach the agent; the image itself is ignored.`\n : `Unknown capabilities for ${agentVision.modelLabel ?? \"this model\"} — image handling depends on the upstream provider.`\n }\n className={`shrink-0 inline-flex items-center justify-center w-5 h-5 rounded ${\n agentVision.supported\n ? \"text-emerald-600 dark:text-emerald-400\"\n : agentVision.classified\n ? \"text-amber-600 dark:text-amber-400\"\n : \"text-fg-faint\"\n }`}\n >\n <Camera size={11} />\n </span>\n )}\n <button\n onClick={() => void onDelete()}\n className=\"p-1 rounded text-fg-faint hover:text-rose-700 dark:hover:text-rose-400 hover:bg-surface-3\"\n title=\"Delete route\"\n >\n <Trash2 size={11} />\n </button>\n </div>\n <label className=\"mt-1 flex items-start gap-2 cursor-pointer select-none px-0.5\">\n <input\n type=\"checkbox\"\n className=\"mt-0.5 rounded border-border\"\n checked={route.silent_mode}\n onChange={(e) => void onToggleSilent(e.target.checked)}\n />\n <span className=\"text-[11px] text-fg-subtle leading-snug\">\n <span className=\"text-fg-muted font-medium\">Silent mode</span> — listen only, never auto-reply.\n <span className=\"block text-[10px] text-fg-faint\">\n The agent still receives every message and can run tools / update memory{isGroup ? \" (with the sender's name prepended so it can tell group members apart)\" : \"\"}, but nothing is sent back to {isGroup ? \"the group\" : \"this chat\"}. Overrides the reply-trigger below.\n </span>\n </span>\n </label>\n <div className={`mt-1 flex items-start gap-2 px-0.5 ${route.silent_mode ? \"opacity-50\" : \"\"}`}>\n <span className=\"text-[11px] text-fg-subtle leading-snug flex-1\">\n <span className=\"text-fg-muted font-medium\">Reply trigger</span> — auto-reply when…\n <span className=\"block text-[10px] text-fg-faint\">\n {route.respond_to === \"counterpart\"\n ? isGroup\n ? \"Another group member sends a message. The agent stays quiet on your own messages.\"\n : \"Your counterpart sends a message. The agent stays quiet on your own messages.\"\n : \"You send a message yourself (e.g. expand-my-draft assistant). The agent stays quiet on others'.\"}\n </span>\n </span>\n <select\n value={route.respond_to}\n disabled={route.silent_mode}\n onChange={(e) => void onChangeRespondTo(e.target.value as \"user\" | \"counterpart\")}\n className=\"px-1.5 py-0.5 text-[11px] bg-surface-3 rounded border border-border focus:border-accent outline-none disabled:cursor-not-allowed\"\n >\n <option value=\"counterpart\">{isGroup ? \"Group members\" : \"Counterpart\"}</option>\n <option value=\"user\">Me</option>\n </select>\n </div>\n </div>\n );\n}\n\nfunction formatRelative(ms: number): string {\n const diff = Date.now() - ms;\n if (diff < 60_000) return \"just now\";\n if (diff > 7 * 86_400_000) return new Date(ms).toLocaleDateString();\n return formatRelativeOrDate(ms).replace(/\\sago$/, \"\");\n}\n","\"use client\";\nimport { AlertCircle, CheckCircle2, Loader2, MessageSquareText, Plus, RefreshCw, Smartphone, Trash2 } from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { Bridge, BridgeLiveStatus } from \"@/api/types\";\nimport { useBridges } from \"@/hooks/useBridges\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { BridgeEditor } from \"./BridgeEditor\";\n\n/**\n * Bridges panel.\n *\n * Lists configured bridges (WhatsApp adapters via Baileys). Each row shows\n * status + pair button. Clicking a row opens BridgeEditor with the routing\n * table for that bridge.\n *\n * The first WhatsApp account a user pairs is usually a throwaway / business\n * line — re-pair is destructive (wipes auth state on disk and forces a new\n * QR), so we put it behind an explicit button rather than a row toggle.\n */\nexport function BridgesPanel() {\n const { bridges, loading, refresh, create, update, remove } = useBridges();\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [creating, setCreating] = useState(false);\n const [newName, setNewName] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"bridges\", \"bridge\", containerRef);\n\n // Poll the list every 5s so status pills flip from pairing → connected as\n // Baileys' connection.update events drive the runtime status writeback.\n useEffect(() => {\n const t = setInterval(() => void refresh(), 5_000);\n return () => clearInterval(t);\n }, [refresh]);\n\n async function onCreate() {\n const name = newName.trim();\n if (!name) return;\n const b = await create({ kind: \"whatsapp\", name });\n setNewName(\"\");\n setCreating(false);\n setSelectedId(b.id);\n }\n\n async function onDelete(b: Bridge) {\n if (!confirm(`Delete bridge \"${b.name}\"? This also removes its WhatsApp auth and all routes.`)) return;\n if (selectedId === b.id) setSelectedId(null);\n await remove(b.id);\n }\n\n async function onToggleEnabled(b: Bridge) {\n await update(b.id, { enabled: !b.enabled });\n // Status flips on next poll once Baileys opens the WS.\n }\n\n if (selectedId) {\n const b = bridges.find((x) => x.id === selectedId);\n if (!b) { setSelectedId(null); return null; }\n return (\n <BridgeEditor\n bridge={b}\n onBack={() => { setSelectedId(null); void refresh(); }}\n onRename={(name) => update(b.id, { name })}\n onToggleEnabled={() => onToggleEnabled(b)}\n />\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Smartphone size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Bridges</h2>\n <button\n onClick={() => setCreating(true)}\n className=\"px-2 py-1 text-xs rounded bg-accent/15 hover:bg-accent/25 text-accent flex items-center gap-1\"\n >\n <Plus size={12} /> New\n </button>\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-3\">\n {creating && (\n <div className=\"mb-3 rounded-lg border border-accent/30 bg-surface-2 p-3 space-y-2\">\n <p className=\"text-xs text-fg-subtle\">\n Create a WhatsApp bridge. After creating, enable it and scan the QR with WhatsApp → Linked Devices.\n </p>\n <input\n autoFocus\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n placeholder=\"Name (e.g. Personal, Support)\"\n className=\"w-full px-2 py-1.5 text-sm bg-surface-3 rounded border border-border focus:border-accent outline-none\"\n onKeyDown={(e) => { if (e.key === \"Enter\") void onCreate(); if (e.key === \"Escape\") setCreating(false); }}\n />\n <div className=\"flex gap-2\">\n <button onClick={onCreate} className=\"px-3 py-1 text-xs rounded bg-accent hover:bg-accent/90 text-white\">\n Create\n </button>\n <button onClick={() => { setCreating(false); setNewName(\"\"); }} className=\"px-3 py-1 text-xs rounded text-fg-subtle hover:bg-surface-3\">\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {loading && bridges.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && bridges.length === 0 && !creating && (\n <div className=\"text-fg-faint text-sm py-8 text-center space-y-2\">\n <p>No bridges yet.</p>\n <p className=\"text-xs text-fg-faint leading-relaxed\">\n A bridge connects an external comm channel (WhatsApp) to one of your agents.\n Each WhatsApp chat is routed to exactly one agent — unrouted messages are silently ignored.\n </p>\n </div>\n )}\n\n {bridges.map((b) => (\n <BridgeRow\n key={b.id}\n bridge={b}\n onSelect={() => setSelectedId(b.id)}\n onToggleEnabled={() => onToggleEnabled(b)}\n onDelete={() => onDelete(b)}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction BridgeRow({\n bridge, onSelect, onToggleEnabled, onDelete,\n}: {\n bridge: Bridge;\n onSelect: () => void;\n onToggleEnabled: () => void | Promise<void>;\n onDelete: () => void | Promise<void>;\n}) {\n return (\n <div data-deep-link-id={bridge.id} className=\"mb-2 rounded-lg border border-border bg-surface-2 hover:bg-surface-2/70 transition-colors\">\n <div className=\"flex items-center gap-3 px-3 py-2.5\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-emerald-500 to-teal-600 flex items-center justify-center shrink-0\">\n <MessageSquareText size={16} className=\"text-white\" />\n </div>\n <button onClick={onSelect} className=\"flex-1 min-w-0 text-left\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-fg truncate\">{bridge.name}</span>\n <StatusPill status={bridge.status} />\n </div>\n <p className=\"text-[11px] text-fg-faint truncate mt-0.5\">\n {bridge.paired_id ?? \"Not paired\"}\n {bridge.last_error ? ` · ${bridge.last_error}` : \"\"}\n </p>\n </button>\n\n <label className=\"flex items-center gap-1.5 text-[11px] text-fg-subtle cursor-pointer select-none\">\n <input\n type=\"checkbox\"\n checked={bridge.enabled}\n onChange={onToggleEnabled}\n className=\"accent-accent\"\n />\n {bridge.enabled ? \"On\" : \"Off\"}\n </label>\n\n <button\n onClick={(e) => { e.stopPropagation(); void onDelete(); }}\n className=\"p-1.5 rounded text-fg-faint hover:text-rose-700 dark:hover:text-rose-400 hover:bg-surface-3\"\n title=\"Delete\"\n >\n <Trash2 size={13} />\n </button>\n </div>\n </div>\n );\n}\n\nexport function StatusPill({ status }: { status: Bridge[\"status\"] }) {\n const cfg = {\n connected: { label: \"connected\", cls: \"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 border-emerald-500/30\", icon: <CheckCircle2 size={9} /> },\n pairing: { label: \"pairing\", cls: \"bg-sky-500/15 text-sky-700 dark:text-sky-300 border-sky-500/30\", icon: <Loader2 size={9} className=\"animate-spin\" /> },\n disconnected: { label: \"disconnected\", cls: \"bg-fg-faint/15 text-fg-subtle border-fg-faint/30\", icon: <RefreshCw size={9} /> },\n error: { label: \"error\", cls: \"bg-rose-500/15 text-rose-700 dark:text-rose-300 border-rose-500/30\", icon: <AlertCircle size={9} /> },\n }[status];\n return (\n <span className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full border text-[9px] uppercase tracking-wide font-semibold ${cfg.cls}`}>\n {cfg.icon}\n {cfg.label}\n </span>\n );\n}\n\n// Exported for BridgeEditor's status polling.\nexport async function fetchStatus(bridge_id: string): Promise<BridgeLiveStatus | null> {\n try { return await api.bridges.status(bridge_id); }\n catch { return null; }\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { BuiltinToolCategoryInfo, ToolInfo } from \"@/api/types\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\n\n// Built-in tool category toggles. Each row is one category from the tool\n// registry; turning it off filters its tools out of the agent permission\n// editor AND blocks them from being invoked at runtime (defense in depth\n// in lib/tools/index.ts).\n//\n// Categories with no registered tools simply don't appear — the API\n// derives the list from `registeredTools()` so this UI auto-updates\n// whenever a new built-in lands.\n\nconst CATEGORY_BLURB: Record<string, string> = {\n Memory: \"Long-term recall: remember/recall facts across sessions.\",\n Documents: \"Semantic search over folders you indexed (RAG).\",\n Files: \"Read / write / list files in the workspace.\",\n Shell: \"Execute shell commands locally.\",\n Web: \"Fetch URLs and run web searches.\",\n Images: \"Generate images via configured providers.\",\n Voice: \"Synthesize speech via TTS.\",\n Schedule: \"Create one-off and recurring scheduled tasks.\",\n Atlassian: \"Jira and Confluence read/write.\",\n JiraAlign: \"Jira Align portfolio-level read/write.\",\n GitHub: \"Issues, pull requests, code search via the GitHub API.\",\n Mail: \"Read and send email via Gmail / Outlook.\",\n Calendar: \"Read and write calendar events.\",\n Config: \"Read/write Jarela's own settings.\",\n};\n\nexport function BuiltinToolsPanel() {\n const [rows, setRows] = useState<BuiltinToolCategoryInfo[]>([]);\n const [tools, setTools] = useState<ToolInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n const [query, setQuery] = useState(\"\");\n const [sourceFilter, setSourceFilter] = useState<\"all\" | \"builtin\" | \"mcp\">(\"all\");\n const [statusFilter, setStatusFilter] = useState<\"all\" | \"new\" | \"healthy\" | \"attention\">(\"all\");\n\n useEffect(() => {\n Promise.all([api.builtinTools.list(), api.tools.list()])\n .then(([categoryRows, toolRows]) => {\n setRows(categoryRows);\n setTools(toolRows);\n })\n .catch((e: unknown) => {\n pushErrorToast({\n title: \"Couldn't load tool catalog\",\n error: e,\n context: { panel: \"tools\", action: \"list\" },\n });\n })\n .finally(() => setLoading(false));\n }, []);\n\n async function toggle(row: BuiltinToolCategoryInfo) {\n const next = !row.enabled;\n setBusy((b) => ({ ...b, [row.category]: true }));\n try {\n await api.builtinTools.setEnabled(row.category, next);\n setRows((prev) =>\n prev.map((r) => (r.category === row.category ? { ...r, enabled: next } : r)),\n );\n setTools(await api.tools.list());\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't toggle built-in tool\",\n error: e,\n context: { panel: \"tools\", action: \"toggle\", category: row.category, target_enabled: next },\n });\n } finally {\n setBusy((b) => ({ ...b, [row.category]: false }));\n }\n }\n\n const filteredTools = tools.filter((tool) => {\n const q = query.trim().toLowerCase();\n if (q) {\n const haystack = `${tool.name} ${tool.category ?? \"\"} ${tool.description ?? \"\"}`.toLowerCase();\n if (!haystack.includes(q)) return false;\n }\n if (sourceFilter !== \"all\" && tool.source !== sourceFilter) return false;\n const stats = tool.stats;\n if (statusFilter === \"new\" && !stats?.never_used) return false;\n if (statusFilter === \"healthy\" && (stats?.never_used || (stats?.score ?? 0) < 0.75)) return false;\n if (statusFilter === \"attention\" && (stats?.never_used || (stats?.score ?? 0) >= 0.75)) return false;\n return true;\n });\n\n const issueHref = buildIssueHref(query);\n\n return (\n <div className=\"p-4 space-y-3\">\n <header className=\"space-y-1\">\n <h2 className=\"text-sm font-semibold text-fg\">Built-in tools</h2>\n <p className=\"text-xs text-fg-faint\">\n Turn whole categories of built-in tools on or off. Disabled categories\n disappear from the agent permission editor and cannot be invoked even\n if an older agent still has them in its allow-list.\n </p>\n </header>\n\n {loading && <p className=\"text-fg-faint text-sm py-3 text-center\">Loading…</p>}\n\n <ul className=\"space-y-2\">\n {rows.map((r) => (\n <li\n key={r.category}\n className=\"rounded-lg border border-border bg-surface-2 px-3 py-2.5\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{r.category}</span>\n <span className=\"text-[11px] text-fg-faint\">\n {r.toolCount} tool{r.toolCount === 1 ? \"\" : \"s\"}\n </span>\n </div>\n <p className=\"text-xs text-fg-muted mt-0.5\">\n {CATEGORY_BLURB[r.category] ?? \"\"}\n </p>\n <details className=\"mt-1.5\">\n <summary className=\"text-[11px] text-fg-faint cursor-pointer select-none hover:text-fg-muted\">\n Tools\n </summary>\n <ul className=\"mt-1 ml-2 flex flex-wrap gap-1\">\n {r.toolNames.map((n) => (\n <li\n key={n}\n className=\"font-mono text-[10px] px-1.5 py-0.5 rounded bg-surface-3 text-fg-muted\"\n >\n {n}\n </li>\n ))}\n </ul>\n </details>\n </div>\n <label className=\"text-[11px] text-fg-faint flex items-center gap-1 select-none shrink-0 pt-0.5\">\n <input\n type=\"checkbox\"\n checked={r.enabled}\n disabled={busy[r.category]}\n onChange={() => void toggle(r)}\n />\n enabled\n </label>\n </div>\n </li>\n ))}\n </ul>\n\n <section className=\"pt-3 border-t border-border space-y-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-semibold text-fg\">Ranked tool catalog</h3>\n <p className=\"text-xs text-fg-faint\">\n Success rate tracks completed calls without errors. Usefulness tracks results whose content appears in the final assistant answer.\n </p>\n </div>\n <a\n href={issueHref}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"shrink-0 rounded-md border border-border px-2.5 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-2\"\n >\n Report issue\n </a>\n </div>\n\n <div className=\"grid gap-2 md:grid-cols-[minmax(0,1fr)_140px_140px]\">\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Filter by name, category, or description\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n />\n <select\n value={sourceFilter}\n onChange={(e) => setSourceFilter(e.target.value as typeof sourceFilter)}\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n >\n <option value=\"all\">All sources</option>\n <option value=\"builtin\">Built-in + RAG</option>\n <option value=\"mcp\">MCP</option>\n </select>\n <select\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as typeof statusFilter)}\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n >\n <option value=\"all\">All health states</option>\n <option value=\"new\">New: 100%</option>\n <option value=\"healthy\">Healthy</option>\n <option value=\"attention\">Needs attention</option>\n </select>\n </div>\n\n <div className=\"space-y-2\">\n {filteredTools.length === 0 && (\n <p className=\"rounded-lg border border-border bg-surface-2 px-3 py-4 text-sm text-fg-faint text-center\">\n No tools match the current filters.\n </p>\n )}\n {filteredTools.map((tool) => {\n const stats = tool.stats;\n const score = Math.round((stats?.score ?? 1) * 100);\n const success = Math.round((stats?.success_rate ?? 1) * 100);\n const usefulness = Math.round((stats?.usefulness_rate ?? 1) * 100);\n return (\n <article\n key={tool.name}\n className=\"rounded-lg border border-border bg-surface-2 px-3 py-3\"\n >\n <div className=\"flex flex-wrap items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-mono text-sm text-fg\">{tool.name}</span>\n <span className=\"rounded-full bg-surface-3 px-2 py-0.5 text-[11px] text-fg-faint border border-border\">\n {tool.category ?? \"Other\"}\n </span>\n <span className=\"rounded-full bg-surface-3 px-2 py-0.5 text-[11px] text-fg-faint border border-border uppercase\">\n {tool.source ?? \"builtin\"}\n </span>\n {stats?.never_used && (\n <span className=\"rounded-full border border-emerald-500/30 bg-emerald-500/10 px-2 py-0.5 text-[11px] text-emerald-700 dark:text-emerald-300\">\n new 100%\n </span>\n )}\n </div>\n <p className=\"mt-1 text-xs text-fg-muted\">{tool.description}</p>\n </div>\n <div className=\"rounded-lg border border-border bg-surface-1 px-3 py-2 text-right min-w-[120px]\">\n <div className={`text-lg font-semibold ${score >= 75 ? \"text-emerald-700 dark:text-emerald-300\" : \"text-amber-700 dark:text-amber-300\"}`}>\n {score}%\n </div>\n <div className=\"text-[11px] text-fg-faint\">rank score</div>\n </div>\n </div>\n <div className=\"mt-3 grid gap-2 sm:grid-cols-4\">\n <Metric label=\"Calls\" value={String(stats?.call_count ?? 0)} />\n <Metric label=\"Success\" value={`${success}%`} />\n <Metric label=\"Used\" value={`${usefulness}%`} />\n <Metric label=\"Errors\" value={String(stats?.error_count ?? 0)} />\n </div>\n </article>\n );\n })}\n </div>\n </section>\n </div>\n );\n}\n\nfunction Metric({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"rounded-md border border-border bg-surface-1 px-2.5 py-2\">\n <div className=\"text-[11px] text-fg-faint uppercase tracking-wide\">{label}</div>\n <div className=\"text-sm text-fg font-medium\">{value}</div>\n </div>\n );\n}\n\nfunction buildIssueHref(query: string): string {\n const url = new URL(\"https://github.com/CircuitWall/jarela/issues/new\");\n url.searchParams.set(\"title\", query.trim() ? `tool issue: ${query.trim()}` : \"tool issue: describe the failing tool\");\n url.searchParams.set(\n \"body\",\n [\n \"## What happened\",\n \"\",\n \"Describe the tool, MCP server, or documents/RAG issue.\",\n \"\",\n \"## Tool name / filter\",\n query.trim() || \"(fill in)\",\n \"\",\n \"## Expected result\",\n \"\",\n \"## Actual result\",\n \"\",\n \"## Additional context\",\n \"\",\n ].join(\"\\n\"),\n );\n return url.toString();\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type {\n LangChainPackageInstallResponse,\n LangChainPackageListResponse,\n LangChainPackageManifestInput,\n LangChainPackageManifestRecord,\n LangChainPackagePendingInstall,\n} from \"@/api/types\";\n\nexport interface UsePackagesResult {\n loadResult: LangChainPackageListResponse | null;\n manifests: LangChainPackageManifestRecord[];\n pending: LangChainPackagePendingInstall[];\n loading: boolean;\n refresh: () => Promise<void>;\n install: (spec: string, version?: string) => Promise<LangChainPackageInstallResponse>;\n approveInstall: (id: string) => Promise<LangChainPackageInstallResponse>;\n denyInstall: (id: string) => Promise<void>;\n createManifest: (data: LangChainPackageManifestInput) => Promise<void>;\n updateManifest: (\n name: string,\n data: Omit<LangChainPackageManifestInput, \"name\">,\n ) => Promise<void>;\n deleteManifest: (name: string) => Promise<void>;\n reload: () => Promise<void>;\n}\n\nexport function usePackages(): UsePackagesResult {\n const [loadResult, setLoadResult] = useState<LangChainPackageListResponse | null>(null);\n const [manifests, setManifests] = useState<LangChainPackageManifestRecord[]>([]);\n const [pending, setPending] = useState<LangChainPackagePendingInstall[]>([]);\n const [loading, setLoading] = useState(false);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [load, mfs, pend] = await Promise.all([\n api.packages.list(),\n api.packages.listManifests(),\n api.packages.listPending(),\n ]);\n setLoadResult(load);\n setManifests(mfs);\n setPending(pend);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const install = useCallback(async (spec: string, version?: string) => {\n const res = await api.packages.install(spec, version);\n await refresh();\n return res;\n }, [refresh]);\n\n const approveInstall = useCallback(async (id: string) => {\n const res = await api.packages.approveInstall(id);\n await refresh();\n return res;\n }, [refresh]);\n\n const denyInstall = useCallback(async (id: string) => {\n await api.packages.denyInstall(id);\n await refresh();\n }, [refresh]);\n\n const createManifest = useCallback(async (data: LangChainPackageManifestInput) => {\n await api.packages.createManifest(data);\n await refresh();\n }, [refresh]);\n\n const updateManifest = useCallback(async (\n name: string,\n data: Omit<LangChainPackageManifestInput, \"name\">,\n ) => {\n await api.packages.updateManifest(name, data);\n await refresh();\n }, [refresh]);\n\n const deleteManifest = useCallback(async (name: string) => {\n await api.packages.deleteManifest(name);\n await refresh();\n }, [refresh]);\n\n const reload = useCallback(async () => {\n const res = await api.packages.reload();\n setLoadResult(res);\n }, []);\n\n return {\n loadResult,\n manifests,\n pending,\n loading,\n refresh,\n install,\n approveInstall,\n denyInstall,\n createManifest,\n updateManifest,\n deleteManifest,\n reload,\n };\n}\n","\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { RefreshCw, Trash2, Check, X, Package } from \"lucide-react\";\nimport { usePackages } from \"@/hooks/usePackages\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport type {\n LangChainPackageInstallResponse,\n LangChainPackageManifestRecord,\n} from \"@/api/types\";\n\nconst CATEGORIES = [\n \"Memory\", \"Documents\", \"Files\", \"Shell\", \"Web\", \"Images\", \"Voice\",\n \"Schedule\", \"Atlassian\", \"JiraAlign\", \"GitHub\", \"Mail\", \"Calendar\",\n \"Config\", \"Agent\",\n] as const;\n\nconst CAPABILITIES = [\"read\", \"write\", \"execute\"] as const;\n\ninterface ManifestFormState {\n name: string;\n package: string;\n exportName: string;\n category: (typeof CATEGORIES)[number];\n capability: (typeof CAPABILITIES)[number];\n requiredEnv: string;\n}\n\nconst EMPTY_FORM: ManifestFormState = {\n name: \"\",\n package: \"\",\n exportName: \"\",\n category: \"Web\",\n capability: \"execute\",\n requiredEnv: \"\",\n};\n\nexport function LangChainPackagesPanel() {\n const {\n loadResult,\n manifests,\n pending,\n loading,\n refresh,\n install,\n approveInstall,\n denyInstall,\n createManifest,\n deleteManifest,\n reload,\n } = usePackages();\n\n const [installSpec, setInstallSpec] = useState(\"\");\n const [installVersion, setInstallVersion] = useState(\"\");\n const [installing, setInstalling] = useState(false);\n const [installNotice, setInstallNotice] = useState<string | null>(null);\n\n const [form, setForm] = useState<ManifestFormState>(EMPTY_FORM);\n const [savingManifest, setSavingManifest] = useState(false);\n\n const errorRows = useMemo(() => loadResult?.errors ?? [], [loadResult]);\n const skippedRows = useMemo(() => loadResult?.skipped ?? [], [loadResult]);\n\n async function handleInstall(e: React.FormEvent) {\n e.preventDefault();\n if (!installSpec.trim()) return;\n setInstalling(true);\n setInstallNotice(null);\n try {\n const res: LangChainPackageInstallResponse = await install(\n installSpec.trim(),\n installVersion.trim() || undefined,\n );\n if (res.status === \"pending\") {\n setInstallNotice(\n `Publisher \"${res.publisher}\" not in allowlist — pending approval below.`,\n );\n } else {\n setInstallNotice(\n `Installed ${res.resolvedPackage}@${res.installedVersion ?? \"?\"} (${res.tools.length} tool${res.tools.length === 1 ? \"\" : \"s\"} found).`,\n );\n setInstallSpec(\"\");\n setInstallVersion(\"\");\n }\n } catch (e) {\n pushErrorToast({\n title: \"Install failed\",\n error: e,\n context: { panel: \"packages\", action: \"install\", spec: installSpec },\n });\n } finally {\n setInstalling(false);\n }\n }\n\n async function handleApprove(id: string) {\n try {\n await approveInstall(id);\n } catch (e) {\n pushErrorToast({\n title: \"Approval failed\",\n error: e,\n context: { panel: \"packages\", action: \"approve\", id },\n });\n }\n }\n\n async function handleDeny(id: string) {\n try {\n await denyInstall(id);\n } catch (e) {\n pushErrorToast({\n title: \"Deny failed\",\n error: e,\n context: { panel: \"packages\", action: \"deny\", id },\n });\n }\n }\n\n async function handleCreateManifest(e: React.FormEvent) {\n e.preventDefault();\n if (!form.name.trim() || !form.package.trim()) return;\n setSavingManifest(true);\n try {\n const requiredEnv = form.requiredEnv\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n await createManifest({\n name: form.name.trim(),\n package: form.package.trim(),\n export: form.exportName.trim() || undefined,\n category: form.category,\n capability: form.capability,\n requiredEnv: requiredEnv.length > 0 ? requiredEnv : undefined,\n });\n setForm(EMPTY_FORM);\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't create manifest\",\n error: e,\n context: { panel: \"packages\", action: \"create-manifest\", name: form.name },\n });\n } finally {\n setSavingManifest(false);\n }\n }\n\n async function handleDeleteManifest(record: LangChainPackageManifestRecord) {\n if (typeof window !== \"undefined\") {\n if (!window.confirm(`Delete manifest \"${record.name}\"?`)) return;\n }\n try {\n await deleteManifest(record.name);\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't delete manifest\",\n error: e,\n context: { panel: \"packages\", action: \"delete-manifest\", name: record.name },\n });\n }\n }\n\n async function handleReload() {\n try {\n await reload();\n } catch (e) {\n pushErrorToast({\n title: \"Reload failed\",\n error: e,\n context: { panel: \"packages\", action: \"reload\" },\n });\n }\n }\n\n return (\n <div className=\"p-4 space-y-5\">\n <header className=\"space-y-1\">\n <h2 className=\"text-sm font-semibold text-fg\">LangChain packages</h2>\n <p className=\"text-xs text-fg-faint\">\n Hot-load vanilla LangChain tool packages from npm without a rebuild. Trusted\n publishers (<code className=\"font-mono text-[11px]\">@langchain/</code>,{\" \"}\n <code className=\"font-mono text-[11px]\">@circuitwall/</code>,{\" \"}\n <code className=\"font-mono text-[11px]\">langchain</code>) install\n immediately; everything else waits for approval below.\n </p>\n {loadResult?.packagesDir && (\n <p className=\"text-[11px] text-fg-faint font-mono\">\n {loadResult.packagesDir}\n </p>\n )}\n </header>\n\n <section className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-semibold text-fg flex-1\">Install from npm</h3>\n <button\n type=\"button\"\n onClick={handleReload}\n className=\"shrink-0 rounded-md border border-border px-2.5 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-2 inline-flex items-center gap-1.5\"\n aria-label=\"Reload installed packages\"\n >\n <RefreshCw className=\"w-3.5 h-3.5\" /> Reload\n </button>\n </div>\n <form\n onSubmit={handleInstall}\n className=\"grid gap-2 md:grid-cols-[minmax(0,1fr)_140px_auto]\"\n >\n <input\n type=\"text\"\n value={installSpec}\n onChange={(e) => setInstallSpec(e.target.value)}\n placeholder=\"@langchain/community\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Package spec\"\n />\n <input\n type=\"text\"\n value={installVersion}\n onChange={(e) => setInstallVersion(e.target.value)}\n placeholder=\"version (optional)\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Version\"\n />\n <button\n type=\"submit\"\n disabled={installing || !installSpec.trim()}\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg hover:bg-surface-3 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {installing ? \"Installing…\" : \"Install\"}\n </button>\n </form>\n {installNotice && (\n <p className=\"text-xs text-fg-muted\">{installNotice}</p>\n )}\n </section>\n\n {pending.length > 0 && (\n <section className=\"space-y-2\">\n <h3 className=\"text-sm font-semibold text-fg\">\n Pending approvals ({pending.length})\n </h3>\n <ul className=\"space-y-2\">\n {pending.map((p) => (\n <li\n key={p.id}\n className=\"rounded-lg border border-border bg-surface-2 px-3 py-2.5\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-mono text-fg\">\n {p.spec}\n {p.version ? `@${p.version}` : \"\"}\n </div>\n <p className=\"text-xs text-fg-muted mt-0.5\">\n Publisher{\" \"}\n <span className=\"font-mono\">{p.publisher}</span> · {p.reason}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <button\n type=\"button\"\n onClick={() => handleApprove(p.id)}\n className=\"rounded-md border border-border px-2 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-3 inline-flex items-center gap-1\"\n aria-label={`Approve ${p.spec}`}\n >\n <Check className=\"w-3.5 h-3.5\" /> Approve\n </button>\n <button\n type=\"button\"\n onClick={() => handleDeny(p.id)}\n className=\"rounded-md border border-border px-2 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-3 inline-flex items-center gap-1\"\n aria-label={`Deny ${p.spec}`}\n >\n <X className=\"w-3.5 h-3.5\" /> Deny\n </button>\n </div>\n </div>\n </li>\n ))}\n </ul>\n </section>\n )}\n\n <section className=\"space-y-2 pt-3 border-t border-border\">\n <h3 className=\"text-sm font-semibold text-fg\">Tool manifests</h3>\n <p className=\"text-xs text-fg-faint\">\n A manifest maps an exported class from an installed npm package to a\n built-in category. Surfaced under{\" \"}\n <code className=\"font-mono text-[11px]\">/api/v1/tools</code> after a\n reload.\n </p>\n\n {loading && (\n <p className=\"text-fg-faint text-sm py-3 text-center\">Loading…</p>\n )}\n\n {!loading && manifests.length === 0 && (\n <p className=\"text-xs text-fg-faint py-2\">\n No manifests yet. Add one below.\n </p>\n )}\n\n <ul className=\"space-y-2\">\n {manifests.map((r) => (\n <li\n key={r.name}\n className=\"rounded-lg border border-border bg-surface-2 px-3 py-2.5\"\n >\n <div className=\"flex items-start gap-3\">\n <Package className=\"w-4 h-4 text-fg-faint mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-baseline gap-2 flex-wrap\">\n <span className=\"text-sm font-semibold text-fg\">{r.name}</span>\n <span className=\"text-[11px] text-fg-faint\">\n {r.manifest.category} · {r.manifest.capability}\n </span>\n </div>\n <p className=\"text-xs text-fg-muted mt-0.5 font-mono break-all\">\n {r.manifest.package}#{r.manifest.export}\n </p>\n {r.manifest.requiredEnv && r.manifest.requiredEnv.length > 0 && (\n <p className=\"text-[11px] text-fg-faint mt-1\">\n env: {r.manifest.requiredEnv.join(\", \")}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => handleDeleteManifest(r)}\n className=\"rounded-md border border-border px-2 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-3 shrink-0\"\n aria-label={`Delete manifest ${r.name}`}\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n </li>\n ))}\n </ul>\n\n <form\n onSubmit={handleCreateManifest}\n className=\"rounded-lg border border-border bg-surface-2 p-3 space-y-2\"\n >\n <h4 className=\"text-xs font-semibold text-fg-muted uppercase tracking-wide\">\n Add manifest\n </h4>\n <div className=\"grid gap-2 md:grid-cols-2\">\n <input\n type=\"text\"\n value={form.name}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n placeholder=\"name (e.g. tavily)\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Manifest name\"\n />\n <input\n type=\"text\"\n value={form.package}\n onChange={(e) => setForm({ ...form, package: e.target.value })}\n placeholder=\"package (e.g. @langchain/community/tools/tavily_search)\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Package import path\"\n />\n <input\n type=\"text\"\n value={form.exportName}\n onChange={(e) => setForm({ ...form, exportName: e.target.value })}\n placeholder=\"export (default: default)\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Export name\"\n />\n <input\n type=\"text\"\n value={form.requiredEnv}\n onChange={(e) => setForm({ ...form, requiredEnv: e.target.value })}\n placeholder=\"required env, comma-separated\"\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Required env vars\"\n />\n <select\n value={form.category}\n onChange={(e) =>\n setForm({\n ...form,\n category: e.target.value as (typeof CATEGORIES)[number],\n })\n }\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Category\"\n >\n {CATEGORIES.map((c) => (\n <option key={c} value={c}>\n {c}\n </option>\n ))}\n </select>\n <select\n value={form.capability}\n onChange={(e) =>\n setForm({\n ...form,\n capability: e.target.value as (typeof CAPABILITIES)[number],\n })\n }\n className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-sm text-fg outline-none focus:border-fg-faint\"\n aria-label=\"Capability\"\n >\n {CAPABILITIES.map((c) => (\n <option key={c} value={c}>\n {c}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex justify-end\">\n <button\n type=\"submit\"\n disabled={savingManifest || !form.name.trim() || !form.package.trim()}\n className=\"rounded-md border border-border bg-surface-2 px-3 py-1.5 text-xs text-fg hover:bg-surface-3 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {savingManifest ? \"Saving…\" : \"Add manifest\"}\n </button>\n </div>\n </form>\n </section>\n\n {(errorRows.length > 0 || skippedRows.length > 0) && (\n <section className=\"space-y-2 pt-3 border-t border-border\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-semibold text-fg flex-1\">Load status</h3>\n <button\n type=\"button\"\n onClick={refresh}\n className=\"shrink-0 rounded-md border border-border px-2.5 py-1.5 text-xs text-fg-muted hover:text-fg hover:bg-surface-2\"\n >\n Refresh\n </button>\n </div>\n {errorRows.length > 0 && (\n <ul className=\"space-y-1\">\n {errorRows.map((e) => (\n <li\n key={e.manifest}\n className=\"rounded border border-red-500/40 bg-red-500/10 px-2 py-1.5 text-xs text-fg\"\n >\n <span className=\"font-mono\">{e.manifest}</span>: {e.error}\n </li>\n ))}\n </ul>\n )}\n {skippedRows.length > 0 && (\n <ul className=\"space-y-1\">\n {skippedRows.map((s) => (\n <li\n key={s.manifest}\n className=\"rounded border border-border bg-surface-2 px-2 py-1.5 text-xs text-fg-muted\"\n >\n <span className=\"font-mono\">{s.manifest}</span> skipped — {s.reason}\n </li>\n ))}\n </ul>\n )}\n </section>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { ExtensionsPanel } from \"@/components/extensions/ExtensionsPanel\";\nimport { MCPPanel } from \"@/components/mcp/MCPPanel\";\nimport { DocumentsPanel } from \"@/components/documents/DocumentsPanel\";\nimport { MemoryPanel } from \"@/components/memory/MemoryPanel\";\nimport { BridgesPanel } from \"@/components/bridges/BridgesPanel\";\nimport { BuiltinToolsPanel } from \"./BuiltinToolsPanel\";\nimport { LangChainPackagesPanel } from \"./LangChainPackagesPanel\";\n\n// \"Tools\" is about *capability presence* — every surface that determines\n// what an agent can sense or act on lives here:\n// - \"Built-in\" — categories of tools that ship with Jarela.\n// - \"Packages\" — vanilla LangChain tool packages hot-loaded from npm.\n// - \"Documents\" — indexed knowledge sources the agent can search.\n// - \"Memory\" — long-lived facts persisted across conversations.\n// - \"MCP\" — external Model Context Protocol servers.\n// - \"Extensions\" — the Jarela browser extension surface.\n// - \"Bridges\" — mobile / messaging bridge pairings.\n// Credentials still flow through the Credentials tab; this surface owns\n// the capability roster.\n\ntype Sub =\n | \"builtin\"\n | \"packages\"\n | \"documents\"\n | \"memory\"\n | \"mcp\"\n | \"extensions\"\n | \"bridges\";\n\nconst SUBS: Sub[] = [\n \"builtin\",\n \"packages\",\n \"documents\",\n \"memory\",\n \"mcp\",\n \"extensions\",\n \"bridges\",\n];\n\nconst SUB_TITLES: Record<Sub, string> = {\n builtin: \"Built-in\",\n packages: \"LangChain packages\",\n documents: \"Documents\",\n memory: \"Memory\",\n mcp: \"MCP servers\",\n extensions: \"Browser extension\",\n bridges: \"Bridges\",\n};\n\nexport function ToolsPanel() {\n const { state, dispatch } = useAppContext();\n const raw = state.selectedItem.tools;\n const active: Sub = (SUBS as string[]).includes(raw ?? \"\")\n ? (raw as Sub)\n : \"builtin\";\n\n const setSub = (s: Sub) => dispatch({ type: \"SET_SELECTION\", tab: \"tools\", itemId: s });\n\n return (\n <div className=\"flex flex-col h-full min-h-0\">\n <div\n role=\"tablist\"\n aria-label=\"Tools sub-section\"\n className=\"flex gap-1 border-b border-[var(--border)] bg-[var(--bg-secondary)] px-3 pt-2 overflow-x-auto\"\n >\n {SUBS.map((s) => {\n const selected = s === active;\n return (\n <button\n key={s}\n role=\"tab\"\n type=\"button\"\n aria-selected={selected}\n onClick={() => setSub(s)}\n className={\n \"px-3 py-1.5 text-sm rounded-t-md border-b-2 -mb-px transition-colors whitespace-nowrap \" +\n (selected\n ? \"border-[var(--accent)] text-[var(--text-primary)] bg-[var(--bg-primary)]\"\n : \"border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]\")\n }\n >\n {SUB_TITLES[s]}\n </button>\n );\n })}\n </div>\n <div className=\"flex-1 min-h-0 overflow-auto\">\n {active === \"builtin\" && <BuiltinToolsPanel />}\n {active === \"packages\" && <LangChainPackagesPanel />}\n {active === \"documents\" && <DocumentsPanel />}\n {active === \"memory\" && <MemoryPanel />}\n {active === \"mcp\" && <MCPPanel />}\n {active === \"extensions\" && <ExtensionsPanel />}\n {active === \"bridges\" && <BridgesPanel />}\n </div>\n </div>\n );\n}\n","// Minimal best-effort humanizer for 5-field cron expressions\n// (`minute hour day-of-month month day-of-week`). Returns null when the\n// expression is too exotic to summarize accurately so the UI falls back\n// to the raw expression instead of misleading text.\n\nexport function humanizeCron(expr: string): string | null {\n if (!expr) return null;\n const parts = expr.trim().split(/\\s+/);\n if (parts.length !== 5) return null;\n const [minute, hour, dom, month, dow] = parts;\n\n // every minute / every N minutes\n if (hour === \"*\" && dom === \"*\" && month === \"*\" && dow === \"*\") {\n if (minute === \"*\") return \"every minute\";\n const step = parseStep(minute);\n if (step) return `every ${step} minutes`;\n }\n\n // hourly at HH:MM\n if (hour === \"*\" && dom === \"*\" && month === \"*\" && dow === \"*\" && /^\\d+$/.test(minute)) {\n return `hourly at :${pad(minute)}`;\n }\n\n // every N hours\n if (dom === \"*\" && month === \"*\" && dow === \"*\" && /^\\d+$/.test(minute)) {\n const step = parseStep(hour);\n if (step) return `every ${step} hours at :${pad(minute)}`;\n }\n\n const time = formatTime(minute, hour);\n if (!time) return null;\n\n // weekday(s) at HH:MM\n if (dom === \"*\" && month === \"*\" && dow !== \"*\") {\n const days = formatDow(dow);\n if (days) return `${days} at ${time}`;\n }\n\n // monthly on day N at HH:MM\n if (month === \"*\" && dow === \"*\" && /^\\d+$/.test(dom)) {\n return `monthly on day ${dom} at ${time}`;\n }\n\n // daily at HH:MM\n if (dom === \"*\" && month === \"*\" && dow === \"*\") {\n return `daily at ${time}`;\n }\n\n return null;\n}\n\nfunction formatTime(minute: string, hour: string): string | null {\n if (!/^\\d+$/.test(minute) || !/^\\d+$/.test(hour)) return null;\n return `${pad(hour)}:${pad(minute)}`;\n}\n\nfunction pad(n: string): string {\n return n.length >= 2 ? n : `0${n}`;\n}\n\nfunction parseStep(field: string): number | null {\n const m = /^\\*\\/(\\d+)$/.exec(field);\n return m ? Number(m[1]) : null;\n}\n\nconst DOW_NAMES = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\nfunction formatDow(field: string): string | null {\n if (field === \"1-5\") return \"weekdays\";\n if (field === \"0,6\" || field === \"6,0\") return \"weekends\";\n if (/^\\d$/.test(field)) {\n const n = Number(field);\n if (n >= 0 && n <= 6) return DOW_NAMES[n];\n }\n if (/^\\d(,\\d)+$/.test(field)) {\n const ns = field.split(\",\").map(Number).filter((n) => n >= 0 && n <= 6);\n if (ns.length) return ns.map((n) => DOW_NAMES[n]).join(\"/\");\n }\n return null;\n}\n","\"use client\";\nimport { AlertTriangle } from \"lucide-react\";\nimport type { AgentModelStatus } from \"@/lib/agents/effective-model\";\n\n// Inline warning badge for scheduled-task and watcher cards. Renders nothing\n// when the agent's model resolves cleanly so the row stays uncluttered; only\n// surfaces when a future run would `no_model` or silently substitute the\n// workspace default. Both cases are easy to miss for unattended runs.\nexport function AgentModelBadge({ status }: { status: AgentModelStatus }) {\n if (status.state === \"ok\") return null;\n\n let label: string;\n let tooltip: string;\n if (status.state === \"no-agent\") {\n label = \"agent missing\";\n tooltip = \"The agent for this task was deleted. It will fail on the next run.\";\n } else if (status.state === \"no-model\") {\n label = \"no model\";\n tooltip =\n \"Agent has no model assigned and no workspace default is set. Runs will fail with no_model — open the Models panel and add or default a model.\";\n } else if (status.fallback) {\n label = `model \"${status.requested}\" missing`;\n tooltip = `Configured model \"${status.requested}\" no longer exists; runs will silently fall back to the default model \"${status.fallback.name}\". Reassign the agent to a present model.`;\n } else {\n label = `model \"${status.requested}\" missing`;\n tooltip = `Configured model \"${status.requested}\" no longer exists and there is no workspace default. Runs will fail with no_model.`;\n }\n\n return (\n <span\n className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded-full bg-amber-500/15 text-amber-700 dark:text-amber-300 border border-amber-500/30\"\n title={tooltip}\n >\n <AlertTriangle size={10} />\n {label}\n </span>\n );\n}\n","\"use client\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\n\n// Shared reaction-discriminator UI for triggers (ADR-0031 + ADR-0032).\n// - `KindPill` — small pill button used for the agent_prompt /\n// script toggle.\n// - `ReactionScriptEditor` — kind='script' editor: pick a registered\n// reaction.* script + edit JSON args. Pass\n// `diffContext={true}` for watchers (where\n// previous/current are auto-merged) and\n// `false` for scheduled tasks.\n//\n// The agent_prompt branch differs per target (watchers use a dedicated\n// reaction_prompt column; scheduled tasks reuse their existing prompt\n// field), so each caller still renders its own prompt editor inline. This\n// module only owns the parts that genuinely repeat: the kind toggle and\n// the script editor.\n\nconst REACTION_SCRIPT_ARGS_MAX = 4000;\n\nexport function KindPill({\n active, onClick, disabled, title, children,\n}: {\n active: boolean;\n onClick: () => void;\n disabled?: boolean;\n title?: string;\n children: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n title={title}\n className={\n \"px-2 py-0.5 text-[10px] rounded border transition-colors disabled:opacity-50 \" +\n (active\n ? \"border-fg-muted bg-surface-3 text-fg\"\n : \"border-border text-fg-faint hover:text-fg hover:border-fg-muted\")\n }\n >\n {children}\n </button>\n );\n}\n\nexport interface ReactionScriptEditorProps {\n initialScript: string | null;\n initialArgs: unknown | null;\n /** Called when the user saves a valid script + args. */\n onSave: (next: { script: string; args: Record<string, unknown> | null }) => Promise<void>;\n /** Context tag forwarded to error toasts so the reporter can identify the panel. */\n errorContext: Record<string, unknown>;\n /** True for watchers (diff context auto-merged); false for scheduled tasks. */\n diffContext: boolean;\n}\n\nexport function ReactionScriptEditor({\n initialScript, initialArgs, onSave, errorContext, diffContext,\n}: ReactionScriptEditorProps) {\n const [scripts, setScripts] = useState<string[] | null>(null);\n const initialArgsText = useMemo(() => {\n if (initialArgs === null || initialArgs === undefined) return \"\";\n try { return JSON.stringify(initialArgs, null, 2); } catch { return \"\"; }\n }, [initialArgs]);\n\n const [script, setScript] = useState(initialScript ?? \"\");\n const [argsText, setArgsText] = useState(initialArgsText);\n const [saving, setSaving] = useState(false);\n const [argsError, setArgsError] = useState<string | null>(null);\n\n useEffect(() => { setScript(initialScript ?? \"\"); }, [initialScript]);\n useEffect(() => { setArgsText(initialArgsText); }, [initialArgsText]);\n\n useEffect(() => {\n let alive = true;\n api.watchers.listReactionScripts()\n .then((r) => { if (alive) setScripts(r.scripts); })\n .catch((e) => {\n if (!alive) return;\n console.error(e);\n setScripts([]);\n });\n return () => { alive = false; };\n }, []);\n\n function validateArgs(text: string): { value: Record<string, unknown> | null; error: string | null } {\n const trimmed = text.trim();\n if (!trimmed) return { value: null, error: null };\n if (trimmed.length > REACTION_SCRIPT_ARGS_MAX) {\n return { value: null, error: `Args JSON too long (${trimmed.length}/${REACTION_SCRIPT_ARGS_MAX} chars)` };\n }\n try {\n const parsed = JSON.parse(trimmed);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return { value: null, error: \"Args must be a JSON object\" };\n }\n return { value: parsed as Record<string, unknown>, error: null };\n } catch (e) {\n return { value: null, error: e instanceof Error ? e.message : \"Invalid JSON\" };\n }\n }\n\n const dirty = script !== (initialScript ?? \"\") || argsText.trim() !== initialArgsText.trim();\n\n async function save() {\n const { value, error } = validateArgs(argsText);\n if (error) { setArgsError(error); return; }\n setArgsError(null);\n if (!script.trim()) {\n setArgsError(\"Pick a reaction script first.\");\n return;\n }\n setSaving(true);\n try {\n await onSave({ script, args: value });\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't save reaction script\",\n error: e,\n context: { ...errorContext, script },\n });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div className=\"space-y-1\">\n <select\n value={script}\n onChange={(e) => setScript(e.target.value)}\n className=\"w-full text-[11px] font-mono rounded border border-border bg-surface-1 px-2 py-1 text-fg-muted focus:outline-none focus:border-fg-muted\"\n >\n <option value=\"\">— pick a reaction script —</option>\n {scripts?.map((s) => (\n <option key={s} value={s}>{s}</option>\n ))}\n </select>\n <textarea\n value={argsText}\n onChange={(e) => { setArgsText(e.target.value); if (argsError) setArgsError(null); }}\n rows={3}\n placeholder='Optional args JSON, e.g. { \"title\": \"Trigger fired\", \"level\": \"warning\" }'\n className=\"w-full text-[11px] font-mono rounded border border-border bg-surface-1 px-2 py-1 text-fg-muted focus:outline-none focus:border-fg-muted resize-y\"\n />\n <div className=\"flex items-center gap-2 text-[10px] text-fg-faint\">\n {argsError ? (\n <span className=\"text-rose-700 dark:text-rose-400\">{argsError}</span>\n ) : diffContext ? (\n <span>\n Diff context (<code>watcher</code>, <code>previous</code>, <code>current</code>) is auto-merged.\n </span>\n ) : (\n <span>\n A <code>task</code> descriptor is auto-merged. Diff context (<code>previous</code>/<code>current</code>) is watcher-only.\n </span>\n )}\n <button\n onClick={() => void save()}\n disabled={saving || !dirty}\n className=\"ml-auto px-2 py-0.5 rounded border border-border hover:text-emerald-700 dark:hover:text-emerald-400 hover:border-emerald-700 disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { AlertCircle, Bell, CheckCircle2, EyeOff, Play, Power, Trash2, Zap } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, ModelConfig, Watcher } from \"@/api/types\";\nimport { formatRelative as sharedFormatRelative } from \"@/lib/utils/time\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport { pushToast } from \"@/lib/ui/toasts\";\nimport { agentModelStatus } from \"@/lib/agents/effective-model\";\nimport { AgentModelBadge } from \"./AgentModelBadge\";\nimport { KindPill, ReactionScriptEditor } from \"@/components/triggers/ReactionEditor\";\nimport { MarkdownTextarea } from \"@/components/ui/MarkdownTextarea\";\nimport { Select } from \"@/components/ui/Select\";\n\n// Event-driven tasks (ADR-0027). Sibling to ScheduledTasksPanel — same\n// card aesthetic, but rows describe a tool poll + diff detector, not a\n// cron firing. Watchers are agent-created via the `schedule_watcher`\n// tool; the UI is read-only-ish (cancel / pause / run-now / silent).\nexport function WatchersSection({ agents, models }: { agents: Record<string, AgentConfig>; models: ModelConfig[] }) {\n const [watchers, setWatchers] = useState<Watcher[]>([]);\n const [loading, setLoading] = useState(true);\n\n async function load() {\n setLoading(true);\n try {\n setWatchers(await api.watchers.list());\n } catch (e) {\n // Surface the failure instead of silently rendering \"No watchers\".\n // A swallowed catch here was masking real list errors and made it\n // look like the panel was filtering watchers it actually wasn't.\n console.error(e);\n pushToast({\n kind: \"error\",\n source: \"system\",\n sourceLabel: \"Watchers\",\n title: \"Couldn't load watchers\",\n body: e instanceof Error ? e.message : String(e),\n agent_id: null,\n thread_id: null,\n ttl: 6000,\n });\n }\n finally { setLoading(false); }\n }\n useEffect(() => { void load(); }, []);\n useEffect(() => {\n const t = setInterval(() => void load(), 15_000);\n return () => clearInterval(t);\n }, []);\n\n async function cancel(w: Watcher) {\n if (!confirm(`Cancel watcher \"${w.label}\"?`)) return;\n await api.watchers.cancel(w.id);\n void load();\n }\n async function runNow(w: Watcher) {\n try { await api.watchers.runNow(w.id); }\n catch (e) {\n pushErrorToast({\n title: \"Couldn't run watcher\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"watcher.runNow\", watcher_id: w.id, label: w.label },\n });\n }\n finally { void load(); }\n }\n\n const sorted = useMemo(\n () => [...watchers].sort((a, b) => a.next_run_at.localeCompare(b.next_run_at)),\n [watchers],\n );\n\n return (\n <div className=\"mt-4\">\n <div className=\"flex items-center gap-2 px-1 py-2 border-b border-border/60\">\n <Zap size={14} className=\"text-fg-subtle\" />\n <h3 className=\"text-xs font-semibold text-fg mr-auto\">Event-driven Tasks</h3>\n {watchers.length > 0 && (\n <span className=\"text-[11px] text-fg-faint\">{watchers.length}</span>\n )}\n </div>\n\n {loading && watchers.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && watchers.length === 0 && (\n <div className=\"text-fg-faint text-sm py-6 text-center space-y-2\">\n <p>No watchers.</p>\n <p className=\"text-xs text-fg-faint leading-relaxed\">\n Ask any agent “watch Jira issue ABC-123 and tell me when it changes” or\n “poll my inbox every 5 minutes”. The agent will register a watcher via\n its <code className=\"px-1 rounded bg-surface-3 text-fg-subtle\">schedule_watcher</code> tool\n and it will only fire when the underlying tool result actually changes.\n </p>\n </div>\n )}\n <div className=\"mt-2\">\n {sorted.map((w) => (\n <WatcherCard\n key={w.id}\n watcher={w}\n agent={agents[w.agent_id]}\n agents={agents}\n models={models}\n onCancel={() => cancel(w)}\n onRunNow={() => runNow(w)}\n onChanged={() => void load()}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction WatcherCard({\n watcher, agent, agents, models, onCancel, onRunNow, onChanged,\n}: {\n watcher: Watcher;\n agent?: AgentConfig;\n agents: Record<string, AgentConfig>;\n models: ModelConfig[];\n onCancel: () => void;\n onRunNow: () => void;\n onChanged: () => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [running, setRunning] = useState(false);\n const nextRun = sharedFormatRelative(watcher.next_run_at, { collapseSeconds: true });\n const lastRun = watcher.last_run_at\n ? sharedFormatRelative(watcher.last_run_at, { collapseSeconds: true })\n : null;\n const lastFired = watcher.last_fired_at\n ? sharedFormatRelative(watcher.last_fired_at, { collapseSeconds: true })\n : null;\n const overdue = !watcher.last_error && new Date(watcher.next_run_at).getTime() < Date.now() - 60_000;\n // Pre-flight model availability for the assigned agent; only relevant\n // when the watcher reacts via an agent prompt (not a pure script).\n const modelStatus = watcher.reaction_kind === \"agent_prompt\"\n ? agentModelStatus(agent ?? null, models)\n : null;\n\n return (\n <div data-deep-link-id={watcher.id} className=\"mb-2 rounded-lg border border-border bg-surface-2 overflow-hidden\">\n <button\n onClick={() => setExpanded((v) => !v)}\n className=\"w-full text-left px-3 py-2 hover:bg-surface-3/40 transition-colors\"\n >\n <div className=\"flex items-start gap-2\">\n <Bell size={12} className=\"mt-1 text-amber-700 dark:text-amber-400 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm text-fg truncate\">{watcher.label}</p>\n <div className=\"flex items-center gap-2 mt-1 text-[11px] text-fg-faint flex-wrap\">\n <span className=\"font-mono\">{watcher.tool}</span>\n <span>·</span>\n <span>every {formatInterval(watcher.interval_seconds)}</span>\n <span>·</span>\n <span className={overdue ? \"text-amber-700 dark:text-amber-400\" : \"\"}>\n {overdue ? \"overdue\" : `next: ${nextRun}`}\n </span>\n {agent && (\n <>\n <span>·</span>\n <span className=\"truncate\">{agent.name}</span>\n </>\n )}\n {modelStatus && modelStatus.state !== \"ok\" && (\n <>\n <span>·</span>\n <AgentModelBadge status={modelStatus} />\n </>\n )}\n {watcher.silent && (\n <>\n <span>·</span>\n <span\n className=\"inline-flex items-center gap-0.5 text-fg-faint\"\n title=\"Silent: suppresses the task_completed notification and tells the agent to reply only on material diffs. Errors still notify.\"\n >\n <EyeOff size={10} /> silent\n </span>\n </>\n )}\n </div>\n </div>\n </div>\n </button>\n\n {expanded && (\n <div className=\"px-3 py-2 border-t border-border/60 text-[11px] text-fg-subtle space-y-2\">\n <Row label=\"Agent\">\n <Select\n size=\"sm\"\n value={watcher.agent_id}\n onChange={async (e) => {\n const next = e.target.value;\n if (next === watcher.agent_id) return;\n try {\n await api.watchers.update(watcher.id, { agent_id: next });\n onChanged();\n } catch (err) {\n pushErrorToast({\n title: \"Couldn't re-assign watcher\",\n error: err,\n context: { panel: \"scheduled-tasks\", action: \"watcher.reassign\", watcher_id: watcher.id, target_agent: next },\n });\n }\n }}\n >\n {Object.values(agents).length === 0 && (\n <option value={watcher.agent_id}>{watcher.agent_id}</option>\n )}\n {Object.values(agents)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((a) => (\n <option key={a.id} value={a.id}>{a.name}</option>\n ))}\n </Select>\n </Row>\n <Row label=\"Tool\">\n <span className=\"font-mono\">{watcher.tool}</span>\n </Row>\n <Row label=\"Args\">\n <pre className=\"whitespace-pre-wrap break-words font-mono text-fg-muted\">\n {JSON.stringify(watcher.args ?? {}, null, 2)}\n </pre>\n </Row>\n <Row label=\"Reaction\">\n <ReactionEditor watcher={watcher} onSaved={onChanged} />\n </Row>\n <Row label=\"Interval\">\n <span>{formatInterval(watcher.interval_seconds)}</span>\n </Row>\n <Row label=\"Next poll\">\n <span>{new Date(watcher.next_run_at).toLocaleString()}</span>\n <span className=\"ml-1 text-fg-faint\">({nextRun})</span>\n </Row>\n {lastRun && (\n <Row label=\"Last poll\">\n <span>{new Date(watcher.last_run_at!).toLocaleString()}</span>\n <span className=\"ml-1 text-fg-faint\">({lastRun})</span>\n </Row>\n )}\n {lastFired && (\n <Row label=\"Last fire\">\n <span>{new Date(watcher.last_fired_at!).toLocaleString()}</span>\n <span className=\"ml-1 text-fg-faint\">({lastFired})</span>\n </Row>\n )}\n <Row label=\"Status\">\n {watcher.last_error ? (\n <span className=\"inline-flex items-center gap-1 text-rose-700 dark:text-rose-400\">\n <AlertCircle size={11} /> error\n </span>\n ) : watcher.enabled ? (\n <span className=\"inline-flex items-center gap-1 text-emerald-700 dark:text-emerald-400\">\n <CheckCircle2 size={11} /> active\n </span>\n ) : (\n <span className=\"text-fg-faint\">disabled</span>\n )}\n </Row>\n {watcher.last_error && (\n <Row label=\"Error\">\n <pre className=\"whitespace-pre-wrap break-words text-rose-700 dark:text-rose-300/90\">{watcher.last_error}</pre>\n </Row>\n )}\n <div className=\"flex justify-end pt-1 gap-2\">\n <button\n onClick={async () => {\n try {\n await api.watchers.update(watcher.id, { enabled: !watcher.enabled });\n onChanged();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't toggle watcher\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"watcher.toggle\", watcher_id: watcher.id, target_enabled: !watcher.enabled },\n });\n }\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:text-fg hover:border-fg-muted\"\n title={watcher.enabled ? \"Pause this watcher\" : \"Resume this watcher\"}\n >\n <Power size={11} /> {watcher.enabled ? \"Pause\" : \"Resume\"}\n </button>\n <button\n onClick={async () => {\n if (running) return;\n setRunning(true);\n try { await onRunNow(); } finally { setRunning(false); }\n }}\n disabled={running}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:text-emerald-700 dark:hover:text-emerald-400 hover:border-emerald-700 disabled:opacity-50\"\n title=\"Poll the tool right now. If the result differs from the last poll, the agent fires.\"\n >\n <Play size={11} /> {running ? \"Polling…\" : \"Poll now\"}\n </button>\n <button\n onClick={onCancel}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-subtle hover:text-rose-700 dark:hover:text-rose-400 hover:border-rose-700\"\n >\n <Trash2 size={11} /> Cancel watcher\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Row({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2\">\n <span className=\"w-20 shrink-0 text-fg-faint\">{label}</span>\n <div className=\"flex-1 min-w-0\">{children}</div>\n </div>\n );\n}\n\n// ADR-0030 + ADR-0031. The Reaction row routes between two editors based on\n// `reaction_kind`. A kind toggle at the top swaps the column atomically via\n// PATCH (reaction_kind: ...). The store enforces the discriminated-union\n// rules — switching to 'script' clears reaction_prompt and vice versa.\nconst REACTION_PROMPT_MAX = 4000;\n\nfunction ReactionEditor({\n watcher, onSaved,\n}: {\n watcher: Watcher;\n onSaved: () => void;\n}) {\n const [switching, setSwitching] = useState(false);\n\n async function switchKind(next: \"agent_prompt\" | \"script\", scriptName?: string) {\n setSwitching(true);\n try {\n if (next === \"script\") {\n await api.watchers.update(watcher.id, {\n reaction_kind: \"script\",\n reaction_script: scriptName ?? null,\n reaction_script_args: null,\n });\n } else {\n await api.watchers.update(watcher.id, {\n reaction_kind: \"agent_prompt\",\n reaction_prompt: null,\n });\n }\n onSaved();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't switch reaction kind\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"watcher.reaction_kind\", watcher_id: watcher.id, target_kind: next },\n });\n } finally {\n setSwitching(false);\n }\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1\">\n <KindPill\n active={watcher.reaction_kind === \"agent_prompt\"}\n onClick={() => watcher.reaction_kind !== \"agent_prompt\" && void switchKind(\"agent_prompt\")}\n disabled={switching}\n title=\"On change, run this watcher's agent with a custom prompt (default behaviour).\"\n >\n Agent prompt\n </KindPill>\n <KindPill\n active={watcher.reaction_kind === \"script\"}\n onClick={() => watcher.reaction_kind !== \"script\" && void switchKind(\"script\")}\n disabled={switching}\n title=\"On change, run a built-in reaction.* script with no LLM round-trip.\"\n >\n Script\n </KindPill>\n </div>\n <p className=\"text-[10px] text-fg-faint leading-snug\">\n Choose how this watcher reacts on change:\n <span className=\"text-fg-subtle\"> Agent prompt</span> runs the assigned agent with diff context;\n <span className=\"text-fg-subtle\"> Script</span> runs a built-in automation without an LLM round-trip.\n </p>\n {watcher.reaction_kind === \"script\"\n ? (\n <ReactionScriptEditor\n initialScript={watcher.reaction_script}\n initialArgs={watcher.reaction_script_args}\n onSave={async ({ script, args }) => {\n await api.watchers.update(watcher.id, {\n reaction_script: script,\n reaction_script_args: args,\n });\n onSaved();\n }}\n errorContext={{ panel: \"scheduled-tasks\", action: \"watcher.reaction_script\", watcher_id: watcher.id }}\n diffContext={true}\n />\n )\n : <ReactionPromptEditor watcher={watcher} onSaved={onSaved} />}\n </div>\n );\n}\n\nfunction ReactionPromptEditor({\n watcher, onSaved,\n}: {\n watcher: Watcher;\n onSaved: () => void;\n}) {\n const initial = watcher.reaction_prompt ?? \"\";\n const [value, setValue] = useState(initial);\n const [saving, setSaving] = useState(false);\n // Reset local state if the watcher was refetched and the prompt\n // changed (e.g. agent edited it via the tool while this card was open).\n useEffect(() => { setValue(watcher.reaction_prompt ?? \"\"); }, [watcher.reaction_prompt]);\n const dirty = value.trim() !== initial.trim();\n const tooLong = value.length > REACTION_PROMPT_MAX;\n\n async function save(next: string | null) {\n setSaving(true);\n try {\n await api.watchers.update(watcher.id, { reaction_prompt: next });\n onSaved();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't save reaction\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"watcher.reaction_prompt\", watcher_id: watcher.id },\n });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div className=\"space-y-1\">\n <MarkdownTextarea\n value={value}\n onChange={setValue}\n rows={3}\n monospace\n maxLength={REACTION_PROMPT_MAX}\n placeholder=\"Default: summarise what changed and decide whether the user needs to know.\"\n className=\"w-full text-[11px] rounded border border-border bg-surface-1 px-2 py-1 text-fg-muted focus:outline-none focus:border-fg-muted resize-y\"\n />\n <div className=\"flex items-center gap-2 text-[10px] text-fg-faint\">\n <span className={tooLong ? \"text-rose-700 dark:text-rose-400\" : \"\"}>\n {value.length}/{REACTION_PROMPT_MAX}\n </span>\n <span className=\"ml-auto flex gap-2\">\n {watcher.reaction_prompt !== null && (\n <button\n onClick={() => { setValue(\"\"); void save(null); }}\n disabled={saving}\n className=\"px-2 py-0.5 rounded border border-border hover:text-fg hover:border-fg-muted disabled:opacity-50\"\n title=\"Clear the custom instruction; fall back to the default directive.\"\n >\n Reset to default\n </button>\n )}\n <button\n onClick={() => void save(value.trim() ? value : null)}\n disabled={saving || !dirty || tooLong}\n className=\"px-2 py-0.5 rounded border border-border hover:text-emerald-700 dark:hover:text-emerald-400 hover:border-emerald-700 disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </span>\n </div>\n </div>\n );\n}\n\nfunction formatInterval(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n if (seconds < 3600) return `${Math.round(seconds / 60)}m`;\n if (seconds < 86400) return `${Math.round(seconds / 3600)}h`;\n return `${Math.round(seconds / 86400)}d`;\n}\n","\"use client\";\nimport { AlertCircle, Calendar, CheckCircle2, Clock, EyeOff, Pencil, Play, Power, Repeat, Save, Trash2, X } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig, ModelConfig, ScheduledTask } from \"@/api/types\";\nimport { useDeepLinkScroll } from \"@/hooks/useDeepLinkScroll\";\nimport { formatRelative } from \"@/lib/utils/time\";\nimport { humanizeCron } from \"@/lib/utils/cron\";\nimport { pushErrorToast } from \"@/lib/ui/error-report\";\nimport { agentModelStatus } from \"@/lib/agents/effective-model\";\nimport { AgentModelBadge } from \"./AgentModelBadge\";\nimport { WatchersSection } from \"./WatchersSection\";\nimport { KindPill, ReactionScriptEditor } from \"@/components/triggers/ReactionEditor\";\nimport { MarkdownTextarea } from \"@/components/ui/MarkdownTextarea\";\n\nexport function ScheduledTasksPanel() {\n const [tasks, setTasks] = useState<ScheduledTask[]>([]);\n const [agents, setAgents] = useState<Record<string, AgentConfig>>({});\n const [models, setModels] = useState<ModelConfig[]>([]);\n const [loading, setLoading] = useState(true);\n const containerRef = useRef<HTMLDivElement>(null);\n useDeepLinkScroll(\"tasks\", \"task\", containerRef);\n\n async function load() {\n setLoading(true);\n try {\n const [taskList, agentList, modelList] = await Promise.all([\n api.scheduledTasks.list(),\n api.agents.list(),\n api.models.list(),\n ]);\n setTasks(taskList);\n setAgents(Object.fromEntries(agentList.map((a) => [a.id, a])));\n setModels(modelList);\n } catch (e) { console.error(e); }\n finally { setLoading(false); }\n }\n useEffect(() => { void load(); }, []);\n\n // Refresh every 15s — scheduler ticks every 30s, so this catches firings\n // before the user opens/closes the panel and missing them.\n useEffect(() => {\n const t = setInterval(() => void load(), 15_000);\n return () => clearInterval(t);\n }, []);\n\n async function cancel(task: ScheduledTask) {\n if (!confirm(`Cancel scheduled task?\\n\\n${task.prompt.slice(0, 200)}${task.prompt.length > 200 ? \"…\" : \"\"}`)) return;\n await api.scheduledTasks.cancel(task.id);\n void load();\n }\n\n async function runNow(task: ScheduledTask) {\n try {\n await api.scheduledTasks.runNow(task.id);\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't run scheduled task\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"task.runNow\", task_id: task.id },\n });\n } finally {\n void load();\n }\n }\n\n const sorted = useMemo(() => {\n // Pending (next_run_at >= now) first, sorted by next-fire ascending.\n // Then completed (last_run_at set, but for cron these will keep cycling).\n return [...tasks].sort((a, b) => a.next_run_at.localeCompare(b.next_run_at));\n }, [tasks]);\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Calendar size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Scheduled Tasks</h2>\n {tasks.length > 0 && (\n <span className=\"text-[11px] text-fg-faint\">{tasks.length}</span>\n )}\n </div>\n\n <div ref={containerRef} className=\"flex-1 overflow-y-auto px-4 py-3\">\n {loading && tasks.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {!loading && tasks.length === 0 && (\n <div className=\"text-fg-faint text-sm py-8 text-center space-y-2\">\n <p>No scheduled tasks.</p>\n <p className=\"text-xs text-fg-faint leading-relaxed\">\n Ask any agent “remind me to X in 30 minutes” or “every weekday at 9am, do Y”.\n The agent will use its <code className=\"px-1 rounded bg-surface-3 text-fg-subtle\">schedule_task</code> tool\n and the run will appear here.\n </p>\n </div>\n )}\n {sorted.map((t) => (\n <TaskCard key={t.id} task={t} agent={agents[t.agent_id]} agents={agents} models={models} onCancel={() => cancel(t)} onRunNow={() => runNow(t)} onChanged={() => void load()} />\n ))}\n <WatchersSection agents={agents} models={models} />\n </div>\n </div>\n );\n}\n\nfunction TaskCard({\n task, agent, agents, models, onCancel, onRunNow, onChanged,\n}: {\n task: ScheduledTask;\n agent?: AgentConfig;\n agents: Record<string, AgentConfig>;\n models: ModelConfig[];\n onCancel: () => void;\n onRunNow: () => void;\n onChanged: () => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [running, setRunning] = useState(false);\n const [editing, setEditing] = useState(false);\n const isCron = task.kind === \"cron\";\n const nextRun = formatRelative(task.next_run_at, { collapseSeconds: true });\n const lastRun = task.last_run_at ? formatRelative(task.last_run_at, { collapseSeconds: true }) : null;\n const overdue = !task.last_error && new Date(task.next_run_at).getTime() < Date.now() - 60_000;\n // Pre-flight model availability: catches \"agent's model was deleted\" /\n // \"no workspace default\" before the next firing silently throws no_model.\n // Script-only reactions don't talk to an LLM, so skip the check.\n const modelStatus = task.reaction_kind === \"agent_prompt\"\n ? agentModelStatus(agent ?? null, models)\n : null;\n\n return (\n <div data-deep-link-id={task.id} className=\"mb-2 rounded-lg border border-border bg-surface-2 overflow-hidden\">\n <button\n onClick={() => setExpanded((v) => !v)}\n className=\"w-full text-left px-3 py-2 hover:bg-surface-3/40 transition-colors\"\n >\n <div className=\"flex items-start gap-2\">\n {isCron\n ? <Repeat size={12} className=\"mt-1 text-violet-700 dark:text-violet-400 shrink-0\" />\n : <Clock size={12} className=\"mt-1 text-sky-700 dark:text-sky-400 shrink-0\" />}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm text-fg truncate\">{task.prompt}</p>\n <div className=\"flex items-center gap-2 mt-1 text-[11px] text-fg-faint flex-wrap\">\n <span className=\"font-mono\">\n {isCron ? task.schedule : new Date(task.schedule).toLocaleString()}\n </span>\n {isCron && humanizeCron(task.schedule) && (\n <span className=\"text-fg-muted\">({humanizeCron(task.schedule)})</span>\n )}\n <span>·</span>\n <span className={overdue ? \"text-amber-700 dark:text-amber-400\" : \"\"}>\n {overdue ? \"overdue\" : `next: ${nextRun}`}\n </span>\n {agent && (\n <>\n <span>·</span>\n <span className=\"truncate\">{agent.name}</span>\n </>\n )}\n {modelStatus && modelStatus.state !== \"ok\" && (\n <>\n <span>·</span>\n <AgentModelBadge status={modelStatus} />\n </>\n )}\n {task.silent && (\n <>\n <span>·</span>\n <span\n className=\"inline-flex items-center gap-0.5 text-fg-faint\"\n title=\"Silent: suppresses the task_completed notification and tells the agent to reply only when something material surfaces. Errors still notify.\"\n >\n <EyeOff size={10} /> silent\n </span>\n </>\n )}\n </div>\n </div>\n </div>\n </button>\n\n {expanded && (\n <div className=\"px-3 py-2 border-t border-border/60 text-[11px] text-fg-subtle space-y-2\">\n {editing ? (\n <TaskEditor task={task} agents={agents} onCancel={() => setEditing(false)} onSaved={() => { setEditing(false); onChanged(); }} />\n ) : (\n <>\n {task.reaction_kind === \"agent_prompt\" && (\n <Row label=\"Prompt\">\n <pre className=\"whitespace-pre-wrap break-words font-mono text-fg-muted\">{task.prompt}</pre>\n </Row>\n )}\n {task.reaction_kind === \"script\" && (\n <Row label=\"Prompt\">\n <span className=\"text-fg-faint italic\">\n (running script: <span className=\"font-mono\">{task.reaction_script}</span> — no agent prompt)\n </span>\n </Row>\n )}\n <Row label=\"Reaction\">\n <TaskReactionEditor task={task} onChanged={onChanged} />\n </Row>\n {task.description && (\n <Row label=\"Description\">{task.description}</Row>\n )}\n <Row label=\"Kind\">\n <span className=\"font-mono\">{task.kind}</span>\n </Row>\n <Row label={isCron ? \"Cron\" : \"When\"}>\n <span className=\"font-mono\">{task.schedule}</span>\n {isCron && humanizeCron(task.schedule) && (\n <span className=\"ml-1 text-fg-faint\">({humanizeCron(task.schedule)})</span>\n )}\n {!isCron && (\n <span className=\"ml-1 text-fg-faint\">({new Date(task.schedule).toLocaleString()})</span>\n )}\n </Row>\n <Row label=\"Next run\">\n <span>{new Date(task.next_run_at).toLocaleString()}</span>\n <span className=\"ml-1 text-fg-faint\">({nextRun})</span>\n </Row>\n {lastRun && (\n <Row label=\"Last run\">\n <span>{new Date(task.last_run_at!).toLocaleString()}</span>\n <span className=\"ml-1 text-fg-faint\">({lastRun})</span>\n </Row>\n )}\n <Row label=\"Status\">\n {task.last_error ? (\n <span className=\"inline-flex items-center gap-1 text-rose-700 dark:text-rose-400\">\n <AlertCircle size={11} /> error\n </span>\n ) : task.enabled ? (\n <span className=\"inline-flex items-center gap-1 text-emerald-700 dark:text-emerald-400\">\n <CheckCircle2 size={11} /> active\n </span>\n ) : (\n <span className=\"text-fg-faint\">disabled</span>\n )}\n </Row>\n {task.last_error && (\n <Row label=\"Error\">\n <pre className=\"whitespace-pre-wrap break-words text-rose-700 dark:text-rose-300/90\">{task.last_error}</pre>\n </Row>\n )}\n <div className=\"flex justify-end pt-1 gap-2\">\n <button\n onClick={async () => {\n try {\n await api.scheduledTasks.update(task.id, { enabled: !task.enabled });\n onChanged();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't toggle scheduled task\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"task.toggle\", task_id: task.id, target_enabled: !task.enabled },\n });\n }\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:text-fg hover:border-fg-muted\"\n title={task.enabled ? \"Pause this task (scheduler will skip it)\" : \"Resume this task\"}\n >\n <Power size={11} /> {task.enabled ? \"Pause\" : \"Resume\"}\n </button>\n <button\n onClick={() => setEditing(true)}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:text-sky-700 dark:hover:text-sky-400 hover:border-sky-700\"\n >\n <Pencil size={11} /> Edit\n </button>\n <button\n onClick={async () => {\n if (running) return;\n setRunning(true);\n try { await onRunNow(); } finally { setRunning(false); }\n }}\n disabled={running}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-muted hover:text-emerald-700 dark:hover:text-emerald-400 hover:border-emerald-700 disabled:opacity-50\"\n title=\"Trigger this task now to preview the notification + content. Cron tasks still continue on their normal schedule.\"\n >\n <Play size={11} /> {running ? \"Running…\" : \"Run now\"}\n </button>\n <button\n onClick={onCancel}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-subtle hover:text-rose-700 dark:hover:text-rose-400 hover:border-rose-700\"\n >\n <Trash2 size={11} /> Cancel task\n </button>\n </div>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ADR-0032 — kind toggle + script editor for a scheduled task. The\n// agent_prompt branch is the existing `prompt` column on the task,\n// which is rendered above (or via TaskEditor); when the user switches to\n// 'script' the prompt becomes a \"(running script: …)\" stub.\nfunction TaskReactionEditor({\n task, onChanged,\n}: {\n task: ScheduledTask;\n onChanged: () => void;\n}) {\n const [switching, setSwitching] = useState(false);\n\n async function switchKind(next: \"agent_prompt\" | \"script\") {\n if (next === task.reaction_kind) return;\n setSwitching(true);\n try {\n if (next === \"script\") {\n await api.scheduledTasks.update(task.id, {\n reaction_kind: \"script\",\n reaction_script: null,\n reaction_script_args: null,\n });\n } else {\n await api.scheduledTasks.update(task.id, {\n reaction_kind: \"agent_prompt\",\n // Restore a non-empty prompt sentinel so the NOT NULL column\n // stays populated; the user can then edit it via the TaskEditor.\n prompt: task.prompt && task.prompt.trim() ? task.prompt : \"(edit me)\",\n });\n }\n onChanged();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't switch reaction kind\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"task.reaction_kind\", task_id: task.id, target_kind: next },\n });\n } finally {\n setSwitching(false);\n }\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1\">\n <KindPill\n active={task.reaction_kind === \"agent_prompt\"}\n onClick={() => void switchKind(\"agent_prompt\")}\n disabled={switching}\n title=\"On firing, run this task's agent with the prompt above (default).\"\n >\n Agent prompt\n </KindPill>\n <KindPill\n active={task.reaction_kind === \"script\"}\n onClick={() => void switchKind(\"script\")}\n disabled={switching}\n title=\"On firing, run a built-in reaction.* script with no LLM round-trip.\"\n >\n Script\n </KindPill>\n </div>\n <p className=\"text-[10px] text-fg-faint leading-snug\">\n Reaction mode controls what happens when this task fires:\n <span className=\"text-fg-subtle\"> Agent prompt</span> runs the task's agent prompt;\n <span className=\"text-fg-subtle\"> Script</span> runs a built-in reaction script with no LLM chat turn.\n </p>\n {task.reaction_kind === \"script\" && (\n <ReactionScriptEditor\n initialScript={task.reaction_script}\n initialArgs={task.reaction_script_args}\n onSave={async ({ script, args }) => {\n await api.scheduledTasks.update(task.id, {\n reaction_script: script,\n reaction_script_args: args,\n });\n onChanged();\n }}\n errorContext={{ panel: \"scheduled-tasks\", action: \"task.reaction_script\", task_id: task.id }}\n diffContext={false}\n />\n )}\n </div>\n );\n}\n\nfunction Row({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2\">\n <span className=\"w-20 shrink-0 text-fg-faint\">{label}</span>\n <div className=\"flex-1 min-w-0\">{children}</div>\n </div>\n );\n}\n\n// Editable form for an existing task. Keeps inline within the expanded\n// card. For \"once\" tasks the schedule field is a datetime-local input\n// (ISO conversion happens on save); for \"cron\" it's a free-text cron expr\n// the server validates with cron-parser.\nfunction TaskEditor({\n task, agents, onCancel, onSaved,\n}: {\n task: ScheduledTask;\n agents: Record<string, AgentConfig>;\n onCancel: () => void;\n onSaved: () => void;\n}) {\n const [agentId, setAgentId] = useState(task.agent_id);\n const [prompt, setPrompt] = useState(task.prompt);\n const [description, setDescription] = useState(task.description ?? \"\");\n const [kind, setKind] = useState<\"once\" | \"cron\">(task.kind);\n const [schedule, setSchedule] = useState(() =>\n task.kind === \"once\" ? isoToLocalInput(task.schedule) : task.schedule,\n );\n const [enabled, setEnabled] = useState(task.enabled);\n const [silent, setSilent] = useState(task.silent ?? false);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function save() {\n if (saving) return;\n setError(null);\n const trimmedPrompt = prompt.trim();\n if (!trimmedPrompt) { setError(\"Prompt cannot be empty.\"); return; }\n const trimmedSchedule = schedule.trim();\n if (!trimmedSchedule) { setError(\"Schedule cannot be empty.\"); return; }\n let scheduleOut = trimmedSchedule;\n if (kind === \"once\") {\n const ts = new Date(trimmedSchedule);\n if (Number.isNaN(ts.getTime())) { setError(\"Invalid date/time.\"); return; }\n scheduleOut = ts.toISOString();\n }\n setSaving(true);\n try {\n await api.scheduledTasks.update(task.id, {\n agent_id: agentId,\n prompt: trimmedPrompt,\n description: description.trim() ? description.trim() : null,\n kind,\n schedule: scheduleOut,\n enabled,\n silent,\n });\n onSaved();\n } catch (e) {\n pushErrorToast({\n title: \"Couldn't save scheduled task\",\n error: e,\n context: { panel: \"scheduled-tasks\", action: \"task.save\", task_id: task.id },\n });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div className=\"space-y-2\">\n <Row label=\"Agent\">\n <select\n value={agentId}\n onChange={(e) => setAgentId(e.target.value)}\n className=\"w-full rounded border border-border bg-surface-1 px-2 py-1 text-[12px] text-fg\"\n >\n {Object.values(agents).length === 0 && (\n <option value={agentId}>{agentId}</option>\n )}\n {Object.values(agents)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((a) => (\n <option key={a.id} value={a.id}>{a.name}</option>\n ))}\n </select>\n </Row>\n <Row label=\"Prompt\">\n <MarkdownTextarea\n value={prompt}\n onChange={setPrompt}\n rows={3}\n monospace\n className=\"w-full rounded border border-border bg-surface-1 px-2 py-1 text-[12px] text-fg resize-y\"\n />\n </Row>\n <Row label=\"Description\">\n <input\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"optional\"\n className=\"w-full rounded border border-border bg-surface-1 px-2 py-1 text-[12px] text-fg\"\n />\n </Row>\n <Row label=\"Kind\">\n <div className=\"inline-flex rounded border border-border overflow-hidden\">\n {([\"once\", \"cron\"] as const).map((k) => (\n <button\n key={k}\n type=\"button\"\n onClick={() => {\n setKind(k);\n // Reset the schedule field to a sane default when switching kinds.\n if (k === \"once\" && task.kind !== \"once\") setSchedule(isoToLocalInput(new Date(Date.now() + 60 * 60_000).toISOString()));\n if (k === \"cron\" && task.kind !== \"cron\") setSchedule(\"0 9 * * *\");\n }}\n className={`px-2 py-0.5 text-[11px] ${kind === k ? \"bg-surface-3 text-fg\" : \"text-fg-faint hover:text-fg\"}`}\n >\n {k}\n </button>\n ))}\n </div>\n </Row>\n <Row label={kind === \"cron\" ? \"Cron\" : \"When\"}>\n {kind === \"cron\" ? (\n <input\n value={schedule}\n onChange={(e) => setSchedule(e.target.value)}\n placeholder=\"0 9 * * *\"\n className=\"w-full rounded border border-border bg-surface-1 px-2 py-1 text-[12px] text-fg font-mono\"\n />\n ) : (\n <input\n type=\"datetime-local\"\n value={schedule}\n onChange={(e) => setSchedule(e.target.value)}\n className=\"rounded border border-border bg-surface-1 px-2 py-1 text-[12px] text-fg\"\n />\n )}\n </Row>\n <Row label=\"Enabled\">\n <label className=\"inline-flex items-center gap-1 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n className=\"accent-emerald-600\"\n />\n <span className=\"text-[11px]\">{enabled ? \"active\" : \"paused\"}</span>\n </label>\n </Row>\n <Row label=\"Silent\">\n <label className=\"inline-flex items-center gap-1 cursor-pointer\" title=\"When silent: suppresses the task_completed notification AND tells the agent to reply only when something material surfaces (NO_REPLY answers are dropped). Errors still notify so failures aren't hidden. Firings remain visible in chat tagged 'scheduled' — use the filter toolbar to hide them.\">\n <input\n type=\"checkbox\"\n checked={silent}\n onChange={(e) => setSilent(e.target.checked)}\n className=\"accent-sky-600\"\n />\n <span className=\"text-[11px]\">{silent ? \"muted (no notification)\" : \"always notify\"}</span>\n </label>\n </Row>\n {error && (\n <p className=\"text-[11px] text-rose-700 dark:text-rose-400\">{error}</p>\n )}\n <div className=\"flex justify-end gap-2 pt-1\">\n <button\n onClick={onCancel}\n disabled={saving}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-subtle hover:text-fg disabled:opacity-50\"\n >\n <X size={11} /> Cancel\n </button>\n <button\n onClick={() => void save()}\n disabled={saving}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-emerald-700 text-emerald-700 dark:text-emerald-400 hover:bg-emerald-700/10 disabled:opacity-50\"\n >\n <Save size={11} /> {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n );\n}\n\n// Convert an ISO timestamp (\"2026-05-21T14:00:00.000Z\") to the value\n// expected by <input type=\"datetime-local\"> (\"2026-05-21T22:00\", in\n// local time). Browsers don't accept the trailing Z.\nfunction isoToLocalInput(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","export const HARNESS_SECTION_KEYS = [\n \"capabilities\",\n \"plan_first\",\n \"presentation\",\n \"citation\",\n \"self_config\",\n] as const;\n\nexport type HarnessSectionKey = typeof HARNESS_SECTION_KEYS[number];\n\nexport interface HarnessSection {\n enabled: boolean;\n body: string;\n}\n\nexport interface Harness {\n id: string;\n name: string;\n description?: string;\n builtin: boolean;\n sections: Record<HarnessSectionKey, HarnessSection>;\n}\n\nexport const BUILTIN_HARNESS_ID_PREFIX = \"builtin:\";\nexport const CUSTOM_HARNESS_ID_PREFIX = \"custom:\";\nexport const DEFAULT_HARNESS_ID = \"builtin:default\";\n\nexport function isBuiltinHarnessId(id: string): boolean {\n return id.startsWith(BUILTIN_HARNESS_ID_PREFIX);\n}\n\nexport const SECTION_DISPLAY: Record<HarnessSectionKey, { title: string; hint: string }> = {\n capabilities: {\n title: \"Host capabilities\",\n hint: \"What the surrounding app can do — notifications, scheduling, watchers, document indexing.\",\n },\n plan_first: {\n title: \"Plan-first acknowledgment\",\n hint: \"Acknowledge-before-acting rules, action principle, anti-fabrication, follow-through.\",\n },\n presentation: {\n title: \"Output formatting\",\n hint: \"Markdown / HTML extras, code fences, images, maps, citation refs block.\",\n },\n citation: {\n title: \"Source attribution\",\n hint: \"Anti-hallucination rules: every substantive claim must be tagged with its source.\",\n },\n self_config: {\n title: \"Self-configuration proposals\",\n hint: \"Lets the agent propose config changes (install MCP, edit agent, set keys) for user approval.\",\n },\n};\n","export interface AgentInfo {\n id: string;\n name: string;\n description: string;\n icon: string | null;\n}\n\nexport interface AgentConfig {\n id: string;\n name: string;\n icon: string | null;\n identity: string;\n instructions: string;\n tools: string[];\n model_config_name: string | null;\n is_default: boolean;\n history_limit: number;\n history_window_hours: number;\n never_reply: boolean;\n adaptive_persona_enabled: boolean;\n adaptive_persona_strength: number;\n adaptive_empathy: number;\n adaptive_expressiveness: number;\n adaptive_verbosity: number;\n adaptive_mbti: string;\n voice_enabled: boolean;\n voice_model: string;\n voice_name: string;\n voice_stt_model: string;\n voice_auto_speak: boolean;\n /**\n * Optional override for which behavioral harness wraps this agent's system\n * prompt. NULL = inherit the global default. Built-in IDs are prefixed\n * `builtin:`; user-created customs are prefixed `custom:`.\n */\n harness_id: string | null;\n /**\n * IDs of other agents this agent is allowed to hand subtasks to via the\n * built-in `delegate_to_agent` tool. Empty array (default) disables\n * delegation even if the tool itself is enabled.\n */\n delegate_targets: string[];\n /**\n * ADR-0043 — per-agent override of the hot/warm/facts split. Any positive\n * numbers; the backend divides by sum so the UI can ship raw weights and\n * never has to reconcile to 100. NULL/missing = inherit the model config's\n * value.\n */\n context_tier_proportions: { hot: number; warm: number; facts: number } | null;\n /**\n * Per-agent override of the anti-hallucination classifier mode.\n * null = inherit the global JARELA_HALLUCINATION_DETECTOR_MODE\n * \"off\" = no classifier on this agent's turns\n * \"report\" = classifier runs alongside regex; logs disagreements +\n * appends a footer when classifier flags a stall regex missed\n * \"enforce\" = either regex OR classifier vote triggers retry\n */\n anti_hallucination_mode: \"off\" | \"regex\" | \"model\" | null;\n /**\n * Per-agent override of the anti-hallucination classifier model.\n * Stores the `name` of a saved model config (see Models settings) — pick\n * a fast/cheap one (Haiku, gpt-4o-mini, gemini-flash). NULL = inherit the\n * global JARELA_HALLUCINATION_DETECTOR_MODEL.\n */\n anti_hallucination_model_config: string | null;\n /**\n * Citation strictness (independent of the stall detector). One of:\n * - `off` : no checker, no system-prompt directive\n * - `informational` : checker runs and surfaces a references panel; the\n * agent is NOT asked to cite\n * - `standard` : agent nudged to cite KEY (load-bearing) claims\n * with `[N]` markers\n * - `strict` : agent must cite EVERY factual claim AND the stall\n * classifier is forced to mode='model' for this\n * agent's turns\n * The checker reuses `anti_hallucination_model_config` as the LLM judge.\n */\n citation_strictness: CitationStrictness;\n created_at: string;\n updated_at: string;\n}\n\n/** Citation strictness enum exposed over the wire. Mirrors\n * `lib/stores/agent-configs#CitationStrictness`. */\nexport type CitationStrictness = \"off\" | \"informational\" | \"standard\" | \"strict\";\n\nexport interface AgentConfigIn {\n name: string;\n icon?: string | null;\n identity?: string;\n instructions?: string;\n tools?: string[];\n model_config_name?: string | null;\n is_default?: boolean;\n history_limit?: number;\n history_window_hours?: number;\n never_reply?: boolean;\n adaptive_persona_enabled?: boolean;\n adaptive_persona_strength?: number;\n adaptive_empathy?: number;\n adaptive_expressiveness?: number;\n adaptive_verbosity?: number;\n adaptive_mbti?: string;\n voice_enabled?: boolean;\n voice_model?: string;\n voice_name?: string;\n voice_stt_model?: string;\n voice_auto_speak?: boolean;\n harness_id?: string | null;\n delegate_targets?: string[];\n // null = clear and inherit from the model; undefined = leave as-is.\n context_tier_proportions?: { hot: number; warm: number; facts: number } | null;\n // null = clear override; undefined = leave as-is.\n anti_hallucination_mode?: \"off\" | \"regex\" | \"model\" | null;\n anti_hallucination_model_config?: string | null;\n // Independent citation strictness ('off' | 'informational' | 'standard' |\n // 'strict'). undefined = leave as-is.\n citation_strictness?: CitationStrictness;\n}\n\nexport interface ThreadSummary {\n thread_id: string;\n agent_id: string;\n title: string | null;\n created_at: string;\n updated_at: string;\n message_count: number;\n}\n\nexport interface PersistedToolEvent {\n id: string;\n phase: \"call\" | \"result\";\n name: string;\n payload: unknown;\n}\n\nexport interface Message {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n created_at: string;\n // Captured live during the run, persisted with the assistant message.\n // Lets the chat UI render historical tool invocations the same way it\n // renders live streaming ones.\n tool_events?: PersistedToolEvent[];\n // Optional classification tag. NULL/undefined = ordinary chat content.\n // Known values: 'scheduled_task' (scheduler firings), 'watcher'\n // (watcher-trigger firings, ADR-0027), 'bridge' (bridge adapter\n // traffic), 'synthetic' (page-capture / file-upload synthetic user\n // messages). The chat-panel filter toolbar lets the user toggle each\n // category on/off; persistence is the same regardless.\n category?: string | null;\n // Per-turn usage snapshot from message_usage (assistant turns only).\n // Lets the chat UI render a context-window utilisation bar without\n // re-querying. Absent for user turns and for assistant rows persisted\n // before message_usage existed.\n usage?: MessageUsage | null;\n // Auxiliary per-turn metadata. Currently carries the citation-checker\n // verdict when the agent's `citation_strictness` is not `off`. Absent on\n // legacy rows and on turns where no checker ran.\n metadata?: MessageMetadata | null;\n}\n\nexport interface CitationClaim {\n /** Short paraphrase of the claim the checker extracted from the turn. */\n text: string;\n /** Marker number the agent wrote in `[N]` next to the claim, if any. */\n marker?: number | null;\n /** URL or workspace-relative path the agent cited, if any. Resolved from\n * the source manifest when `marker` is present; null when the agent\n * attached no marker or the marker wasn't in the manifest. */\n link: string | null;\n /** true = marker present AND in this thread's source manifest. */\n verified: boolean;\n /** Short human-readable explanation; capped at ~120 chars. */\n reason: string;\n}\n\nexport interface SourceManifestEntry {\n /** 1-based number shown to the agent and used as the inline `[N]` marker. */\n n: number;\n /** Short display label (hostname+path for URLs, the path itself for files). */\n label: string;\n /** Full URL or workspace-relative path the marker resolves to. */\n href: string;\n}\n\n/** Per-message tally of values the redaction layer held back from the\n * LLM. Each entry is a coarse type bucket plus a count; original values\n * are NEVER stored here — they live in the local checkpoint and never\n * cross the trust boundary. The chat UI surfaces this as a shield\n * indicator under the assistant bubble. ADR-0064. */\nexport interface RedactionSummaryEntry {\n /** Coarse type bucket: `anthropic_api_key`, `swedish_personnummer`,\n * `iban`, `unknown_long_string`, etc. */\n type_hint: string;\n count: number;\n}\n\nexport interface MessageMetadata {\n citations?: {\n /** Model config name used as the checker. */\n checker_model: string;\n /** Per-claim verdicts. */\n claims: CitationClaim[];\n /** URLs/paths the agent cited but that aren't in the visited-source set. */\n unverified_links: string[];\n /** Numbered source manifest the agent saw at prompt time. The chat UI\n * uses it to render inline `[N]` markers as clickable links. */\n sources?: SourceManifestEntry[];\n };\n /** Total values held back from the LLM during this turn (ADR-0064).\n * Absent on legacy rows and on turns where nothing matched. */\n redaction_summary?: RedactionSummaryEntry[];\n}\n\nexport interface MessageUsage {\n input_tokens: number;\n output_tokens: number;\n // Per-tier input-token breakdown + the budget cap each tier was given,\n // captured at history-window assembly time. NULL on legacy rows persisted\n // before ADR-0044 wired this up — the chat UI falls back to a proportional\n // visualisation in that case.\n hot_tokens: number | null;\n warm_tokens: number | null;\n facts_tokens: number | null;\n overhead_tokens: number | null;\n hot_budget_tokens: number | null;\n warm_budget_tokens: number | null;\n facts_budget_tokens: number | null;\n context_window_tokens: number | null;\n // Anthropic prompt-cache breakdown (ADR-0062). Disjoint from\n // `input_tokens`: Anthropic returns fresh-input separate from cache\n // reads/writes, and total billable input = sum of the three. NULL on\n // rows persisted before cache plumbing landed; 0 on Anthropic turns\n // where caching didn't fire. Non-Anthropic providers leave both NULL\n // until they grow the equivalent breakdown.\n cache_creation_input_tokens: number | null;\n cache_read_input_tokens: number | null;\n}\n\nexport interface ThreadDetail extends ThreadSummary {\n messages: Message[];\n has_more: boolean;\n // Effective context-window size (in tokens) for this thread's current\n // agent + model config. Used by the chat UI to scale the per-turn\n // context-usage bar against the same cap the agent applies at run time.\n context_window_tokens?: number | null;\n // ADR-0042 — explicit context boundary + cached warm summary. NULL on\n // threads with no pin (the agent's history_window_hours default applies).\n // The summary is fresh iff `warm_summary_before === hot_since`; the chat\n // UI uses that comparison to decide whether to show the live summary or\n // a \"will appear after your next reply\" placeholder.\n hot_since?: string | null;\n warm_summary?: string | null;\n warm_summary_before?: string | null;\n warm_summary_computed_at?: string | null;\n // Compaction stats — drive the boundary chip's \"N msgs · old → new chars\"\n // readout. Null when the summary was produced before these columns existed.\n warm_summary_source_messages?: number | null;\n warm_summary_source_chars?: number | null;\n}\n\nexport interface ThreadContextPin {\n hot_since: string | null;\n warm_summary: string | null;\n warm_summary_before: string | null;\n warm_summary_computed_at: string | null;\n warm_summary_source_messages: number | null;\n warm_summary_source_chars: number | null;\n}\n\nexport interface MemoryItem {\n namespace: string;\n key: string;\n value: unknown;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ModelConfig {\n name: string;\n provider: \"openai\" | \"anthropic\" | \"github-copilot\" | string;\n model_id: string;\n params: {\n api_key?: string;\n base_url?: string;\n extra_headers?: Record<string, string>;\n temperature?: number;\n max_tokens?: number;\n context_window_tokens?: number;\n context_tier_proportions?: {\n hot?: number;\n warm?: number;\n facts?: number;\n };\n context_tier_priority?: [\"hot\" | \"warm\" | \"facts\", \"hot\" | \"warm\" | \"facts\", \"hot\" | \"warm\" | \"facts\"];\n };\n // Linked credential row that carries api_key / base_url / extra_headers\n // (or OAuth tokens). NULL on freshly seeded rows; auto-migration fills\n // this for legacy rows that had inline secrets.\n credential_id?: string | null;\n is_default: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ModelConfigIn {\n provider: string;\n model_id: string;\n params?: ModelConfig[\"params\"];\n credential_id?: string | null;\n is_default?: boolean;\n}\n\nexport type CredentialType = \"model\" | \"tts\" | \"integration\" | \"bridge\";\nexport type CredentialAuthMethod = \"api_key\" | \"oauth\";\n\nexport interface Credential {\n id: string;\n type: CredentialType;\n provider: string;\n auth_method: CredentialAuthMethod;\n // Server returns this with secret fields redacted to \"***\" when\n // present. Clients never see plaintext for `api_key`/`client_secret`/\n // `refresh_token`/`access_token` — only their existence.\n params: {\n api_key?: string;\n base_url?: string;\n extra_headers?: Record<string, string>;\n client_id?: string;\n client_secret?: string;\n refresh_token?: string;\n access_token?: string;\n expires_at?: string;\n };\n created_at: string;\n updated_at: string;\n}\n\nexport interface CredentialIn {\n // Omit to let the server allocate `<type>-<provider>[-N]`.\n id?: string;\n type: CredentialType;\n provider: string;\n auth_method?: CredentialAuthMethod;\n params?: Credential[\"params\"];\n}\n\nexport interface TaskAssignment {\n agent_id: string;\n model_config_name: string;\n tool_policy?: ToolPolicy;\n created_at: string;\n updated_at: string;\n}\n\nexport interface StreamFilters {\n include_tools?: boolean;\n include_thinking?: boolean;\n}\n\nexport interface ToolPolicy {\n allow?: string[];\n deny?: string[];\n}\n\nexport interface StreamOptions {\n filters?: StreamFilters;\n tool_policy?: ToolPolicy;\n // Back-compat: pre-rename clients may still send \"normal\" / \"advanced\".\n // Server-side normalization lives in lib/agents/run-thread.ts.\n ui_experience_mode?: \"essential\" | \"full\" | \"normal\" | \"advanced\";\n}\n\nexport interface UserProfile {\n id: string;\n name: string;\n icon: string | null;\n about: string;\n created_at: string;\n updated_at: string;\n // Geolocation (opt-in). All null when sharing is off.\n location_lat?: number | null;\n location_lng?: number | null;\n location_accuracy_m?: number | null;\n location_label?: string | null;\n location_updated_at?: string | null;\n location_consent?: number; // 0 | 1\n /**\n * Persona preset selected in the Profile editor (home/work/dev/custom).\n * Drives the Credentials panel's category filter. `null` or absent\n * = no filter (show all integrations — the legacy behaviour).\n */\n preset?: \"home\" | \"work\" | \"dev\" | \"custom\" | null;\n}\n\nexport interface AccessWhitelistEntry {\n identity: string;\n display_name: string | null;\n added_at: string;\n last_seen_at: string | null;\n}\n\nexport interface ToolInfo {\n name: string;\n description: string;\n /** \"builtin\" = shipped with Jarela; \"mcp\" = provided by a connected MCP server. */\n source?: \"builtin\" | \"mcp\";\n /** UI grouping label (e.g. \"Files\", \"Web\", \"MCP\"). */\n category?: string;\n /**\n * Optional parent group rendered above the category in the Agent editor.\n * Currently used to collapse vendor-native categories (Atlassian, GitHub)\n * under a single \"Work\" header. `null` (or absent) means render flat.\n */\n group?: string | null;\n stats?: ToolUsefulnessStats;\n}\n\nexport interface ToolUsefulnessStats {\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n success_rate: number;\n usefulness_rate: number;\n score: number;\n never_used: boolean;\n last_called_at: string | null;\n}\n\nexport interface DashboardTierTokens {\n hot_tokens: number;\n warm_tokens: number;\n facts_tokens: number;\n overhead_tokens: number;\n measured_input_tokens: number;\n}\n\nexport interface DashboardDataQuality {\n measured_messages: number;\n estimated_messages: number;\n measured_pct: number;\n}\n\nexport interface DashboardSeriesPoint {\n day: string;\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n tool_calls: number;\n tool_successes: number;\n tool_errors: number;\n success_rate: number;\n error_rate: number;\n tier_tokens: DashboardTierTokens;\n}\n\nexport interface DashboardToolTop {\n name: string;\n call_count: number;\n success_count: number;\n error_count: number;\n score: number;\n success_rate: number;\n last_called_at: string | null;\n}\n\nexport interface DashboardAgentTop {\n agent_id: string;\n agent_name: string;\n message_count: number;\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n}\n\nexport interface DashboardProviderRate {\n provider: string;\n input_per_1m_usd: number | null;\n output_per_1m_usd: number | null;\n source: string;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n ok: boolean;\n status: number | null;\n error: string | null;\n}\n\nexport interface DashboardModelRate {\n provider: string;\n model_id: string;\n input_per_1m_usd: number | null;\n output_per_1m_usd: number | null;\n source: string;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n ok: boolean;\n status: number | null;\n error: string | null;\n}\n\nexport interface DashboardProviderBreakdown {\n provider: string;\n message_count: number;\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n}\n\nexport interface DashboardModelBreakdown {\n model_config_name: string;\n provider: string;\n model_id: string;\n message_count: number;\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n}\n\nexport interface DashboardDayBreakdown {\n day: string;\n summary: {\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n tool_calls: number;\n tool_successes: number;\n tool_errors: number;\n success_rate: number;\n error_rate: number;\n tier_tokens: DashboardTierTokens;\n };\n top_agents: DashboardAgentTop[];\n by_provider: DashboardProviderBreakdown[];\n by_model: DashboardModelBreakdown[];\n}\n\nexport interface DashboardMetrics {\n generated_at: string;\n days: number;\n summary: {\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n tool_calls: number;\n tool_successes: number;\n tool_errors: number;\n success_rate: number;\n error_rate: number;\n tier_tokens: DashboardTierTokens;\n data_quality: DashboardDataQuality;\n };\n series: DashboardSeriesPoint[];\n top_tools: DashboardToolTop[];\n top_agents: DashboardAgentTop[];\n by_provider: DashboardProviderBreakdown[];\n by_model: DashboardModelBreakdown[];\n breakdowns_by_day: Record<string, DashboardDayBreakdown>;\n pricing: {\n snapshot_generated_at: string | null;\n rates: DashboardProviderRate[];\n model_rates: DashboardModelRate[];\n notes: string;\n };\n}\n\nexport interface DashboardCurrencyInfo {\n currency: string;\n rate_from_usd: number;\n country_code: string | null;\n source: \"location\" | \"default\" | \"manual\";\n updated_at: string;\n}\n\nexport interface DashboardPricingRefreshResult {\n refreshed: boolean;\n reason: \"forced\" | \"stale\" | \"missing\" | \"fresh\";\n generated_at: string;\n ttl_days: number;\n source_count: number;\n}\n\n/** One built-in tool category with its current enable state. */\nexport interface BuiltinToolCategoryInfo {\n category: string;\n enabled: boolean;\n toolCount: number;\n toolNames: string[];\n}\n\nexport interface McpServer {\n name: string;\n transport: \"stdio\" | \"http\";\n spec: Record<string, unknown>;\n enabled: boolean;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface McpServerIn {\n name: string;\n transport: \"stdio\" | \"http\";\n spec: Record<string, unknown>;\n enabled?: boolean;\n}\n\nexport interface McpRegistryVariable {\n key: string;\n label: string;\n placeholder?: string;\n secret?: boolean;\n default?: string;\n}\n\nexport interface IntegrationField {\n key: string;\n label: string;\n placeholder?: string;\n secret: boolean;\n required: boolean;\n}\n\nexport interface IntegrationDefinition {\n name: string;\n label: string;\n description: string;\n fields: IntegrationField[];\n /**\n * Persona-filter bucket. Drives whether the Credentials panel shows\n * this integration for the current Profile preset. Optional for\n * back-compat with older clients.\n */\n category?: \"llm\" | \"mail\" | \"calendar\" | \"issue-tracker\" | \"chat\" | \"infrastructure\" | \"other\";\n}\n\nexport interface IntegrationStatus {\n name: string;\n configured: boolean;\n values: Record<string, string>; // secrets masked as \"********\"\n updated_at: string | null;\n /**\n * Per-field provenance flags. `\"rc\"` = pulled from a shell-rc /\n * Windows-registry env var by the env-syncer. `\"user\"` = the user\n * typed it into the panel. Drives the \"from your shell\" badge.\n */\n source?: Record<string, \"rc\" | \"user\">;\n /** ISO timestamp of the last successful rc-sync write. */\n rc_synced_at?: string | null;\n}\n\nexport interface IntegrationsListResponse {\n definitions: IntegrationDefinition[];\n statuses: IntegrationStatus[];\n}\n\n// ---------------------------------------------------------------------------\n// Env-sync — auto-pickup of standard credential env vars from shell rc\n// (macOS / Linux) or User-scope registry (Windows). See lib/env/sync.ts.\n// ---------------------------------------------------------------------------\n\nexport type EnvSyncDiscoverySource =\n | \"process\"\n | \"shell-rc\"\n | \"windows-registry\"\n | \"unavailable\";\n\nexport type EnvSyncAction =\n | \"would-write\"\n | \"skipped-user\"\n | \"skipped-equal\"\n | \"skipped-empty\"\n | \"absent\";\n\nexport interface EnvSyncCandidate {\n envVar: string | null;\n integration: string;\n field: string;\n current_source: \"rc\" | \"user\" | \"absent\";\n current_value_present: boolean;\n rc_value_preview: string | null;\n action: EnvSyncAction;\n}\n\nexport interface EnvSyncResult {\n discovered: {\n values: Record<string, string>; // raw values; UI should not display these directly\n source: EnvSyncDiscoverySource;\n shell: string | null;\n warnings: string[];\n elapsed_ms: number;\n };\n candidates: EnvSyncCandidate[];\n applied_count: number;\n ts: string;\n}\n\n/** One allowlist row — env-var name(s) → an existing integration field. */\nexport interface EnvAllowlistMapping {\n envVars: string[];\n integration: string;\n field: string;\n}\n\n/**\n * Allowlist API payload. `defaults` is the code-owned ENV_ALLOWLIST.\n * `overrides` keys are `\"<integration>:<field>\"` pointing at the user's\n * additional env-var aliases (defaults always remain, even if missing\n * from the override list).\n */\nexport interface EnvAllowlistConfig {\n defaults: EnvAllowlistMapping[];\n overrides: Record<string, string[]>;\n}\n\nexport interface ScheduledTask {\n id: string;\n agent_id: string;\n prompt: string;\n description: string | null;\n kind: \"once\" | \"cron\";\n schedule: string; // ISO timestamp for \"once\", cron expr for \"cron\"\n next_run_at: string;\n last_run_at: string | null;\n last_error: string | null;\n enabled: boolean;\n // When true the scheduler wraps the prompt with a \"reply only if material\"\n // directive and a NO_REPLY sentinel. NO_REPLY turns are not persisted at\n // all. All other scheduler firings are tagged with `category=scheduled_task`\n // so the chat-panel filter toolbar can hide them en masse.\n silent: boolean;\n // ADR-0032 — discriminated reaction. 'agent_prompt' (default) runs the\n // agent with `prompt`; 'script' runs a registered reaction.* script with\n // no LLM round-trip.\n reaction_kind: \"agent_prompt\" | \"script\";\n reaction_script: string | null;\n reaction_script_args: unknown | null;\n created_at: string;\n updated_at: string;\n}\n\n// Event-driven watcher (ADR-0027). Sibling of ScheduledTask: instead of\n// firing on a cron, the scheduler polls one built-in tool every\n// `interval_seconds` and only invokes the agent when the tool's output\n// changes since the previous poll.\nexport interface Watcher {\n id: string;\n agent_id: string;\n label: string;\n tool: string;\n args: unknown;\n interval_seconds: number;\n next_run_at: string;\n last_run_at: string | null;\n last_fired_at: string | null;\n last_error: string | null;\n enabled: boolean;\n silent: boolean;\n // ADR-0030: optional user-supplied directive substituted for the default\n // \"summarise the diff\" instruction when the watcher fires. NULL = default.\n reaction_prompt: string | null;\n // ADR-0031: discriminator for the reaction. 'agent_prompt' (default)\n // routes to a PromptFiring (uses reaction_prompt); 'script' routes to a\n // ScriptFiring (uses reaction_script + reaction_script_args).\n reaction_kind: \"agent_prompt\" | \"script\";\n reaction_script: string | null;\n reaction_script_args: unknown | null;\n created_at: string;\n updated_at: string;\n}\n\n// Document RAG (ADR-0024). A folder on the user's machine that Jarela\n// scans on a timer; matching text files are chunked + embedded into\n// `document_chunks` and surfaced to agents via the `documents_search`\n// tool.\nexport interface DocumentSourceStats {\n source_id: string;\n document_count: number;\n chunk_count: number;\n embedded_chunk_count: number;\n}\n\n// ADR-0026 — `kind` discriminates local-folder sources from remote ones\n// (Jira/Confluence). ADR-0029 added GitHub kinds. For local sources\n// `path` is the absolute folder path; for remote sources it is a\n// synthetic key (e.g. `jira-project://ACME`, `github-pulls://owner/repo`)\n// generated by the API and treated as opaque on the client.\nexport type DocumentSourceKind =\n | \"local_folder\"\n | \"confluence_space\"\n | \"confluence_cql\"\n | \"jira_project\"\n | \"jira_jql\"\n | \"github_pulls\"\n | \"github_repo\"\n | \"gmail_mail\"\n | \"outlook_mail\";\n\nexport interface DocumentSource {\n id: string;\n path: string;\n label: string | null;\n enabled: boolean;\n last_scan_at: string | null;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n kind: DocumentSourceKind;\n config: Record<string, unknown> | null;\n stats: DocumentSourceStats;\n}\n\nexport type DocumentSourceIn =\n | { path: string; label?: string | null; kind?: \"local_folder\" }\n | {\n kind: Exclude<DocumentSourceKind, \"local_folder\">;\n label: string;\n config: Record<string, unknown>;\n };\n\nexport interface DocumentSourcePatch {\n label?: string | null;\n enabled?: boolean;\n}\n\nexport interface DocumentHit {\n document_id: string;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n chunk_index: number;\n text: string;\n score: number;\n match: \"semantic\" | \"substring\";\n}\n\nexport interface DocumentReindexResult {\n source_id: string;\n stats: {\n scanned: number;\n added: number;\n updated: number;\n removed: number;\n unchanged: number;\n errors: number;\n embed_failed?: number;\n embed_error?: string | null;\n };\n}\n\nexport interface DocumentSettings {\n embedding_model_config: string | null;\n embedding_probe?: {\n ok: boolean;\n provider: string;\n model_id: string;\n dimension?: number;\n error?: string;\n } | null;\n}\n\n\nexport interface PendingAction {\n id: string;\n agent_id: string;\n kind:\n | \"install_mcp\"\n | \"toggle_mcp\"\n | \"update_agent_tools\"\n | \"update_agent\"\n | \"start_oauth\"\n | \"set_provider_key\"\n | \"enable_integration\"\n | \"upsert_harness\";\n payload: Record<string, unknown>;\n reason: string | null;\n status: \"pending\" | \"approved\" | \"denied\" | \"failed\";\n result: unknown;\n created_at: string;\n decided_at: string | null;\n}\n\nexport interface McpRegistryEntry {\n id: string;\n name: string;\n description: string;\n category: \"Local\" | \"Web\" | \"Data\" | \"Productivity\" | \"Search\" | \"Cloud\" | \"Corporate\";\n source: \"Official\" | \"Community\" | \"Vendor\";\n url?: string;\n transport: \"stdio\" | \"http\";\n spec: Record<string, unknown>;\n variables?: McpRegistryVariable[];\n}\n\nexport interface CatalogModel {\n id: string;\n context_length: number | null;\n max_output_tokens: number | null;\n hosted_on: string | null;\n capabilities: {\n vision: boolean;\n tools: boolean;\n streaming: boolean;\n json_mode: boolean;\n web_search: boolean;\n audio: boolean;\n files: boolean;\n };\n}\n\nexport type { ContentPart, MessageContent } from \"@/lib/tools/types\";\n\nimport type {\n Harness as _Harness,\n HarnessSection as _HarnessSection,\n HarnessSectionKey as _HarnessSectionKey,\n} from \"@/lib/agents/harness/types\";\n\nexport type {\n Harness,\n HarnessSection,\n HarnessSectionKey,\n} from \"@/lib/agents/harness/types\";\nexport {\n HARNESS_SECTION_KEYS,\n DEFAULT_HARNESS_ID,\n isBuiltinHarnessId,\n SECTION_DISPLAY,\n} from \"@/lib/agents/harness/types\";\n\nexport interface HarnessListResponse {\n harnesses: _Harness[];\n default_harness_id: string;\n}\n\nexport interface HarnessIn {\n name: string;\n description?: string;\n sections?: Partial<Record<_HarnessSectionKey, Partial<_HarnessSection>>>;\n}\n\nexport interface HarnessPatch {\n name?: string;\n description?: string;\n sections?: Partial<Record<_HarnessSectionKey, Partial<_HarnessSection>>>;\n}\n\nexport type SSEEventType =\n | { type: \"text_delta\"; delta: string }\n | { type: \"thinking_delta\"; delta: string }\n | { type: \"tool_call\"; id: string; name: string; arguments: Record<string, unknown> }\n | { type: \"tool_result\"; id: string; name: string; result: unknown }\n | { type: \"done\"; message_id: string; usage: { input_tokens: number; output_tokens: number } }\n | { type: \"error\"; message: string; code: string }\n // Server is rejecting a new POST/WS message because a run is already in\n // flight for this thread (another tab, another device). The stream that\n // follows replays the in-flight run's buffered events plus live deltas;\n // the client should re-queue the user message locally and resubmit after\n // the upcoming `done` event.\n | { type: \"run_in_flight\"; thread_id: string };\n\n// ---------------------------------------------------------------------------\n// Bridges (external comm channels: WhatsApp via Baileys, …)\n// ---------------------------------------------------------------------------\n\nexport type BridgeKind = \"whatsapp\";\nexport type BridgeStatus = \"disconnected\" | \"pairing\" | \"connected\" | \"error\";\n\nexport interface Bridge {\n id: string;\n kind: BridgeKind;\n name: string;\n status: BridgeStatus;\n last_error: string | null;\n paired_id: string | null;\n enabled: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface BridgeIn {\n kind: BridgeKind;\n name: string;\n}\n\nexport interface BridgePatch {\n name?: string;\n enabled?: boolean;\n}\n\nexport interface BridgeLiveStatus {\n id: string;\n status: BridgeStatus;\n /** Data URL (image/png;base64,…) for the pairing QR, present only while `status==='pairing'`. */\n qr_data_url: string | null;\n last_error: string | null;\n paired_id: string | null;\n running: boolean;\n enabled: boolean;\n}\n\nexport interface BridgeRoute {\n id: string;\n bridge_id: string;\n remote_jid: string; // \"*\" (catch-all) or e.g. \"5511999990000@s.whatsapp.net\" / \"<group-id>@g.us\"\n agent_id: string;\n label: string | null;\n // When true, the agent still runs (records history, executes tools) on\n // every inbound message but the dispatcher suppresses the outbound reply.\n // Per-route so the same agent can be a replier in one chat and an\n // observer in another. Hardwired guard — overrides `respond_to`; the\n // adapter re-checks this inside its own send path so even tool calls\n // can't bypass it.\n silent_mode: boolean;\n // Which inbound sender role triggers an outbound reply. The agent\n // ALWAYS runs (so it sees the full conversation), but the reply only\n // goes out when the message that triggered the run matches this role.\n // - 'counterpart' (default): agent answers the user's chat partner /\n // group members but stays quiet on the user's own messages.\n // - 'user': agent only reacts to the paired user's own messages.\n // silent_mode overrides — when set, nothing goes out regardless.\n respond_to: \"user\" | \"counterpart\";\n created_at: string;\n updated_at: string;\n}\n\nexport interface BridgeRouteIn {\n remote_jid: string; // \"*\" enables fallback routing for otherwise-unmatched chats\n agent_id: string;\n label?: string | null;\n silent_mode?: boolean;\n respond_to?: \"user\" | \"counterpart\";\n}\n\nexport interface BridgeRoutePatch {\n remote_jid?: string;\n agent_id?: string;\n label?: string | null;\n silent_mode?: boolean;\n respond_to?: \"user\" | \"counterpart\";\n}\n\nexport interface BridgeChat {\n remote_jid: string;\n name: string | null;\n is_group: boolean;\n last_message_at: number | null;\n}\n\nexport interface BridgeChatsResponse {\n running: boolean;\n chats: BridgeChat[];\n}\n\n// ---------------------------------------------------------------------------\n// Proxy configuration (ADR-0009)\n// ---------------------------------------------------------------------------\n\nexport type ProxyMode = \"off\" | \"manual\" | \"system\";\nexport type ProxyScheme = \"http\" | \"https\"; // ADR-0012\n\nexport interface ProxyConfigStatus {\n mode: ProxyMode;\n scheme: ProxyScheme; // ADR-0012\n host: string | null;\n port: number | null;\n username: string | null;\n password: string | null; // SECRET_MASK (\"********\") when set, null when unset\n no_proxy: string | null;\n ca_bundle: string | null; // PEM, plaintext (ADR-0012). Public cert, not masked.\n updated_at: string | null;\n}\n\nexport interface ProxyConfigInput {\n mode: ProxyMode;\n scheme?: ProxyScheme;\n host?: string | null;\n port?: number | null;\n username?: string | null;\n password?: string | null; // omit or send SECRET_MASK to keep existing\n no_proxy?: string | null;\n ca_bundle?: string | null; // null/\"\" clears; non-empty must be PEM\n}\n\nexport interface ProxyApplyResult {\n source: \"env\" | \"manual\" | \"system\" | \"off\";\n proxyUrl: string | null; // password redacted as \"***\"\n note?: string;\n // ADR-0020: in `system` mode on macOS the dispatcher auto-extracts the\n // System + login keychain trust stores into a PEM bundle and uses it\n // as the per-request CA. Surfaced so the UI can show\n // \"System trust: 187 certs from ~/.jarela/system-ca.pem\".\n caBundlePath?: string;\n caBundleCertCount?: number;\n caBundleSource?: \"macos-keychain\";\n}\n\nexport interface ProxyConfigEnvelope {\n config: ProxyConfigStatus;\n env_override: boolean; // true when HTTPS_PROXY env var was set at boot — DB config is ignored\n applied?: ProxyApplyResult; // present on PUT/DELETE responses\n}\n\n// A host the user has approved the agent to use as them. The single\n// approval grants both browser-RPC navigation and cookie passthrough.\n// Cookie values never appear here — only `has_cookies` and the timestamps.\nexport interface AllowedSiteStatus {\n hostname: string;\n ssrf_bypass: boolean;\n has_cookies: boolean;\n created_at: string;\n last_used_at: string | null;\n cookies_updated_at: string | null;\n}\n\nexport interface TailscaleStatus {\n installed: boolean;\n logged_in: boolean;\n fqdn: string | null;\n serving: boolean;\n serve_recipe: string;\n install_script: string;\n uninstall_script: string;\n}\n\nexport interface ExtensionInfo {\n name: string;\n file: string | null;\n}\n\n// A secret slot declared by an external tool (ADR-0023). `is_set` indicates\n// whether a value is currently persisted in the encrypted store; the actual\n// secret never leaves the server.\nexport interface ToolSecretSlotInfo {\n key: string;\n label?: string;\n required?: boolean;\n description?: string;\n is_set: boolean;\n}\n\nexport interface ExternalToolInfo extends ExtensionInfo {\n description: string;\n category: string | null;\n secrets: ToolSecretSlotInfo[];\n}\n\nexport interface ExtensionLoadError {\n kind: \"provider\" | \"tool\";\n file: string;\n error: string;\n}\n\nexport interface ExtensionsListResponse {\n directories: { providers: string; tools: string };\n providers: ExtensionInfo[];\n tools: ExternalToolInfo[];\n errors: ExtensionLoadError[];\n}\n\n/**\n * Hot-loaded vanilla LangChain tool packages. Surface for the\n * Tools → LangChain packages UI panel.\n */\nexport interface LangChainPackageManifest {\n package: string;\n export: string;\n category: string;\n capability: \"read\" | \"write\" | \"execute\";\n args?: Record<string, unknown>;\n requiredEnv?: string[];\n}\n\nexport interface LangChainPackageManifestRecord {\n name: string;\n manifest: LangChainPackageManifest;\n}\n\nexport interface LangChainPackageLoadResult {\n registered: string[];\n skipped: { manifest: string; reason: string }[];\n errors: { manifest: string; error: string }[];\n}\n\nexport interface LangChainPackageListResponse extends LangChainPackageLoadResult {\n packagesDir: string;\n}\n\nexport interface LangChainPackageManifestInput {\n name: string;\n package: string;\n export?: string;\n category: string;\n capability?: \"read\" | \"write\" | \"execute\";\n args?: Record<string, unknown>;\n requiredEnv?: string[];\n}\n\nexport interface LangChainPackagePendingInstall {\n id: string;\n spec: string;\n version: string | null;\n publisher: string;\n reason: string;\n createdAt: string;\n}\n\nexport interface LangChainPackageIntrospectedTool {\n export: string;\n name: string;\n description: string;\n requiredEnv: string[];\n}\n\nexport interface LangChainPackageInstallResult {\n status: \"installed\";\n spec: string;\n publisher: string;\n resolvedPackage: string;\n installedVersion: string | null;\n tools: LangChainPackageIntrospectedTool[];\n}\n\nexport interface LangChainPackagePendingResponse {\n status: \"pending\";\n approvalId: string;\n publisher: string;\n spec: string;\n reason: string;\n}\n\nexport type LangChainPackageInstallResponse =\n | LangChainPackageInstallResult\n | LangChainPackagePendingResponse;\n\nexport interface LangChainPackageManifestCreateResult {\n record: LangChainPackageManifestRecord;\n load: LangChainPackageLoadResult;\n}\n","\"use client\";\nimport { ChevronDown, RotateCcw, X } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useEscapeKey } from \"@/hooks/useEscapeKey\";\nimport { MarkdownTextarea } from \"@/components/ui/MarkdownTextarea\";\nimport {\n DEFAULT_HARNESS_ID,\n HARNESS_SECTION_KEYS,\n SECTION_DISPLAY,\n type Harness,\n type HarnessIn,\n type HarnessPatch,\n type HarnessSection,\n type HarnessSectionKey,\n} from \"@/api/types\";\n\ninterface Props {\n /** Undefined when creating a new custom harness. */\n harness?: Harness;\n /** Built-in harnesses, used as the source for the per-section \"reset\" button. */\n builtins: Harness[];\n onSave: (input: HarnessIn | HarnessPatch, id?: string) => Promise<void>;\n onClose: () => void;\n}\n\nfunction emptySections(): Record<HarnessSectionKey, HarnessSection> {\n return Object.fromEntries(\n HARNESS_SECTION_KEYS.map((k) => [k, { enabled: true, body: \"\" }]),\n ) as Record<HarnessSectionKey, HarnessSection>;\n}\n\nexport function HarnessEditor({ harness, builtins, onSave, onClose }: Props) {\n const isEdit = !!harness;\n const [name, setName] = useState(harness?.name ?? \"\");\n const [description, setDescription] = useState(harness?.description ?? \"\");\n const [sections, setSections] = useState<Record<HarnessSectionKey, HarnessSection>>(() => {\n if (!harness) {\n // Seed a new harness from the built-in default so users see something to edit.\n const seed = builtins.find((b) => b.id === DEFAULT_HARNESS_ID) ?? builtins[0];\n if (seed) {\n return Object.fromEntries(\n HARNESS_SECTION_KEYS.map((k) => [k, { ...seed.sections[k] }]),\n ) as Record<HarnessSectionKey, HarnessSection>;\n }\n return emptySections();\n }\n return Object.fromEntries(\n HARNESS_SECTION_KEYS.map((k) => [k, { ...harness.sections[k] }]),\n ) as Record<HarnessSectionKey, HarnessSection>;\n });\n const [openSection, setOpenSection] = useState<HarnessSectionKey | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n\n const builtinDefault = useMemo(\n () => builtins.find((b) => b.id === DEFAULT_HARNESS_ID),\n [builtins],\n );\n\n useEscapeKey(onClose);\n\n function patchSection(key: HarnessSectionKey, patch: Partial<HarnessSection>) {\n setSections((prev) => ({ ...prev, [key]: { ...prev[key], ...patch } }));\n }\n\n function resetSection(key: HarnessSectionKey) {\n if (!builtinDefault) return;\n patchSection(key, { ...builtinDefault.sections[key] });\n }\n\n async function handleSave() {\n setError(null);\n if (!name.trim()) { setError(\"Name is required\"); return; }\n setSaving(true);\n try {\n const payload: HarnessIn | HarnessPatch = {\n name: name.trim(),\n description: description.trim() || undefined,\n sections,\n };\n await onSave(payload, harness?.id);\n onClose();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <div className=\"fixed inset-0 bg-black/60 flex items-start justify-center z-50 p-2 sm:p-4 overflow-y-auto\">\n <div className=\"bg-surface-2 border border-border rounded-2xl w-full max-w-2xl shadow-xl my-2 sm:my-4\">\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <h3 className=\"text-sm font-semibold text-fg\">\n {isEdit ? `Edit harness — ${harness?.name}` : \"New harness\"}\n </h3>\n <button onClick={onClose} className=\"text-fg-subtle hover:text-fg transition-colors\">\n <X size={16} />\n </button>\n </div>\n\n <div className=\"p-4 space-y-3\">\n <div className=\"grid grid-cols-1 gap-3\">\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Name</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. strict-citation\"\n maxLength={120}\n />\n </label>\n <label className=\"block\">\n <span className=\"text-xs text-fg-subtle mb-1 block\">Description</span>\n <input\n className=\"w-full bg-surface-3 text-fg text-sm rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Shown in the picker\"\n maxLength={500}\n />\n </label>\n </div>\n\n <div className=\"space-y-2\">\n <p className=\"text-xs text-fg-subtle\">Sections</p>\n {HARNESS_SECTION_KEYS.map((key) => {\n const section = sections[key];\n const display = SECTION_DISPLAY[key];\n const isOpen = openSection === key;\n return (\n <div key={key} className=\"border border-border rounded-lg bg-surface-3 overflow-hidden\">\n <div className=\"flex items-center gap-2 px-3 py-2\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={section.enabled}\n onChange={(e) => patchSection(key, { enabled: e.target.checked })}\n onClick={(e) => e.stopPropagation()}\n />\n <button\n type=\"button\"\n onClick={() => setOpenSection(isOpen ? null : key)}\n className=\"flex-1 flex items-center gap-2 text-left min-w-0\"\n >\n <ChevronDown\n size={12}\n className={`shrink-0 transition-transform ${isOpen ? \"rotate-0\" : \"-rotate-90\"}`}\n />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium text-fg truncate\">{display.title}</p>\n <p className=\"text-[11px] text-fg-faint truncate\">{display.hint}</p>\n </div>\n </button>\n {builtinDefault && (\n <button\n type=\"button\"\n onClick={() => resetSection(key)}\n title=\"Reset to built-in default\"\n className=\"p-1 text-fg-subtle hover:text-fg transition-colors shrink-0\"\n >\n <RotateCcw size={11} />\n </button>\n )}\n </div>\n {isOpen && (\n <div className=\"px-3 pb-3\">\n <MarkdownTextarea\n className=\"w-full bg-surface text-fg text-xs rounded px-2 py-1.5 border border-border focus:outline-none focus:ring-1 focus:ring-accent resize-y\"\n value={section.body}\n onChange={(body) => patchSection(key, { body })}\n rows={10}\n monospace\n placeholder=\"Section body…\"\n />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs\">{error}</p>}\n </div>\n\n <div className=\"flex justify-end gap-2 px-4 pb-4\">\n <button onClick={onClose} className=\"px-3 py-1.5 text-sm text-fg-subtle hover:text-fg transition-colors\">\n Cancel\n </button>\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"px-4 py-1.5 text-sm bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors disabled:opacity-50\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { Lock, Pencil, Plus, Star, Trash2, Wrench } from \"lucide-react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport {\n HARNESS_SECTION_KEYS,\n type Harness,\n type HarnessIn,\n type HarnessPatch,\n isBuiltinHarnessId,\n} from \"@/api/types\";\nimport { HarnessEditor } from \"./HarnessEditor\";\n\nexport function HarnessPanel() {\n const [harnesses, setHarnesses] = useState<Harness[]>([]);\n const [defaultId, setDefaultId] = useState<string>(\"builtin:default\");\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [editing, setEditing] = useState<Harness | \"new\" | null>(null);\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const res = await api.harnesses.list();\n setHarnesses(res.harnesses);\n setDefaultId(res.default_harness_id);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function handleSetDefault(id: string) {\n try {\n await api.harnesses.setDefault(id);\n setDefaultId(id);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function handleDelete(id: string) {\n if (!confirm(\"Delete this harness? Agents pointing at it will fall back to the global default.\")) return;\n try {\n await api.harnesses.delete(id);\n await load();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function handleClone(source: Harness) {\n const data: HarnessIn = {\n name: `${source.name} (copy)`,\n description: source.description,\n sections: Object.fromEntries(\n HARNESS_SECTION_KEYS.map((k) => [k, { ...source.sections[k] }]),\n ),\n };\n try {\n const created = await api.harnesses.create(data);\n await load();\n setEditing(created);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n }\n\n async function handleSave(input: HarnessIn | HarnessPatch, id?: string) {\n if (id) {\n await api.harnesses.update(id, input as HarnessPatch);\n } else {\n await api.harnesses.create(input as HarnessIn);\n }\n await load();\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"border-b border-border px-4 py-3 flex items-center gap-2\">\n <Wrench size={14} className=\"text-fg-subtle\" />\n <h2 className=\"text-sm font-semibold text-fg mr-auto\">Harnesses</h2>\n <button\n onClick={() => setEditing(\"new\")}\n className=\"flex items-center gap-1 text-xs text-accent hover:text-accent-hover transition-colors\"\n >\n <Plus size={14} /> New\n </button>\n </div>\n\n <div className=\"px-4 py-2 border-b border-border bg-surface-2/50 text-xs text-fg-muted\">\n Harnesses control the behavioral scaffolding (formatting rules, anti-fabrication, citation,\n self-config) wrapped around every agent's system prompt. Built-in presets are read-only —\n clone one to customize.\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-2\">\n {loading && harnesses.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">Loading…</p>\n )}\n {error && <p className=\"text-red-700 dark:text-red-400 text-xs mb-2 px-1\">{error}</p>}\n {!loading && harnesses.length === 0 && (\n <p className=\"text-fg-faint text-sm py-6 text-center\">No harnesses yet</p>\n )}\n {harnesses.map((h) => {\n const isBuiltin = isBuiltinHarnessId(h.id);\n const isDefault = h.id === defaultId;\n const enabledCount = HARNESS_SECTION_KEYS.filter(\n (k) => h.sections[k]?.enabled,\n ).length;\n return (\n <div\n key={h.id}\n className=\"flex items-center gap-3 py-2.5 border-b border-border/60 group\"\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-sm font-medium text-fg truncate\">{h.name}</span>\n {isBuiltin && <Lock size={10} className=\"text-fg-faint shrink-0\" />}\n {isDefault && (\n <Star\n size={11}\n className=\"text-yellow-700 dark:text-yellow-400 fill-yellow-400 shrink-0\"\n />\n )}\n <span className=\"text-[10px] text-fg-faint shrink-0\">\n {enabledCount}/{HARNESS_SECTION_KEYS.length} sections\n </span>\n </div>\n {h.description && (\n <p className=\"text-xs text-fg-subtle truncate\">{h.description}</p>\n )}\n </div>\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity shrink-0\">\n {!isDefault && (\n <button\n onClick={() => handleSetDefault(h.id)}\n className=\"p-1 text-fg-subtle hover:text-yellow-700 dark:hover:text-yellow-400 transition-colors\"\n title=\"Set as global default\"\n >\n <Star size={13} />\n </button>\n )}\n {isBuiltin ? (\n <button\n onClick={() => handleClone(h)}\n className=\"px-2 py-0.5 text-[11px] text-accent hover:text-accent-hover transition-colors\"\n title=\"Clone to edit\"\n >\n Clone\n </button>\n ) : (\n <>\n <button\n onClick={() => setEditing(h)}\n className=\"p-1 text-fg-subtle hover:text-fg transition-colors\"\n title=\"Edit\"\n >\n <Pencil size={13} />\n </button>\n <button\n onClick={() => handleDelete(h.id)}\n className=\"p-1 text-fg-subtle hover:text-red-700 dark:hover:text-red-400 transition-colors\"\n title=\"Delete\"\n >\n <Trash2 size={13} />\n </button>\n </>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {editing !== null && (\n <HarnessEditor\n harness={editing === \"new\" ? undefined : editing}\n builtins={harnesses.filter((h) => isBuiltinHarnessId(h.id))}\n onSave={handleSave}\n onClose={() => setEditing(null)}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { ChevronDown, Download, Filter, Pause, Play, Search, Trash2 } from \"lucide-react\";\n\ninterface LogEntry {\n seq: number;\n ts: number;\n level: \"log\" | \"info\" | \"warn\" | \"error\";\n text: string;\n}\n\nconst LEVEL_LABEL: Record<LogEntry[\"level\"], string> = {\n log: \"log\",\n info: \"info\",\n warn: \"warn\",\n error: \"error\",\n};\n\nconst LEVEL_BG: Record<LogEntry[\"level\"], string> = {\n log: \"bg-fg-faint/15\",\n info: \"bg-sky-500/15\",\n warn: \"bg-amber-500/20\",\n error: \"bg-rose-500/25\",\n};\n\nconst LEVEL_FG: Record<LogEntry[\"level\"], string> = {\n log: \"text-fg-faint\",\n info: \"text-sky-700 dark:text-sky-300\",\n warn: \"text-amber-700 dark:text-amber-300\",\n error: \"text-rose-700 dark:text-rose-300\",\n};\n\n// Display cap. The server ring is 2000; we keep the same on the client so\n// scrollback stays bounded across long sessions even if the server ring\n// is bigger via env override.\nconst CLIENT_RING_CAP = 2000;\n\nconst DEFAULT_LEVELS: ReadonlySet<LogEntry[\"level\"]> = new Set([\"log\", \"info\", \"warn\", \"error\"]);\n\n/**\n * Live server-log panel. Subscribes to /api/v1/logs (SSE), renders a\n * scrollback with level filters + free-text grep + autoscroll toggle +\n * export-to-clipboard.\n *\n * Reconnects via EventSource auto-retry. Passes `?since=<seq>` on\n * reconnect so the server replays only what we missed since the last\n * seen entry — no duplicates across drops.\n */\nexport function LogsPanel() {\n const [entries, setEntries] = useState<LogEntry[]>([]);\n const [paused, setPaused] = useState(false);\n const [autoscroll, setAutoscroll] = useState(true);\n const [search, setSearch] = useState(\"\");\n const [levels, setLevels] = useState<Set<LogEntry[\"level\"]>>(new Set(DEFAULT_LEVELS));\n const [connected, setConnected] = useState(false);\n const scrollRef = useRef<HTMLDivElement | null>(null);\n const lastSeqRef = useRef<number>(0);\n\n // Track lastSeq via ref so the EventSource handler doesn't re-bind on\n // every entry update. Same pattern as useSSE in the chat hook.\n useEffect(() => {\n if (entries.length > 0) lastSeqRef.current = entries[entries.length - 1].seq;\n }, [entries]);\n\n // Open the SSE feed once on mount; close on unmount. EventSource handles\n // reconnect natively — we just have to re-subscribe to events on each\n // reconnect (the stream is server-driven), and pass `?since=` on the\n // initial open so the backlog reflects what we've already seen.\n useEffect(() => {\n if (paused) return;\n const since = lastSeqRef.current;\n const url = `/api/v1/logs${since > 0 ? `?since=${since}` : \"\"}`;\n const es = new EventSource(url);\n let alive = true;\n\n es.onopen = () => { if (alive) setConnected(true); };\n es.onerror = () => { if (alive) setConnected(false); /* EventSource auto-retries */ };\n es.onmessage = (ev) => {\n let parsed: LogEntry | null = null;\n try { parsed = JSON.parse(ev.data) as LogEntry; } catch { return; }\n if (!parsed || typeof parsed.seq !== \"number\") return;\n setEntries((prev) => {\n // Drop dupes (same seq could arrive on reconnect if the server\n // replayed it before we updated lastSeq).\n if (prev.length > 0 && prev[prev.length - 1].seq >= parsed.seq) return prev;\n const next = prev.length >= CLIENT_RING_CAP ? prev.slice(prev.length - CLIENT_RING_CAP + 1) : prev;\n return [...next, parsed];\n });\n };\n\n return () => {\n alive = false;\n es.close();\n setConnected(false);\n };\n }, [paused]);\n\n // Autoscroll only when the user hasn't manually scrolled away from the\n // bottom. We piggy-back on the autoscroll toggle — when it's on, every\n // new entry pins the scroll to the bottom; when off, the user can read\n // arbitrary backlog without being yanked down.\n useEffect(() => {\n if (!autoscroll) return;\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [entries, autoscroll]);\n\n // Pre-filter once per render.\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n return entries.filter((e) => {\n if (!levels.has(e.level)) return false;\n if (q && !e.text.toLowerCase().includes(q)) return false;\n return true;\n });\n }, [entries, search, levels]);\n\n function toggleLevel(level: LogEntry[\"level\"]): void {\n setLevels((prev) => {\n const next = new Set(prev);\n if (next.has(level)) next.delete(level);\n else next.add(level);\n // Don't allow zero levels — that would render an empty panel and\n // confuse \"is the feed broken or did I filter everything out?\"\n if (next.size === 0) return prev;\n return next;\n });\n }\n\n function copyAll(): void {\n if (typeof navigator === \"undefined\" || !navigator.clipboard) return;\n const text = filtered\n .map((e) => `[${new Date(e.ts).toISOString()}] ${e.level.toUpperCase()} ${e.text}`)\n .join(\"\\n\");\n void navigator.clipboard.writeText(text).catch(() => {});\n }\n\n function clearLocal(): void {\n setEntries([]);\n lastSeqRef.current = 0;\n }\n\n return (\n <div className=\"flex flex-col h-full min-h-0 p-4\">\n <div className=\"mb-2 flex items-center gap-2 flex-wrap\">\n <h2 className=\"text-sm font-medium text-fg\">Server logs</h2>\n <span\n className={`text-[10px] uppercase tracking-wider ${connected ? \"text-emerald-600 dark:text-emerald-400\" : \"text-fg-faint\"}`}\n title={connected ? \"Streaming live from /api/v1/logs\" : \"Disconnected — EventSource will auto-reconnect\"}\n >\n {connected ? \"● live\" : paused ? \"⏸ paused\" : \"○ connecting…\"}\n </span>\n <span className=\"text-[10px] text-fg-faint\">\n {filtered.length} / {entries.length} entries\n </span>\n <div className=\"flex-1\" />\n <div className=\"flex items-center gap-1.5\">\n {(Object.keys(LEVEL_LABEL) as LogEntry[\"level\"][]).map((level) => (\n <button\n key={level}\n type=\"button\"\n onClick={() => toggleLevel(level)}\n className={`px-2 py-0.5 rounded text-[11px] uppercase tracking-wider border ${\n levels.has(level)\n ? `${LEVEL_BG[level]} ${LEVEL_FG[level]} border-transparent`\n : \"border-border text-fg-faint hover:bg-surface-2\"\n }`}\n title={`Toggle ${level} entries`}\n >\n {LEVEL_LABEL[level]}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-1 text-[11px]\">\n <Filter size={12} className=\"text-fg-faint\" aria-hidden />\n <input\n type=\"text\"\n placeholder=\"grep…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"px-2 py-0.5 rounded border border-border bg-surface text-fg w-32 text-[11px]\"\n />\n </div>\n <button\n type=\"button\"\n onClick={() => setAutoscroll((v) => !v)}\n className={`p-1 rounded border border-border ${autoscroll ? \"bg-accent/20 text-accent\" : \"text-fg-faint\"}`}\n title={autoscroll ? \"Autoscroll on — new entries pin to bottom\" : \"Autoscroll off — scroll manually\"}\n >\n <ChevronDown size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => setPaused((v) => !v)}\n className=\"p-1 rounded border border-border text-fg-faint hover:bg-surface-2\"\n title={paused ? \"Resume streaming\" : \"Pause streaming\"}\n >\n {paused ? <Play size={14} /> : <Pause size={14} />}\n </button>\n <button\n type=\"button\"\n onClick={copyAll}\n className=\"p-1 rounded border border-border text-fg-faint hover:bg-surface-2\"\n title=\"Copy filtered entries to clipboard\"\n >\n <Download size={14} />\n </button>\n <button\n type=\"button\"\n onClick={clearLocal}\n className=\"p-1 rounded border border-border text-fg-faint hover:bg-surface-2\"\n title=\"Clear locally (server ring keeps the entries)\"\n >\n <Trash2 size={14} />\n </button>\n </div>\n\n <div\n ref={scrollRef}\n className=\"panel-scrollbar flex-1 min-h-0 overflow-y-auto rounded-md border border-border bg-surface font-mono text-[11px]\"\n >\n {filtered.length === 0 ? (\n <div className=\"p-4 text-center text-fg-faint flex flex-col items-center gap-2\">\n <Search size={20} aria-hidden />\n <div>{entries.length === 0 ? \"Waiting for log entries…\" : \"No entries match the current filter.\"}</div>\n </div>\n ) : (\n <ul className=\"divide-y divide-border/40\">\n {filtered.map((e) => (\n <li\n key={e.seq}\n className={`px-2 py-1 flex gap-2 items-start hover:bg-surface-2/40 ${LEVEL_FG[e.level]}`}\n >\n <span className=\"shrink-0 text-fg-faint w-[8.5em] tabular-nums\">\n {new Date(e.ts).toISOString().replace(\"T\", \" \").slice(11, 23)}\n </span>\n <span className={`shrink-0 px-1.5 rounded text-[10px] uppercase tracking-wider ${LEVEL_BG[e.level]}`}>\n {LEVEL_LABEL[e.level]}\n </span>\n <span className=\"flex-1 whitespace-pre-wrap break-all\">{e.text}</span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Edit3, RotateCcw, Save, ServerCog, Search, X } from \"lucide-react\";\nimport { refreshRuntimeConfig } from \"@/api/runtime-config\";\n\ninterface EnvRow {\n name: string;\n type: \"int\" | \"string\" | \"bool\" | \"enum\";\n default: number | string | boolean;\n current: string;\n overridden: boolean;\n description: string;\n category: string;\n tier: \"A\" | \"B\" | \"C\";\n requiresRestart: boolean;\n agentWritable: boolean;\n enumValues?: readonly string[];\n min?: number;\n max?: number;\n}\n\nconst CATEGORY_LABEL: Record<string, string> = {\n agent: \"Agent\",\n tools: \"Tools\",\n lifecycle: \"Lifecycle\",\n limits: \"Limits\",\n logging: \"Logging\",\n scheduler: \"Scheduler\",\n documents: \"Documents\",\n ui: \"UI\",\n};\n\nconst CATEGORY_ORDER = [\n \"agent\",\n \"tools\",\n \"lifecycle\",\n \"logging\",\n \"limits\",\n \"scheduler\",\n \"documents\",\n \"ui\",\n];\n\n/**\n * Edit-runtime-overrides panel. Lists every JARELA_* var the schema knows\n * about, lets the user override any of them (persisted to\n * ~/.jarela/env-overrides.json), and surfaces a Restart button when the\n * pending changes flag a requiresRestart=true row.\n */\nexport function EnvVarsPanel() {\n const [rows, setRows] = useState<EnvRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [search, setSearch] = useState(\"\");\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [editing, setEditing] = useState<{ name: string; value: string } | null>(null);\n const [saving, setSaving] = useState(false);\n const [restartNeeded, setRestartNeeded] = useState(false);\n const [restarting, setRestarting] = useState(false);\n const editInputRef = useRef<HTMLInputElement | HTMLSelectElement | null>(null);\n\n const load = useCallback(async () => {\n try {\n const r = await fetch(\"/api/v1/env\", { cache: \"no-store\" });\n if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);\n const body = (await r.json()) as { entries: EnvRow[] };\n // Network vars are surfaced in the Profile page's NetworkPanel\n // so they don't appear in both places. Drop them here.\n setRows(body.entries.filter((row) => row.category !== \"network\"));\n setError(null);\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n // Focus the edit input when it appears.\n useEffect(() => {\n if (editing) editInputRef.current?.focus();\n }, [editing]);\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n return rows.filter((row) => {\n if (!showAdvanced && row.tier === \"C\") return false;\n if (!showAdvanced && row.tier === \"B\") return q.length > 0; // hide B unless searching or advanced on\n if (q && !row.name.toLowerCase().includes(q) && !row.description.toLowerCase().includes(q)) {\n return false;\n }\n return true;\n });\n }, [rows, search, showAdvanced]);\n\n const grouped = useMemo(() => {\n const m = new Map<string, EnvRow[]>();\n for (const cat of CATEGORY_ORDER) m.set(cat, []);\n for (const row of filtered) {\n if (!m.has(row.category)) m.set(row.category, []);\n m.get(row.category)!.push(row);\n }\n return Array.from(m.entries()).filter(([, list]) => list.length > 0);\n }, [filtered]);\n\n const startEdit = useCallback((row: EnvRow) => {\n setEditing({ name: row.name, value: row.current });\n }, []);\n\n const cancelEdit = useCallback(() => setEditing(null), []);\n\n const persist = useCallback(async (name: string, value: string | null, requiresRestart: boolean) => {\n setSaving(true);\n try {\n const r = await fetch(\"/api/v1/env\", {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name, value }),\n });\n if (!r.ok) {\n const body = (await r.json().catch(() => ({}))) as { error?: string };\n throw new Error(body.error ?? `${r.status} ${r.statusText}`);\n }\n if (requiresRestart) setRestartNeeded(true);\n // Re-fetch the public runtime-config snapshot so api/client.ts and\n // any other browser-side reader picks up the new HTTP / SSE / health\n // timeouts on the next call.\n refreshRuntimeConfig();\n await load();\n setEditing(null);\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setSaving(false);\n }\n }, [load]);\n\n const onSave = useCallback(() => {\n if (!editing) return;\n const row = rows.find((r) => r.name === editing.name);\n if (!row) return;\n void persist(editing.name, editing.value, row.requiresRestart);\n }, [editing, rows, persist]);\n\n const onReset = useCallback((row: EnvRow) => {\n void persist(row.name, null, row.requiresRestart);\n }, [persist]);\n\n const onRestart = useCallback(async () => {\n if (!confirm(\"Restart the server? In-flight runs will be aborted; the supervisor (launchd / systemd / Task Scheduler) will relaunch the process.\")) {\n return;\n }\n setRestarting(true);\n try {\n await fetch(\"/api/v1/system/restart\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ reason: \"user clicked Restart in EnvVarsPanel\" }),\n });\n // The server will exit ~250ms after returning. Show a banner and\n // poll /health until it comes back.\n pollUntilUp().then(() => {\n setRestarting(false);\n setRestartNeeded(false);\n void load();\n }).catch(() => {\n setRestarting(false);\n setError(\"Server didn't come back within 30s — check it manually.\");\n });\n } catch (e) {\n setRestarting(false);\n setError((e as Error).message);\n }\n }, [load]);\n\n return (\n <div className=\"flex flex-col h-full min-h-0 p-4 gap-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h2 className=\"text-sm font-medium text-fg\">Defaults</h2>\n <span className=\"text-[10px] text-fg-faint\">{rows.length} vars</span>\n <div className=\"flex-1\" />\n <label className=\"inline-flex items-center gap-1 text-[11px] text-fg-faint cursor-pointer\">\n <input\n type=\"checkbox\"\n className=\"rounded border-border\"\n checked={showAdvanced}\n onChange={(e) => setShowAdvanced(e.target.checked)}\n />\n Show advanced (B/C tier)\n </label>\n <div className=\"flex items-center gap-1 text-[11px]\">\n <Search size={12} className=\"text-fg-faint\" aria-hidden />\n <input\n type=\"text\"\n placeholder=\"filter…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"px-2 py-0.5 rounded border border-border bg-surface text-fg w-32 text-[11px]\"\n />\n </div>\n </div>\n\n {restartNeeded && (\n <div className=\"px-3 py-2 rounded border border-amber-700/50 bg-amber-900/20 text-amber-700 dark:text-amber-300 text-xs flex items-center gap-2\">\n <ServerCog size={14} aria-hidden />\n <span className=\"flex-1\">A change you made requires a server restart to take effect.</span>\n <button\n type=\"button\"\n disabled={restarting}\n onClick={onRestart}\n className=\"px-2 py-0.5 rounded bg-amber-600/80 text-white hover:bg-amber-600 disabled:opacity-50 text-[11px]\"\n >\n {restarting ? \"Restarting…\" : \"Restart server\"}\n </button>\n </div>\n )}\n\n {error && (\n <div className=\"px-3 py-2 rounded border border-rose-700/60 bg-rose-900/30 text-rose-700 dark:text-rose-300 text-xs flex items-center gap-2\">\n <span className=\"flex-1\">{error}</span>\n <button onClick={() => setError(null)} className=\"px-1\" aria-label=\"dismiss\">\n <X size={12} />\n </button>\n </div>\n )}\n\n <div className=\"panel-scrollbar flex-1 min-h-0 overflow-y-auto rounded-md border border-border bg-surface\">\n {loading ? (\n <div className=\"p-4 text-fg-faint text-xs\">Loading…</div>\n ) : grouped.length === 0 ? (\n <div className=\"p-4 text-fg-faint text-xs text-center\">No vars match the current filter.</div>\n ) : (\n grouped.map(([category, list]) => (\n <div key={category} className=\"border-b border-border/40 last:border-b-0\">\n <div className=\"sticky top-0 z-10 bg-surface-2/80 backdrop-blur px-3 py-1 text-[10px] uppercase tracking-wider text-fg-faint border-b border-border/40\">\n {CATEGORY_LABEL[category] ?? category}\n </div>\n <ul className=\"divide-y divide-border/30\">\n {list.map((row) => (\n <li key={row.name} className=\"px-3 py-2 hover:bg-surface-2/40\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n <code className=\"text-[12px] font-mono text-fg\">{row.name}</code>\n {row.overridden && (\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-emerald-500/20 text-emerald-700 dark:text-emerald-300\">\n overridden\n </span>\n )}\n {row.requiresRestart && (\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-amber-500/20 text-amber-700 dark:text-amber-300\">\n restart\n </span>\n )}\n {row.agentWritable && (\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-sky-500/20 text-sky-700 dark:text-sky-300\">\n agent-writable\n </span>\n )}\n <span className=\"px-1.5 rounded text-[9px] uppercase tracking-wider bg-fg-faint/15 text-fg-faint\">\n tier {row.tier}\n </span>\n </div>\n <div className=\"mt-0.5 text-[11px] text-fg-muted\">{row.description}</div>\n {editing?.name === row.name ? (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n {row.type === \"enum\" && row.enumValues ? (\n <select\n ref={(el) => { editInputRef.current = el; }}\n value={editing.value}\n onChange={(e) => setEditing({ name: row.name, value: e.target.value })}\n className=\"px-2 py-1 rounded border border-border bg-surface text-fg text-[11px] font-mono\"\n >\n {row.enumValues.map((v) => <option key={v} value={v}>{v}</option>)}\n </select>\n ) : row.type === \"bool\" ? (\n <select\n ref={(el) => { editInputRef.current = el; }}\n value={editing.value}\n onChange={(e) => setEditing({ name: row.name, value: e.target.value })}\n className=\"px-2 py-1 rounded border border-border bg-surface text-fg text-[11px] font-mono\"\n >\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : (\n <input\n ref={(el) => { editInputRef.current = el; }}\n type={row.type === \"int\" ? \"number\" : \"text\"}\n value={editing.value}\n onChange={(e) => setEditing({ name: row.name, value: e.target.value })}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onSave();\n if (e.key === \"Escape\") cancelEdit();\n }}\n min={row.min}\n max={row.max}\n className=\"px-2 py-1 rounded border border-border bg-surface text-fg text-[11px] font-mono w-48\"\n />\n )}\n <button\n type=\"button\"\n onClick={onSave}\n disabled={saving}\n className=\"px-2 py-1 rounded bg-accent text-white hover:bg-accent/90 disabled:opacity-50 text-[11px] inline-flex items-center gap-1\"\n >\n <Save size={11} /> Save\n </button>\n <button\n type=\"button\"\n onClick={cancelEdit}\n className=\"px-2 py-1 rounded border border-border text-fg-faint hover:bg-surface-2 text-[11px]\"\n >\n Cancel\n </button>\n </div>\n ) : (\n <div className=\"mt-0.5 flex items-center gap-2 flex-wrap\">\n <code className=\"text-[11px] font-mono text-fg-muted\">\n {row.current}\n </code>\n {row.overridden && (\n <span className=\"text-[10px] text-fg-faint\">\n (default: <code className=\"font-mono\">{String(row.default)}</code>)\n </span>\n )}\n </div>\n )}\n </div>\n {editing?.name !== row.name && (\n <div className=\"flex items-center gap-1 shrink-0\">\n <button\n type=\"button\"\n onClick={() => startEdit(row)}\n className=\"p-1.5 rounded border border-border text-fg-faint hover:bg-surface-2 hover:text-fg\"\n title=\"Edit\"\n >\n <Edit3 size={12} />\n </button>\n <button\n type=\"button\"\n onClick={() => onReset(row)}\n disabled={!row.overridden}\n className=\"p-1.5 rounded border border-border text-fg-faint hover:bg-surface-2 hover:text-fg disabled:opacity-30 disabled:hover:bg-transparent\"\n title={row.overridden ? \"Reset to default\" : \"No override to reset\"}\n >\n <RotateCcw size={12} />\n </button>\n </div>\n )}\n </div>\n </li>\n ))}\n </ul>\n </div>\n ))\n )}\n </div>\n </div>\n );\n}\n\nasync function pollUntilUp(timeoutMs = 30_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let delay = 500;\n while (Date.now() < deadline) {\n await new Promise<void>((r) => setTimeout(r, delay));\n delay = Math.min(2000, Math.floor(delay * 1.4));\n try {\n const r = await fetch(\"/api/v1/health\", { cache: \"no-store\" });\n if (r.ok) return;\n } catch { /* still down */ }\n }\n throw new Error(\"server did not return\");\n}\n","\"use client\";\nimport { useActivityLabel } from \"@/lib/ui/loading\";\n\n// Inline \"what is happening right now\" text rendered next to the agent\n// dropdown. Replaces the old TopProgressBar: a single short label that\n// updates live as the run progresses (Sending… / Thinking… / Using <tool>…).\n// Returns null when nothing is in flight so the header stays calm.\nexport function HeaderActivity() {\n const label = useActivityLabel();\n if (!label) return null;\n return (\n <span\n role=\"status\"\n aria-live=\"polite\"\n className=\"ml-1 inline-flex items-center gap-1.5 text-xs text-fg-faint truncate max-w-[14rem]\"\n >\n <span className=\"relative inline-flex h-1.5 w-1.5 shrink-0\">\n <span className=\"absolute inset-0 rounded-full bg-accent/70 animate-ping\" />\n <span className=\"relative inline-flex h-1.5 w-1.5 rounded-full bg-accent\" />\n </span>\n <span className=\"truncate\">{label}</span>\n </span>\n );\n}\n","\"use client\";\nimport { Bell, BellOff, BellRing, X } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { pushToast } from \"@/lib/ui/toasts\";\n\n// Browsers (Chrome, Safari) require a user gesture for Notification.requestPermission().\n// Calling it from an SSE event handler — like we did originally — silently fails on\n// many setups. This banner gives the user a single click to grant permission, with a\n// \"test\" action so they can verify the wiring works end-to-end.\n\ntype Status = \"unsupported\" | \"default\" | \"granted\" | \"denied\";\n\nfunction readStatus(): Status {\n if (typeof Notification === \"undefined\") return \"unsupported\";\n return Notification.permission as Status;\n}\n\nconst DISMISS_KEY = \"jarela:notif-banner-dismissed\";\n\nexport function NotificationStatus() {\n const [status, setStatus] = useState<Status>(\"default\");\n const [dismissed, setDismissed] = useState(true);\n const [testFired, setTestFired] = useState(false);\n\n useEffect(() => {\n setStatus(readStatus());\n setDismissed(typeof localStorage !== \"undefined\" && localStorage.getItem(DISMISS_KEY) === \"1\");\n\n // Re-check on focus — the user may have toggled it in browser settings.\n const onFocus = () => setStatus(readStatus());\n window.addEventListener(\"focus\", onFocus);\n return () => window.removeEventListener(\"focus\", onFocus);\n }, []);\n\n async function enable() {\n if (typeof Notification === \"undefined\") return;\n try {\n const result = await Notification.requestPermission();\n setStatus(result as Status);\n if (result === \"granted\") {\n // Fire a confirmation so the user sees notifications actually work,\n // and so the OS notification center is \"primed\" — some macOS setups\n // hide the very first notification until the system center registers\n // the source.\n new Notification(\"Jarela notifications enabled\", {\n body: \"You'll see a ping when an agent finishes a turn while you're away.\",\n icon: \"/icon-192.png\",\n tag: \"jarela-enable\",\n });\n }\n } catch (err) {\n console.warn(\"[notifications] permission request failed:\", err);\n }\n }\n\n function testFire() {\n if (typeof Notification === \"undefined\" || Notification.permission !== \"granted\") return;\n new Notification(\"Jarela test\", {\n body: \"If you see this, notifications are wired correctly.\",\n icon: \"/icon-192.png\",\n tag: \"jarela-test\",\n });\n setTestFired(true);\n setTimeout(() => setTestFired(false), 2000);\n }\n\n function dismiss() {\n setDismissed(true);\n localStorage.setItem(DISMISS_KEY, \"1\");\n }\n\n // Hide the banner when granted (just show a tiny test affordance) or when user dismissed.\n if (status === \"unsupported\") return null;\n if (status === \"granted\") {\n // Persistent tiny \"test\" link in the corner so the user can confirm anytime.\n return null; // suppress entirely once granted; access via the gear settings if needed\n }\n if (dismissed) return null;\n\n return (\n <div className=\"absolute top-9 left-0 right-0 z-30 mx-auto max-w-2xl px-4 mt-2 pointer-events-none\">\n <div className=\"pointer-events-auto rounded-lg border border-amber-700/60 bg-amber-950/40 backdrop-blur px-3 py-2 flex items-center gap-2 shadow-lg\">\n {status === \"denied\"\n ? <BellOff size={14} className=\"text-rose-700 dark:text-rose-400 shrink-0\" />\n : <Bell size={14} className=\"text-amber-700 dark:text-amber-400 shrink-0\" />}\n <p className=\"text-xs text-fg mr-auto\">\n {status === \"denied\"\n ? \"OS notifications are blocked. In-app pop-ups still work; for system-level alerts when Jarela isn't focused, allow Notifications via the lock icon in the URL bar.\"\n : \"Enable OS notifications to also get pinged when Jarela isn't focused (in-app pop-ups already work).\"}\n </p>\n {status === \"default\" && (\n <button\n onClick={enable}\n className=\"inline-flex items-center gap-1 px-2.5 py-1 text-xs rounded bg-amber-600 hover:bg-amber-500 text-white\"\n >\n <BellRing size={11} /> Enable\n </button>\n )}\n {testFired && (\n <span className=\"text-[10px] text-emerald-700 dark:text-emerald-400\">test sent</span>\n )}\n <button onClick={dismiss} className=\"p-1 text-fg-subtle hover:text-fg\" title=\"Dismiss\">\n <X size={12} />\n </button>\n </div>\n </div>\n );\n}\n\n// Test affordance — always visible, regardless of permission state.\n// Fires both layers so the user can verify each independently:\n// - In-app toast: always works (no permission needed)\n// - OS Web Notification: only fires if permission is granted\nexport function NotificationTestButton() {\n const [status, setStatus] = useState<Status>(\"default\");\n useEffect(() => { setStatus(readStatus()); }, []);\n\n function fire() {\n // 1. In-app toast — should appear bottom-right immediately.\n pushToast({\n kind: \"info\",\n source: \"system\",\n sourceLabel: \"Test\",\n title: \"Test notification\",\n body: \"If you see this card slide in, in-app pop-ups are working.\",\n agent_id: null,\n thread_id: null,\n ttl: 6000,\n });\n // 2. OS Web Notification — only works if permission granted.\n if (typeof Notification !== \"undefined\" && Notification.permission === \"granted\") {\n try {\n new Notification(\"Jarela test\", {\n body: \"If you see this, OS notifications are wired correctly.\",\n icon: \"/icon-192.png\",\n tag: \"jarela-test\",\n });\n } catch { /* OS rejected, ignore */ }\n }\n }\n\n return (\n <button\n onClick={fire}\n title={status === \"granted\"\n ? \"Fires both an in-app toast and an OS notification\"\n : \"Fires an in-app toast (OS notifications require permission)\"}\n className=\"inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded border border-border text-fg-subtle hover:text-fg hover:bg-surface-3\"\n >\n <Bell size={11} /> Test notification\n </button>\n );\n}\n","\"use client\";\n\n// Persistent warning surfaced when the at-rest encryption master key\n// could not be stored in the host OS keychain and fell back to a\n// 0600-permissioned keyfile next to the database (ADR-0005). The user\n// should know their secrets are no better protected than the DB file\n// itself in this mode.\n\nimport { useEffect, useState } from \"react\";\nimport { ShieldAlert, X } from \"lucide-react\";\n\nconst DISMISS_KEY = \"jarela:crypto-fallback-banner-dismissed\";\n\nexport function CryptoFallbackBanner() {\n const [show, setShow] = useState(false);\n const [dismissed, setDismissed] = useState(true);\n\n useEffect(() => {\n setDismissed(typeof localStorage !== \"undefined\" && localStorage.getItem(DISMISS_KEY) === \"1\");\n let cancelled = false;\n fetch(\"/api/v1/health\")\n .then((r) => r.json())\n .then((j) => {\n if (cancelled) return;\n if (j?.crypto?.source === \"keyfile\") setShow(true);\n })\n .catch(() => { /* health endpoint flakiness shouldn't block UI */ });\n return () => { cancelled = true; };\n }, []);\n\n if (!show || dismissed) return null;\n\n return (\n <div className=\"fixed left-0 right-0 z-30 px-3 pt-2 pointer-events-none\" style={{ top: \"calc(3rem + var(--app-safe-top))\" }}>\n <div className=\"mx-auto max-w-4xl pointer-events-auto flex items-start gap-2 rounded-lg border border-amber-300 bg-amber-50/95 px-3 py-2 text-xs text-amber-950 shadow-sm backdrop-blur dark:border-amber-700/50 dark:bg-amber-950/85 dark:text-amber-100\">\n <ShieldAlert size={14} className=\"mt-0.5 shrink-0\" />\n <div className=\"flex-1\">\n <span className=\"font-medium\">At-rest encryption is using the keyfile fallback.</span>{\" \"}\n The master key lives next to the database because the OS keychain\n was unavailable. Protect the data directory like you would the\n secrets it contains.{\" \"}\n <a\n href=\"https://github.com/Pcordeironeto/langGUI/blob/main/docs/adr/0005-encrypt-secrets-at-rest.md\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium underline underline-offset-2\"\n >\n Why?\n </a>\n </div>\n <button\n type=\"button\"\n onClick={() => {\n localStorage.setItem(DISMISS_KEY, \"1\");\n setDismissed(true);\n }}\n className=\"shrink-0 rounded p-0.5 hover:bg-amber-200/70 dark:hover:bg-amber-800/40\"\n aria-label=\"Dismiss warning\"\n >\n <X size={14} />\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\n// Surfaces a dismissible banner when the running version is behind the latest\n// published to npm. Backed by /api/v1/update.\n\nimport { useEffect, useState } from \"react\";\nimport { Download, X } from \"lucide-react\";\n\ntype UpdateInfo = {\n channel?: \"stable\" | \"main\";\n current: string;\n latest: string | null;\n behind: boolean;\n latestCommit?: { sha: string; date: string | null };\n currentCommit?: string;\n};\n\nconst DISMISS_KEY = \"jarela:update-banner-dismissed-for\";\n\nexport function UpdateAvailableBanner() {\n const [info, setInfo] = useState<UpdateInfo | null>(null);\n const [dismissed, setDismissed] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n fetch(\"/api/v1/update\")\n .then((r) => r.json())\n .then((j: UpdateInfo) => {\n if (cancelled) return;\n if (!j?.behind || !j.latest) return;\n const dismissKey = j.channel === \"main\" && j.latestCommit?.sha\n ? `${j.latest}@${j.latestCommit.sha}`\n : j.latest;\n const dismissedFor =\n typeof localStorage !== \"undefined\" ? localStorage.getItem(DISMISS_KEY) : null;\n // Dismissals are scoped to the version/commit that was offered: once\n // a newer one ships, the banner reappears.\n if (dismissedFor === dismissKey) {\n setDismissed(true);\n }\n setInfo(j);\n })\n .catch(() => { /* update check is best-effort */ });\n return () => { cancelled = true; };\n }, []);\n\n if (!info || !info.behind || !info.latest || dismissed) return null;\n\n const isMain = info.channel === \"main\";\n const shortRemote = info.latestCommit?.sha?.slice(0, 7);\n const shortLocal = info.currentCommit?.slice(0, 7);\n const upgradeCmd = isMain\n ? \"jarela update\"\n : \"jarela update\";\n const altCmd = isMain\n ? \"npm i -g github:CircuitWall/jarela#main\"\n : \"npm i -g @circuitwall/jarela@latest\";\n\n return (\n <div\n className=\"fixed left-0 right-0 z-30 px-3 pt-2 pointer-events-none\"\n style={{ top: \"calc(3rem + var(--app-safe-top))\" }}\n >\n <div className=\"mx-auto max-w-4xl pointer-events-auto flex items-start gap-2 border border-emerald-900/40 rounded-lg bg-emerald-950/60 backdrop-blur px-3 py-2 text-xs text-emerald-800 dark:text-emerald-200\">\n <Download size={14} className=\"mt-0.5 shrink-0\" />\n <div className=\"flex-1\">\n <span className=\"font-medium\">\n {isMain ? \"Experimental update available:\" : \"Update available:\"}\n </span>{\" \"}\n {isMain && shortRemote\n ? <>{shortLocal ?? info.current} → {shortRemote} ({info.latest}).</>\n : <>{info.current} → {info.latest}.</>}\n {\" \"}\n Run <code className=\"font-mono text-[11px]\">{upgradeCmd}</code>{\" \"}\n (or <code className=\"font-mono text-[11px]\">{altCmd}</code>) and restart.\n </div>\n <button\n type=\"button\"\n onClick={() => {\n const key = isMain && info.latestCommit?.sha\n ? `${info.latest}@${info.latestCommit.sha}`\n : info.latest;\n if (key) localStorage.setItem(DISMISS_KEY, key);\n setDismissed(true);\n }}\n className=\"shrink-0 rounded p-0.5 hover:bg-emerald-900/40\"\n aria-label=\"Dismiss update notice\"\n >\n <X size={14} />\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\n// Health-check overlay. Polls /api/v1/health on a slow cadence while the\n// server is reachable; on repeated failures, flips into a fast retry loop\n// behind a blocking banner. When the server comes back, reloads the page so\n// any in-flight UI state (caches, EventSource subscriptions, agent list)\n// gets a clean restart instead of trying to splice partial state back\n// together.\n//\n// A single failed ping is NOT enough to show the overlay: long agent turns\n// can briefly stall the Node event loop / SQLite reader past the fetch\n// timeout. We require FAILURE_THRESHOLD consecutive failures before\n// surfacing \"Server unavailable\" — otherwise normal long tool calls would\n// flash the offline banner and force a page reload mid-turn.\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { CloudOff, Loader2 } from \"lucide-react\";\nimport { runtimeConfig } from \"@/api/runtime-config\";\n\nconst HEALTHY_INTERVAL_MS = 20_000;\nconst DOWN_INTERVAL_MS = 2_000;\nconst RETRY_INTERVAL_MS = 3_000;\nconst FAILURE_THRESHOLD = 3;\n\nasync function ping(): Promise<boolean> {\n const ctrl = new AbortController();\n const t = setTimeout(() => ctrl.abort(), runtimeConfig().healthCheckTimeoutMs);\n try {\n const res = await fetch(\"/api/v1/health\", { cache: \"no-store\", signal: ctrl.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(t);\n }\n}\n\nexport function ServerStatus() {\n const [down, setDown] = useState(false);\n const wasDownRef = useRef(false);\n const failureCountRef = useRef(0);\n\n useEffect(() => {\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const tick = async () => {\n const ok = await ping();\n if (cancelled) return;\n if (!ok) {\n failureCountRef.current += 1;\n if (failureCountRef.current >= FAILURE_THRESHOLD) {\n wasDownRef.current = true;\n setDown(true);\n timer = setTimeout(tick, DOWN_INTERVAL_MS);\n } else {\n // Sub-threshold blip (likely a long agent turn briefly stalling\n // the event loop). Retry soon without surfacing the overlay.\n timer = setTimeout(tick, RETRY_INTERVAL_MS);\n }\n return;\n }\n failureCountRef.current = 0;\n if (wasDownRef.current) {\n // Server recovered after the overlay actually showed — full reload\n // to drop any stale in-memory state (EventSource queues, agent\n // cache, MCP clients) and re-bootstrap.\n window.location.reload();\n return;\n }\n setDown(false);\n timer = setTimeout(tick, HEALTHY_INTERVAL_MS);\n };\n\n tick();\n\n const onVisible = () => {\n if (document.visibilityState === \"visible\") {\n if (timer) clearTimeout(timer);\n tick();\n }\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n\n return () => {\n cancelled = true;\n if (timer) clearTimeout(timer);\n document.removeEventListener(\"visibilitychange\", onVisible);\n };\n }, []);\n\n if (!down) return null;\n\n return (\n <div className=\"fixed inset-0 z-[100] flex items-center justify-center bg-black/50 backdrop-blur-sm\">\n <div className=\"mx-4 max-w-sm w-full flex flex-col items-center gap-3 rounded-xl border border-border bg-surface text-fg px-6 py-5 text-center shadow-lg\">\n <CloudOff size={28} className=\"text-amber-500\" />\n <div className=\"text-sm font-medium\">Server unavailable</div>\n <div className=\"text-xs text-fg-muted\">\n Lost connection to Jarela. Retrying…\n </div>\n <div className=\"flex items-center gap-2 text-xs text-fg-subtle\">\n <Loader2 size={14} className=\"animate-spin\" />\n <span>Reconnecting</span>\n </div>\n <button\n type=\"button\"\n onClick={() => window.location.reload()}\n className=\"mt-1 text-xs underline text-fg-subtle hover:text-fg\"\n >\n Reload now\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { AlertCircle, Bot, ChevronDown, ChevronRight, Copy, ExternalLink, X } from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { dismissToast, type Toast, useToasts } from \"@/lib/ui/toasts\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { parseHref } from \"@/lib/ui/navigate\";\nimport { buildReport } from \"@/lib/ui/error-report\";\n\nconst GRADIENTS = [\n \"from-violet-500 to-indigo-600\",\n \"from-blue-500 to-cyan-600\",\n \"from-emerald-500 to-teal-600\",\n \"from-orange-500 to-amber-600\",\n \"from-rose-500 to-pink-600\",\n \"from-fuchsia-500 to-purple-600\",\n];\nfunction gradientFor(id: string): string {\n let h = 0;\n for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) | 0;\n return GRADIENTS[Math.abs(h) % GRADIENTS.length];\n}\n\n// Bottom-right stack, max 4 visible. Older toasts beyond that auto-collapse.\nconst MAX_VISIBLE = 4;\n\nexport function Toaster() {\n const toasts = useToasts();\n const visible = toasts.slice(-MAX_VISIBLE);\n\n return (\n <div\n className=\"fixed z-50 flex flex-col-reverse gap-2 pointer-events-none w-[360px] max-w-[calc(100vw-2rem)]\"\n style={{\n right: \"max(1rem, calc(env(safe-area-inset-right) + 0.5rem))\",\n bottom: \"max(1rem, calc(env(safe-area-inset-bottom) + 0.5rem))\",\n }}\n aria-live=\"polite\"\n >\n {visible.map((t) => (\n <ToastCard key={t.id} toast={t} />\n ))}\n </div>\n );\n}\n\nfunction ToastCard({ toast }: { toast: Toast }) {\n const { dispatch } = useAppContext();\n const [paused, setPaused] = useState(false);\n const [exiting, setExiting] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const remainingRef = useRef<number>(toast.ttl);\n // Lazy useState init runs during the first render only and is invoked by\n // React itself, satisfying react-hooks/purity. We capture mount time as a\n // stable value (effectively a ref) without calling Date.now() inline.\n const [startedAt] = useState<number>(() => Date.now());\n const startedRef = useRef<number>(startedAt);\n\n // Auto-dismiss with hover-to-pause. Reset timer on hover-out using the\n // remaining duration so a 6s toast that you hovered for 3s still gets ~3s\n // after you leave, not a fresh 6s.\n useEffect(() => {\n if (toast.ttl <= 0) return;\n if (paused) {\n if (timerRef.current) clearTimeout(timerRef.current);\n remainingRef.current -= Date.now() - startedRef.current;\n return;\n }\n startedRef.current = Date.now();\n timerRef.current = setTimeout(() => {\n setExiting(true);\n setTimeout(() => dismissToast(toast.id), 200);\n }, Math.max(remainingRef.current, 0));\n return () => { if (timerRef.current) clearTimeout(timerRef.current); };\n }, [paused, toast.id, toast.ttl]);\n\n function close() {\n setExiting(true);\n setTimeout(() => dismissToast(toast.id), 200);\n }\n\n function open() {\n if (toast.href) {\n const parsed = parseHref(toast.href);\n if (parsed.tab) {\n dispatch({ type: \"SET_TAB\", tab: parsed.tab });\n dispatch({ type: \"SET_SELECTION\", tab: parsed.tab, itemId: parsed.item ?? null });\n }\n if (parsed.hash && typeof window !== \"undefined\") {\n window.history.replaceState(null, \"\", `${window.location.pathname}${window.location.search}#${parsed.hash}`);\n window.dispatchEvent(new HashChangeEvent(\"hashchange\"));\n }\n } else if (toast.thread_id && toast.agent_id) {\n // Reply / scheduled-task / bridge-message toasts — land on the exact\n // thread the event happened in, not just the agent's last-active one.\n dispatch({ type: \"SELECT_THREAD\", threadId: toast.thread_id, agentId: toast.agent_id });\n } else if (toast.agent_id) {\n dispatch({ type: \"SET_AGENT\", agentId: toast.agent_id });\n dispatch({ type: \"SET_TAB\", tab: \"chat\" });\n }\n close();\n }\n\n const isError = toast.kind === \"error\";\n // Error toasts with expandable details (stack trace + Copy + Report).\n // Stop propagation on every interactive sub-element so clicks don't\n // trigger the body's open()/navigate behavior.\n const hasReport = isError && (toast.details != null || toast.reportInput != null);\n const [expanded, setExpanded] = useState(false);\n const [copied, setCopied] = useState(false);\n\n async function onCopy(e: React.MouseEvent) {\n e.stopPropagation();\n if (!toast.reportInput) return;\n const { body } = await buildReport(toast.reportInput);\n try {\n await navigator.clipboard.writeText(body);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch {\n // Clipboard rejected (no focus, secure context, etc.) — open a window\n // with the text instead so the user can copy manually.\n const win = window.open(\"\", \"_blank\", \"noopener,noreferrer,width=600,height=400\");\n if (win) {\n win.document.body.innerText = body;\n }\n }\n }\n\n async function onReport(e: React.MouseEvent) {\n e.stopPropagation();\n if (!toast.reportInput) return;\n const { url } = await buildReport(toast.reportInput);\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }\n // Avatar — when we have an agent_id use a deterministic gradient. Otherwise\n // fall back to a generic bot icon.\n const avatar = toast.agent_id ? (\n <div className={`w-9 h-9 rounded-lg bg-gradient-to-br ${gradientFor(toast.agent_id)} flex items-center justify-center text-sm font-bold text-white shrink-0`}>\n {toast.title.charAt(0).toUpperCase()}\n </div>\n ) : (\n <div className=\"w-9 h-9 rounded-lg bg-surface-3 flex items-center justify-center shrink-0\">\n {isError ? <AlertCircle size={16} className=\"text-rose-700 dark:text-rose-400\" /> : <Bot size={16} className=\"text-fg-muted\" />}\n </div>\n );\n\n return (\n <div\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onClick={open}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => { if (e.key === \"Enter\") open(); }}\n className={`pointer-events-auto group relative cursor-pointer rounded-xl border bg-surface-2/95 backdrop-blur shadow-2xl transition-all duration-200 ${\n exiting ? \"opacity-0 translate-x-2\" : \"opacity-100 translate-x-0\"\n } ${isError ? \"border-rose-700/60\" : \"border-border hover:border-border\"}`}\n >\n <div className=\"flex items-start gap-3 px-3 py-2.5\">\n {avatar}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-[10px] uppercase tracking-wider text-fg-faint font-semibold truncate\">\n {toast.sourceLabel}\n </p>\n <p className=\"text-sm font-medium text-fg truncate\">{toast.title}</p>\n {toast.preview ? (\n <p className={`text-xs ${isError ? \"text-rose-700 dark:text-rose-300/90\" : \"text-fg-muted\"} line-clamp-2 mt-0.5 italic`}>\n “{toast.preview}”\n </p>\n ) : (\n <p className={`text-xs ${isError ? \"text-rose-700 dark:text-rose-300/90\" : \"text-fg-subtle\"} line-clamp-2 mt-0.5`}>\n {toast.body}\n </p>\n )}\n {toast.href ? (\n <p className=\"text-[10px] text-accent/80 mt-1\">{toast.hrefLabel ?? \"Open →\"}</p>\n ) : (toast.agent_id || toast.thread_id) ? (\n <p className=\"text-[10px] text-accent/80 mt-1\">Open chat →</p>\n ) : null}\n {hasReport && (\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); setExpanded((v) => !v); }}\n className=\"control-tap mt-1.5 inline-flex items-center gap-1 text-[10px] text-rose-700 dark:text-rose-300/90 hover:text-rose-900 dark:hover:text-rose-200\"\n aria-expanded={expanded}\n >\n {expanded ? <ChevronDown size={11} /> : <ChevronRight size={11} />}\n {expanded ? \"Hide details\" : \"Show details\"}\n </button>\n )}\n </div>\n <button\n onClick={(e) => { e.stopPropagation(); close(); }}\n className=\"control-tap opacity-0 group-hover:opacity-100 pointer-coarse:opacity-100 transition-opacity px-1.5 -mr-1 -mt-0.5 text-fg-faint hover:text-fg\"\n aria-label=\"Dismiss\"\n >\n <X size={13} />\n </button>\n </div>\n {hasReport && expanded && (\n <div\n className=\"border-t border-rose-700/30 bg-rose-50/40 dark:bg-rose-950/20 px-3 py-2 space-y-2\"\n onClick={(e) => e.stopPropagation()}\n >\n {toast.details && (\n <pre className=\"text-[10px] leading-snug text-rose-900 dark:text-rose-200/90 max-h-40 overflow-auto whitespace-pre-wrap break-words font-mono bg-surface-3/60 rounded p-2\">\n {toast.details}\n </pre>\n )}\n {toast.reportInput && (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onCopy}\n className=\"control-tap inline-flex items-center gap-1 text-[11px] px-2 py-1 rounded-md bg-surface-3 hover:bg-surface-4 text-fg border border-border\"\n >\n <Copy size={11} />\n {copied ? \"Copied\" : \"Copy report\"}\n </button>\n <button\n type=\"button\"\n onClick={onReport}\n className=\"control-tap inline-flex items-center gap-1 text-[11px] px-2 py-1 rounded-md bg-rose-600 hover:bg-rose-700 text-white\"\n title=\"Opens a pre-filled GitHub issue\"\n >\n <ExternalLink size={11} />\n Report this issue\n </button>\n </div>\n )}\n </div>\n )}\n {/* Bottom progress sliver showing time remaining; pauses on hover. */}\n {toast.ttl > 0 && !exiting && (\n <div\n className=\"absolute bottom-0 left-0 right-0 h-[2px] origin-left rounded-bl-xl\"\n style={{\n backgroundColor: isError ? \"#fb7185\" : \"#3b82f6\",\n animation: paused ? \"none\" : `jarela-toast-shrink ${toast.ttl}ms linear forwards`,\n }}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { AgentConfig } from \"@/api/types\";\nimport { api } from \"@/api/client\";\nimport { Logo } from \"@/components/ui/Logo\";\n\n// Hash an agent id to a deterministic gradient so the same agent always\n// renders the same color, but the colors are spread across the agent set.\nconst GRADIENTS = [\n \"from-violet-500 to-indigo-600\",\n \"from-blue-500 to-cyan-600\",\n \"from-emerald-500 to-teal-600\",\n \"from-orange-500 to-amber-600\",\n \"from-rose-500 to-pink-600\",\n \"from-fuchsia-500 to-purple-600\",\n];\nfunction gradientFor(id: string): string {\n let h = 0;\n for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) | 0;\n return GRADIENTS[Math.abs(h) % GRADIENTS.length];\n}\n\ninterface Props {\n agents: AgentConfig[];\n agentsLoaded: boolean;\n activeAgentId: string | null;\n onPickAgent: (agentId: string) => void;\n // Boot picker is a chat-tab gate; suppress on non-chat tabs so it doesn't overlay them.\n suppressed?: boolean;\n}\n\n// Three-phase first-screen experience:\n// 1. `loading` — agents haven't resolved yet. Logo + pulsing \"loading agents\".\n// 2. `pick` — agents resolved, no active selection. Logo + default agent\n// big tile + up to 3 recent agents in a row.\n// 3. `opening` — user clicked an agent (or one was persisted). Logo + just\n// that agent's icon + animated \"opening <name>…\" text. Fades\n// out 600ms after the active agent is set, giving ChatView\n// time to mount and request the session.\n//\n// Replaces the previous splash + ChatView empty-state agent picker. The\n// header (z-40) is hidden while this is visible so the user lands on a\n// focused, one-purpose screen.\nexport function BootScreen({ agents, agentsLoaded, activeAgentId, onPickAgent, suppressed }: Props) {\n // Capture which agent we transitioned through so the icon can keep\n // showing during the fade-out, even if a parent state shift would\n // otherwise clear it.\n const [pickedId, setPickedId] = useState<string | null>(null);\n const [dismissing, setDismissing] = useState(false);\n const [done, setDone] = useState(false);\n const dismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Prefetch checklist. Drives both the step display and the dismiss\n // gate — we don't fade out until every step is settled so ChatView\n // mounts onto warm data instead of showing its own loading spinners.\n type StepStatus = \"pending\" | \"active\" | \"done\";\n type Step = { key: string; label: string; status: StepStatus };\n const [steps, setSteps] = useState<Step[]>([]);\n const prefetchStartedRef = useRef(false);\n\n const defaultAgent = useMemo(\n () => agents.find((a) => a.is_default) ?? null,\n [agents],\n );\n const recentAgents = useMemo(\n () =>\n agents\n .filter((a) => !a.is_default)\n .sort((a, b) => b.updated_at.localeCompare(a.updated_at))\n .slice(0, 3),\n [agents],\n );\n\n // The agent whose icon we show during the opening phase. Prefer the\n // explicitly-picked one (so a click animates that icon even if the\n // active-agent state changes), fall back to the active agent, then\n // the default if available.\n const focusAgent = useMemo(() => {\n const id = pickedId ?? activeAgentId;\n if (!id) return null;\n return agents.find((a) => a.id === id) ?? null;\n }, [pickedId, activeAgentId, agents]);\n\n const markStep = useCallback((key: string, status: StepStatus) => {\n setSteps((prev) => prev.map((s) => (s.key === key ? { ...s, status } : s)));\n }, []);\n\n // Prefetch agent profile, config, thread, and recent messages BEFORE\n // we let the chat view take over. The user stays on the boot screen\n // and sees each step tick off, which is far better than landing on a\n // half-rendered chat that has to fetch the same data anyway.\n useEffect(() => {\n const id = activeAgentId ?? pickedId;\n if (!id || !agentsLoaded) return;\n if (prefetchStartedRef.current) return;\n prefetchStartedRef.current = true;\n\n setSteps([\n { key: \"profile\", label: \"loading your profile\", status: \"active\" },\n { key: \"agent\", label: \"loading agent config\", status: \"active\" },\n { key: \"thread\", label: \"preparing conversation\", status: \"active\" },\n { key: \"messages\", label: \"loading recent messages\", status: \"pending\" },\n ]);\n\n let cancelled = false;\n\n void (async () => {\n await Promise.allSettled([\n api.profile.get().finally(() => {\n if (!cancelled) markStep(\"profile\", \"done\");\n }),\n api.agents\n .get(id)\n .finally(() => {\n if (!cancelled) markStep(\"agent\", \"done\");\n }),\n (async () => {\n try {\n const t = await api.agents.getThread(id);\n if (cancelled) return;\n markStep(\"thread\", \"done\");\n markStep(\"messages\", \"active\");\n await api.threads.get(t.thread_id);\n } catch {\n // Errors here are non-fatal for boot — ChatView will surface\n // them with its own retry path. Just mark the steps done so\n // we don't block the user behind the splash forever.\n } finally {\n if (!cancelled) {\n markStep(\"thread\", \"done\");\n markStep(\"messages\", \"done\");\n }\n }\n })(),\n ]);\n if (cancelled) return;\n // Short grace period so the user actually sees the final \"all\n // done\" state before the screen fades.\n const settleTimer = setTimeout(() => {\n if (cancelled) return;\n setDismissing(true);\n dismissTimerRef.current = setTimeout(() => setDone(true), 500);\n }, 250);\n dismissTimerRef.current = settleTimer;\n })();\n\n return () => {\n cancelled = true;\n if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current);\n };\n }, [activeAgentId, pickedId, agentsLoaded, markStep]);\n\n if (done) return null;\n if (suppressed) return null;\n\n const phase: \"loading\" | \"pick\" | \"opening\" =\n !agentsLoaded\n ? \"loading\"\n : activeAgentId || pickedId\n ? \"opening\"\n : \"pick\";\n\n // Show the in-flight step in the headline so the user always knows\n // what we're waiting on. Falls back to \"opening <name>\" before the\n // checklist initialises and after every step is done.\n const activeStep = steps.find((s) => s.status === \"active\");\n const statusText =\n phase === \"loading\"\n ? \"loading agents\"\n : phase === \"opening\"\n ? activeStep?.label ?? `opening ${focusAgent?.name ?? \"agent\"}`\n : \"pick an agent to begin\";\n\n function handlePick(id: string) {\n if (pickedId) return;\n setPickedId(id);\n onPickAgent(id);\n }\n\n // The agent rendered in the centered tile. During `loading` and\n // `pick` it's the default (so the user sees the same artwork as soon\n // as agents resolve). During `opening` it's whatever was picked.\n // Keeping this slot stable across phases is what makes the transition\n // feel seamless — only the surrounding chrome (pill, recent list)\n // fades in or out.\n const tileAgent = focusAgent ?? defaultAgent;\n const tileClickable = phase === \"pick\" && tileAgent !== null;\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-hidden={dismissing}\n className={[\n \"fixed inset-0 z-[70]\",\n \"bg-surface text-fg\",\n \"transition-opacity duration-500 ease-out\",\n dismissing ? \"opacity-0 pointer-events-none\" : \"opacity-100\",\n ].join(\" \")}\n style={{\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }}\n >\n {/*\n Fixed three-row layout so the Logo and headline never reflow as\n the phase changes:\n - Logo + headline pinned in a stable block above center\n - Tile slot always 11rem tall, centered\n - Recent list sits in its own slot below the tile and just\n fades its opacity in/out — it never adds or removes layout\n height, so the tile and headline stay put.\n */}\n <div className=\"absolute inset-0 flex flex-col items-center justify-center gap-6\">\n <Logo className=\"h-16 w-auto\" />\n <p\n className=\"text-[11px] uppercase tracking-[0.3em] text-fg-faint animate-pulse min-h-[1.25rem] text-center px-6\"\n >\n {statusText}\n </p>\n\n {/* Tile slot — always reserves the same 11rem so neighbours don't shift. */}\n <div className=\"w-44 h-44 relative\">\n {tileAgent ? (\n <button\n type=\"button\"\n onClick={tileClickable ? () => handlePick(tileAgent.id) : undefined}\n disabled={!tileClickable}\n aria-label={\n tileClickable\n ? `Open ${tileAgent.name}`\n : `Opening ${tileAgent.name}`\n }\n className={[\n \"absolute inset-0 rounded-3xl overflow-hidden\",\n \"ring-2 ring-accent/40 ring-offset-4 ring-offset-surface\",\n \"shadow-2xl shadow-accent/20\",\n tileClickable\n ? \"hover:ring-accent/70 hover:shadow-accent/30 transition-all cursor-pointer\"\n : \"cursor-default\",\n ].join(\" \")}\n >\n <div\n className={`absolute inset-0 bg-gradient-to-br ${gradientFor(tileAgent.id)} flex items-center justify-center text-5xl font-bold text-white select-none`}\n >\n {tileAgent.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={tileAgent.icon}\n alt=\"\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n tileAgent.name.charAt(0).toUpperCase()\n )}\n </div>\n\n {/*\n \"default\" pill — only meaningful in the picker. Fades\n out as we transition to opening so the same tile keeps\n showing without a remount flash.\n */}\n <span\n className={[\n \"absolute top-2 right-2 text-[9px] uppercase tracking-wider\",\n \"px-1.5 py-0.5 rounded-full text-white bg-accent/80\",\n \"backdrop-blur-sm shadow transition-opacity duration-300\",\n phase === \"pick\" && tileAgent.is_default\n ? \"opacity-100\"\n : \"opacity-0\",\n ].join(\" \")}\n >\n default\n </span>\n\n <div className=\"absolute inset-x-0 bottom-0 pt-10 pb-3 px-3 bg-gradient-to-t from-black/85 via-black/55 to-transparent\">\n <p className=\"text-base font-semibold text-white drop-shadow-sm truncate text-center\">\n {tileAgent.name}\n </p>\n </div>\n </button>\n ) : (\n <div\n className=\"absolute inset-0 rounded-3xl bg-surface-2/60 ring-2 ring-border/30 ring-offset-4 ring-offset-surface\"\n aria-hidden\n />\n )}\n </div>\n\n {/*\n Recent list slot. Fixed size (so neighbours don't reflow when\n phase changes). Opacity-toggled instead of conditionally\n rendered so the picker→opening transition is a fade, not a\n layout shift.\n */}\n <div className=\"w-48 min-h-[8rem] relative\">\n <div\n className={[\n \"absolute inset-x-0 top-0 flex flex-col items-center gap-2\",\n \"transition-opacity duration-300\",\n phase === \"pick\" && recentAgents.length > 0\n ? \"opacity-100\"\n : \"opacity-0 pointer-events-none\",\n ].join(\" \")}\n >\n <p className=\"text-[10px] text-fg-faint uppercase tracking-wider\">\n Recent\n </p>\n <div className=\"flex flex-col gap-1.5 w-full\">\n {recentAgents.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n onClick={() => handlePick(a.id)}\n title={a.identity || a.name}\n aria-label={`Open ${a.name}`}\n disabled={phase !== \"pick\"}\n className=\"flex items-center gap-3 px-3 py-2 rounded-xl border border-border/60 bg-surface-2/60 hover:bg-surface-3 hover:border-border transition-colors text-left\"\n >\n <div\n className={`w-9 h-9 shrink-0 rounded-lg bg-gradient-to-br ${gradientFor(a.id)} flex items-center justify-center text-sm font-bold text-white select-none overflow-hidden`}\n >\n {a.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={a.icon}\n alt=\"\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n a.name.charAt(0).toUpperCase()\n )}\n </div>\n <p className=\"text-sm text-fg-muted truncate flex-1\">\n {a.name}\n </p>\n </button>\n ))}\n </div>\n </div>\n\n {phase === \"pick\" &&\n !defaultAgent &&\n recentAgents.length === 0 && (\n <p className=\"absolute inset-x-0 top-0 text-xs text-fg-faint px-6 text-center\">\n No agents configured yet. Open the menu to create one.\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { PinKeypad } from \"./PinKeypad\";\n\n// Screen-lock overlay (presence check). Mounted by AppShell when the\n// idle timer fires or the server returns 423 `screen-locked`. Does\n// NOT touch the in-memory master key — background work (agents,\n// scheduler, bridges) keeps running underneath. The /verify-pin\n// endpoint just confirms the human at the keyboard and clears the\n// idle flag.\n\nexport function ScreenLock({ onUnlock }: { onUnlock: () => void }) {\n return <PinKeypad mode=\"unlock\" onSuccess={onUnlock} />;\n}\n","\"use client\";\nimport { BarChart3, Bot, Brain, Calendar, ChevronDown, Cpu, FolderSearch, Key, MessageSquare, Monitor, Moon, ScrollText, ServerCog, Shapes, Smartphone, Sun, User, Wrench } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { useAppContext, type Tab } from \"@/contexts/AppContext\";\nimport type { AgentConfig } from \"@/api/types\";\nimport { api } from \"@/api/client\";\nimport { useUnreadByAgent } from \"@/lib/ui/toasts\";\nimport { useTheme, type Theme } from \"@/contexts/ThemeContext\";\n\ninterface Props {\n activeTab: Tab;\n agentId: string | null;\n onClose: () => void;\n onAgentChange: (agentId: string) => void;\n onSetTab: (tab: Tab) => void;\n}\n\nconst TAB_ICONS: Record<Tab, React.ReactNode> = {\n chat: <MessageSquare size={13} />,\n dashboard: <BarChart3 size={13} />,\n agents: <Bot size={13} />,\n memory: <Brain size={13} />,\n documents: <FolderSearch size={13} />,\n models: <Cpu size={13} />,\n credentials: <Key size={13} />,\n mcp: <Wrench size={13} />,\n extensions: <Wrench size={13} />,\n tools: <Wrench size={13} />,\n tasks: <Calendar size={13} />,\n bridges: <Smartphone size={13} />,\n profile: <User size={13} />,\n harness: <Shapes size={13} />,\n logs: <ScrollText size={13} />,\n env: <ServerCog size={13} />,\n};\n\nconst TAB_TITLES: Record<Tab, string> = {\n chat: \"Chat\",\n dashboard: \"Dashboard\",\n agents: \"Agents\",\n memory: \"Memory\",\n documents: \"Documents\",\n models: \"Models\",\n credentials: \"Credentials\",\n mcp: \"MCP\",\n extensions: \"Extensions\",\n tools: \"Tools\",\n tasks: \"Tasks\",\n bridges: \"Bridges\",\n profile: \"Profile\",\n harness: \"Harness\",\n logs: \"Logs\",\n env: \"Defaults\",\n};\n\nconst TAB_SHORT: Record<Tab, string> = {\n chat: \"Chat\",\n dashboard: \"Dash\",\n agents: \"AI\",\n memory: \"Mem\",\n documents: \"Docs\",\n models: \"Model\",\n credentials: \"Keys\",\n mcp: \"MCP\",\n extensions: \"Ext\",\n tools: \"Tools\",\n tasks: \"Tasks\",\n bridges: \"Bridge\",\n profile: \"Me\",\n harness: \"Test\",\n logs: \"Logs\",\n env: \"Defaults\",\n};\n\n// Two-tier menu. \"Common\" surfaces the day-to-day verbs plus the most\n// relevant configuration touchpoints. \"Advanced\" hides the less-frequently\n// used engine-room surfaces behind a collapsible header.\n//\n// Capability-presence surfaces (documents, memory, MCP, extensions,\n// bridges, built-in tool categories) all live under the \"Tools\" tab now —\n// they were scattered across the top-level menu before but they're all\n// answering the same question: \"what can the agent see / do?\". The legacy\n// top-level Tab entries remain wired so deep-links (?tab=documents&item=…)\n// still resolve, but they're hidden from the menu grid.\n//\n// \"credentials\" is the single home for every auth surface — saved API\n// keys + built-in integrations (Gmail, GitHub, Atlassian…) live there as\n// sub-tabs.\n//\n// \"models\" lives in Advanced — most users let the default model do its\n// job; switching providers is power-user territory.\nconst COMMON_TABS: Tab[] = [\"chat\", \"dashboard\", \"agents\", \"credentials\", \"tools\", \"tasks\", \"profile\"];\nconst ADVANCED_TABS: Tab[] = [\"models\", \"harness\", \"logs\", \"env\"];\n\nconst ADVANCED_KEY = \"jarela.menu.advanced\";\n\nconst GRADIENTS = [\n \"from-violet-500 to-indigo-600\",\n \"from-blue-500 to-cyan-600\",\n \"from-emerald-500 to-teal-600\",\n \"from-orange-500 to-amber-600\",\n \"from-rose-500 to-pink-600\",\n \"from-fuchsia-500 to-purple-600\",\n];\n\nconst TAB_ACCENT: Partial<Record<Tab, string>> = {\n chat: \"from-sky-500/20 to-cyan-500/5\",\n dashboard: \"from-cyan-500/20 to-blue-500/5\",\n agents: \"from-emerald-500/20 to-teal-500/5\",\n memory: \"from-indigo-500/20 to-violet-500/5\",\n documents: \"from-amber-500/20 to-orange-500/5\",\n tasks: \"from-rose-500/20 to-pink-500/5\",\n bridges: \"from-blue-500/20 to-indigo-500/5\",\n profile: \"from-fuchsia-500/20 to-purple-500/5\",\n models: \"from-violet-500/20 to-indigo-500/5\",\n credentials: \"from-amber-500/20 to-yellow-500/5\",\n tools: \"from-emerald-500/20 to-lime-500/5\",\n harness: \"from-orange-500/20 to-amber-500/5\",\n logs: \"from-slate-500/20 to-zinc-500/5\",\n env: \"from-teal-500/20 to-cyan-500/5\",\n};\n\nfunction avatarGradient(id: string): string {\n let h = 0;\n for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) | 0;\n return GRADIENTS[Math.abs(h) % GRADIENTS.length];\n}\n\nfunction AgentSessionList({\n activeAgentId,\n onSelect,\n}: {\n activeAgentId: string | null;\n onSelect: (id: string) => void;\n}) {\n const [agents, setAgents] = useState<AgentConfig[]>([]);\n const unread = useUnreadByAgent();\n\n useEffect(() => {\n let cancelled = false;\n const load = () => api.agents.list().then((rows) => { if (!cancelled) setAgents(rows); }).catch(console.error);\n void load();\n function onAgentsChanged() { void load(); }\n window.addEventListener(\"jarela:agents-changed\", onAgentsChanged);\n return () => {\n cancelled = true;\n window.removeEventListener(\"jarela:agents-changed\", onAgentsChanged);\n };\n }, []);\n\n if (agents.length === 0) {\n return (\n <p className=\"text-fg-faint text-xs text-center py-6 select-none px-3\">\n No agents yet — create one in the Agents tab.\n </p>\n );\n }\n\n return (\n <div className=\"py-1.5 space-y-0.5 px-2\">\n {agents.map((a) => {\n const isActive = a.id === activeAgentId;\n const n = unread.get(a.id) ?? 0;\n return (\n <button\n key={a.id}\n onClick={() => onSelect(a.id)}\n className={`w-full flex items-center gap-3 px-2.5 py-2.5 rounded-xl transition-colors text-left ${\n isActive\n ? \"bg-accent/15 border border-accent/30\"\n : \"hover:bg-surface-3 border border-transparent\"\n }`}\n >\n {/* Avatar */}\n <div className=\"relative shrink-0\">\n {a.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={a.icon}\n alt={a.name}\n className=\"w-9 h-9 rounded-lg object-cover\"\n />\n ) : (\n <div\n className={`w-9 h-9 rounded-lg flex items-center justify-center text-sm font-bold text-white bg-gradient-to-br select-none ${avatarGradient(a.id)}`}\n >\n {a.name.charAt(0).toUpperCase()}\n </div>\n )}\n {n > 0 && (\n <span className=\"absolute -top-1 -right-1 min-w-[16px] h-[16px] px-1 rounded-full bg-rose-500 border border-surface-2 text-[10px] font-bold text-white flex items-center justify-center leading-none\">\n {n > 9 ? \"9+\" : n}\n </span>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span className={`text-sm font-medium truncate ${isActive ? \"text-fg\" : \"text-fg\"}`}>\n {a.name}\n </span>\n {a.is_default && (\n <span className=\"text-[9px] uppercase tracking-wide text-accent font-semibold shrink-0\">\n default\n </span>\n )}\n </div>\n {a.identity ? (\n <p className=\"text-[11px] text-fg-faint truncate leading-tight mt-0.5\">{a.identity}</p>\n ) : (\n <p className=\"text-[11px] text-fg-faint italic leading-tight mt-0.5\">No persona</p>\n )}\n </div>\n\n {/* Active indicator */}\n {isActive && (\n <div className=\"w-1.5 h-1.5 rounded-full bg-accent shrink-0\" />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function MenuPanel({\n activeTab,\n agentId,\n onClose,\n onAgentChange,\n onSetTab,\n}: Props) {\n const { state, dispatch } = useAppContext();\n const isFullMode = state.experienceMode === \"full\";\n const setMode = (mode: \"essential\" | \"full\") => {\n if ((mode === \"full\") === isFullMode) return;\n dispatch({ type: \"SET_EXPERIENCE_MODE\", mode });\n };\n // Advanced section starts collapsed once the user has dismissed it\n // once (persisted to localStorage). Defaults to *expanded* on first\n // boot so the engine room is visible to power users out of the box.\n const [advancedOpen, setAdvancedOpen] = useState<boolean>(true);\n useEffect(() => {\n try {\n const v = window.localStorage.getItem(ADVANCED_KEY);\n if (v != null) setAdvancedOpen(v === \"1\");\n } catch {\n /* localStorage may throw in private mode; harmless. */\n }\n }, []);\n // If the user navigates into an Advanced tab via deep-link, auto-open\n // the section so the active state is visible.\n useEffect(() => {\n if (ADVANCED_TABS.includes(activeTab) && !advancedOpen) {\n setAdvancedOpen(true);\n try { window.localStorage.setItem(ADVANCED_KEY, \"1\"); } catch { /* ignore */ }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeTab]);\n\n const toggleAdvanced = () => {\n setAdvancedOpen((prev) => {\n const next = !prev;\n try { window.localStorage.setItem(ADVANCED_KEY, next ? \"1\" : \"0\"); } catch { /* ignore */ }\n return next;\n });\n };\n\n const renderTabButton = (tab: Tab) => (\n <button\n key={tab}\n onClick={() => onSetTab(tab)}\n title={TAB_TITLES[tab]}\n aria-label={TAB_TITLES[tab]}\n aria-current={activeTab === tab ? \"page\" : undefined}\n className={`control-tap min-w-0 relative overflow-hidden flex flex-col items-center justify-center gap-1 rounded-xl py-2 px-1 transition-all duration-200 ${\n activeTab === tab\n ? \"bg-surface-3 text-fg ring-1 ring-border shadow-sm\"\n : \"text-fg-faint hover:text-fg-muted hover:bg-surface-3/50 hover:-translate-y-px\"\n }`}\n >\n {activeTab === tab && (\n <span className={`absolute inset-0 bg-gradient-to-br ${TAB_ACCENT[tab] ?? \"from-accent/20 to-transparent\"}`} />\n )}\n <span className=\"shrink-0\">{TAB_ICONS[tab]}</span>\n <span className=\"text-[10px] leading-none truncate max-w-full relative z-10 max-[380px]:hidden\">{TAB_TITLES[tab]}</span>\n <span className=\"text-[10px] leading-none truncate max-w-full relative z-10 min-[381px]:hidden\">{TAB_SHORT[tab]}</span>\n </button>\n );\n\n return (\n <div\n className=\"glass-elevated fixed right-0 bottom-0 w-full sm:w-[26rem] max-w-full border-l border-border/60 z-40 flex flex-col pb-safe\"\n style={{ top: \"calc(3rem + var(--app-safe-top))\" }}\n >\n {/* Common navigation — the day-to-day surface. */}\n <div className=\"px-3 pt-2 pb-1 border-b border-border/60 bg-gradient-to-r from-surface-2/50 to-transparent\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-[10px] uppercase tracking-wide text-fg-faint\">Workspace mode</span>\n <div\n role=\"radiogroup\"\n aria-label=\"Workspace mode\"\n className=\"inline-flex items-center rounded-full border border-border bg-surface-3 p-0.5\"\n >\n {([\"essential\", \"full\"] as const).map((mode) => {\n const active = (mode === \"full\") === isFullMode;\n return (\n <button\n key={mode}\n type=\"button\"\n role=\"radio\"\n aria-checked={active}\n onClick={() => setMode(mode)}\n title={active ? `${mode} mode (current)` : `Switch to ${mode} mode`}\n className={`control-tap text-[10px] uppercase tracking-wide px-2 py-0.5 rounded-full transition-colors ${\n active\n ? \"bg-accent/15 text-fg-subtle\"\n : \"text-fg-faint hover:text-fg-muted\"\n }`}\n >\n {mode}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n <div className=\"grid grid-cols-4 sm:grid-cols-6 gap-1.5 px-2 py-2 border-b border-border shrink-0\">\n {COMMON_TABS.map(renderTabButton)}\n </div>\n\n {isFullMode && (\n <div className=\"border-b border-border shrink-0\">\n <button\n type=\"button\"\n onClick={toggleAdvanced}\n aria-expanded={advancedOpen}\n className=\"control-tap w-full flex items-center justify-between px-3 py-2 text-[11px] uppercase tracking-wide text-fg-faint hover:text-fg-muted transition-colors bg-gradient-to-r from-surface-2/40 to-transparent\"\n >\n <span className=\"font-medium\">Advanced</span>\n <ChevronDown\n size={12}\n className={`transition-transform ${advancedOpen ? \"rotate-0\" : \"-rotate-90\"}`}\n />\n </button>\n {advancedOpen && (\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-1.5 px-2 pb-2\">\n {ADVANCED_TABS.map(renderTabButton)}\n </div>\n )}\n </div>\n )}\n\n {/* Main content area */}\n <div className=\"flex-1 overflow-y-auto min-h-0 panel-scrollbar\">\n <AgentSessionList\n activeAgentId={agentId}\n onSelect={(id) => { onAgentChange(id); onSetTab(\"chat\"); onClose(); }}\n />\n </div>\n\n {/* Display toggles */}\n <div className=\"border-t border-border px-3 py-3 shrink-0 bg-surface-1/30\">\n <p className=\"text-[11px] text-fg-faint mb-1.5 font-medium uppercase tracking-wide\">Display</p>\n <div className=\"flex flex-col gap-1.5\">\n <ThemePicker />\n </div>\n </div>\n </div>\n );\n}\n\nfunction ThemePicker() {\n const { theme, setTheme } = useTheme();\n const options: { value: Theme; label: string; icon: React.ReactNode }[] = [\n { value: \"light\", label: \"Light\", icon: <Sun size={12} /> },\n { value: \"dark\", label: \"Dark\", icon: <Moon size={12} /> },\n { value: \"system\", label: \"System\", icon: <Monitor size={12} /> },\n ];\n return (\n <div className=\"flex items-center gap-2 text-xs text-fg-muted rounded-lg border border-border bg-surface-3/70 px-2.5 py-2\">\n <span className=\"shrink-0\">Theme</span>\n <div className=\"flex flex-1 rounded-lg border border-border overflow-hidden bg-surface\">\n {options.map((o) => (\n <button\n key={o.value}\n onClick={() => setTheme(o.value)}\n title={o.label}\n className={`control-tap flex-1 inline-flex items-center justify-center gap-1 py-1 text-[11px] transition-colors ${\n theme === o.value\n ? \"bg-surface-3 text-fg shadow-sm\"\n : \"text-fg-faint hover:text-fg-muted hover:bg-surface-3/50\"\n }`}\n >\n {o.icon}\n <span>{o.label}</span>\n </button>\n ))}\n </div>\n </div>\n );\n}\n","import type { DashboardCurrencyInfo } from \"@/api/types\";\n\nexport type WindowDays = 7 | 14 | 30 | 60;\nexport type CurrencyMode = \"auto\" | \"manual\";\n\nexport const WINDOWS: WindowDays[] = [7, 14, 30, 60];\nexport const MANUAL_CURRENCIES = [\"USD\", \"EUR\", \"GBP\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\", \"BRL\", \"MXN\"] as const;\n\nexport const TOOL_SORT_OPTIONS = [\n { value: \"best\", label: \"Sort: best first\" },\n { value: \"calls_desc\", label: \"Sort: most calls\" },\n { value: \"errors_desc\", label: \"Sort: most errors\" },\n { value: \"error_rate_desc\", label: \"Sort: highest error rate\" },\n { value: \"name_asc\", label: \"Sort: name A->Z\" },\n] as const;\n\nexport const MODEL_SORT_OPTIONS = [\n { value: \"model_asc\", label: \"Sort: model A->Z\" },\n { value: \"model_desc\", label: \"Sort: model Z->A\" },\n { value: \"input_desc\", label: \"Sort: highest input rate\" },\n { value: \"input_asc\", label: \"Sort: lowest input rate\" },\n { value: \"output_desc\", label: \"Sort: highest output rate\" },\n { value: \"output_asc\", label: \"Sort: lowest output rate\" },\n { value: \"confidence_desc\", label: \"Sort: confidence\" },\n { value: \"confidence_asc\", label: \"Sort: lowest confidence\" },\n] as const;\n\nexport const CURRENCY_MODE_KEY = \"jarela.dashboard.currency.mode\";\nexport const CURRENCY_PICK_KEY = \"jarela.dashboard.currency.pick\";\n\nexport const USD_CURRENCY: DashboardCurrencyInfo = {\n currency: \"USD\",\n rate_from_usd: 1,\n country_code: null,\n source: \"default\",\n updated_at: \"\",\n};\n\n// Per-tier breakdown colors shared by the stacked token chart legend.\nexport const TIER_COLORS: Record<\"hot\" | \"warm\" | \"facts\" | \"overhead\", string> = {\n hot: \"#22d3ee\",\n warm: \"#f59e0b\",\n facts: \"#a78bfa\",\n overhead: \"#94a3b8\",\n};\n","\"use client\";\nimport type { DashboardCurrencyInfo } from \"@/api/types\";\nimport { MANUAL_CURRENCIES, type CurrencyMode } from \"./dashboard-constants\";\n\ninterface CurrencyPickerRowProps {\n currencyMode: CurrencyMode;\n onModeChange: (mode: CurrencyMode) => void;\n manualCurrency: string;\n onManualChange: (code: string) => void;\n currencyInfo: DashboardCurrencyInfo;\n}\n\nexport function CurrencyPickerRow({ currencyMode, onModeChange, manualCurrency, onManualChange, currencyInfo }: CurrencyPickerRowProps) {\n return (\n <div className=\"relative flex flex-wrap items-center gap-2 px-1 py-1\">\n <span className=\"text-xs text-[var(--text-secondary)]\">Currency</span>\n <div className=\"inline-flex rounded-md border border-[var(--border)] bg-[var(--bg-secondary)]/80 p-0.5 text-xs\">\n <button\n type=\"button\"\n onClick={() => onModeChange(\"auto\")}\n className={`px-2 py-0.5 rounded transition-colors ${\n currencyMode === \"auto\"\n ? \"bg-[var(--accent)] text-white\"\n : \"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\n }`}\n >\n Auto\n </button>\n <button\n type=\"button\"\n onClick={() => onModeChange(\"manual\")}\n className={`px-2 py-0.5 rounded transition-colors ${\n currencyMode === \"manual\"\n ? \"bg-[var(--accent)] text-white\"\n : \"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\n }`}\n >\n Manual\n </button>\n </div>\n {currencyMode === \"manual\" ? (\n <select\n value={manualCurrency}\n onChange={(e) => onManualChange(e.target.value)}\n className=\"rounded-md bg-[var(--bg-primary)]/60 px-2 py-1 text-xs text-[var(--text-primary)]\"\n >\n {MANUAL_CURRENCIES.map((code) => (\n <option key={code} value={code}>{code}</option>\n ))}\n </select>\n ) : (\n <span className=\"text-[11px] text-[var(--text-secondary)]\">\n using <span className=\"text-[var(--text-primary)] font-medium\">{currencyInfo.currency}</span>\n {currencyInfo.country_code ? ` (${currencyInfo.country_code})` : \"\"}\n </span>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { RotateCw } from \"lucide-react\";\nimport { WINDOWS, type WindowDays } from \"./dashboard-constants\";\n\ninterface DashboardHeaderProps {\n days: WindowDays;\n onDaysChange: (d: WindowDays) => void;\n refreshingPricing: boolean;\n refreshHint: string | null;\n onRefreshPricing: () => void;\n}\n\nexport function DashboardHeader({ days, onDaysChange, refreshingPricing, refreshHint, onRefreshPricing }: DashboardHeaderProps) {\n return (\n <div className=\"sticky top-0 z-20 -mx-4 md:-mx-6 -mt-4 md:-mt-6 mb-2 border-b border-[var(--border)] bg-[var(--bg-primary)]/85 px-4 md:px-6 py-3 md:py-4 shadow-[0_8px_24px_-12px_rgba(0,0,0,0.45)] backdrop-blur-xl backdrop-saturate-150 supports-[backdrop-filter]:bg-[var(--bg-primary)]/70 [mask-image:linear-gradient(to_bottom,black_85%,transparent)] [-webkit-mask-image:linear-gradient(to_bottom,black_85%,transparent)]\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-xl font-semibold tracking-tight text-[var(--text-primary)]\">Usage dashboard</h2>\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\n Cost, token flow, and reliability across your configured models.\n </p>\n </div>\n <div className=\"inline-flex rounded-xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-1 shadow-sm\">\n {WINDOWS.map((w) => (\n <button\n key={w}\n type=\"button\"\n onClick={() => onDaysChange(w)}\n className={\n \"px-2.5 py-1 text-xs rounded-lg transition-colors \" +\n (w === days\n ? \"bg-[var(--accent)] text-white shadow-sm\"\n : \"text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-primary)]\")\n }\n >\n {w}d\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={onRefreshPricing}\n disabled={refreshingPricing}\n className=\"inline-flex items-center gap-1.5 rounded-xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 px-3 py-1.5 text-xs text-[var(--text-primary)] transition-colors hover:bg-[var(--bg-primary)] disabled:opacity-60\"\n >\n <RotateCw size={13} className={refreshingPricing ? \"animate-spin\" : \"\"} />\n {refreshingPricing ? \"Refreshing...\" : \"Refresh pricing\"}\n </button>\n </div>\n {refreshHint ? <p className=\"mt-2 text-[11px] text-[var(--text-secondary)]\">{refreshHint}</p> : null}\n </div>\n );\n}\n","// Currency + number formatting used by the dashboard. Centralised so the\n// \"lowest first\" sorts and compact donut center labels share one\n// definition.\n\nexport interface CurrencyConversion {\n currency: string;\n rate_from_usd: number;\n}\n\nexport function convertUsd(usd: number, currencyInfo: CurrencyConversion): number {\n const rate = Number.isFinite(currencyInfo.rate_from_usd) && currencyInfo.rate_from_usd > 0\n ? currencyInfo.rate_from_usd\n : 1;\n return usd * rate;\n}\n\nexport function formatInt(value: number): string {\n return new Intl.NumberFormat(\"en-US\").format(value);\n}\n\nexport function formatMoney(usd: number, currencyInfo: CurrencyConversion): string {\n const converted = convertUsd(usd, currencyInfo);\n const abs = Math.abs(converted);\n const useMicroPrecision = abs > 0 && abs < 0.01;\n const minFractionDigits = useMicroPrecision ? 4 : 2;\n const maxFractionDigits = useMicroPrecision ? 8 : 4;\n const code = currencyInfo.currency || \"USD\";\n\n if (abs > 0 && abs < 0.000001) {\n try {\n const floor = new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: code,\n minimumFractionDigits: 6,\n maximumFractionDigits: 6,\n }).format(0.000001);\n return `< ${floor}`;\n } catch {\n return `${code} < 0.000001`;\n }\n }\n\n try {\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: code,\n minimumFractionDigits: minFractionDigits,\n maximumFractionDigits: maxFractionDigits,\n }).format(converted);\n } catch {\n return `${code} ${converted.toFixed(maxFractionDigits)}`;\n }\n}\n\nexport function formatMoneyCompact(usd: number, currencyInfo: CurrencyConversion): string {\n const converted = convertUsd(usd, currencyInfo);\n const code = currencyInfo.currency || \"USD\";\n try {\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: code,\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(converted);\n } catch {\n const sign = converted < 0 ? \"-\" : \"\";\n const abs = Math.abs(converted);\n if (abs >= 1_000_000_000) return `${sign}${(abs / 1_000_000_000).toFixed(1)}B`;\n if (abs >= 1_000_000) return `${sign}${(abs / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${sign}${(abs / 1_000).toFixed(1)}K`;\n return `${sign}${abs.toFixed(2)}`;\n }\n}\n\nexport function safeHttpUrl(value: string | null | undefined): string | null {\n if (!value) return null;\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\" ? url.toString() : null;\n } catch {\n return null;\n }\n}\n","\"use client\";\n\nexport function MetricCard({ label, value, icon }: { label: string; value: string; icon?: React.ReactNode }) {\n return (\n <div className=\"rounded-xl bg-[var(--bg-secondary)]/70 px-3 py-3\">\n <p className=\"text-[10px] uppercase tracking-[0.12em] text-[var(--text-secondary)] inline-flex items-center gap-1.5\">\n {icon ? <span className=\"text-[var(--text-secondary)]\">{icon}</span> : null}\n {label}\n </p>\n <p className=\"mt-1 text-lg font-semibold text-[var(--text-primary)] leading-tight\">{value}</p>\n </div>\n );\n}\n\nexport function InsightChip({ label, value, hint }: { label: string; value: string; hint: string }) {\n return (\n <div className=\"rounded-xl bg-[var(--bg-secondary)]/55 px-3 py-2.5\">\n <div className=\"text-[10px] uppercase tracking-[0.12em] text-[var(--text-secondary)]\">{label}</div>\n <div className=\"mt-1 text-base font-semibold text-[var(--text-primary)]\">{value}</div>\n <div className=\"mt-0.5 text-[11px] text-[var(--text-secondary)]\">{hint}</div>\n </div>\n );\n}\n","\"use client\";\nimport { Activity, BarChart3, Coins, ShieldCheck, TrendingUp } from \"lucide-react\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { formatInt, formatMoney } from \"@/lib/dashboard/format\";\nimport { InsightChip, MetricCard } from \"./Cards\";\n\ninterface SummaryStripProps {\n data: DashboardMetrics;\n currencyInfo: DashboardCurrencyInfo;\n windowTokenTotal: number;\n activeDays: number;\n avgDailyTokens: number;\n avgDailyCostUsd: number;\n}\n\nexport function SummaryStrip({ data, currencyInfo, windowTokenTotal, activeDays, avgDailyTokens, avgDailyCostUsd }: SummaryStripProps) {\n return (\n <div className=\"relative grid gap-2 md:grid-cols-4\">\n <InsightChip\n label=\"Window tokens\"\n value={formatInt(windowTokenTotal)}\n hint={`${formatInt(activeDays)} active day${activeDays === 1 ? \"\" : \"s\"} in ${data.days}d`}\n />\n <InsightChip\n label=\"Avg tokens / day\"\n value={formatInt(avgDailyTokens)}\n hint=\"Heuristic from message length\"\n />\n <InsightChip\n label=\"Window cost\"\n value={formatMoney(data.summary.estimated_cost_usd, currencyInfo)}\n hint=\"Estimated from pricing snapshot\"\n />\n <InsightChip\n label=\"Avg cost / day\"\n value={formatMoney(avgDailyCostUsd, currencyInfo)}\n hint=\"Smoothes short-day spikes\"\n />\n </div>\n );\n}\n\ninterface EffectiveSummary {\n input_tokens_est: number;\n output_tokens_est: number;\n estimated_cost_usd: number;\n success_rate: number;\n error_rate: number;\n}\n\ninterface MetricCardsGridProps {\n effectiveSummary: EffectiveSummary | undefined;\n currencyInfo: DashboardCurrencyInfo;\n selectedDay: string | null;\n}\n\nexport function MetricCardsGrid({ effectiveSummary, currencyInfo, selectedDay }: MetricCardsGridProps) {\n return (\n <div className=\"grid grid-cols-2 lg:grid-cols-5 gap-3\">\n <MetricCard\n label={selectedDay ? `Input tokens on ${selectedDay}` : \"Input tokens (est)\"}\n value={formatInt(effectiveSummary?.input_tokens_est ?? 0)}\n icon={<BarChart3 size={15} />}\n />\n <MetricCard\n label={selectedDay ? `Output tokens on ${selectedDay}` : \"Output tokens (est)\"}\n value={formatInt(effectiveSummary?.output_tokens_est ?? 0)}\n icon={<TrendingUp size={15} />}\n />\n <MetricCard\n label={selectedDay ? `Cost on ${selectedDay} (${currencyInfo.currency})` : `Estimated cost (${currencyInfo.currency})`}\n value={formatMoney(effectiveSummary?.estimated_cost_usd ?? 0, currencyInfo)}\n icon={<Coins size={15} />}\n />\n <MetricCard\n label=\"Tool success rate\"\n value={`${((effectiveSummary?.success_rate ?? 1) * 100).toFixed(1)}%`}\n icon={<ShieldCheck size={15} />}\n />\n <MetricCard\n label=\"Tool error rate\"\n value={`${((effectiveSummary?.error_rate ?? 0) * 100).toFixed(1)}%`}\n icon={<Activity size={15} />}\n />\n </div>\n );\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { convertUsd, formatInt, formatMoney, formatMoneyCompact } from \"@/lib/dashboard/format\";\nimport { TIER_COLORS } from \"./dashboard-constants\";\n\ninterface TokenChartProps {\n series: DashboardMetrics[\"series\"];\n selectedDay?: string | null;\n onSelectDay?: (day: string) => void;\n}\n\nexport function InteractiveTokenChart({ series, selectedDay, onSelectDay }: TokenChartProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n const [barsReady, setBarsReady] = useState(false);\n const maxTotal = series.reduce((max, p) => Math.max(max, p.input_tokens_est + p.output_tokens_est), 0);\n const active = hovered != null ? series[hovered] : null;\n const animationSignature = series.map((s) => `${s.day}:${s.input_tokens_est}:${s.output_tokens_est}`).join(\"|\");\n\n useEffect(() => {\n setBarsReady(false);\n const frame = requestAnimationFrame(() => setBarsReady(true));\n return () => cancelAnimationFrame(frame);\n }, [animationSignature]);\n\n if (series.length === 0) {\n return <p className=\"text-xs text-[var(--text-secondary)]\">No token data yet.</p>;\n }\n\n return (\n <div>\n <div className=\"relative h-48 rounded-xl bg-[var(--bg-primary)]/35 p-2\">\n <div\n className={`absolute right-2 top-2 inline-flex h-6 items-center gap-1.5 rounded-full px-2.5 text-[10px] tracking-wide transition-opacity ${\n active ? \"bg-[var(--bg-secondary)]/85 text-[var(--text-primary)] opacity-100\" : \"text-[var(--text-secondary)] opacity-60\"\n }`}\n >\n {active\n ? `${active.day} · ${formatInt(active.input_tokens_est + active.output_tokens_est)} tokens`\n : \"hover bars for details\"}\n </div>\n <div className=\"h-full flex items-end gap-1 pt-5\">\n {series.map((point, idx) => (\n <TokenBar\n key={point.day}\n point={point}\n idx={idx}\n maxTotal={maxTotal}\n barsReady={barsReady}\n hovered={hovered === idx}\n selected={selectedDay === point.day}\n onHover={setHovered}\n onSelectDay={onSelectDay}\n />\n ))}\n </div>\n </div>\n <TokenChartLegend active={active} />\n </div>\n );\n}\n\ninterface TokenBarProps {\n point: DashboardMetrics[\"series\"][number];\n idx: number;\n maxTotal: number;\n barsReady: boolean;\n hovered: boolean;\n selected: boolean;\n onHover: (i: number | null) => void;\n onSelectDay?: (day: string) => void;\n}\n\nfunction TokenBar({ point, idx, maxTotal, barsReady, hovered, selected, onHover, onSelectDay }: TokenBarProps) {\n const total = point.input_tokens_est + point.output_tokens_est;\n const hasData = total > 0;\n const totalHeight = hasData && maxTotal > 0 ? Math.max(4, Math.round((total / maxTotal) * 150)) : 0;\n const inputHeight = hasData ? Math.round((point.input_tokens_est / total) * totalHeight) : 0;\n const outputHeight = hasData ? Math.max(0, totalHeight - inputHeight) : 0;\n // Subdivide the input portion by measured tier breakdown when the day\n // has at least one snapshotted assistant turn. Legacy days (measured\n // input == 0) fall back to a solid violet block.\n const tier = point.tier_tokens;\n const tierTotal = tier?.measured_input_tokens ?? 0;\n const hotPx = tierTotal > 0 ? Math.round((tier.hot_tokens / tierTotal) * inputHeight) : 0;\n const warmPx = tierTotal > 0 ? Math.round((tier.warm_tokens / tierTotal) * inputHeight) : 0;\n const factsPx = tierTotal > 0 ? Math.round((tier.facts_tokens / tierTotal) * inputHeight) : 0;\n const overheadPx = tierTotal > 0 ? Math.max(0, inputHeight - hotPx - warmPx - factsPx) : 0;\n const clickable = !!onSelectDay && hasData;\n const tieredSegments = [\n { color: TIER_COLORS.hot, height: hotPx, delay: 30 },\n { color: TIER_COLORS.warm, height: warmPx, delay: 42 },\n { color: TIER_COLORS.facts, height: factsPx, delay: 54 },\n { color: TIER_COLORS.overhead, height: overheadPx, delay: 66 },\n ];\n\n return (\n <div\n onMouseEnter={() => onHover(idx)}\n onMouseLeave={() => onHover(null)}\n onClick={clickable ? () => onSelectDay!(point.day) : undefined}\n role={clickable ? \"button\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onKeyDown={clickable ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelectDay!(point.day);\n }\n } : undefined}\n className={`flex-1 min-w-0 h-full flex flex-col items-center justify-end ${clickable ? \"cursor-pointer\" : \"\"}`}\n aria-label={`${point.day} tokens${clickable ? \" — click to filter\" : \" (informational)\"}`}\n aria-pressed={clickable ? selected : undefined}\n >\n <div className={`w-full rounded-t overflow-hidden border transition-colors ${\n selected\n ? \"border-[var(--accent)]/70 shadow-[0_0_0_1px_var(--accent)]\"\n : hovered\n ? \"border-cyan-300/60 shadow-[0_0_0_1px_rgba(34,211,238,0.35)]\"\n : \"border-transparent\"\n }`}>\n {hasData ? (\n <>\n <div\n className=\"w-full bg-gradient-to-t from-amber-500 to-amber-300\"\n style={{\n height: barsReady ? `${outputHeight}px` : \"0px\",\n transition: `height 420ms cubic-bezier(0.2, 0.8, 0.2, 1) ${idx * 18}ms`,\n }}\n />\n {tierTotal > 0 ? (\n tieredSegments.map((seg, i) => (\n <div\n key={i}\n className=\"w-full\"\n style={{\n background: seg.color,\n height: barsReady ? `${seg.height}px` : \"0px\",\n transition: `height 420ms cubic-bezier(0.2, 0.8, 0.2, 1) ${idx * 18 + seg.delay}ms`,\n }}\n />\n ))\n ) : (\n <div\n className=\"w-full bg-gradient-to-t from-indigo-500 to-violet-400\"\n style={{\n height: barsReady ? `${inputHeight}px` : \"0px\",\n transition: `height 420ms cubic-bezier(0.2, 0.8, 0.2, 1) ${idx * 18 + 30}ms`,\n }}\n />\n )}\n </>\n ) : null}\n </div>\n <span className={`mt-1 text-[10px] truncate w-full text-center ${hasData ? \"text-[var(--text-secondary)]\" : \"text-[var(--text-secondary)]/50\"}`}>\n {point.day.slice(5)}\n </span>\n </div>\n );\n}\n\nfunction TokenChartLegend({ active }: { active: DashboardMetrics[\"series\"][number] | null }) {\n return (\n <div className=\"mt-2 flex flex-wrap items-center gap-3 text-[11px] text-[var(--text-secondary)]\">\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-sm\" style={{ background: TIER_COLORS.hot }} />hot</span>\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-sm\" style={{ background: TIER_COLORS.warm }} />warm</span>\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-sm\" style={{ background: TIER_COLORS.facts }} />facts</span>\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-sm\" style={{ background: TIER_COLORS.overhead }} />overhead</span>\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-full bg-violet-400\" />input (est)</span>\n <span className=\"inline-flex items-center gap-1\"><span className=\"w-2 h-2 rounded-full bg-amber-400\" />output</span>\n {active && (\n <span className=\"ml-auto text-[var(--text-primary)]\">\n {active.tier_tokens.measured_input_tokens > 0\n ? `hot ${formatInt(active.tier_tokens.hot_tokens)} · warm ${formatInt(active.tier_tokens.warm_tokens)} · facts ${formatInt(active.tier_tokens.facts_tokens)} · overhead ${formatInt(active.tier_tokens.overhead_tokens)} · out ${formatInt(active.output_tokens_est)}`\n : `in ${formatInt(active.input_tokens_est)} · out ${formatInt(active.output_tokens_est)}`}\n </span>\n )}\n </div>\n );\n}\n\ninterface CostChartProps {\n series: DashboardMetrics[\"series\"];\n currencyInfo: DashboardCurrencyInfo;\n selectedDay?: string | null;\n onSelectDay?: (day: string) => void;\n}\n\nexport function InteractiveCostChart({ series, currencyInfo, selectedDay, onSelectDay }: CostChartProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n const [lineAnimCycle, setLineAnimCycle] = useState(0);\n const width = 720;\n const height = 180;\n const padX = 24;\n const padY = 22;\n const maxCost = Math.max(0.000001, ...series.map((s) => convertUsd(s.estimated_cost_usd, currencyInfo)));\n\n const points = series.map((p, idx) => {\n const x = series.length <= 1\n ? width / 2\n : padX + (idx / (series.length - 1)) * (width - (padX * 2));\n const converted = convertUsd(p.estimated_cost_usd, currencyInfo);\n const y = height - padY - ((converted / maxCost) * (height - (padY * 2)));\n return { x, y, p, idx };\n });\n\n const polyline = points.map((pt) => `${pt.x},${pt.y}`).join(\" \");\n const active = hovered != null ? points[hovered] : null;\n const selectedIdx = selectedDay ? points.findIndex((pt) => pt.p.day === selectedDay) : -1;\n const selected = selectedIdx >= 0 ? points[selectedIdx] : null;\n const animationSignature = series.map((s) => `${s.day}:${s.estimated_cost_usd}`).join(\"|\");\n\n useEffect(() => { setLineAnimCycle((v) => v + 1); }, [animationSignature, selectedDay]);\n\n if (series.length === 0) {\n return <p className=\"text-xs text-[var(--text-secondary)]\">No cost data yet.</p>;\n }\n\n return (\n <div>\n <div className=\"relative rounded-xl bg-[var(--bg-primary)]/35 p-2\">\n <svg viewBox={`0 0 ${width} ${height}`} className=\"w-full h-48\" role=\"img\" aria-label=\"Estimated cost over time\">\n {[0.25, 0.5, 0.75].map((frac) => {\n const y = padY + (1 - frac) * (height - padY * 2);\n return (\n <line key={frac} x1={padX} y1={y} x2={width - padX} y2={y} stroke=\"rgba(148,163,184,0.12)\" strokeWidth=\"1\" strokeDasharray=\"3 4\" />\n );\n })}\n {[0.25, 0.5, 0.75, 1].map((frac) => {\n const y = padY + (1 - frac) * (height - padY * 2);\n const value = maxCost * frac;\n return (\n <text key={`tick-${frac}`} x={padX - 4} y={y + 3} textAnchor=\"end\" fill=\"currentColor\" className=\"fill-[var(--text-secondary)] text-[8px]\">\n {formatMoneyCompact(value / (currencyInfo.rate_from_usd || 1), currencyInfo)}\n </text>\n );\n })}\n <line x1={padX} y1={height - padY} x2={width - padX} y2={height - padY} stroke=\"rgba(148,163,184,0.45)\" strokeWidth=\"1\" />\n <line x1={padX} y1={padY} x2={padX} y2={height - padY} stroke=\"rgba(148,163,184,0.25)\" strokeWidth=\"1\" />\n <polyline\n key={`cost-line-${lineAnimCycle}`}\n fill=\"none\"\n stroke=\"rgba(16,185,129,0.95)\"\n strokeWidth=\"2.6\"\n points={polyline}\n pathLength={100}\n strokeDasharray={100}\n strokeDashoffset={100}\n >\n <animate attributeName=\"stroke-dashoffset\" from=\"100\" to=\"0\" dur=\"700ms\" fill=\"freeze\" />\n </polyline>\n {points.map((pt) => (\n <CostPoint\n key={pt.p.day}\n pt={pt}\n isActive={pt.idx === hovered}\n isSelected={pt.idx === selectedIdx}\n padY={padY}\n height={height}\n animCycle={lineAnimCycle}\n onHover={setHovered}\n onSelectDay={onSelectDay}\n />\n ))}\n </svg>\n <div\n className={`absolute right-3 top-3 inline-flex h-6 items-center gap-1.5 rounded-full px-2.5 text-[10px] tracking-wide transition-opacity ${\n active || selected\n ? \"bg-[var(--bg-secondary)]/85 text-[var(--text-primary)] opacity-100\"\n : \"text-[var(--text-secondary)] opacity-60\"\n }`}\n >\n {active\n ? `${active.p.day} · ${formatMoney(active.p.estimated_cost_usd, currencyInfo)}`\n : selected\n ? `selected ${selected.p.day} · ${formatMoney(selected.p.estimated_cost_usd, currencyInfo)}`\n : \"click a day to narrow breakdown\"}\n </div>\n </div>\n <div className=\"mt-2 flex flex-wrap items-center justify-between gap-3 text-[11px] text-[var(--text-secondary)]\">\n <span className=\"inline-flex items-center gap-1.5\">\n <span className=\"h-2 w-2 rounded-full bg-emerald-400\" />daily cost\n </span>\n <span className=\"tabular-nums text-[var(--text-primary)]\">\n window total {formatMoney(series.reduce((sum, s) => sum + s.estimated_cost_usd, 0), currencyInfo)}\n </span>\n </div>\n </div>\n );\n}\n\ninterface CostPointProps {\n pt: { x: number; y: number; p: DashboardMetrics[\"series\"][number]; idx: number };\n isActive: boolean;\n isSelected: boolean;\n padY: number;\n height: number;\n animCycle: number;\n onHover: (i: number | null) => void;\n onSelectDay?: (day: string) => void;\n}\n\nfunction CostPoint({ pt, isActive, isSelected, padY, height, animCycle, onHover, onSelectDay }: CostPointProps) {\n return (\n <g>\n {(isActive || isSelected) && (\n <line\n x1={pt.x}\n y1={padY}\n x2={pt.x}\n y2={height - padY}\n stroke={isSelected ? \"rgba(34,197,94,0.55)\" : \"rgba(20,184,166,0.35)\"}\n strokeWidth={isSelected ? 1.8 : 1.5}\n />\n )}\n {isSelected && (\n <circle cx={pt.x} cy={pt.y} r={8} fill=\"none\" stroke=\"rgba(34,197,94,0.85)\" strokeWidth={1.5}>\n <animate attributeName=\"r\" from=\"3.8\" to=\"9\" dur=\"800ms\" repeatCount=\"indefinite\" />\n <animate attributeName=\"opacity\" from=\"0.9\" to=\"0\" dur=\"800ms\" repeatCount=\"indefinite\" />\n </circle>\n )}\n <circle\n key={`${pt.p.day}-${animCycle}`}\n cx={pt.x}\n cy={pt.y}\n r={isSelected ? 5 : 3.8}\n fill={isSelected ? \"rgba(34,197,94,1)\" : isActive ? \"rgba(16,185,129,1)\" : \"rgba(52,211,153,0.85)\"}\n className={onSelectDay ? \"cursor-pointer\" : undefined}\n onMouseEnter={() => onHover(pt.idx)}\n onMouseLeave={() => onHover(null)}\n onClick={() => onSelectDay?.(pt.p.day)}\n >\n <animate attributeName=\"r\" from=\"0\" to={isSelected ? 5 : 3.8} dur=\"260ms\" begin={`${pt.idx * 28}ms`} fill=\"freeze\" />\n </circle>\n </g>\n );\n}\n","\"use client\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { InteractiveCostChart, InteractiveTokenChart } from \"./Series\";\n\ninterface TokensCostSectionProps {\n series: DashboardMetrics[\"series\"];\n currencyInfo: DashboardCurrencyInfo;\n selectedDay: string | null;\n onToggleDay: (day: string) => void;\n onClearDay: () => void;\n}\n\nexport function TokensCostSection({ series, currencyInfo, selectedDay, onToggleDay, onClearDay }: TokensCostSectionProps) {\n return (\n <section className=\"rounded-2xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 shadow-sm\">\n <div className=\"mb-3 flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium text-[var(--text-primary)]\">Tokens & cost over time</h3>\n {selectedDay ? (\n <button\n type=\"button\"\n onClick={onClearDay}\n className=\"inline-flex items-center gap-1.5 rounded-full border border-[var(--accent)]/40 bg-[var(--accent)]/10 px-2.5 py-1 text-[11px] text-[var(--text-primary)] transition-colors hover:bg-[var(--accent)]/20\"\n aria-label=\"Clear day selection\"\n >\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--accent)]\" />\n Showing breakdown for {selectedDay} · clear\n </button>\n ) : (\n <span className=\"text-[11px] text-[var(--text-secondary)]\">Click a day to narrow the breakdown</span>\n )}\n </div>\n <InteractiveTokenChart series={series} selectedDay={selectedDay} onSelectDay={onToggleDay} />\n <div className=\"mt-3 border-t border-[var(--border)]/60 pt-3\">\n <InteractiveCostChart series={series} currencyInfo={currencyInfo} selectedDay={selectedDay} onSelectDay={onToggleDay} />\n </div>\n </section>\n );\n}\n","// Heuristic model-functionality classifier driving the dashboard's\n// functionality filter. Pure so it can be exercised with table-driven tests.\n\nexport type ModelFunctionality =\n | \"embeddings\"\n | \"reranking\"\n | \"moderation\"\n | \"multimodal\"\n | \"audio\"\n | \"coding\"\n | \"reasoning\"\n | \"chat\"\n | \"other\";\n\nexport function detectModelFunctionality(modelId: string): ModelFunctionality {\n const id = (modelId ?? \"\").toLowerCase();\n if (/(embed|embedding|text-embedding|voyage-)/.test(id)) return \"embeddings\";\n if (/(rerank|rank)/.test(id)) return \"reranking\";\n if (/(moderation|safety)/.test(id)) return \"moderation\";\n if (/(image|vision|multimodal|omni|vl)/.test(id)) return \"multimodal\";\n if (/(audio|speech|tts|stt|whisper)/.test(id)) return \"audio\";\n if (/(code|coder|coding)/.test(id)) return \"coding\";\n if (/(reason|thinking|r1|o1|o3|deepthink)/.test(id)) return \"reasoning\";\n if (/(chat|instruct|gpt|claude|gemini|command|llama|mistral|qwen)/.test(id)) return \"chat\";\n return \"other\";\n}\n","// Pure sort + filter helpers for dashboard report panels. Extracted from the\n// React component so each rule can be table-tested without rendering.\n\nimport { detectModelFunctionality } from \"./classify\";\n\nexport type ModelSort =\n | \"model_asc\"\n | \"model_desc\"\n | \"input_desc\"\n | \"input_asc\"\n | \"output_desc\"\n | \"output_asc\"\n | \"confidence_desc\"\n | \"confidence_asc\";\n\nexport type ToolSort =\n | \"best\"\n | \"calls_desc\"\n | \"errors_desc\"\n | \"error_rate_desc\"\n | \"name_asc\";\n\nexport type Confidence = \"high\" | \"medium\" | \"low\";\n\nexport interface ModelRateRow {\n provider: string;\n model_id: string;\n input_per_1m_usd: number | null;\n output_per_1m_usd: number | null;\n confidence: Confidence;\n}\n\nexport interface ToolRow {\n name: string;\n call_count: number;\n error_count: number;\n score: number;\n success_rate: number;\n}\n\nexport interface ModelFilter {\n vendor: string;\n functionality: string;\n search: string;\n}\n\nfunction confidenceRank(c: Confidence): number {\n return c === \"high\" ? 3 : c === \"medium\" ? 2 : 1;\n}\n\nexport function filterModelRates<T extends ModelRateRow>(\n rows: ReadonlyArray<T>,\n filter: ModelFilter,\n): T[] {\n const query = (filter.search ?? \"\").trim().toLowerCase();\n return rows.filter((row) => {\n if (filter.vendor && filter.vendor !== \"all\" && row.provider !== filter.vendor) return false;\n if (\n filter.functionality &&\n filter.functionality !== \"all\" &&\n detectModelFunctionality(row.model_id) !== filter.functionality\n ) {\n return false;\n }\n if (!query) return true;\n return `${row.provider}/${row.model_id}`.toLowerCase().includes(query);\n });\n}\n\nexport function sortModelRates<T extends ModelRateRow>(\n rows: ReadonlyArray<T>,\n sort: ModelSort,\n): T[] {\n const copy = [...rows];\n copy.sort((a, b) => {\n if (sort === \"model_desc\") return b.model_id.localeCompare(a.model_id);\n if (sort === \"input_desc\") return (b.input_per_1m_usd ?? -1) - (a.input_per_1m_usd ?? -1);\n if (sort === \"input_asc\") {\n return (\n (a.input_per_1m_usd ?? Number.POSITIVE_INFINITY) -\n (b.input_per_1m_usd ?? Number.POSITIVE_INFINITY)\n );\n }\n if (sort === \"output_desc\") return (b.output_per_1m_usd ?? -1) - (a.output_per_1m_usd ?? -1);\n if (sort === \"output_asc\") {\n return (\n (a.output_per_1m_usd ?? Number.POSITIVE_INFINITY) -\n (b.output_per_1m_usd ?? Number.POSITIVE_INFINITY)\n );\n }\n if (sort === \"confidence_desc\") {\n const rankDiff = confidenceRank(b.confidence) - confidenceRank(a.confidence);\n if (rankDiff !== 0) return rankDiff;\n }\n if (sort === \"confidence_asc\") {\n const rankDiff = confidenceRank(a.confidence) - confidenceRank(b.confidence);\n if (rankDiff !== 0) return rankDiff;\n }\n return a.model_id.localeCompare(b.model_id);\n });\n return copy;\n}\n\nexport function groupModelRatesByVendor<T extends ModelRateRow>(\n rows: ReadonlyArray<T>,\n): Array<[string, T[]]> {\n const grouped = new Map<string, T[]>();\n for (const row of rows) {\n const arr = grouped.get(row.provider) ?? [];\n arr.push(row);\n grouped.set(row.provider, arr);\n }\n return [...grouped.entries()].sort((a, b) => a[0].localeCompare(b[0]));\n}\n\nexport function sortTools<T extends ToolRow>(\n rows: ReadonlyArray<T>,\n sort: ToolSort,\n): T[] {\n const copy = [...rows];\n copy.sort((a, b) => {\n if (sort === \"calls_desc\") {\n if (b.call_count !== a.call_count) return b.call_count - a.call_count;\n } else if (sort === \"errors_desc\") {\n if (b.error_count !== a.error_count) return b.error_count - a.error_count;\n } else if (sort === \"error_rate_desc\") {\n const aRate = a.call_count > 0 ? a.error_count / a.call_count : 0;\n const bRate = b.call_count > 0 ? b.error_count / b.call_count : 0;\n if (bRate !== aRate) return bRate - aRate;\n } else if (sort === \"name_asc\") {\n return a.name.localeCompare(b.name);\n } else {\n if (b.score !== a.score) return b.score - a.score;\n if (b.success_rate !== a.success_rate) return b.success_rate - a.success_rate;\n if (b.call_count !== a.call_count) return b.call_count - a.call_count;\n }\n return a.name.localeCompare(b.name);\n });\n return copy;\n}\n","// Pure color helpers used by dashboard chart rendering. Kept side-effect free\n// so they can be unit-tested in node and reused across visualizations.\n\nexport function parseHexColor(value: string): [number, number, number] | null {\n if (typeof value !== \"string\") return null;\n const hex = value.trim();\n if (!/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(hex)) return null;\n const normalized = hex.length === 4\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex;\n const raw = normalized.slice(1);\n const r = Number.parseInt(raw.slice(0, 2), 16);\n const g = Number.parseInt(raw.slice(2, 4), 16);\n const b = Number.parseInt(raw.slice(4, 6), 16);\n return [r, g, b];\n}\n\nexport function shiftHex(value: string, amount: number): string {\n const rgb = parseHexColor(value);\n if (!rgb) return value;\n const t = Math.max(-1, Math.min(1, amount));\n const shiftChannel = (channel: number): number => {\n if (t >= 0) return Math.round(channel + ((255 - channel) * t));\n return Math.round(channel * (1 + t));\n };\n return `rgb(${shiftChannel(rgb[0])}, ${shiftChannel(rgb[1])}, ${shiftChannel(rgb[2])})`;\n}\n\nexport function withAlpha(value: string, alpha: number): string {\n const rgb = parseHexColor(value);\n const a = Math.max(0, Math.min(1, alpha));\n if (!rgb) return `rgba(34, 197, 94, ${a})`;\n return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${a})`;\n}\n","// SVG arc geometry helper for donut/pie charts.\n\nexport function arcPath(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n): string {\n if (!(endAngle > startAngle)) return \"\";\n const x1 = cx + r * Math.cos(startAngle);\n const y1 = cy + r * Math.sin(startAngle);\n const x2 = cx + r * Math.cos(endAngle);\n const y2 = cy + r * Math.sin(endAngle);\n const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;\n return `M ${x1} ${y1} A ${r} ${r} 0 ${largeArc} 1 ${x2} ${y2}`;\n}\n","\"use client\";\nimport { useEffect, useId, useState } from \"react\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { withAlpha } from \"@/lib/dashboard/color\";\nimport { arcPath } from \"@/lib/dashboard/geometry\";\nimport { formatInt, formatMoney, formatMoneyCompact } from \"@/lib/dashboard/format\";\n\nexport type DonutSlice = {\n id: string;\n label: string;\n value: number;\n color: string;\n};\n\ninterface DonutProps {\n ariaLabel: string;\n size: number;\n centerAmount: string;\n slices: DonutSlice[];\n hovered: number | null;\n onHoverChange: (index: number | null) => void;\n}\n\nexport function SharedDonutChart({ ariaLabel, size, centerAmount, slices, hovered, onHoverChange }: DonutProps) {\n const uid = useId().replace(/:/g, \"\");\n const [animCycle, setAnimCycle] = useState(0);\n const stroke = size >= 170 ? 26 : 20;\n const padding = Math.ceil(stroke / 2) + 6;\n const cx = size / 2;\n const cy = size / 2;\n const radius = Math.max(16, (size - (padding * 2) - stroke) / 2);\n const innerRadius = Math.max(14, radius - (stroke / 2) + 2);\n const gap = 0.03;\n const total = slices.reduce((sum, s) => sum + Math.max(0, s.value), 0);\n const animationSignature = slices.map((slice) => `${slice.id}:${slice.value.toFixed(6)}`).join(\"|\");\n\n useEffect(() => { setAnimCycle((v) => v + 1); }, [animationSignature]);\n\n const segments = slices.map((slice, idx) => {\n const value = Math.max(0, slice.value);\n const fraction = total > 0 ? value / total : 1 / Math.max(1, slices.length);\n const startAngle = -Math.PI / 2 + slices\n .slice(0, idx)\n .reduce((sum, s) => sum + (total > 0 ? Math.max(0, s.value) / total : 1 / Math.max(1, slices.length)), 0) * Math.PI * 2;\n const sweep = fraction * Math.PI * 2;\n const gapSafe = Math.min(gap, sweep * 0.45);\n const arcStart = startAngle + (gapSafe / 2);\n const arcEnd = startAngle + sweep - (gapSafe / 2);\n return { ...slice, idx, fraction, path: arcPath(cx, cy, radius, arcStart, arcEnd) };\n });\n\n const active = hovered != null ? segments[hovered] : null;\n const glowColor = active?.color ?? \"#22c55e\";\n\n return (\n <div className=\"flex flex-col items-center\">\n <div className=\"relative\" style={{ width: `${size}px`, height: `${size}px` }}>\n <div\n className=\"pointer-events-none absolute inset-4 rounded-full blur-2xl\"\n style={{\n background: `radial-gradient(circle, ${withAlpha(glowColor, 0.28)} 0%, transparent 72%)`,\n opacity: active ? 0.85 : 0.55,\n transition: \"opacity 180ms ease\",\n }}\n />\n <svg viewBox={`0 0 ${size} ${size}`} className=\"h-full w-full\" role=\"img\" aria-label={ariaLabel}>\n <defs>\n <radialGradient id={`${uid}-center`} cx=\"50%\" cy=\"38%\" r=\"70%\">\n <stop offset=\"0%\" stopColor=\"var(--bg-secondary)\" stopOpacity=\"0.98\" />\n <stop offset=\"100%\" stopColor=\"var(--bg-primary)\" stopOpacity=\"0.92\" />\n </radialGradient>\n </defs>\n <circle cx={cx} cy={cy} r={radius} fill=\"none\" stroke=\"rgba(148,163,184,0.18)\" strokeWidth={stroke} />\n {segments.map((segment) => (\n <g key={segment.id}>\n <path\n key={`${segment.id}-${animCycle}`}\n d={segment.path}\n fill=\"none\"\n stroke={segment.color}\n strokeLinecap=\"butt\"\n strokeLinejoin=\"round\"\n strokeWidth={hovered === segment.idx ? stroke + 2 : stroke}\n pathLength={100}\n strokeDasharray={100}\n strokeDashoffset={100}\n opacity={hovered == null || hovered === segment.idx ? 0.97 : 0.54}\n style={{ transition: \"opacity 180ms ease, stroke-width 180ms ease\" }}\n onMouseEnter={() => onHoverChange(segment.idx)}\n onMouseLeave={() => onHoverChange(null)}\n >\n <animate attributeName=\"stroke-dashoffset\" from=\"100\" to=\"0\" dur=\"620ms\" begin={`${segment.idx * 65}ms`} fill=\"freeze\" />\n </path>\n </g>\n ))}\n <circle cx={cx} cy={cy} r={innerRadius} fill={`url(#${uid}-center)`} stroke=\"var(--border)\" strokeWidth=\"1\" />\n </svg>\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center text-center\">\n <div className=\"max-w-[70%]\">\n <div className={`${size >= 170 ? \"text-sm\" : \"text-xs\"} font-semibold leading-tight text-[var(--text-primary)] truncate`}>\n {centerAmount}\n </div>\n </div>\n </div>\n </div>\n <div\n className={`mt-2 inline-flex h-6 items-center gap-1.5 rounded-full px-2.5 text-[10px] tracking-wide transition-opacity ${\n active ? \"bg-[var(--bg-primary)]/60 text-[var(--text-primary)] opacity-100\" : \"bg-transparent text-[var(--text-secondary)] opacity-60\"\n }`}\n >\n {active ? (\n <>\n <span className=\"h-2 w-2 rounded-full\" style={{ backgroundColor: active.color }} />\n <span className=\"max-w-[160px] truncate\">{active.label}</span>\n <span className=\"font-medium\">{(active.fraction * 100).toFixed(1)}%</span>\n </>\n ) : (\n <span>hover a segment</span>\n )}\n </div>\n </div>\n );\n}\n\nconst AGENT_PALETTE = [\"#22c55e\", \"#06b6d4\", \"#3b82f6\", \"#8b5cf6\", \"#f59e0b\", \"#ef4444\"];\n\ninterface AgentCostPieProps {\n agents: DashboardMetrics[\"top_agents\"];\n currencyInfo: DashboardCurrencyInfo;\n}\n\nexport function AgentCostPie({ agents, currencyInfo }: AgentCostPieProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n if (agents.length === 0) {\n return <p className=\"text-xs text-[var(--text-secondary)]\">No recent traffic yet.</p>;\n }\n const total = agents.reduce((sum, a) => sum + Math.max(0, a.estimated_cost_usd), 0);\n const fractions = agents.map((agent) => {\n const value = Math.max(0, agent.estimated_cost_usd);\n return total > 0 ? value / total : 1 / agents.length;\n });\n const slices = agents.map((agent, idx) => ({\n idx,\n agent,\n value: Math.max(0, agent.estimated_cost_usd),\n fraction: fractions[idx],\n color: AGENT_PALETTE[idx % AGENT_PALETTE.length],\n }));\n\n return (\n <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-[190px_1fr]\">\n <SharedDonutChart\n ariaLabel=\"Agent cost share pie chart\"\n size={190}\n centerAmount={formatMoneyCompact(total, currencyInfo)}\n hovered={hovered}\n onHoverChange={setHovered}\n slices={slices.map((slice) => ({\n id: slice.agent.agent_id,\n label: slice.agent.agent_name,\n value: slice.value,\n color: slice.color,\n }))}\n />\n <div className=\"space-y-2\">\n {slices.map((slice) => (\n <div\n key={slice.agent.agent_id}\n onMouseEnter={() => setHovered(slice.idx)}\n onMouseLeave={() => setHovered(null)}\n className={`rounded-lg border px-3 py-2 transition-colors ${\n hovered === slice.idx\n ? \"border-[var(--accent)]/50 bg-[var(--bg-primary)]/70\"\n : \"border-[var(--border)] bg-[var(--bg-primary)]/45\"\n }`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"inline-flex min-w-0 items-center gap-2 text-sm text-[var(--text-primary)]\">\n <span className=\"h-2.5 w-2.5 shrink-0 rounded-full\" style={{ backgroundColor: slice.color }} />\n <span className=\"truncate\">{slice.agent.agent_name}</span>\n </span>\n <span className=\"text-xs text-[var(--text-secondary)]\">{formatMoney(slice.value, currencyInfo)}</span>\n </div>\n <div className=\"mt-1 text-xs text-[var(--text-secondary)]\">\n {(slice.fraction * 100).toFixed(1)}% · {formatInt(slice.agent.message_count)} msgs · {formatInt(slice.agent.input_tokens_est + slice.agent.output_tokens_est)} tokens\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nconst BREAKDOWN_PALETTE = [\"#14b8a6\", \"#22c55e\", \"#3b82f6\", \"#8b5cf6\", \"#f59e0b\", \"#ef4444\", \"#06b6d4\", \"#84cc16\"];\n\ninterface BreakdownPieProps {\n title: string;\n items: Array<{ id: string; label: string; cost: number; detail: string }>;\n currencyInfo: DashboardCurrencyInfo;\n emptyLabel: string;\n}\n\nexport function BreakdownPiePanel({ title, items, currencyInfo, emptyLabel }: BreakdownPieProps) {\n const [hovered, setHovered] = useState<number | null>(null);\n\n if (items.length === 0) {\n return (\n <div className=\"rounded-lg border border-[var(--border)] bg-[var(--bg-primary)]/35 p-3\">\n <div className=\"text-xs font-medium text-[var(--text-primary)]\">{title}</div>\n <p className=\"mt-2 text-xs text-[var(--text-secondary)]\">{emptyLabel}</p>\n </div>\n );\n }\n\n const total = items.reduce((sum, item) => sum + Math.max(0, item.cost), 0);\n const fractions = items.map((item) => {\n const value = Math.max(0, item.cost);\n return total > 0 ? value / total : 1 / items.length;\n });\n const slices = items.map((item, idx) => ({\n ...item,\n idx,\n value: Math.max(0, item.cost),\n fraction: fractions[idx],\n color: BREAKDOWN_PALETTE[idx % BREAKDOWN_PALETTE.length],\n }));\n\n return (\n <div className=\"rounded-lg border border-[var(--border)] bg-[var(--bg-primary)]/35 p-3\">\n <div className=\"mb-2 text-xs font-medium text-[var(--text-primary)]\">{title}</div>\n <div className=\"grid grid-cols-[136px_1fr] gap-3\">\n <SharedDonutChart\n ariaLabel={`${title} pie chart`}\n size={136}\n centerAmount={formatMoneyCompact(total, currencyInfo)}\n hovered={hovered}\n onHoverChange={setHovered}\n slices={slices.map((slice) => ({ id: slice.id, label: slice.label, value: slice.value, color: slice.color }))}\n />\n <div className=\"max-h-56 space-y-1.5 overflow-auto pr-1\">\n {slices.map((slice) => (\n <div\n key={slice.id}\n onMouseEnter={() => setHovered(slice.idx)}\n onMouseLeave={() => setHovered(null)}\n className={`rounded-md px-2.5 py-2 ${\n hovered === slice.idx ? \"bg-[var(--bg-primary)]/70\" : \"bg-[var(--bg-primary)]/35\"\n }`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"inline-flex min-w-0 items-center gap-1.5 text-xs text-[var(--text-primary)]\">\n <span className=\"h-2.5 w-2.5 shrink-0 rounded-full\" style={{ backgroundColor: slice.color }} />\n <span className=\"truncate\">{slice.label}</span>\n </span>\n <span className=\"text-[11px] text-[var(--text-secondary)]\">{formatMoney(slice.value, currencyInfo)}</span>\n </div>\n <div className=\"mt-0.5 text-[10px] text-[var(--text-secondary)] truncate\">\n {(slice.fraction * 100).toFixed(1)}% · {slice.detail}\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { sortTools, type ToolSort } from \"@/lib/dashboard/sort\";\nimport { AgentCostPie } from \"./Donuts\";\nimport { TOOL_SORT_OPTIONS } from \"./dashboard-constants\";\n\ninterface ToolsAndAgentsRowProps {\n data: DashboardMetrics;\n toolSort: ToolSort;\n onToolSortChange: (sort: ToolSort) => void;\n effectiveTopAgents: DashboardMetrics[\"top_agents\"];\n selectedDay: string | null;\n currencyInfo: DashboardCurrencyInfo;\n}\n\nexport function ToolsAndAgentsRow({ data, toolSort, onToolSortChange, effectiveTopAgents, selectedDay, currencyInfo }: ToolsAndAgentsRowProps) {\n const sortedTools = sortTools(data.top_tools, toolSort);\n return (\n <div className=\"grid md:grid-cols-2 gap-4\">\n <section className=\"rounded-2xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 shadow-sm\">\n <div className=\"mb-3 flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium text-[var(--text-primary)]\">Favorite tools</h3>\n <select\n value={toolSort}\n onChange={(e) => onToolSortChange(e.target.value as ToolSort)}\n className=\"rounded-md border border-[var(--border)] bg-[var(--bg-primary)] px-2 py-1 text-xs text-[var(--text-primary)]\"\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-primary)\" }}\n >\n {TOOL_SORT_OPTIONS.map((opt) => (\n <option\n key={opt.value}\n value={opt.value}\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}\n >\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n <div className=\"space-y-2\">\n {sortedTools.length === 0 ? (\n <p className=\"text-xs text-[var(--text-secondary)]\">No tool calls recorded yet.</p>\n ) : (\n sortedTools.map((tool) => (\n <div key={tool.name} className=\"rounded-lg bg-[var(--bg-primary)]/35 px-3 py-2\">\n <div className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm text-[var(--text-primary)]\">{tool.name}</div>\n <div className=\"mt-0.5 text-[11px] text-[var(--text-secondary)]\">\n score {tool.score.toFixed(2)} · {(tool.success_rate * 100).toFixed(1)}% success · {tool.call_count} calls · {tool.error_count} errors\n </div>\n </div>\n <span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${\n tool.score >= 0.85\n ? \"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300\"\n : tool.score >= 0.65\n ? \"bg-amber-500/15 text-amber-700 dark:text-amber-300\"\n : \"bg-rose-500/15 text-rose-700 dark:text-rose-300\"\n }`}>\n {tool.score >= 0.85 ? \"keep\" : tool.score >= 0.65 ? \"review\" : \"consider disable\"}\n </span>\n </div>\n </div>\n ))\n )}\n </div>\n </section>\n\n <section className=\"rounded-2xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 shadow-sm\">\n <h3 className=\"text-sm font-medium text-[var(--text-primary)] mb-3\">\n Agent cost hotspots\n {selectedDay ? <span className=\"ml-2 text-[11px] text-[var(--text-secondary)]\">on {selectedDay}</span> : null}\n </h3>\n <AgentCostPie\n key={`agents-${selectedDay ?? \"all\"}`}\n agents={effectiveTopAgents.slice(0, 6)}\n currencyInfo={currencyInfo}\n />\n </section>\n </div>\n );\n}\n","\"use client\";\nimport type { DashboardCurrencyInfo, DashboardMetrics } from \"@/api/types\";\nimport { formatInt } from \"@/lib/dashboard/format\";\nimport { BreakdownPiePanel } from \"./Donuts\";\n\ninterface VendorModelReportSectionProps {\n effectiveByProvider: DashboardMetrics[\"by_provider\"];\n effectiveByModel: DashboardMetrics[\"by_model\"];\n selectedDay: string | null;\n currencyInfo: DashboardCurrencyInfo;\n}\n\nexport function VendorModelReportSection({ effectiveByProvider, effectiveByModel, selectedDay, currencyInfo }: VendorModelReportSectionProps) {\n return (\n <section className=\"rounded-2xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 space-y-3 shadow-sm\">\n <h3 className=\"text-sm font-medium text-[var(--text-primary)]\">\n Vendor and model report\n {selectedDay ? <span className=\"ml-2 text-[11px] text-[var(--text-secondary)]\">scoped to {selectedDay}</span> : null}\n </h3>\n <div className=\"grid lg:grid-cols-2 gap-3\">\n <BreakdownPiePanel\n key={`vendor-${selectedDay ?? \"all\"}`}\n title=\"By vendor\"\n emptyLabel={selectedDay ? `No vendor activity on ${selectedDay}.` : \"No vendor breakdown data yet.\"}\n items={effectiveByProvider.slice(0, 12).map((row) => ({\n id: row.provider,\n label: row.provider,\n cost: row.estimated_cost_usd,\n detail: `${formatInt(row.message_count)} msgs · ${formatInt(row.input_tokens_est + row.output_tokens_est)} tokens`,\n }))}\n currencyInfo={currencyInfo}\n />\n <BreakdownPiePanel\n key={`model-${selectedDay ?? \"all\"}`}\n title=\"By model config\"\n emptyLabel={selectedDay ? `No model activity on ${selectedDay}.` : \"No model breakdown data yet.\"}\n items={effectiveByModel.slice(0, 16).map((row) => ({\n id: `${row.provider}:${row.model_config_name}:${row.model_id}`,\n label: row.model_config_name,\n cost: row.estimated_cost_usd,\n detail: `${row.provider}/${row.model_id} · ${formatInt(row.message_count)} msgs`,\n }))}\n currencyInfo={currencyInfo}\n />\n </div>\n </section>\n );\n}\n","\"use client\";\nimport type { DashboardMetrics } from \"@/api/types\";\nimport { detectModelFunctionality } from \"@/lib/dashboard/classify\";\nimport { safeHttpUrl } from \"@/lib/dashboard/format\";\nimport {\n filterModelRates,\n groupModelRatesByVendor,\n sortModelRates,\n type ModelSort,\n} from \"@/lib/dashboard/sort\";\nimport { MODEL_SORT_OPTIONS } from \"./dashboard-constants\";\n\ninterface ModelPricingSectionProps {\n data: DashboardMetrics;\n modelVendorFilter: string;\n onVendorFilterChange: (v: string) => void;\n modelFunctionFilter: string;\n onFunctionFilterChange: (v: string) => void;\n modelSearch: string;\n onSearchChange: (v: string) => void;\n modelSort: ModelSort;\n onSortChange: (s: ModelSort) => void;\n}\n\nexport function ModelPricingSection({\n data,\n modelVendorFilter,\n onVendorFilterChange,\n modelFunctionFilter,\n onFunctionFilterChange,\n modelSearch,\n onSearchChange,\n modelSort,\n onSortChange,\n}: ModelPricingSectionProps) {\n const filtered = sortModelRates(\n filterModelRates(data.pricing.model_rates, {\n vendor: modelVendorFilter,\n functionality: modelFunctionFilter,\n search: modelSearch,\n }),\n modelSort,\n );\n const grouped = groupModelRatesByVendor(filtered);\n const vendors = [...new Set(data.pricing.model_rates.map((r) => r.provider))].sort();\n const functionalities = [...new Set(data.pricing.model_rates.map((r) => detectModelFunctionality(r.model_id)))].sort();\n\n return (\n <section className=\"rounded-2xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 space-y-2 shadow-sm\">\n <h3 className=\"text-sm font-medium text-[var(--text-primary)]\">Pricing source and assumptions</h3>\n <p className=\"text-xs text-[var(--text-secondary)]\">\n Snapshot: {data.pricing.snapshot_generated_at ?? \"not found\"}\n </p>\n <div className=\"rounded-lg bg-[var(--bg-primary)]/25 overflow-hidden\">\n <div className=\"px-3 py-2 text-xs font-medium text-[var(--text-primary)]\">\n Model pricing (detected)\n </div>\n <div className=\"px-3 pb-2\">\n <div className=\"grid gap-2 md:grid-cols-[160px_160px_1fr_190px]\">\n <select\n value={modelVendorFilter}\n onChange={(e) => onVendorFilterChange(e.target.value)}\n className=\"rounded-md border border-[var(--border)] bg-[var(--bg-primary)] px-2 py-1 text-xs text-[var(--text-primary)]\"\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-primary)\" }}\n >\n <option value=\"all\" style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}>All vendors</option>\n {vendors.map((provider) => (\n <option key={provider} value={provider} style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}>\n {provider}\n </option>\n ))}\n </select>\n <select\n value={modelFunctionFilter}\n onChange={(e) => onFunctionFilterChange(e.target.value)}\n className=\"rounded-md border border-[var(--border)] bg-[var(--bg-primary)] px-2 py-1 text-xs text-[var(--text-primary)]\"\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-primary)\" }}\n >\n <option value=\"all\" style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}>All functions</option>\n {functionalities.map((func) => (\n <option key={func} value={func} style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}>\n {func}\n </option>\n ))}\n </select>\n <input\n value={modelSearch}\n onChange={(e) => onSearchChange(e.target.value)}\n placeholder=\"Filter models (e.g. gpt, gemini, deepseek)\"\n className=\"rounded-md border border-[var(--border)] bg-[var(--bg-primary)] px-2 py-1 text-xs text-[var(--text-primary)]\"\n />\n <select\n value={modelSort}\n onChange={(e) => onSortChange(e.target.value as ModelSort)}\n className=\"rounded-md border border-[var(--border)] bg-[var(--bg-primary)] px-2 py-1 text-xs text-[var(--text-primary)]\"\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-primary)\" }}\n >\n {MODEL_SORT_OPTIONS.map((opt) => (\n <option\n key={opt.value}\n value={opt.value}\n style={{ color: \"var(--text-primary)\", backgroundColor: \"var(--bg-secondary)\" }}\n >\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"max-h-72 overflow-auto\">\n {filtered.length === 0 ? (\n <p className=\"p-3 text-xs text-[var(--text-secondary)]\">No model rates match the selected filters.</p>\n ) : (\n grouped.map(([provider, rows]) => (\n <ModelPricingGroup key={provider} provider={provider} rows={rows} />\n ))\n )}\n </div>\n </div>\n <p className=\"text-[11px] text-[var(--text-secondary)]\">{data.pricing.notes}</p>\n </section>\n );\n}\n\nfunction ModelPricingGroup({ provider, rows }: { provider: string; rows: DashboardMetrics[\"pricing\"][\"model_rates\"] }) {\n return (\n <div className=\"border-b border-[var(--border)]/60 last:border-b-0\">\n <div className=\"sticky top-0 z-10 flex items-center justify-between gap-2 border-l-2 border-l-[var(--accent)] bg-[var(--bg-secondary)]/95 px-3 py-2 text-xs font-semibold uppercase tracking-wider text-[var(--text-primary)] backdrop-blur\">\n <span>{provider}</span>\n <span className=\"rounded-full border border-[var(--border)] bg-[var(--bg-primary)]/60 px-2 py-0.5 text-[10px] font-medium normal-case tracking-normal text-[var(--text-secondary)]\">\n {rows.length} model{rows.length === 1 ? \"\" : \"s\"}\n </span>\n </div>\n {rows.map((row) => (\n <ModelPricingRow key={`${row.provider}:${row.model_id}`} row={row} />\n ))}\n </div>\n );\n}\n\nfunction ModelPricingRow({ row }: { row: DashboardMetrics[\"pricing\"][\"model_rates\"][number] }) {\n return (\n <div className=\"px-3 py-2 border-t border-[var(--border)]/40 hover:bg-[var(--bg-primary)]/35 transition-colors\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm text-[var(--text-primary)] truncate\">{row.model_id}</span>\n <span className=\"text-[11px] tabular-nums text-[var(--text-secondary)]\">\n in <span className=\"text-[var(--text-primary)]\">${row.input_per_1m_usd?.toFixed(2) ?? \"n/a\"}</span>\n {\" · \"}out <span className=\"text-[var(--text-primary)]\">${row.output_per_1m_usd?.toFixed(2) ?? \"n/a\"}</span>\n </span>\n </div>\n <div className=\"mt-1.5 flex flex-wrap items-center gap-1.5 text-[10px]\">\n <span className={`rounded-full px-1.5 py-0.5 font-medium ${\n row.inferred\n ? \"bg-amber-500/15 text-amber-700 dark:text-amber-300\"\n : \"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300\"\n }`}>\n {row.inferred ? \"inferred\" : \"explicit\"}\n </span>\n <span className={`rounded-full px-1.5 py-0.5 font-medium ${\n row.confidence === \"high\"\n ? \"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300\"\n : row.confidence === \"medium\"\n ? \"bg-amber-500/15 text-amber-700 dark:text-amber-300\"\n : \"bg-rose-500/15 text-rose-700 dark:text-rose-300\"\n }`}>\n {row.confidence}\n </span>\n <span className=\"rounded-full bg-[var(--bg-primary)]/60 px-1.5 py-0.5 text-[var(--text-secondary)]\">\n {detectModelFunctionality(row.model_id)}\n </span>\n {safeHttpUrl(row.source) ? (\n <a\n href={row.source}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-auto rounded-full bg-cyan-500/15 px-1.5 py-0.5 text-cyan-700 hover:bg-cyan-500/25 dark:text-cyan-300\"\n >\n source ↗\n </a>\n ) : null}\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { DashboardCurrencyInfo, UserProfile } from \"@/api/types\";\nimport { CURRENCY_MODE_KEY, CURRENCY_PICK_KEY, USD_CURRENCY, type CurrencyMode } from \"./dashboard-constants\";\n\nexport interface UseCurrencyPreferenceResult {\n currencyInfo: DashboardCurrencyInfo;\n currencyMode: CurrencyMode;\n setCurrencyMode: (m: CurrencyMode) => void;\n manualCurrency: string;\n setManualCurrency: (c: string) => void;\n}\n\nexport function useCurrencyPreference(): UseCurrencyPreferenceResult {\n const [currencyInfo, setCurrencyInfo] = useState<DashboardCurrencyInfo>(USD_CURRENCY);\n const [currencyMode, setCurrencyMode] = useState<CurrencyMode>(\"auto\");\n const [manualCurrency, setManualCurrency] = useState<string>(\"USD\");\n const [profileLocation, setProfileLocation] = useState<{ lat: number | null; lng: number | null }>({ lat: null, lng: null });\n\n useEffect(() => {\n try {\n const savedMode = window.localStorage.getItem(CURRENCY_MODE_KEY);\n if (savedMode === \"auto\" || savedMode === \"manual\") setCurrencyMode(savedMode);\n const savedCurrency = window.localStorage.getItem(CURRENCY_PICK_KEY);\n if (savedCurrency && /^[A-Z]{3}$/.test(savedCurrency)) setManualCurrency(savedCurrency);\n } catch { /* ignore storage failures */ }\n }, []);\n\n useEffect(() => {\n try {\n window.localStorage.setItem(CURRENCY_MODE_KEY, currencyMode);\n window.localStorage.setItem(CURRENCY_PICK_KEY, manualCurrency);\n } catch { /* ignore storage failures */ }\n }, [currencyMode, manualCurrency]);\n\n useEffect(() => {\n let cancelled = false;\n api.profile.get()\n .then((profile: UserProfile) => {\n if (cancelled) return;\n setProfileLocation({\n lat: Number.isFinite(profile.location_lat) ? (profile.location_lat as number) : null,\n lng: Number.isFinite(profile.location_lng) ? (profile.location_lng as number) : null,\n });\n })\n .catch(() => { if (!cancelled) setProfileLocation({ lat: null, lng: null }); });\n return () => { cancelled = true; };\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n if (currencyMode === \"manual\") {\n api.dashboard.currency({ currency: manualCurrency })\n .then((resolved) => { if (!cancelled) setCurrencyInfo(resolved); })\n .catch(() => { if (!cancelled) setCurrencyInfo(USD_CURRENCY); });\n return () => { cancelled = true; };\n }\n if (!Number.isFinite(profileLocation.lat) || !Number.isFinite(profileLocation.lng)) {\n setCurrencyInfo(USD_CURRENCY);\n return () => { cancelled = true; };\n }\n api.dashboard.currency({ lat: profileLocation.lat, lng: profileLocation.lng })\n .then((resolved) => { if (!cancelled) setCurrencyInfo(resolved); })\n .catch(() => { if (!cancelled) setCurrencyInfo(USD_CURRENCY); });\n return () => { cancelled = true; };\n }, [currencyMode, manualCurrency, profileLocation.lat, profileLocation.lng]);\n\n return { currencyInfo, currencyMode, setCurrencyMode, manualCurrency, setManualCurrency };\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { api } from \"@/api/client\";\nimport type { DashboardMetrics } from \"@/api/types\";\nimport type { WindowDays } from \"./dashboard-constants\";\n\nexport interface UseDashboardDataResult {\n days: WindowDays;\n setDays: (d: WindowDays) => void;\n loading: boolean;\n error: string | null;\n data: DashboardMetrics | null;\n refreshingPricing: boolean;\n refreshHint: string | null;\n onRefreshPricing: () => Promise<void>;\n}\n\nexport function useDashboardData(initialDays: WindowDays = 30): UseDashboardDataResult {\n const [days, setDays] = useState<WindowDays>(initialDays);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [data, setData] = useState<DashboardMetrics | null>(null);\n const [refreshingPricing, setRefreshingPricing] = useState(false);\n const [refreshHint, setRefreshHint] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(null);\n api.dashboard.metrics(days)\n .then((res) => { if (!cancelled) setData(res); })\n .catch((err: unknown) => { if (!cancelled) setError(err instanceof Error ? err.message : String(err)); })\n .finally(() => { if (!cancelled) setLoading(false); });\n return () => { cancelled = true; };\n }, [days]);\n\n const onRefreshPricing = async () => {\n setRefreshingPricing(true);\n setRefreshHint(null);\n try {\n const res = await api.dashboard.refreshPricing({ force: true });\n setRefreshHint(res.refreshed ? \"Pricing snapshot refreshed.\" : \"Pricing snapshot already fresh.\");\n setLoading(true);\n setError(null);\n const metrics = await api.dashboard.metrics(days);\n setData(metrics);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Failed to refresh pricing.\";\n setRefreshHint(message);\n setError(message);\n } finally {\n setLoading(false);\n setRefreshingPricing(false);\n }\n };\n\n return { days, setDays, loading, error, data, refreshingPricing, refreshHint, onRefreshPricing };\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { ModelSort, ToolSort } from \"@/lib/dashboard/sort\";\nimport { CurrencyPickerRow } from \"./CurrencyPickerRow\";\nimport { DashboardHeader } from \"./DashboardHeader\";\nimport { MetricCardsGrid, SummaryStrip } from \"./SummaryCards\";\nimport { TokensCostSection } from \"./TokensCostSection\";\nimport { ToolsAndAgentsRow } from \"./ToolsAndAgentsRow\";\nimport { VendorModelReportSection } from \"./VendorModelReportSection\";\nimport { ModelPricingSection } from \"./ModelPricingSection\";\nimport { useCurrencyPreference } from \"./useCurrencyPreference\";\nimport { useDashboardData } from \"./useDashboardData\";\n\nexport function DashboardPanel() {\n const {\n days, setDays, loading, error, data,\n refreshingPricing, refreshHint, onRefreshPricing,\n } = useDashboardData(30);\n const {\n currencyInfo, currencyMode, setCurrencyMode,\n manualCurrency, setManualCurrency,\n } = useCurrencyPreference();\n const [toolSort, setToolSort] = useState<ToolSort>(\"best\");\n const [modelVendorFilter, setModelVendorFilter] = useState<string>(\"all\");\n const [modelFunctionFilter, setModelFunctionFilter] = useState<string>(\"all\");\n const [modelSearch, setModelSearch] = useState<string>(\"\");\n const [modelSort, setModelSort] = useState<ModelSort>(\"model_asc\");\n const [selectedDay, setSelectedDay] = useState<string | null>(null);\n\n // Drop the day selection whenever the window changes; otherwise the\n // breakdown would silently show stale numbers for a day no longer in range.\n useEffect(() => { setSelectedDay(null); }, [days]);\n\n const series = useMemo(() => data?.series ?? [], [data]);\n const dayBreakdown = useMemo(() => {\n if (!data || !selectedDay) return null;\n return data.breakdowns_by_day[selectedDay] ?? null;\n }, [data, selectedDay]);\n\n const effectiveTopAgents = dayBreakdown?.top_agents ?? data?.top_agents ?? [];\n const effectiveByProvider = dayBreakdown?.by_provider ?? data?.by_provider ?? [];\n const effectiveByModel = dayBreakdown?.by_model ?? data?.by_model ?? [];\n const effectiveSummary = dayBreakdown?.summary ?? data?.summary;\n\n const windowTokenTotal = (data?.summary.input_tokens_est ?? 0) + (data?.summary.output_tokens_est ?? 0);\n const activeDays = series.filter((s) => (s.input_tokens_est + s.output_tokens_est) > 0).length;\n const avgDailyTokens = data ? Math.round(windowTokenTotal / Math.max(data.days, 1)) : 0;\n const avgDailyCostUsd = data ? data.summary.estimated_cost_usd / Math.max(data.days, 1) : 0;\n\n const toggleDay = (day: string) => setSelectedDay((prev) => (prev === day ? null : day));\n\n return (\n <div className=\"relative h-full overflow-y-auto p-4 md:p-6 space-y-4\">\n <div className=\"mx-auto max-w-7xl space-y-4\">\n <div className=\"pointer-events-none absolute inset-0 overflow-hidden\">\n <div className=\"absolute -top-20 -right-20 w-72 h-72 rounded-full bg-cyan-500/10 blur-3xl\" />\n <div className=\"absolute top-64 -left-24 w-80 h-80 rounded-full bg-emerald-500/10 blur-3xl\" />\n </div>\n\n <DashboardHeader\n days={days}\n onDaysChange={setDays}\n refreshingPricing={refreshingPricing}\n refreshHint={refreshHint}\n onRefreshPricing={onRefreshPricing}\n />\n\n {!loading && !error && data ? (\n <SummaryStrip\n data={data}\n currencyInfo={currencyInfo}\n windowTokenTotal={windowTokenTotal}\n activeDays={activeDays}\n avgDailyTokens={avgDailyTokens}\n avgDailyCostUsd={avgDailyCostUsd}\n />\n ) : null}\n\n <CurrencyPickerRow\n currencyMode={currencyMode}\n onModeChange={setCurrencyMode}\n manualCurrency={manualCurrency}\n onManualChange={setManualCurrency}\n currencyInfo={currencyInfo}\n />\n\n {loading && (\n <div className=\"relative rounded-xl border border-[var(--border)] bg-[var(--bg-secondary)]/90 p-4 text-sm text-[var(--text-secondary)] shadow-sm\">\n Loading dashboard metrics...\n </div>\n )}\n\n {!loading && error && (\n <div className=\"rounded-xl border border-rose-400/40 bg-rose-500/10 p-4 text-sm text-rose-200\">\n Failed to load dashboard metrics: {error}\n </div>\n )}\n\n {!loading && !error && data && (\n <>\n <MetricCardsGrid\n effectiveSummary={effectiveSummary}\n currencyInfo={currencyInfo}\n selectedDay={selectedDay}\n />\n\n <p className=\"text-[11px] text-[var(--text-secondary)]\">\n {currencyInfo.source === \"manual\"\n ? `Currency manually set to ${currencyInfo.currency}.`\n : currencyInfo.source === \"location\"\n ? `Currency converted from USD to ${currencyInfo.currency} based on saved location.`\n : \"Currency defaults to USD because no location-based currency is available.\"}\n </p>\n\n <TokensCostSection\n series={series}\n currencyInfo={currencyInfo}\n selectedDay={selectedDay}\n onToggleDay={toggleDay}\n onClearDay={() => setSelectedDay(null)}\n />\n\n <ToolsAndAgentsRow\n data={data}\n toolSort={toolSort}\n onToolSortChange={setToolSort}\n effectiveTopAgents={effectiveTopAgents}\n selectedDay={selectedDay}\n currencyInfo={currencyInfo}\n />\n\n <VendorModelReportSection\n effectiveByProvider={effectiveByProvider}\n effectiveByModel={effectiveByModel}\n selectedDay={selectedDay}\n currencyInfo={currencyInfo}\n />\n\n <ModelPricingSection\n data={data}\n modelVendorFilter={modelVendorFilter}\n onVendorFilterChange={setModelVendorFilter}\n modelFunctionFilter={modelFunctionFilter}\n onFunctionFilterChange={setModelFunctionFilter}\n modelSearch={modelSearch}\n onSearchChange={setModelSearch}\n modelSort={modelSort}\n onSortChange={setModelSort}\n />\n </>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\nimport { Check, ChevronDown, Menu } from \"lucide-react\";\nimport { Activity, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useAppContext } from \"@/contexts/AppContext\";\nimport { useAgentSession } from \"@/hooks/useAgentSession\";\nimport { useEventNotifications } from \"@/hooks/useEventNotifications\";\nimport { useUrlSync } from \"@/hooks/useUrlSync\";\nimport { useConfigurationIssues } from \"@/hooks/useConfigurationIssues\";\nimport { api } from \"@/api/client\";\nimport type { AgentConfig } from \"@/api/types\";\nimport { ChatView } from \"@/components/chat/ChatView\";\nimport { MemoryPanel } from \"@/components/memory/MemoryPanel\";\nimport { ModelsPanel } from \"@/components/models/ModelsPanel\";\nimport { CredentialsPanel } from \"@/components/credentials/CredentialsPanel\";\nimport { DocumentsPanel } from \"@/components/documents/DocumentsPanel\";import { AgentsPanel } from \"@/components/agents/AgentsPanel\";\nimport { ProfilePanel } from \"@/components/profile/ProfilePanel\";\nimport { MCPPanel } from \"@/components/mcp/MCPPanel\";\nimport { ExtensionsPanel } from \"@/components/extensions/ExtensionsPanel\";\nimport { ToolsPanel } from \"@/components/tools/ToolsPanel\";\nimport { ScheduledTasksPanel } from \"@/components/scheduled-tasks/ScheduledTasksPanel\";\nimport { BridgesPanel } from \"@/components/bridges/BridgesPanel\";\nimport { HarnessPanel } from \"@/components/harness/HarnessPanel\";\nimport { LogsPanel } from \"@/components/logs/LogsPanel\";\nimport { EnvVarsPanel } from \"@/components/env/EnvVarsPanel\";\nimport { HeaderActivity } from \"@/components/ui/HeaderActivity\";\nimport { NotificationStatus } from \"@/components/ui/NotificationStatus\";\nimport { CryptoFallbackBanner } from \"@/components/ui/CryptoFallbackBanner\";\nimport { UpdateAvailableBanner } from \"@/components/ui/UpdateAvailableBanner\";\nimport { ServerStatus } from \"@/components/ui/ServerStatus\";\nimport { Toaster } from \"@/components/ui/Toaster\";\nimport { Logo } from \"@/components/ui/Logo\";\nimport { BootScreen } from \"@/components/ui/BootScreen\";\nimport { ScreenLock } from \"@/components/setup/ScreenLock\";\nimport { UnlockScreen } from \"@/components/setup/UnlockScreen\";\nimport { clearUnreadForAgent, useUnreadCount } from \"@/lib/ui/toasts\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport { MenuPanel } from \"./MenuPanel\";\nimport { DashboardPanel } from \"@/components/dashboard/DashboardPanel\";\n\nconst ADVANCED_TABS = new Set([\"memory\", \"bridges\", \"harness\", \"logs\", \"env\"]);\n\nexport function AppShell() {\n const { state, dispatch } = useAppContext();\n const isFullMode = state.experienceMode === \"full\";\n useUrlSync();\n useConfigurationIssues();\n const { threadId, loading: sessionLoading, error: sessionError } = useAgentSession(\n state.activeAgentId,\n state.activeThreadId,\n );\n\n const [showMenu, setShowMenu] = useState(false);\n const [showAgentPicker, setShowAgentPicker] = useState(false);\n const agentPickerRef = useRef<HTMLDivElement | null>(null);\n\n // Lazy-mount tabs on first visit, then keep them mounted via <Activity> so\n // state survives subsequent switches. Without this, opening the app forces\n // React to render and commit all 8 panel trees up front — Safari (esp. iOS\n // PWA) takes long enough on that synchronous commit that the initial\n // agents fetch in this very component visibly stalls.\n const [mountedTabs, setMountedTabs] = useState<Set<string>>(\n () => new Set([state.activeTab]),\n );\n useEffect(() => {\n setMountedTabs((prev) => prev.has(state.activeTab) ? prev : new Set(prev).add(state.activeTab));\n }, [state.activeTab]);\n\n useEffect(() => {\n if (!isFullMode && ADVANCED_TABS.has(state.activeTab)) {\n dispatch({ type: \"SET_TAB\", tab: \"profile\" });\n }\n }, [dispatch, isFullMode, state.activeTab]);\n\n const unreadCount = useUnreadCount();\n\n // Cache agent id → name for notification titles. Refreshed on agent CRUD.\n const [agents, setAgents] = useState<AgentConfig[]>([]);\n const [agentsLoaded, setAgentsLoaded] = useState(false);\n useEffect(() => {\n let cancelled = false;\n const load = () =>\n api.agents\n .list()\n .then((rows) => { if (!cancelled) setAgents(rows); })\n .catch(() => {})\n .finally(() => { if (!cancelled) setAgentsLoaded(true); });\n void load();\n function onAgentsChanged() { void load(); }\n window.addEventListener(\"jarela:agents-changed\", onAgentsChanged);\n return () => {\n cancelled = true;\n window.removeEventListener(\"jarela:agents-changed\", onAgentsChanged);\n };\n }, []);\n const agentsRef = useRef<AgentConfig[]>([]);\n agentsRef.current = agents;\n\n // Track current view so we can suppress notifications for the agent in focus.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // Stable callback references — without these, AppShell re-renders (e.g. on\n // menu toggle, unread counter clearing) hand ChatView fresh function\n // identities. ChatView's hooks re-derive cascading useCallbacks (handleDone\n // → useSSE.consume → useSSE.attach), and effects keyed on `attach` re-fire,\n // forcing a message refetch + chat-window scroll. Stable refs break the cascade.\n const onMessageSent = useCallback(() => {}, []);\n\n // Click on an OS Web Notification → useEventNotifications fires a custom\n // event; handle it here to switch to the relevant agent's chat. Prefers\n // landing on the exact thread the event happened in (run reply, scheduled\n // task, bridge message) so the user sees the originating message, not just\n // the agent's last-active thread.\n useEffect(() => {\n function handler(e: Event) {\n const detail = (e as CustomEvent<{ agentId?: string; threadId?: string | null }>).detail;\n if (!detail?.agentId) return;\n if (detail.threadId) {\n dispatch({ type: \"SELECT_THREAD\", threadId: detail.threadId, agentId: detail.agentId });\n } else {\n dispatch({ type: \"SET_AGENT\", agentId: detail.agentId });\n dispatch({ type: \"SET_TAB\", tab: \"chat\" });\n }\n }\n window.addEventListener(\"jarela:focus-agent\", handler);\n return () => window.removeEventListener(\"jarela:focus-agent\", handler);\n }, [dispatch]);\n\n // When the user is actively viewing an agent's chat, drain that agent's\n // unread bucket. This keeps the per-agent breakdown honest: badges only\n // count notifications the user hasn't yet seen in context.\n useEffect(() => {\n if (state.activeTab === \"chat\" && state.activeAgentId) {\n clearUnreadForAgent(state.activeAgentId);\n }\n }, [state.activeTab, state.activeAgentId]);\n\n useEventNotifications({\n shouldNotify: (ev) => {\n // Scheduled task firings ALWAYS notify. The user explicitly set them up\n // out-of-band — \"remind me at 3pm\", \"every weekday morning\". Even if\n // they happen to be on that agent's chat, they may not be actively\n // reading right when the task fires; the whole point is the ping.\n if (ev.type === \"task_completed\") return true;\n\n // For ordinary run completions (the agent finished a turn the user\n // just sent), suppress only when the user is actively reading that\n // exact chat — the new message is already on screen.\n //\n // Otherwise notify in either of two cases:\n // 1. The PWA isn't focused (background tab, minimized, focused on\n // another app). Detected via document.hidden + !hasFocus().\n // 2. The PWA IS focused but the user is on a different agent / a\n // different tab inside the app (Memory, Tasks, Models, …).\n const pwaUnfocused =\n typeof document !== \"undefined\" &&\n (document.hidden || !document.hasFocus());\n\n const evAgentId = ev.agent_id;\n const onSameAgentChat =\n stateRef.current.activeTab === \"chat\" &&\n evAgentId !== null &&\n evAgentId === stateRef.current.activeAgentId;\n\n return pwaUnfocused || !onSameAgentChat;\n },\n resolveAgentName: (agentId) => {\n if (!agentId) return getAppName();\n const a = agentsRef.current.find((x) => x.id === agentId);\n return a?.name ?? getAppName();\n },\n resolveAgentIcon: (agentId) => {\n if (!agentId) return null;\n const a = agentsRef.current.find((x) => x.id === agentId);\n return a?.icon ?? null;\n },\n });\n\n // Dismiss the logo-anchored agent picker when tapping outside it.\n useEffect(() => {\n if (!showAgentPicker) return;\n function onPointerDown(e: MouseEvent) {\n const root = agentPickerRef.current;\n if (!root) return;\n if (!root.contains(e.target as Node)) setShowAgentPicker(false);\n }\n function onEscape(e: KeyboardEvent) {\n if (e.key === \"Escape\") setShowAgentPicker(false);\n }\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onEscape);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onEscape);\n };\n }, [showAgentPicker]);\n\n const activeAgent = state.activeAgentId\n ? agents.find((a) => a.id === state.activeAgentId) ?? null\n : null;\n\n // Screen-lock overlay (presence check) AND master-key-locked overlay\n // (decrypt). Distinct from the boot-time gate in `app/page.tsx`:\n // those mounts are triggered mid-session — either by an idle timer\n // (screen-lock) or by the master key being re-locked by an external\n // process (decrypt). Both are signalled by the API client when it\n // sees the matching 423 response.\n const [screenLocked, setScreenLocked] = useState(false);\n const [masterKeyLocked, setMasterKeyLocked] = useState(false);\n // Bumped after each unlock so BootScreen remounts with fresh state\n // (its `done` / `pickedId` / `prefetchStartedRef` would otherwise\n // suppress the picker on the second appearance). Both unlock paths\n // bump this — the agent selector is always the post-unlock landing.\n const [bootSeq, setBootSeq] = useState(0);\n useEffect(() => {\n let cancelled = false;\n let timer: ReturnType<typeof setInterval> | null = null;\n\n function onScreenLocked() {\n if (!cancelled) setScreenLocked(true);\n }\n function onMasterKeyLocked() {\n if (!cancelled) setMasterKeyLocked(true);\n }\n window.addEventListener(\"jarela:screen-locked\", onScreenLocked);\n window.addEventListener(\"jarela:master-key-locked\", onMasterKeyLocked);\n\n // Soft poll every 30s so the overlay still appears if no user\n // action triggered a request after the idle timer elapsed.\n async function probe() {\n try {\n const res = await fetch(\"/api/v1/security/state\");\n if (!res.ok) return;\n const body = (await res.json()) as {\n screen_locked?: boolean;\n state?: string;\n };\n if (cancelled) return;\n if (body.state === \"locked\") setMasterKeyLocked(true);\n if (body.screen_locked === true) setScreenLocked(true);\n } catch (err) {\n // Network blip; try again next tick. Logged at debug-level so\n // a sustained outage is at least findable in devtools.\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[security/state] probe failed:\", err);\n }\n }\n }\n void probe();\n timer = setInterval(probe, 30_000);\n\n return () => {\n cancelled = true;\n if (timer) clearInterval(timer);\n window.removeEventListener(\"jarela:screen-locked\", onScreenLocked);\n window.removeEventListener(\"jarela:master-key-locked\", onMasterKeyLocked);\n };\n }, []);\n\n // Shared post-unlock landing: clear the current chat and force the\n // BootScreen to remount so the user lands on the agent picker. Used\n // by BOTH the screen-unlock and the master-key decrypt paths so the\n // two transitions feel identical from the user's side.\n const landOnAgentPicker = useCallback(() => {\n dispatch({ type: \"NEW_CHAT\" });\n setBootSeq((n) => n + 1);\n }, [dispatch]);\n\n return (\n // `dvh` natively tracks the visible viewport on iOS 16.4+ / modern\n // Chromium, including the on-screen keyboard. The `--actual-vh`\n // override (set by the iOS-standalone-PWA shim in layout.tsx) covers\n // the separate WebKit bug where 100dvh under-reports the physical\n // screen by ~safe-area-inset-top, which leaves a white strip above\n // the home indicator. Inline style instead of `h-[...]` because\n // Tailwind arbitrary values choke on commas inside `var(...)`.\n <div\n className=\"flex flex-col text-fg overflow-hidden px-safe\"\n style={{ height: \"var(--actual-vh, 100dvh)\" }}\n >\n <BootScreen\n key={bootSeq}\n agents={agents}\n agentsLoaded={agentsLoaded}\n activeAgentId={state.activeAgentId}\n onPickAgent={(id) => {\n dispatch({ type: \"SET_AGENT\", agentId: id });\n dispatch({ type: \"SET_TAB\", tab: \"chat\" });\n }}\n suppressed={state.activeTab !== \"chat\"}\n />\n {screenLocked && !masterKeyLocked && (\n <ScreenLock\n onUnlock={() => {\n // Drop the user back on the picker so they consciously\n // re-enter their workspace rather than landing mid-chat.\n landOnAgentPicker();\n setScreenLocked(false);\n }}\n />\n )}\n {masterKeyLocked && (\n // Master key got re-locked mid-session (e.g. external lock\n // command). Mount the decrypt splash — same shared keypad as\n // boot — and on success drop back to the agent picker. The\n // existing components below stay mounted underneath; once\n // unlocked they resume against the now-unlocked DB.\n //\n // If the screen-lock flag is also up (idle overlap), the\n // decrypt route clears it server-side, so we also drop the\n // screen-lock flag here. One PIN entry covers both.\n <UnlockScreen\n onUnlock={() => {\n landOnAgentPicker();\n setMasterKeyLocked(false);\n if (screenLocked) setScreenLocked(false);\n }}\n />\n )}\n <NotificationStatus />\n <Toaster />\n <ServerStatus />\n {/*\n Spacer reserving the slot the floating header visually occupies.\n Keeps the flex layout intact so panel content doesn't slide under\n the bar — the bar itself is `fixed` (like TopProgressBar) so it\n always sits on top of scrolling content with a glassy backdrop.\n\n Omitted on the chat tab: the MessageList scroll viewport has a\n top mask-image fade designed to dissolve messages under the glass\n header. Reserving the slot would defeat that — messages would\n butt against an empty band beneath the header instead of scrolling\n behind it.\n */}\n {state.activeTab !== \"chat\" && (\n <div\n className=\"shrink-0\"\n aria-hidden\n style={{ height: \"calc(3rem + var(--app-safe-top))\" }}\n />\n )}\n <CryptoFallbackBanner />\n <UpdateAvailableBanner />\n <header\n className=\"glass fixed top-0 left-0 right-0 z-40 flex items-center px-4 border-b border-border/60\"\n style={{\n // Top safe-area is mobile-scoped via --app-safe-top so desktop\n // windows stay flush to the edge.\n paddingTop: \"var(--app-safe-top)\",\n paddingLeft: \"calc(env(safe-area-inset-left) + 1rem)\",\n paddingRight: \"calc(env(safe-area-inset-right) + 1rem)\",\n height: \"calc(3rem + var(--app-safe-top))\",\n }}\n >\n <div className=\"relative flex items-center gap-2 select-none\" ref={agentPickerRef}>\n <button\n type=\"button\"\n onClick={() => setShowAgentPicker((v) => !v)}\n className=\"control-tap inline-flex items-center gap-2 rounded-lg px-1.5 py-1 hover:bg-surface-3/60 transition-colors\"\n title={activeAgent ? `Active agent: ${activeAgent.name} — click to switch` : \"Select active agent\"}\n aria-haspopup=\"menu\"\n aria-expanded={showAgentPicker}\n >\n {activeAgent?.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={activeAgent.icon}\n alt=\"\"\n className=\"h-6 w-6 rounded-md object-cover shrink-0\"\n />\n ) : activeAgent ? (\n <span\n aria-hidden\n className=\"h-6 w-6 rounded-md bg-surface-3 text-[11px] font-semibold text-fg-subtle inline-flex items-center justify-center shrink-0\"\n >\n {activeAgent.name.charAt(0).toUpperCase()}\n </span>\n ) : (\n // No active agent yet — fall back to the app mark. The Logo\n // component renders both color variants and CSS picks the\n // visible one based on the active theme.\n <Logo className=\"h-6 w-auto\" />\n )}\n <span className=\"text-fg font-semibold tracking-tight truncate max-w-[12rem] sm:max-w-[16rem]\">\n {activeAgent?.name ?? getAppName()}\n </span>\n <ChevronDown size={14} className={`text-fg-faint transition-transform ${showAgentPicker ? \"rotate-180\" : \"\"}`} />\n </button>\n {showAgentPicker && (\n <div\n role=\"menu\"\n className=\"panel-scrollbar absolute top-full left-0 mt-2 w-[min(24rem,calc(100vw-2rem))] max-h-[55vh] overflow-y-auto rounded-xl border border-border bg-surface-2/95 backdrop-blur-md shadow-2xl p-1.5\"\n >\n {agents.length === 0 ? (\n <p className=\"text-xs text-fg-faint px-2 py-2\">No agents available yet.</p>\n ) : (\n agents.map((a) => {\n const selected = a.id === state.activeAgentId;\n return (\n <button\n key={a.id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={selected}\n onClick={() => {\n dispatch({ type: \"SET_AGENT\", agentId: a.id });\n dispatch({ type: \"SET_TAB\", tab: \"chat\" });\n setShowAgentPicker(false);\n }}\n className={`control-tap w-full flex items-center gap-2 px-2 py-1.5 rounded-lg text-left text-sm transition-colors ${\n selected\n ? \"bg-surface-3 text-fg\"\n : \"text-fg-muted hover:bg-surface-3/60 hover:text-fg\"\n }`}\n >\n <span className=\"w-4 h-4 shrink-0 inline-flex items-center justify-center text-accent\">\n {selected ? <Check size={14} /> : null}\n </span>\n {a.icon ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={a.icon} alt=\"\" className=\"w-5 h-5 rounded-md object-cover shrink-0\" />\n ) : (\n <span className=\"w-5 h-5 rounded-md bg-surface-3 text-[10px] font-semibold text-fg-subtle inline-flex items-center justify-center shrink-0\">\n {a.name.charAt(0).toUpperCase()}\n </span>\n )}\n <span className=\"truncate flex-1\">{a.name}</span>\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n <HeaderActivity />\n <button\n onClick={() => { setShowMenu((v) => !v); }}\n className={`control-tap ml-auto relative p-2.5 rounded transition-colors ${showMenu ? \"text-fg bg-surface-3\" : \"text-fg-faint hover:text-fg-muted hover:bg-surface-3/50\"}`}\n title={unreadCount > 0 ? `${unreadCount} new ${unreadCount === 1 ? \"alert\" : \"alerts\"}` : \"Menu\"}\n >\n <Menu size={21} />\n {unreadCount > 0 && (\n <span className=\"absolute top-1 right-1 min-w-[14px] h-[14px] px-1 rounded-full bg-rose-500 border border-surface-2 text-[9px] font-bold text-white flex items-center justify-center leading-none animate-pulse\">\n {unreadCount > 9 ? \"9+\" : unreadCount}\n </span>\n )}\n </button>\n </header>\n\n <div className=\"flex-1 relative overflow-hidden\">\n {/*\n Each tab is wrapped in <Activity> on its first visit, then kept\n mounted so scroll position, expanded rows, and local form/filter\n state survive tab switches. Background panels stay in the DOM but\n their effects pause until shown again, so data refreshes on focus\n rather than going stale. ChatView keeps its `key={activeAgentId}`\n so picking a different agent still forces a clean remount with\n that agent's thread.\n\n We lazy-mount on first visit (not eagerly on app start) because\n rendering all 8 panel trees up front blocks Safari/iOS PWA long\n enough to stall the very first paint.\n */}\n {mountedTabs.has(\"chat\") && (\n <Activity mode={state.activeTab === \"chat\" ? \"visible\" : \"hidden\"}>\n <ChatView\n key={state.activeAgentId ?? \"no-agent\"}\n threadId={threadId}\n agentId={state.activeAgentId}\n sessionLoading={sessionLoading}\n sessionError={sessionError}\n onMessageSent={onMessageSent}\n />\n </Activity>\n )}\n {mountedTabs.has(\"dashboard\") && (\n <Activity mode={state.activeTab === \"dashboard\" ? \"visible\" : \"hidden\"}>\n <DashboardPanel />\n </Activity>\n )}\n {mountedTabs.has(\"agents\") && (\n <Activity mode={state.activeTab === \"agents\" ? \"visible\" : \"hidden\"}>\n <AgentsPanel />\n </Activity>\n )}\n {isFullMode && mountedTabs.has(\"memory\") && (\n <Activity mode={state.activeTab === \"memory\" ? \"visible\" : \"hidden\"}>\n <MemoryPanel />\n </Activity>\n )}\n {mountedTabs.has(\"documents\") && (\n <Activity mode={state.activeTab === \"documents\" ? \"visible\" : \"hidden\"}>\n <DocumentsPanel />\n </Activity>\n )}\n {mountedTabs.has(\"models\") && (\n <Activity mode={state.activeTab === \"models\" ? \"visible\" : \"hidden\"}>\n <ModelsPanel />\n </Activity>\n )}\n {mountedTabs.has(\"credentials\") && (\n <Activity mode={state.activeTab === \"credentials\" ? \"visible\" : \"hidden\"}>\n <CredentialsPanel />\n </Activity>\n )}\n {mountedTabs.has(\"mcp\") && (\n <Activity mode={state.activeTab === \"mcp\" ? \"visible\" : \"hidden\"}>\n <MCPPanel />\n </Activity>\n )}\n {mountedTabs.has(\"extensions\") && (\n <Activity mode={state.activeTab === \"extensions\" ? \"visible\" : \"hidden\"}>\n <ExtensionsPanel />\n </Activity>\n )}\n {mountedTabs.has(\"tools\") && (\n <Activity mode={state.activeTab === \"tools\" ? \"visible\" : \"hidden\"}>\n <ToolsPanel />\n </Activity>\n )}\n {mountedTabs.has(\"tasks\") && (\n <Activity mode={state.activeTab === \"tasks\" ? \"visible\" : \"hidden\"}>\n <ScheduledTasksPanel />\n </Activity>\n )}\n {isFullMode && mountedTabs.has(\"bridges\") && (\n <Activity mode={state.activeTab === \"bridges\" ? \"visible\" : \"hidden\"}>\n <BridgesPanel />\n </Activity>\n )}\n {mountedTabs.has(\"profile\") && (\n <Activity mode={state.activeTab === \"profile\" ? \"visible\" : \"hidden\"}>\n <ProfilePanel />\n </Activity>\n )}\n {isFullMode && mountedTabs.has(\"harness\") && (\n <Activity mode={state.activeTab === \"harness\" ? \"visible\" : \"hidden\"}>\n <HarnessPanel />\n </Activity>\n )}\n {isFullMode && mountedTabs.has(\"logs\") && (\n <Activity mode={state.activeTab === \"logs\" ? \"visible\" : \"hidden\"}>\n <LogsPanel />\n </Activity>\n )}\n {isFullMode && mountedTabs.has(\"env\") && (\n <Activity mode={state.activeTab === \"env\" ? \"visible\" : \"hidden\"}>\n <EnvVarsPanel />\n </Activity>\n )}\n\n {showMenu && (\n <div\n className=\"fixed left-0 right-0 bottom-0 bg-black/30 backdrop-blur-sm z-30\"\n style={{ top: \"calc(3rem + var(--app-safe-top))\" }}\n onClick={() => setShowMenu(false)}\n />\n )}\n\n {showMenu && (\n <MenuPanel\n activeTab={state.activeTab}\n agentId={state.activeAgentId}\n onClose={() => setShowMenu(false)}\n onAgentChange={(agentId) => dispatch({ type: \"SET_AGENT\", agentId })}\n onSetTab={(tab) => {\n dispatch({ type: \"SET_TAB\", tab });\n setShowMenu(false);\n }}\n />\n )}\n </div>\n </div>\n );\n}\n","import(/* webpackMode: \"eager\", webpackExports: [\"AppShell\"] */ \"/home/runner/work/jarela/jarela/components/layout/AppShell.tsx\");\n;\nimport(/* webpackMode: \"eager\", webpackExports: [\"UnlockScreen\"] */ \"/home/runner/work/jarela/jarela/components/setup/UnlockScreen.tsx\");\n"],"names":["createContext","useCallback","useContext","useEffect","useState","STORAGE_KEY","isTheme","v","readStored","window","localStorage","getItem","LIGHT_CHROME","DARK_CHROME","resolveChrome","theme","matchMedia","matches","syncChrome","document","meta","querySelector","setAttribute","apply","documentElement","ThemeContext","ThemeProvider","children","setThemeState","stored","mq","onChange","addEventListener","removeEventListener","setTheme","t","setItem","Provider","value","useTheme","ctx","Error","api","useAgentSession","agentId","preferredThreadId","threadId","setThreadId","loading","setLoading","error","setError","cancelled","d","threads","get","limit","agent_id","agents","getThread","thread_id","err","String","console","toasts","listeners","Set","unreadByAgent","Map","unreadListeners","notify","l","notifyUnread","pushToast","input","id","Date","now","Math","random","toString","slice","created_at","key","set","ttl","setTimeout","dismissToast","before","length","filter","clearUnread","size","clear","clearUnreadForAgent","has","delete","snapshotByAgent","totalUnread","n","values","useToasts","s","setS","fn","add","useUnreadCount","setN","useUnreadByAgent","m","setM","useUnreadForAgent","useRef","LAST_TS_KEY","loadLastTs","raw","Number","isFinite","MAX_WINDOW_MS","max","saveLastTs","ts","useEventNotifications","options","lastTsRef","optsRef","current","EventSource","es","backoff","reconnectTimer","connect","url","onmessage","msg","ev","JSON","parse","data","type","dispatchEvent","CustomEvent","detail","source","agentName","resolveAgentName","kind","sourceLabel","title","body","recovered","status","category","label","href","hrefLabel","evThreadId","handleEvent","onerror","close","min","shouldNotify","format","preview","undefined","canOSNotify","Notification","permission","customIcon","resolveAgentIcon","tag","task_id","bridge_id","remote_jid","icon","onclick","focus","onVisible","visibilityState","clearTimeout","resolveName","name","who","push_name","sender","is_group","channel","ensureNotificationPermission","requestPermission","TABS","parseHref","external","test","hash","hashIdx","indexOf","queryStr","qIdx","params","URLSearchParams","tabRaw","tab","includes","item","thread","agent","buildHref","qs","fragment","replace","useAppContext","useUrlSync","state","dispatch","lastWrittenRef","applyFromUrl","location","search","parsed","itemId","selectedItem","activeTab","next","pathname","history","replaceState","resolveAgentModel","models","defaultModel","find","is_default","model_config_name","agentModelStatus","exact","model","requested","fallback","useConfigurationIssues","activeRef","refresh","Promise","all","list","force","pushIssue","toastId","some","a","encodeURIComponent","entries","activeCount","startLoading","cleared","useLoadingCount","useTrackLoading","active","activitySeq","activityStack","activityListeners","currentActivity","notifyActivity","top","pushActivity","push","slot","idx","findIndex","splice","useActivityLabel","setLabel","submitRun","subscribeRun","useSSE","onDone","streaming","setStreaming","streamingContent","setStreamingContent","thinkingContent","setThinkingContent","toolEvents","setToolEvents","abortRef","threadIdRef","activityRef","activeToolsRef","pendingTextRef","pendingThinkingRef","rafIdRef","flushPending","delta","p","scheduleFlush","requestAnimationFrame","cancelPendingFlush","cancelAnimationFrame","openActivity","initial","closeActivity","consume","iterable","event","prev","phase","payload","arguments","result","remaining","message","start","attachments","hotSince","abort","ctrl","AbortController","submit","signal","accepted","stop","tid","abortRun","catch","attach","clearStreamingContent","Check","ChevronDown","ChevronUp","ShieldAlert","X","approvalToastTarget","action","str","k","resultId","pushApprovalToast","reason","ApprovalsBanner","pending","setPending","open","setOpen","busyIds","setBusyIds","secretForm","setSecretForm","filtered","e","setInterval","hidden","clearInterval","markBusy","busy","plainApprove","approve","deny","approveStartOauth","integrationId","integration_id","resp","integrations","gmailOauthStart","outlookOauthStart","authorize_url","openProviderKeyModal","fields","secret","required","placeholder","submitting","openIntegrationModal","def","definitions","map","f","submitSecretForm","missing","trim","join","extras","Object","div","className","button","onClick","span","pre","stringify","disabled","SecretFormModal","onChangeValue","val","onCancel","onSubmit","h2","htmlFor","target","autoComplete","spellCheck","Mic","Paperclip","Send","Square","useMemo","ACCEPT","SLASH_COMMANDS","description","isIosStandalonePwa","ua","navigator","userAgent","isiOS","standalone","fileToContentPart","file","resolve","reject","reader","FileReader","startsWith","onload","dataUrl","split","media_type","readAsDataURL","readAsText","attachmentKey","i","text","InputBar","onAttachmentsChange","onQueue","onStop","voiceEnabled","onVoiceTranscript","setValue","fileInputRef","textareaRef","hlIdx","setHlIdx","recording","setRecording","transcribing","setTranscribing","voiceError","setVoiceError","recorderRef","chunksRef","iosPwaFix","r","stream","getTracks","forEach","startRecording","mediaDevices","getUserMedia","audio","mime","MediaRecorder","isTypeSupported","rec","mimeType","ondataavailable","onstop","blob","Blob","fd","FormData","append","res","fetch","method","ok","json","trimmed","stopRecording","style","height","suggestions","trimStart","q","toLowerCase","c","showSuggestions","activeIdx","applySuggestion","fireSubmit","fireQueue","handleKeyDown","shiftKey","preventDefault","metaKey","ctrlKey","handlePaste","items","Array","from","clipboardData","imageItems","getAsFile","then","part","handleFileChange","files","parts","removeAttachment","_","paddingBottom","img","src","alt","onMouseDown","onMouseEnter","ref","multiple","accept","click","aria-label","textarea","rows","currentTarget","preventScroll","scrollHeight","onKeyDown","onPaste","role","aria-live","ChevronRight","COLLAPSE_THRESHOLD","ToolList","events","openId","setOpenId","expanded","setExpanded","uniqueNames","Boolean","callCount","errorCount","isErrorPayload","aria-hidden","summary","previewPayload","isError","dotColor","oneLine","fmtTokens","toFixed","ContextUsageBar","usage","fallbackContextWindow","showDetails","setShowDetails","cap","context_window_tokens","hasTierBreakdown","hot_tokens","warm_tokens","facts_tokens","overhead_tokens","hot_budget_tokens","warm_budget_tokens","facts_budget_tokens","usedPct","input_tokens","toLocaleString","width","hotBudget","warmBudget","factsBudget","hotUsed","warmUsed","factsUsed","overheadUsed","cacheRead","cache_read_input_tokens","cacheCreation","cache_creation_input_tokens","cacheActive","overheadBudget","totalBudget","trailing","toPct","output_tokens","Slot","widthPct","fill","empty","overflow","round","Row","color","used","budget","hint","filledOfSlot","pct","runtimeConfig","CountdownRing","inflightToolCount","deadlineMs","setDeadlineMs","runMaxMs","PI","spinnerArc","progressRef","activeMsRef","lastTickRef","inflightRef","raf","tick","performance","node","progress","strokeDashoffset","svg","viewBox","circle","cx","cy","stroke","strokeOpacity","strokeWidth","strokeLinecap","strokeDasharray","transform","formatBridgePrompt","note","roleNote","silent","lines","chat_id","chat_name","sender_id","sender_name","parseBridgePrompt","headers","line","exec","chatId","chat_jid","senderId","sender_jid","bridge","chat_type","bridgeId","chatJid","chatName","isGroup","senderJid","senderName","trimEnd","z","ExtensionActionEnum","enum","composePrompt","header","instruction","selector","page_context","ACTION_LABEL","refine","rewrite_clipboard","parseExtensionTurn","headerRe","hm","actionWord","rest","takeLine","re","RegExp","pageContext","pageHeaderRe","selectedText","selHeaderRe","sm","actionLabel","memo","ReactMarkdown","remarkGfm","rehypeRaw","rehypeHighlight","rehypeSanitize","defaultSchema","Bot","Clock","Copy","Eye","EyeOff","Globe","Link","LinkIcon","Link2","Loader2","MessageCircle","Pause","Play","RotateCcw","ShieldCheck","User","Users","Zap","plainTextForTts","content","isArray","extractRefs","match","refs","inner","linkRe","u","index","stripDeclaredReferencesFence","playedAutoplayHrefs","InlineAudio","wantsAuto","auto","controls","preload","autoPlay","onPlay","parseCapturedContext","bareRe","lm","bm","out","truncated","originalBytes","tm","CapturedContextCard","accent","hostname","URL","chips","rel","stopPropagation","sections","defaultOpen","StructuredTurnCard","categoryKey","Icon","titleTooltip","ExtensionTurnCard","MarkdownContent","CATEGORY_BADGE","scheduled_task","cls","watcher","page_capture","extension","synthetic","CategorySourceBadge","UserCategoryChip","CollapsibleSection","aria-expanded","CollapsibleLong","threshold","innerRef","overflows","setOverflows","firstFitRef","wasStreamingRef","el","check","over","ro","ResizeObserver","observe","disconnect","collapsed","maxHeight","sanitizeSchema","tagNames","attributes","aside","abbr","details","MD_REMARK_PLUGINS","MD_REHYPE_PLUGINS","detect","ignoreMissing","reactChildrenToText","props","GRADIENTS","gradientFor","h","charCodeAt","abs","AgentAvatar","config","charAt","toUpperCase","UserAvatar","profile","parseBridgeContext","SILENT_TRIGGER_RE","stripSilentEnvelope","parseTriggerMessage","prompt","tool","args","diff","directive","TriggerMessageCard","BridgeMessageCard","showChat","parseContent","ResilientMarkdownImage","retryNonce","setRetryNonce","failed","setFailed","normalizedSrc","createObjectURL","effectiveSrc","onError","MapEmbed","parseError","obj","sp","keys","direct","iframe","referrerPolicy","allowFullScreen","border","display","onInAppLink","unverifiedLinks","sourceManifest","renderedText","entry","parseInt","remarkPlugins","rehypePlugins","components","isUnverified","isCitationMarker","citationText","inApp","unverifiedCls","unverifiedTitle","markerNum","isAnchor","sup","code","CodeFence","language","ReferencesPanel","sources","ol","isMemory","li","CitationsSummary","claims","checkerModel","buckets","high","med","low","impact","uncitedHigh","verified","totalUncited","total","allCited","trigger","impactBadge","styles","bucket","ul","link","RedactionShield","reduce","acc","count","type_hint","RefsFooter","copied","setCopied","codeText","copyCode","clipboard","writeText","ContentPartView","isUser","ClickableImage","video","playsInline","objectFit","messageTextForCopy","MessageBubble","agentConfig","userProfile","showAvatar","showToolEvents","contextWindowTokens","isLatest","onRetry","messageId","handleInAppLink","samePath","HashChangeEvent","copyLink","origin","canRetry","handleRetry","atts","copiedMessage","setCopiedMessage","copyMessage","voice_enabled","ttsAbleText","audioRef","audioUrlRef","audioState","setAudioState","audioError","setAudioError","releaseAudio","pause","revokeObjectURL","speak","play","Audio","onended","onpause","onSpeak","renderedString","citations","metadata","redactionSummary","redaction_summary","unverified_links","createdAt","timeLabel","toLocaleTimeString","hour","minute","ext","firstText","tool_events","checker_model","Archive","WarmSummaryCard","olderCount","summaryBefore","computedAt","fresh","computing","formatRelative","stripWarmHeader","summaryLong","x","ContextBoundaryDivider","sourceMessages","sourceChars","summaryChars","hasStats","ratio","formatBytes","stripped","iso","getTime","MESSAGE_FILTER_KEYS","LEGACY_GLOBAL_KEY","CACHE_KEY_PREFIX","MIGRATION_FLAG_KEY","DEFAULTS","tool_use","thinking","readCache","writeCache","filters","readLegacyGlobal","useMessageFilters","setFilters","seqRef","cached","mySeq","legacy","removeItem","merged","toggle","reset","useLayoutEffect","ArrowDown","MessageList","messages","notices","hasMore","loadingMore","onLoadMore","queuedMessages","onRemoveQueued","warmSummary","warmSummaryBefore","warmSummaryComputedAt","warmSummarySourceMessages","warmSummarySourceChars","onSetContextPin","onRetryMessage","scrollRef","autoRecoveredRef","visibleMessages","cat","hiddenCount","lastId","availableChips","atBottomRef","showScrollButton","setShowScrollButton","prependAnchorRef","scrollTop","anchor","handleScroll","isAtBottom","clientHeight","scrollToHashTarget","decodeURIComponent","root","safe","scrollIntoView","behavior","block","classList","remove","handleResize","scrollToBottom","toolbarRef","toolbarH","setToolbarH","contentRect","FilterToolbar","onToggle","onScroll","scrollPaddingTop","boundaryIndex","pinAfterAll","hasBoundary","olderInVisible","olderCountLabel","renderBoundary","nodes","flatMap","startsTurn","data-message-id","ThinkingLine","StreamingBubble","QueuedBubble","onRemove","CHIP_LABELS","on","aria-pressed","tail","attachmentCount","appendUnique","incoming","seen","concat","applyThreadMeta","setHotSince","hot_since","setWarmSummary","warm_summary","setWarmSummaryBefore","warm_summary_before","setWarmSummaryComputedAt","warm_summary_computed_at","setWarmSummarySourceMessages","warm_summary_source_messages","setWarmSummarySourceChars","warm_summary_source_chars","setContextWindowTokens","makeQueuedId","prefix","getAppIssueUrl","MAX_ISSUE_BODY_BYTES","stringifyError","stack","formatContext","rendered","formatReport","env","errStr","ctxBlock","context","appVersion","buildIssueUrl","report","Buffer","byteLength","footer","room","labels","cachedVersion","inFlight","readAppVersion","j","version","buildEnv","toISOString","pushErrorToast","reportInput","buildReport","_resetVersionCacheForTests","asHttpLike","extractStatus","isAbort","isNetwork","friendlyErrorTitle","reportError","fallbackTitle","useChatErrorReporting","sessionError","streamError","lastSessionErrorRef","panel","lastStreamErrorRef","useChatQueue","compacting","launchRun","queue","setQueue","queueRef","streamingRef","compactingRef","drainQueueRef","launchRunRef","isReady","enqueue","prepend","removeQueued","retry","useThreadCrossDeviceSync","messagesRef","setMessages","setHasMore","applyMeta","handler","cur","fetchPromise","after","has_more","useThreadData","setNotices","setLoadingMore","messagesLoading","setMessagesLoading","metaApplier","addNotice","finally","setContextPin","updated","loadOlder","oldest","useUserProfileAndAgent","setUserProfile","profileLoading","setProfileLoading","setAgentConfig","agentConfigLoading","setAgentConfigLoading","ChatView","sessionLoading","onMessageSent","setAttachments","setCompacting","attachRef","stableAttach","pendingAutoSpeakRef","clearStreamingRef","queueApiRef","handleDone","finalizeRunFromServer","clearStreaming","sse","optId","optimisticContent","include_tools","include_thinking","ui_experience_mode","experienceMode","handleCompact","compact","compacted","handleSubmit","rawInput","handleQueue","handleVoiceTranscript","voice_auto_speak","handleRetryMessage","composerPlaceholder","latest","reverse","useMemory","namespace","setItems","memory","create","ns","update","HIGHLIGHT_CLASS","HIGHLIGHT_MS","useDeepLinkScroll","idPrefix","containerRef","lastSeenRef","useEscapeKey","onEscape","enabled","onKey","MemoryEditor","onSave","onClose","setNamespace","setKey","valueStr","setValueStr","saving","setSaving","isEdit","handleSave","h3","SECRET_KEY_PATTERN","SECRET_MASK","MAX_INLINE_FIELDS","MAX_INLINE_STRING","isSecretKey","truncate","formatLeaf","maskedReplacer","MemoryValuePreview","ExpandableBlock","full","head","extra","React","SIZE_CLASSES","md","BASE_CLASSES","Select","forwardRef","select","Pencil","Plus","Search","Trash2","useDebounce","ms","setD","MemoryPanel","nsFilter","setNsFilter","searchInput","setSearchInput","editing","setEditing","namespaces","sort","option","data-deep-link-id","useModels","setModels","assignments","setAssignments","tasks","assign","tool_policy","exists","unassign","PROVIDER_TO_INTEGRATION","anthropic","openai","gemini","deepseek","cohere","integrationNameForProvider","provider","FALLBACK_PROVIDERS","useIdentityState","setName","nameTouched","setNameTouched","setProvider","providers","setProviders","modelId","setModelId","model_id","useProviderList","useCredentialState","credentialId","setCredentialId","credential_id","credentials","setCredentials","credentialDialogOpen","setCredentialDialogOpen","refreshCredentials","useCredentialList","integrationName","providerCredentials","stillValid","useParamsState","apiKey","setApiKey","api_key","baseUrl","setBaseUrl","base_url","extraHeaders","setExtraHeaders","extra_headers","temperature","setTemperature","maxTokens","setMaxTokens","max_tokens","autoMaxTokens","setAutoMaxTokens","autoContextWindowTokens","setAutoContextWindowTokens","isDefault","setIsDefault","useStatusState","probing","setProbing","probeResult","setProbeResult","allowSaveAnyway","setAllowSaveAnyway","pendingShrinkConfirm","setPendingShrinkConfirm","useCatalogState","showCatalog","setShowCatalog","catalog","setCatalog","catalogLoading","setCatalogLoading","catalogError","setCatalogError","catalogSearch","setCatalogSearch","useIntegrationsState","setIntegrations","useIntegrationList","mounted","names","statuses","useModelEditorForm","cred","integ","toNumberOrUndefined","buildModelEditorPayload","parsed_headers","temp","maxT","win","floor","collectInlineOverrides","form","overrides","buildPayload","runProbeStep","probe","shouldStageShrinkConfirm","oldCtx","newCtx","ctxShrunk","modelIdChanged","oldSnapshot","payloadName","toastSaveFail","modelIdResolved","useModelSaveHandlers","loadCatalog","loadCatalogAction","handleTestConnection","testConnectionAction","saveAction","confirmShrinkAndSave","confirmShrinkAction","skipCompactAndSave","skipCompactAction","compactThreads","EditorChrome","wide","expertToggle","overlays","ExpertToggle","showExpert","CheckCircle2","XCircle","ProbeBanner","EditorFooter","onTest","ExternalLink","Terminal","IntegrationCard","definition","onChanged","setValues","testing","setTesting","testResult","setTestResult","connecting","setConnecting","popupRef","pollRef","connectOAuth","clientId","client_id","clientSecret","client_secret","configured","startFn","statusFn","gmailOauthStatus","outlookOauthStatus","startedAt","updated_at","save","displayName","confirm","GmailSetupGuide","OutlookSetupGuide","fieldSource","onFocus","strong","Step","Ext","em","ChevronLeft","CATEGORY_ORDER","CATEGORY_LABELS","llm","mail","calendar","infrastructure","chat","other","AddCredentialDialog","initialCategory","directProviderName","lockCategory","onSaved","defs","setDefs","setStatuses","step","setStep","activeName","setActiveName","reload","fromEntries","grouped","arr","b","localeCompare","visibleCategories","openProvider","backToPicker","activeDef","activeStatus","section","h4","IdentitySection","BookOpen","CapBadges","ModelIdSection","onLoadCatalog","ModelIdHeader","CatalogPanel","CatalogRow","applyCatalogPick","context_length","fmtCtx","hosted_on","caps","capabilities","max_output_tokens","CredentialSection","CredentialDropdown","emptyLabel","auth_method","rebindCredentialAfterCreate","ConnectionFields","expertVisible","InlineApiKeyField","TemperatureMaxTokensRow","MaxTokensField","ContextWindowField","ExtraHeadersField","makeStartSignIn","setters","startSignIn","setMessage","githubCopilotAuth","interval","setFlow","user_code","verification_uri","device_code","setPolling","pollLoop","expires_in","makeSignOut","signOut","setStatus","deviceCode","intervalSec","expiresInSec","deadline","pollOnce","poll","useGitHubCopilotAuth","flow","polling","signed_in","stored_at","actions","GitHubCopilotAuth","auth","AuthHeader","onSignIn","onSignOut","ConnectedLine","DeviceFlowBlock","ShrinkConfirmDialog","onConfirm","onSkip","DialogActions","ModelFeatureGuide","ModelEditorBody","checked","ModelEditorOverlays","onConfirmShrink","onSkipShrink","ModelEditor","isFullMode","setShowExpert","Cpu","Star","PROVIDER_COLORS","ModelsPanel","deleteError","setDeleteError","handleSetDefault","handleRemove","inUse","RefreshCw","Save","NetworkSection","setEnv","setResult","mode","setMode","scheme","setScheme","host","setHost","port","setPort","username","setUsername","password","setPassword","noProxy","setNoProxy","caBundle","setCaBundle","caLabel","setCaLabel","seed","no_proxy","ca_bundle","humanBytes","load","proxy","applied","onCaFile","removeCa","envOverride","env_override","proxyUrl","caBundlePath","caBundleCertCount","AllowedSitesSection","sites","setSites","adding","setAdding","newHost","setNewHost","newBypass","setNewBypass","allowedSites","ssrf_bypass","toggleBypass","setSsrfBypass","has_cookies","cookies_updated_at","autoCapitalize","autoCorrect","isNaN","sec","ROW_KEY","integration","field","EnvAliasEditor","setConfig","drafts","setDrafts","savingKey","setSavingKey","envSync","allowlist","defaults","saveRow","envVars","Settings2","NetworkPanel","syncing","setSyncing","syncMsg","setSyncMsg","aliasEditorOpen","setAliasEditorOpen","syncFromEnv","discovered","shell","applied_count","userSkipped","candidates","equal","absent","PRESET_CATEGORIES","home","work","dev","custom","isCategoryVisible","preset","allowed","Filter","Key","SUB_TITLES","network","PRESET_LABELS","describeCredential","refresh_token","CredentialsPanel","setSub","selected","aria-selected","CredentialsListPanel","setPreset","addOpen","setAddOpen","editingProvider","setEditingProvider","expandedProvider","setExpandedProvider","ints","defByName","handleDelete","visibleDefs","byCat","defNames","credential","row","isOpen","ArrowUp","Folder","FolderOpen","Home","FolderPickerDialog","initialPath","onSelect","cwd","setCwd","parent","setParent","setHome","setEntries","pathInput","setPathInput","navigate","fs","browse","path","jumpToPath","onDoubleClick","KIND_OPTIONS","isGithubKind","isMailKind","summarizeRemote","project_key","jql","space_key","cql","slug","owner","repo","path_prefix","query","LocalFolderFields","canSubmit","onOpenPicker","addPath","addLabel","SubmitButton","RemoteSourceFields","RemoteKindInputs","RemoteLabelRow","addKind","addProjectKey","addSpaceKey","addQuery","addMailQuery","GithubOwnerRepoInputs","addGhState","GithubRepoExtras","addGhOwner","addGhRepo","addGhRef","addGhPathPrefix","addMailMaxResults","addMailPageSize","addRecencyDays","makeSetField","setState","INITIAL","trimmedPath","maxResults","max_results","pageSize","page_size","recency","recency_days","kindHint","AddSourceForm","pickerOpen","setPickerOpen","fieldProps","o","picked","EmbeddingModelSection","embeddingModel","savingEmbeddingModel","embeddingProbe","readiness","hasWorkingEmbeddingModel","onOpenModels","documentsReady","dimension","SearchProbe","onSearch","setQuery","hits","setHits","searching","setSearching","runSearch","source_label","rel_path","score","document_id","chunk_index","Cloud","SourceList","onReindex","SourceRow","stats","document_count","chunk_count","embedded_chunk_count","last_scan_at","last_error","computeFeatureReadiness","useDocumentsPanel","setSources","setEmbeddingModel","setSavingEmbeddingModel","setEmbeddingProbe","setBusy","sourceRows","modelRows","settings","documents","listSources","getSettings","embedding_model_config","embedding_probe","saveEmbeddingModel","setSettings","addSource","createSource","reindex","embed_failed","embed_error","removeSource","deleteSource","toggleSource","updateSource","selectedProvider","selectedModelId","AlertCircle","FolderSearch","DocumentsPanel","useAgents","setAgents","onAgentsChanged","useTools","tools","setTools","MBTI_PRESETS","INTJ","strength","empathy","expressiveness","verbosity","INTP","ENTJ","ENTP","INFJ","INFP","ENFJ","ENFP","ISTJ","ISFJ","ESTJ","ESFJ","ISTP","ISFP","ESTP","ESFP","MBTI_TYPES","useAgentExternalData","harnesses","setHarnesses","defaultHarnessId","setDefaultHarnessId","otherAgents","setOtherAgents","default_harness_id","READ_PREFIXES","WRITE_PREFIXES","EXECUTE_PREFIXES","permissionKindForTool","toolScoreClass","useAgentToolHandlers","setSelectedTools","groupedTools","buildGroupedTools","allCategories","g","categories","toggleTool","toolName","toggleAllTools","toggleCategory","enable","applyBulkSelection","toggleCategoryPermission","toggleGroup","group","catGroup","orderOf","groupOrder","here","scoreDiff","useAgentEditorForm","iconInputRef","setIcon","identity","setIdentity","instructions","setInstructions","modelConfigName","setModelConfigName","selectedTools","delegateTargets","setDelegateTargets","delegate_targets","harnessId","setHarnessId","harness_id","antiHallucMode","setAntiHallucMode","anti_hallucination_mode","antiHallucModel","setAntiHallucModel","anti_hallucination_model_config","citationStrictness","setCitationStrictness","citation_strictness","tierOverride","setTierOverride","context_tier_proportions","adaptivePersonaEnabled","setAdaptivePersonaEnabled","adaptive_persona_enabled","adaptiveMbti","setAdaptiveMbti","initialMbti","adaptive_mbti","setVoiceEnabled","voiceModel","setVoiceModel","voice_model","voiceName","setVoiceName","voice_name","voiceSttModel","setVoiceSttModel","voice_stt_model","voiceAutoSpeak","setVoiceAutoSpeak","handlers","handleIconFile","handleIconFileFor","buildAgentPayload","useAgentSaveHandler","getName","agent_name","Section","Upload","MarkdownTextarea","IconPicker","autoFocus","isProviderClassified","modelSupportsImages","ModelSection","selectedModel","DocumentsReadinessNotice","vision","SelectedModelDescription","ToolGroupBlock","advancedMode","onToggleTool","onToggleCategory","onToggleCategoryPermission","onToggleGroup","allTools","selectedInGroup","allOn","someOn","headerRef","indeterminate","ToolSelectionSection","selectedCount","totalCount","onToggleAll","bodyClassName","catTools","ToolCategoryBlock","selectedInCat","ToolCheckbox","NormalPermissionControls","isOn","kinds","PermissionTile","ToolsSection","ToolsBody","ToolsHeader","DelegatesSection","canDelegate","hr","DelegateRow","HarnessField","defaultHarnessLabel","builtin","AntiHallucinationFields","CitationStrictnessField","MIN_SEGMENT","MAX_SEGMENT_END","TierProportionBar","readOnly","barRef","normalised","normaliseToHundred","hotEnd","hot","warmEnd","warm","activeHandle","setActiveHandle","onPointerDown","handle","setPointerCapture","pointerId","bar","handleMove","rect","getBoundingClientRect","xPct","clamp","clientX","left","updateAt","handleUp","dim","Chip","centered","facts","right","Handle","ariaLabel","ariaValueNow","ariaValueMin","ariaValueMax","colorMap","amber","teal","align","tabIndex","aria-orientation","aria-valuenow","aria-valuemin","aria-valuemax","endPct","minHot","maxHot","newHot","minBoundary","maxBoundary","newBoundary","sum","TierOverrideField","isOverriding","AdaptivePersonaFields","GEMINI_VOICES","GEMINI_TTS_MODELS","GEMINI_STT_MODELS","VoiceFields","voiceReady","VoiceReadinessNotice","hasGoogleIntegration","onOpenCredentials","VoicePickers","Divider","AdvancedSection","variant","onIsDefaultChange","AgentEditor","AVATAR_GRADIENTS","agentGradient","AgentsPanel","deleting","setDeleting","useLocationSharing","consent","opts","lastPostedAt","geolocation","post","pos","updateLocation","lat","coords","latitude","lng","longitude","accuracy_m","accuracy","warn","getCurrentPosition","enableHighAccuracy","highAccuracy","maximumAge","timeout","watchId","watchPosition","clearWatch","toMs","signed","collapseSeconds","past","txt","formatRelativeOrDate","maxDays","toLocaleDateString","Shield","MapPin","ProfileEditor","fileRef","setProfile","about","setAbout","saved","setSaved","isDirty","PresetPicker","LocationSharing","TailscaleServe","AccessWhitelist","PRESET_OPTIONS","location_consent","setLocationConsent","hasFix","location_lat","location_lng","updatedAt","location_updated_at","location_accuracy_m","setDisplayName","access","display_name","added_at","last_seen_at","tailscale","copyRecipe","serve_recipe","reachableUrl","fqdn","serving","installed","logged_in","install_script","uninstall_script","Lock","SecurityPanel","currentPin","setCurrentPin","newPin","setNewPin","confirmPin","setConfirmPin","setSubmitting","okMsg","setOkMsg","successMsg","pin_enabled","PinInput","inputMode","maxLength","RedactionPanel","showPatterns","setShowPatterns","showAllowlist","setShowAllowlist","setMsg","materialize","created","enabledPatterns","patterns","config_path","config_exists","heuristics","high_entropy","min_length","min_entropy","validator","field_name_allowlist","Edit3","Network","ServerCog","refreshRuntimeConfig","setRows","restartNeeded","setRestartNeeded","restarting","setRestarting","cache","statusText","persist","requiresRestart","onReset","onRestart","pollUntilUp","overridden","default","timeoutMs","delay","Sparkles","OnboardingWizard","ProfilePanel","isEssential","showWizard","setShowWizard","Plug","MCPPanel","servers","setServers","mcp","transport","spec","command","existing","RegistryPicker","existingNames","onPick","registryEntry","onCustom","MCPEditor","server","onBack","setTransport","varValues","setVarValues","init","variables","initialSpecJSON","specJSON","setSpecJSON","setEnabled","switchTransport","template","substituteVars","walk","debouncedQuery","setDebouncedQuery","nextCursor","setNextCursor","registry","loadMore","cursor","Puzzle","KeyRound","ExtensionsPanel","setData","extensions","dir","directories","EmptyHint","what","ToolRow","errors","badge","sub","secrets","is_set","setErr","hasSecrets","setCount","requiredMissing","saveToolSecrets","useBridges","bridges","setBridges","patch","pair","useBridgeRoutes","routes","setRoutes","route_id","ArrowLeft","Camera","QrCode","StatusPill","BridgeEditor","onRename","onToggleEnabled","savingName","setSavingName","live","setLive","repairing","setRepairing","alive","timer","saveName","rePair","onBlur","blur","paired_id","qr_data_url","RouteTable","chats","setChats","chatsRunning","setChatsRunning","chatsLoading","setChatsLoading","manualMode","setManualMode","draft","setDraft","searchQuery","setSearchQuery","searchMsg","setSearchMsg","extraChats","setExtraChats","agentVisionState","cfg","supported","classified","modelLabel","running","usedAgents","availableAgents","hasCatchAll","creatingCatchAll","routedJids","availableChats","byJid","selectChat","jid","lookup","onAdd","last_message_at","RouteRow","route","agentVision","onChangeAgent","onToggleSilent","silent_mode","onChangeRespondTo","respond_to","visionForAgent","onDelete","headline","isCatchAll","showJidSubline","endsWith","MessageSquareText","Smartphone","BridgesPanel","selectedId","setSelectedId","creating","setCreating","newName","setNewName","onCreate","BridgeRow","connected","pairing","disconnected","fetchStatus","CATEGORY_BLURB","Memory","Documents","Files","Shell","Web","Images","Voice","Schedule","Atlassian","JiraAlign","GitHub","Mail","Calendar","Config","BuiltinToolsPanel","sourceFilter","setSourceFilter","statusFilter","setStatusFilter","builtinTools","categoryRows","toolRows","target_enabled","filteredTools","haystack","never_used","issueHref","buildIssueHref","toolCount","toolNames","success","success_rate","usefulness","usefulness_rate","article","Metric","call_count","error_count","searchParams","usePackages","loadResult","setLoadResult","manifests","setManifests","mfs","pend","packages","listManifests","listPending","install","approveInstall","denyInstall","createManifest","updateManifest","deleteManifest","Package","CATEGORIES","CAPABILITIES","EMPTY_FORM","package","exportName","capability","requiredEnv","LangChainPackagesPanel","installSpec","setInstallSpec","installVersion","setInstallVersion","installing","setInstalling","installNotice","setInstallNotice","setForm","savingManifest","setSavingManifest","errorRows","skippedRows","skipped","handleInstall","publisher","resolvedPackage","installedVersion","handleApprove","handleDeny","handleCreateManifest","export","handleDeleteManifest","record","handleReload","packagesDir","manifest","SUBS","ToolsPanel","humanizeCron","expr","dom","month","dow","parseStep","pad","time","formatTime","days","formatDow","DOW_NAMES","AlertTriangle","AgentModelBadge","tooltip","REACTION_SCRIPT_ARGS_MAX","KindPill","ReactionScriptEditor","initialScript","initialArgs","errorContext","diffContext","scripts","setScripts","initialArgsText","script","setScript","argsText","setArgsText","argsError","setArgsError","watchers","listReactionScripts","validateArgs","dirty","Bell","Power","sharedFormatRelative","WatchersSection","setWatchers","cancel","w","runNow","watcher_id","sorted","next_run_at","WatcherCard","onRunNow","setRunning","nextRun","lastRun","last_run_at","lastFired","last_fired_at","overdue","modelStatus","reaction_kind","formatInterval","interval_seconds","target_agent","ReactionEditor","REACTION_PROMPT_MAX","switching","setSwitching","switchKind","scriptName","reaction_script","reaction_script_args","reaction_prompt","target_kind","ReactionPromptEditor","tooLong","monospace","seconds","Repeat","ScheduledTasksPanel","setTasks","taskList","agentList","modelList","scheduledTasks","task","TaskCard","isCron","schedule","TaskEditor","TaskReactionEditor","setAgentId","setPrompt","setDescription","setKind","setSchedule","isoToLocalInput","setSilent","trimmedPrompt","trimmedSchedule","scheduleOut","padStart","getFullYear","getMonth","getDate","getHours","getMinutes","HARNESS_SECTION_KEYS","BUILTIN_HARNESS_ID_PREFIX","CUSTOM_HARNESS_ID_PREFIX","DEFAULT_HARNESS_ID","isBuiltinHarnessId","SECTION_DISPLAY","plan_first","presentation","citation","self_config","emptySections","HarnessEditor","harness","builtins","setSections","openSection","setOpenSection","builtinDefault","patchSection","resetSection","Wrench","HarnessPanel","defaultId","setDefaultId","setDefault","handleClone","isBuiltin","enabledCount","Download","LEVEL_LABEL","log","info","LEVEL_BG","LEVEL_FG","CLIENT_RING_CAP","DEFAULT_LEVELS","LogsPanel","paused","setPaused","autoscroll","setAutoscroll","setSearch","levels","setLevels","setConnected","lastSeqRef","seq","since","onopen","level","toggleLevel","copyAll","clearLocal","CATEGORY_LABEL","lifecycle","limits","logging","scheduler","ui","EnvVarsPanel","showAdvanced","setShowAdvanced","editInputRef","tier","startEdit","cancelEdit","agentWritable","enumValues","HeaderActivity","BellOff","BellRing","readStatus","DISMISS_KEY","NotificationStatus","dismissed","setDismissed","testFired","setTestFired","testFire","dismiss","NotificationTestButton","fire","CryptoFallbackBanner","show","setShow","crypto","UpdateAvailableBanner","setInfo","behind","dismissKey","latestCommit","sha","dismissedFor","isMain","shortRemote","shortLocal","currentCommit","upgradeCmd","altCmd","CloudOff","HEALTHY_INTERVAL_MS","DOWN_INTERVAL_MS","RETRY_INTERVAL_MS","FAILURE_THRESHOLD","ping","healthCheckTimeoutMs","ServerStatus","down","setDown","wasDownRef","failureCountRef","MAX_VISIBLE","Toaster","visible","bottom","ToastCard","toast","exiting","setExiting","timerRef","remainingRef","startedRef","hasReport","onCopy","innerText","onReport","avatar","onMouseLeave","backgroundColor","animation","Logo","BootScreen","agentsLoaded","activeAgentId","onPickAgent","suppressed","pickedId","setPickedId","dismissing","setDismissing","done","setDone","dismissTimerRef","steps","setSteps","prefetchStartedRef","defaultAgent","recentAgents","focusAgent","markStep","allSettled","settleTimer","activeStep","handlePick","tileAgent","tileClickable","paddingTop","paddingLeft","paddingRight","PinKeypad","ScreenLock","onUnlock","onSuccess","BarChart3","Brain","MessageSquare","Monitor","Moon","ScrollText","Shapes","Sun","TAB_ICONS","dashboard","logs","TAB_TITLES","TAB_SHORT","COMMON_TABS","ADVANCED_TABS","ADVANCED_KEY","TAB_ACCENT","avatarGradient","AgentSessionList","unread","isActive","MenuPanel","onAgentChange","onSetTab","advancedOpen","setAdvancedOpen","toggleAdvanced","renderTabButton","aria-current","aria-checked","ThemePicker","WINDOWS","MANUAL_CURRENCIES","TOOL_SORT_OPTIONS","MODEL_SORT_OPTIONS","CURRENCY_MODE_KEY","CURRENCY_PICK_KEY","USD_CURRENCY","currency","rate_from_usd","country_code","TIER_COLORS","overhead","CurrencyPickerRow","currencyMode","onModeChange","manualCurrency","onManualChange","currencyInfo","RotateCw","DashboardHeader","onDaysChange","refreshingPricing","refreshHint","onRefreshPricing","convertUsd","usd","rate","formatInt","Intl","NumberFormat","formatMoney","converted","useMicroPrecision","minFractionDigits","maxFractionDigits","minimumFractionDigits","maximumFractionDigits","formatMoneyCompact","notation","sign","safeHttpUrl","protocol","MetricCard","InsightChip","Activity","Coins","TrendingUp","SummaryStrip","windowTokenTotal","activeDays","avgDailyTokens","avgDailyCostUsd","estimated_cost_usd","MetricCardsGrid","effectiveSummary","selectedDay","input_tokens_est","output_tokens_est","error_rate","InteractiveTokenChart","series","onSelectDay","hovered","setHovered","barsReady","setBarsReady","maxTotal","animationSignature","day","frame","point","TokenBar","onHover","TokenChartLegend","hasData","totalHeight","inputHeight","outputHeight","tier_tokens","tierTotal","measured_input_tokens","hotPx","warmPx","factsPx","overheadPx","clickable","tieredSegments","transition","seg","background","InteractiveCostChart","lineAnimCycle","setLineAnimCycle","padX","padY","maxCost","points","y","polyline","pt","selectedIdx","frac","x1","y1","x2","y2","textAnchor","pathLength","animate","attributeName","to","dur","CostPoint","isSelected","animCycle","repeatCount","begin","TokensCostSection","onToggleDay","onClearDay","detectModelFunctionality","confidenceRank","filterModelRates","vendor","functionality","sortModelRates","copy","input_per_1m_usd","POSITIVE_INFINITY","output_per_1m_usd","rankDiff","confidence","groupModelRatesByVendor","sortTools","aRate","bRate","parseHexColor","hex","normalized","shiftHex","amount","rgb","shiftChannel","withAlpha","alpha","arcPath","startAngle","endAngle","cos","sin","largeArc","useId","SharedDonutChart","centerAmount","slices","onHoverChange","uid","setAnimCycle","padding","ceil","radius","innerRadius","gap","segments","fraction","sweep","gapSafe","arcStart","arcEnd","glowColor","opacity","radialGradient","offset","stopColor","stopOpacity","segment","strokeLinejoin","AGENT_PALETTE","AgentCostPie","fractions","message_count","BREAKDOWN_PALETTE","BreakdownPiePanel","cost","ToolsAndAgentsRow","toolSort","onToolSortChange","effectiveTopAgents","sortedTools","top_tools","opt","VendorModelReportSection","effectiveByProvider","effectiveByModel","ModelPricingSection","modelVendorFilter","onVendorFilterChange","modelFunctionFilter","onFunctionFilterChange","modelSearch","onSearchChange","modelSort","onSortChange","pricing","model_rates","vendors","functionalities","snapshot_generated_at","func","ModelPricingGroup","notes","ModelPricingRow","inferred","useCurrencyPreference","setCurrencyInfo","setCurrencyMode","setManualCurrency","profileLocation","setProfileLocation","savedMode","savedCurrency","resolved","useDashboardData","initialDays","setDays","setRefreshingPricing","setRefreshHint","metrics","refreshPricing","refreshed","DashboardPanel","setToolSort","setModelVendorFilter","setModelFunctionFilter","setModelSearch","setModelSort","setSelectedDay","dayBreakdown","breakdowns_by_day","top_agents","by_provider","by_model","toggleDay","Menu","UnlockScreen","getAppName","AppShell","activeThreadId","showMenu","setShowMenu","showAgentPicker","setShowAgentPicker","agentPickerRef","mountedTabs","setMountedTabs","unreadCount","setAgentsLoaded","agentsRef","stateRef","pwaUnfocused","hasFocus","evAgentId","onSameAgentChat","contains","activeAgent","screenLocked","setScreenLocked","masterKeyLocked","setMasterKeyLocked","bootSeq","setBootSeq","onScreenLocked","onMasterKeyLocked","screen_locked","process","debug","landOnAgentPicker","aria-haspopup"],"sourceRoot":"","ignoreList":[]}
|