@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +22 -7
  3. package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-N546FNNS.js} +38 -23
  4. package/dist/AgentCodeSnippets-N546FNNS.js.map +1 -0
  5. package/dist/AgentMetricChart-YWJYVYYA.js +15 -0
  6. package/dist/{AgentOverview-EEBHJC32.js → AgentOverview-VF74XC7I.js} +7 -7
  7. package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-RFR6LQMY.js} +19 -10
  8. package/dist/AgentSessionEventTimeline-RFR6LQMY.js.map +1 -0
  9. package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-27CQF6FX.js} +144 -57
  10. package/dist/AgentSessionEventTimelineChart-27CQF6FX.js.map +1 -0
  11. package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-4IVX2SGD.js} +36 -12
  12. package/dist/AgentSessions-4IVX2SGD.js.map +1 -0
  13. package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-R5VEP7BO.js} +162 -126
  14. package/dist/ConnectorSettings-R5VEP7BO.js.map +1 -0
  15. package/dist/{DockLayout-LM4AFMFY.js → DockLayout-F44RWGEY.js} +10 -10
  16. package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-SQ323AVM.js} +14 -12
  17. package/dist/DrawerLayout-SQ323AVM.js.map +1 -0
  18. package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-6QLS63HM.js} +22 -28
  19. package/dist/ModelSettings-6QLS63HM.js.map +1 -0
  20. package/dist/OpenUiFenceBlock-4ROX3G4X.js +9 -0
  21. package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-OLKDXIQS.js} +17 -21
  22. package/dist/SandboxSettings-OLKDXIQS.js.map +1 -0
  23. package/dist/SchedulesPage-TMOTK6DR.js +15 -0
  24. package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-GISAH2WU.js} +8 -8
  25. package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-EN33DUQ7.js} +171 -26
  26. package/dist/ShellRouteSync-EN33DUQ7.js.map +1 -0
  27. package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-35K4AKTC.js} +80 -58
  28. package/dist/SidebarLayout-35K4AKTC.js.map +1 -0
  29. package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-JSX2BTII.js} +24 -22
  30. package/dist/SkillSettings-JSX2BTII.js.map +1 -0
  31. package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-6VCR7ES3.js} +9 -9
  32. package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-RKBSN2FZ.js} +10 -10
  33. package/dist/{chunk-ZTMKFZQ3.js → chunk-2O5EJ6QS.js} +4440 -3042
  34. package/dist/chunk-2O5EJ6QS.js.map +1 -0
  35. package/dist/chunk-6WCIL3H2.js +517 -0
  36. package/dist/chunk-6WCIL3H2.js.map +1 -0
  37. package/dist/{chunk-WVE3F724.js → chunk-73FQVITT.js} +21 -4
  38. package/dist/chunk-73FQVITT.js.map +1 -0
  39. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  40. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  41. package/dist/{chunk-CYHJDKFB.js → chunk-F5QVQIBH.js} +172 -46
  42. package/dist/chunk-F5QVQIBH.js.map +1 -0
  43. package/dist/{chunk-FJW36PD7.js → chunk-GIPFF6FZ.js} +28 -24
  44. package/dist/chunk-GIPFF6FZ.js.map +1 -0
  45. package/dist/{chunk-6O6FWUDW.js → chunk-GSJAYYLR.js} +233 -195
  46. package/dist/chunk-GSJAYYLR.js.map +1 -0
  47. package/dist/{chunk-MPNSO7E6.js → chunk-J5BPHEDT.js} +2 -2
  48. package/dist/chunk-KR7WYHVF.js +195 -0
  49. package/dist/chunk-KR7WYHVF.js.map +1 -0
  50. package/dist/{chunk-DMMZSZTN.js → chunk-LUG7E6BL.js} +60 -16
  51. package/dist/chunk-LUG7E6BL.js.map +1 -0
  52. package/dist/chunk-LXJMINS6.js +587 -0
  53. package/dist/chunk-LXJMINS6.js.map +1 -0
  54. package/dist/{chunk-U7KURWW3.js → chunk-PT4EENB3.js} +244 -52
  55. package/dist/chunk-PT4EENB3.js.map +1 -0
  56. package/dist/{chunk-XAU7QFG3.js → chunk-Q6TCT7ZJ.js} +68 -256
  57. package/dist/chunk-Q6TCT7ZJ.js.map +1 -0
  58. package/dist/{chunk-ZKNUMH2M.js → chunk-XLFOXQKZ.js} +13 -11
  59. package/dist/chunk-XLFOXQKZ.js.map +1 -0
  60. package/dist/{chunk-M62XY4NC.js → chunk-XY6LZQES.js} +235 -108
  61. package/dist/chunk-XY6LZQES.js.map +1 -0
  62. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  63. package/dist/index.d.ts +316 -94
  64. package/dist/index.js +65 -488
  65. package/dist/index.js.map +1 -1
  66. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +36 -13
  67. package/dist/plugins/trueforge-agent-server-adapter/index.js +69 -34
  68. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  69. package/dist/styles.css +1 -1
  70. package/package.json +4 -4
  71. package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
  72. package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
  73. package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
  74. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
  75. package/dist/AgentSessions-3MPDZASK.js.map +0 -1
  76. package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
  77. package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
  78. package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
  79. package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
  80. package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
  81. package/dist/SchedulesPage-KKLUDO6B.js +0 -15
  82. package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
  83. package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
  84. package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
  85. package/dist/chunk-2XPPBEYF.js +0 -74
  86. package/dist/chunk-2XPPBEYF.js.map +0 -1
  87. package/dist/chunk-6O6FWUDW.js.map +0 -1
  88. package/dist/chunk-7Z2C2K7F.js +0 -578
  89. package/dist/chunk-7Z2C2K7F.js.map +0 -1
  90. package/dist/chunk-CYHJDKFB.js.map +0 -1
  91. package/dist/chunk-DMMZSZTN.js.map +0 -1
  92. package/dist/chunk-FJW36PD7.js.map +0 -1
  93. package/dist/chunk-M62XY4NC.js.map +0 -1
  94. package/dist/chunk-QC42MLAK.js.map +0 -1
  95. package/dist/chunk-SFZNIO6U.js +0 -18
  96. package/dist/chunk-SFZNIO6U.js.map +0 -1
  97. package/dist/chunk-U7KURWW3.js.map +0 -1
  98. package/dist/chunk-WVE3F724.js.map +0 -1
  99. package/dist/chunk-XAU7QFG3.js.map +0 -1
  100. package/dist/chunk-ZKNUMH2M.js.map +0 -1
  101. package/dist/chunk-ZTMKFZQ3.js.map +0 -1
  102. /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-YWJYVYYA.js.map} +0 -0
  103. /package/dist/{AgentOverview-EEBHJC32.js.map → AgentOverview-VF74XC7I.js.map} +0 -0
  104. /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-F44RWGEY.js.map} +0 -0
  105. /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-4ROX3G4X.js.map} +0 -0
  106. /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-TMOTK6DR.js.map} +0 -0
  107. /package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-GISAH2WU.js.map} +0 -0
  108. /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-6VCR7ES3.js.map} +0 -0
  109. /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-RKBSN2FZ.js.map} +0 -0
  110. /package/dist/{chunk-MPNSO7E6.js.map → chunk-J5BPHEDT.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentSessions.tsx","../src/utils/drainListPages.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type ComponentType } from 'react';\nimport { Group, Panel, Separator } from 'react-resizable-panels';\n\nimport { useResourcePermissions } from '../../hooks/useResourcePermissions.js';\nimport { useSessionShareSearch } from '../../hooks/useSessionShareSearch.js';\nimport { Icon } from '../../icons/Icon.js';\nimport { buildSessionResumeHref } from '../../routing/paths.js';\nimport { useOptionalResolvedRoutes } from '../../routing/ResolvedRoutesContext.js';\nimport { useAgentSessionsServer, useServer } from '../../server/ServerContext.js';\nimport { useOptionalShellMode } from '../../server/ShellModeContext.js';\nimport type { Session, SessionEventItem, SessionListEntry } from '../../server/types.js';\nimport { useSlot } from '../../theme/SlotsProvider.js';\nimport { drainListPages } from '../../utils/drainListPages.js';\nimport { sessionTimeRangeFromCreatedAt } from '../../utils/sessionShareUrl.js';\nimport { EmptyScreen } from '../EmptyScreen.js';\nimport { cn } from '../lib/cn.js';\nimport { sessionIsCreateAgent } from '../lib/sessionCreateAgent.js';\nimport { Skeleton } from '../primitives/Skeleton.js';\nimport type { AgentSessionsProps } from './types.js';\n\nfunction sessionTitle(entry: Pick<SessionListEntry, 'title'>): string {\n const title = entry.title?.trim();\n return title != null && title.length > 0 ? title : 'Untitled session';\n}\n\nfunction entryIsMutable(entry: SessionListEntry): boolean {\n if ('isMutable' in entry && typeof Reflect.get(entry, 'isMutable') === 'boolean') {\n return Reflect.get(entry, 'isMutable') === true;\n }\n return entry.agentName == null;\n}\n\nfunction entrySourceType(entry: SessionListEntry): 'schedule' | undefined {\n return 'sourceType' in entry && Reflect.get(entry, 'sourceType') === 'schedule' ? 'schedule' : undefined;\n}\n\nexport function AgentSessions({ agentId, startTimestamp, endTimestamp, shareView }: AgentSessionsProps) {\n const sessionsServer = useAgentSessionsServer();\n const chatServer = useServer();\n const shell = useOptionalShellMode();\n const routes = useOptionalResolvedRoutes();\n const { sessionId: selectedSessionId, updateShareSearch } = useSessionShareSearch();\n const { allows } = useResourcePermissions({\n resourceType: 'session',\n resourceIds: selectedSessionId == null ? [] : [selectedSessionId],\n });\n const canResume = allows(selectedSessionId, 'MANAGE');\n\n const AgentSessionListRow = useSlot('AgentSessionListRow');\n const AgentSessionDetailHeader = useSlot('AgentSessionDetailHeader');\n const AgentSessionTimelineContainer = useSlot('AgentSessionTimelineContainer');\n\n const [entries, setEntries] = useState<SessionListEntry[]>([]);\n const [nextPageToken, setNextPageToken] = useState<string | undefined>();\n const [listLoading, setListLoading] = useState(true);\n const [listLoadingMore, setListLoadingMore] = useState(false);\n const [listFailed, setListFailed] = useState(false);\n const listRequestIdRef = useRef(0);\n const [detailEvents, setDetailEvents] = useState<SessionEventItem[]>();\n const [detailSession, setDetailSession] = useState<Session>();\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailFailed, setDetailFailed] = useState(false);\n\n const listRequest = useMemo(\n () => ({\n order: 'desc' as const,\n limit: 20,\n ...(agentId == null || agentId.length === 0 ? {} : { agentId }),\n ...(startTimestamp == null ? {} : { startTimestamp }),\n ...(endTimestamp == null ? {} : { endTimestamp }),\n }),\n [agentId, endTimestamp, startTimestamp],\n );\n\n useEffect(() => {\n const requestId = ++listRequestIdRef.current;\n let cancelled = false;\n setListLoading(true);\n setListLoadingMore(false);\n setListFailed(false);\n void sessionsServer\n .listSessions(listRequest)\n .then(page => {\n if (cancelled || listRequestIdRef.current !== requestId) return;\n setEntries(page.data);\n setNextPageToken(page.nextPageToken);\n })\n .catch(() => {\n if (cancelled || listRequestIdRef.current !== requestId) return;\n setEntries([]);\n setNextPageToken(undefined);\n setListFailed(true);\n })\n .finally(() => {\n if (!cancelled && listRequestIdRef.current === requestId) setListLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [listRequest, sessionsServer]);\n\n const loadMore = useCallback(async () => {\n if (nextPageToken == null || listLoadingMore) return;\n const requestId = listRequestIdRef.current;\n setListLoadingMore(true);\n try {\n const page = await sessionsServer.listSessions({ ...listRequest, pageToken: nextPageToken });\n if (listRequestIdRef.current !== requestId) return;\n setEntries(current => [...current, ...page.data]);\n setNextPageToken(page.nextPageToken);\n } catch {\n // Keep the current page and token visible so the user can retry.\n } finally {\n if (listRequestIdRef.current === requestId) setListLoadingMore(false);\n }\n }, [listLoadingMore, listRequest, nextPageToken, sessionsServer]);\n\n useEffect(() => {\n if (selectedSessionId == null || selectedSessionId.length === 0) {\n setDetailEvents(undefined);\n setDetailSession(undefined);\n setDetailFailed(false);\n setDetailLoading(false);\n return;\n }\n\n let cancelled = false;\n setDetailLoading(true);\n setDetailFailed(false);\n setDetailEvents(undefined);\n setDetailSession(undefined);\n\n void Promise.all([\n drainListPages({\n fetchPage: pageToken =>\n sessionsServer.listSessionEvents({\n sessionId: selectedSessionId,\n limit: 100,\n ...(pageToken == null ? {} : { pageToken }),\n }),\n }),\n chatServer.getSession({ sessionId: selectedSessionId }).catch(() => undefined),\n ])\n .then(([itemsNewestFirst, session]) => {\n if (cancelled) return;\n setDetailEvents([...itemsNewestFirst].reverse());\n setDetailSession(session);\n })\n .catch(() => {\n if (!cancelled) setDetailFailed(true);\n })\n .finally(() => {\n if (!cancelled) setDetailLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [chatServer, selectedSessionId, sessionsServer]);\n\n const selectSession = (entry: SessionListEntry) => {\n const pinned = shareView === 'sessions' ? sessionTimeRangeFromCreatedAt(entry.createdAt) : null;\n updateShareSearch({\n sessionId: entry.id,\n ...(shareView === 'sessions'\n ? { view: 'sessions', ...(pinned == null ? {} : { timeRange: pinned }) }\n : { agentId: agentId ?? null, tab: 'sessions', view: null, timeRange: null }),\n });\n };\n\n const clearSelectedSession = () => {\n if (selectedSessionId == null) return;\n updateShareSearch({ sessionId: null });\n };\n\n const selectedEntry = entries.find(entry => entry.id === selectedSessionId);\n const selectedTitle =\n detailSession != null\n ? sessionTitle(detailSession)\n : selectedEntry != null\n ? sessionTitle(selectedEntry)\n : (selectedSessionId ?? 'Untitled session');\n\n const resumeIsCreateAgent =\n detailSession != null\n ? sessionIsCreateAgent(detailSession)\n : selectedEntry != null\n ? sessionIsCreateAgent(selectedEntry)\n : false;\n const resumeIsMutable =\n detailSession != null ? detailSession.isMutable : selectedEntry != null ? entryIsMutable(selectedEntry) : true;\n const resumeLabel = resumeIsCreateAgent ? 'Resume Agent building' : 'Resume Chat';\n const resumeHref =\n selectedSessionId != null && routes != null\n ? buildSessionResumeHref({ sessionId: selectedSessionId, routes })\n : null;\n\n const handleResume = () => {\n if (!canResume || selectedSessionId == null || shell == null) return;\n const agentName = detailSession?.agentName ?? selectedEntry?.agentName;\n shell.openHistorySession({\n sessionId: selectedSessionId,\n isMutable: resumeIsMutable,\n isCreateAgent: resumeIsCreateAgent,\n ...(agentName != null && agentName.length > 0 ? { agentName } : {}),\n });\n };\n\n const resumeProps =\n resumeHref != null ? { resumeHref, resumeLabel } : shell != null ? { onResume: handleResume, resumeLabel } : {};\n\n // Full empty only when nothing is selected — keep the detail pane for deep-linked sessionIds\n // (filters/time range can empty the list while share state still points at a session).\n if (\n !listLoading &&\n !listFailed &&\n entries.length === 0 &&\n (selectedSessionId == null || selectedSessionId.length === 0)\n ) {\n return (\n <EmptyScreen\n title=\"No Sessions Found\"\n description=\"There are no sessions available at the moment.\"\n className=\"bg-primary-bg\"\n />\n );\n }\n\n return (\n <Group\n id=\"agent-sessions-split\"\n orientation=\"horizontal\"\n className=\"h-full min-h-0 w-full\"\n resizeTargetMinimumSize={{ coarse: 24, fine: 11 }}\n >\n <Panel id=\"agent-sessions-list\" defaultSize=\"35%\" minSize=\"20%\" maxSize=\"50%\">\n <aside className=\"flex h-full min-h-0 w-full flex-col bg-sidebar-bg\">\n <div className=\"scrollbar-none min-h-0 flex-1 overflow-y-auto\">\n {listLoading ? (\n <div className=\"space-y-2 p-3\" role=\"status\" aria-label=\"Loading sessions\">\n {['a', 'b', 'c'].map(key => (\n <Skeleton key={key} className=\"h-16 rounded-md\" />\n ))}\n </div>\n ) : listFailed ? (\n <p className=\"px-3 py-6 text-center text-xs text-text-secondary\">Sessions could not be loaded.</p>\n ) : (\n entries.map(entry => (\n <AgentSessionListRow\n key={entry.id}\n title={sessionTitle(entry)}\n agentName={entry.agentName ?? undefined}\n sourceType={entrySourceType(entry)}\n lastActivityAt={entry.lastActivityAt}\n metrics={entry.metrics}\n active={entry.id === selectedSessionId}\n onSelect={() => selectSession(entry)}\n />\n ))\n )}\n </div>\n\n {nextPageToken != null && !listLoading ? (\n <div className=\"shrink-0 border-t border-border p-3\">\n <button\n type=\"button\"\n disabled={listLoadingMore}\n onClick={() => void loadMore()}\n className=\"h-8 w-full rounded-md border border-border text-xs font-medium text-text-primary hover:bg-ghost-button-hover disabled:opacity-60\"\n >\n {listLoadingMore ? 'Loading…' : 'Load more'}\n </button>\n </div>\n ) : null}\n </aside>\n </Panel>\n\n <Separator\n id=\"agent-sessions-resizer\"\n aria-label=\"Resize session list\"\n className=\"group/resizer relative z-10 w-0 cursor-col-resize focus-visible:outline-none\"\n >\n <div aria-hidden className=\"absolute inset-y-0 -left-1.25 w-2.75\" />\n <div aria-hidden className=\"absolute inset-y-0 left-0 w-px bg-border transition-colors\" />\n <div\n aria-hidden\n className={cn(\n 'absolute top-1/2 left-0 z-10 flex h-4 w-2 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-xs shadow-sm transition-colors',\n 'bg-secondary-button-bg text-text-secondary',\n 'group-hover/resizer:bg-primary-button-bg group-hover/resizer:text-primary-button-text',\n 'group-active/resizer:bg-primary-button-bg group-active/resizer:text-primary-button-text',\n 'group-focus-visible/resizer:bg-primary-button-bg group-focus-visible/resizer:text-primary-button-text',\n )}\n >\n <Icon name=\"grip-vertical\" size={10} />\n </div>\n </Separator>\n\n <Panel id=\"agent-session-detail\" defaultSize=\"65%\" minSize=\"30%\">\n <section className=\"flex h-full min-w-0 flex-col bg-primary-bg\">\n {selectedSessionId == null ? (\n <div className=\"flex flex-1 items-center justify-center px-6 text-sm text-text-secondary\">\n Select a session to view details\n </div>\n ) : detailFailed ? (\n <div className=\"flex flex-1 items-center justify-center px-6 text-sm text-text-secondary\">\n Session details could not be loaded.\n </div>\n ) : (\n <>\n <AgentSessionDetailHeader\n title={selectedTitle}\n sessionId={selectedSessionId}\n agentId={agentId}\n createdAt={detailSession?.createdAt ?? selectedEntry?.createdAt}\n view={shareView}\n onClose={clearSelectedSession}\n canResume={canResume}\n {...resumeProps}\n />\n {detailLoading || detailEvents === undefined ? (\n <div className=\"flex flex-1 flex-col p-4\" role=\"status\" aria-label=\"Loading session details\">\n <Skeleton className=\"min-h-64 flex-1 rounded-lg\" />\n </div>\n ) : (\n <AgentSessionTimelineContainer\n sessionId={selectedSessionId}\n events={detailEvents}\n listMetrics={selectedEntry?.metrics}\n />\n )}\n </>\n )}\n </section>\n </Panel>\n </Group>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentSessions: ComponentType<AgentSessionsProps>;\n }\n}\n","import type { ListResult } from '../server/types.js';\n\n/** Drain token-paginated list endpoints until `nextPageToken` is exhausted. */\nexport async function drainListPages<T>({\n fetchPage,\n}: {\n fetchPage: (pageToken?: string) => Promise<ListResult<T>>;\n}): Promise<T[]> {\n const items: T[] = [];\n let pageToken: string | undefined;\n do {\n const page = await fetchPage(pageToken);\n items.push(...page.data);\n pageToken = page.nextPageToken;\n } while (pageToken != null && pageToken.length > 0);\n return items;\n}\n"],"mappings":"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","names":[]}
@@ -7,41 +7,45 @@ import {
7
7
  auiInputClass,
8
8
  useMCPAuth,
9
9
  useToasterOptional
10
- } from "./chunk-ZTMKFZQ3.js";
11
- import "./chunk-2XPPBEYF.js";
10
+ } from "./chunk-2O5EJ6QS.js";
11
+ import "./chunk-KR7WYHVF.js";
12
12
  import {
13
- Icon,
14
- getErrorMessage
15
- } from "./chunk-XAU7QFG3.js";
13
+ Icon
14
+ } from "./chunk-Q6TCT7ZJ.js";
16
15
  import {
16
+ getErrorMessage,
17
17
  useCatalogServer
18
- } from "./chunk-U7KURWW3.js";
18
+ } from "./chunk-PT4EENB3.js";
19
19
  import "./chunk-M6MHLVSO.js";
20
- import "./chunk-MPNSO7E6.js";
20
+ import "./chunk-J5BPHEDT.js";
21
21
  import {
22
22
  cn
23
- } from "./chunk-7Z2C2K7F.js";
23
+ } from "./chunk-LXJMINS6.js";
24
24
 
25
25
  // src/containers/SettingsBuilder/ConnectorSettings.tsx
26
- import { useCallback, useEffect as useEffect2, useMemo, useState as useState3 } from "react";
26
+ import { useCallback, useEffect as useEffect3, useMemo, useState as useState3 } from "react";
27
27
 
28
28
  // src/containers/SettingsBuilder/AddMcpServerForm.tsx
29
- import { useState } from "react";
29
+ import { useEffect, useState } from "react";
30
30
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
31
31
  var AUTH_OPTIONS = [
32
- { value: "dcr", label: "OAuth" },
33
32
  { value: "none", label: "None" },
34
- { value: "header", label: "API Key" }
33
+ { value: "header", label: "API Key" },
34
+ { value: "dcr", label: "OAuth" }
35
35
  ];
36
36
  var inputClassName = auiInputClass("h-11 shadow-sm");
37
37
  var RequiredMark = () => /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-failure-bg", "aria-hidden": true, children: "*" });
38
- var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
38
+ var AddMcpServerForm = ({ open, onOpenChange, onSubmit, connector, busy = false, error }) => {
39
39
  const [name, setName] = useState("");
40
40
  const [url, setUrl] = useState("");
41
41
  const [description, setDescription] = useState("");
42
42
  const [authType, setAuthType] = useState("dcr");
43
43
  const [apiKey, setApiKey] = useState("");
44
44
  const [headerName, setHeaderName] = useState("");
45
+ const isEditing = connector !== void 0;
46
+ const nameInputClassName = auiInputClass(
47
+ `h-11 shadow-sm ${isEditing ? "cursor-not-allowed bg-secondary-bg/60 text-text-secondary opacity-40" : ""}`
48
+ );
45
49
  const resetForm = () => {
46
50
  setName("");
47
51
  setUrl("");
@@ -50,11 +54,21 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
50
54
  setApiKey("");
51
55
  setHeaderName("");
52
56
  };
57
+ useEffect(() => {
58
+ if (!open) return;
59
+ setName(connector?.name ?? "");
60
+ setUrl(connector?.url ?? "");
61
+ setDescription(connector?.description ?? "");
62
+ setAuthType(connector?.auth.type ?? "dcr");
63
+ setApiKey("");
64
+ setHeaderName(connector?.auth.type === "header" ? connector.auth.headerName ?? "" : "");
65
+ }, [connector, open]);
53
66
  const handleOpenChange = (nextOpen) => {
54
67
  if (!nextOpen) resetForm();
55
68
  onOpenChange(nextOpen);
56
69
  };
57
- const isValid = !!name.trim() && !!description.trim() && !!url.trim() && (authType !== "header" || !!apiKey.trim());
70
+ const hasApiKey = !!apiKey.trim() || connector?.auth.type === "header";
71
+ const isValid = !!name.trim() && !!description.trim() && !!url.trim() && (authType !== "header" || hasApiKey);
58
72
  const handleSubmit = async (event) => {
59
73
  event.preventDefault();
60
74
  if (!isValid || busy) return;
@@ -64,7 +78,7 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
64
78
  ...headerName.trim() ? { headerName: headerName.trim() } : {}
65
79
  } : { type: authType };
66
80
  try {
67
- await onAdd({
81
+ await onSubmit({
68
82
  name: name.trim(),
69
83
  url: url.trim(),
70
84
  description: description.trim(),
@@ -80,8 +94,8 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
80
94
  {
81
95
  open,
82
96
  onOpenChange: handleOpenChange,
83
- title: "Add MCP server",
84
- description: "Point at a remote MCP endpoint. It then behaves like any other connector.",
97
+ title: isEditing ? "Edit MCP server" : "Add MCP server",
98
+ description: isEditing ? "Update how this connector authenticates." : "Point at a remote MCP endpoint. It then behaves like any other connector.",
85
99
  contentSized: true,
86
100
  headerIcon: /* @__PURE__ */ jsx(
87
101
  "span",
@@ -105,12 +119,14 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
105
119
  type: "text",
106
120
  required: true,
107
121
  value: name,
122
+ readOnly: isEditing,
123
+ "aria-disabled": isEditing,
108
124
  onChange: (event) => {
109
125
  setName(event.target.value);
110
126
  },
111
127
  placeholder: "analytics-postgres-mcp",
112
- autoFocus: true,
113
- className: inputClassName
128
+ autoFocus: !isEditing,
129
+ className: nameInputClassName
114
130
  }
115
131
  )
116
132
  ] }),
@@ -191,14 +207,14 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
191
207
  /* @__PURE__ */ jsxs("div", { children: [
192
208
  /* @__PURE__ */ jsxs("label", { htmlFor: "mcp-server-api-key", className: "mb-1.5 block text-sm font-medium text-text-primary", children: [
193
209
  "API key",
194
- /* @__PURE__ */ jsx(RequiredMark, {})
210
+ connector?.auth.type === "header" ? /* @__PURE__ */ jsx("span", { className: "font-normal text-text-secondary", children: " (leave blank to keep current)" }) : /* @__PURE__ */ jsx(RequiredMark, {})
195
211
  ] }),
196
212
  /* @__PURE__ */ jsx(
197
213
  "input",
198
214
  {
199
215
  id: "mcp-server-api-key",
200
216
  type: "password",
201
- required: true,
217
+ required: connector?.auth.type !== "header",
202
218
  value: apiKey,
203
219
  onChange: (event) => {
204
220
  setApiKey(event.target.value);
@@ -231,7 +247,7 @@ var AddMcpServerForm = ({ open, onOpenChange, onAdd, busy = false, error }) => {
231
247
  ] }),
232
248
  /* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-3", children: [
233
249
  error ? /* @__PURE__ */ jsx("p", { className: "text-failure-bg text-sm", children: error }) : null,
234
- /* @__PURE__ */ jsx(Button, { type: "submit", size: "lg", disabled: !isValid || busy, className: "w-full shrink-0", children: "Add" })
250
+ /* @__PURE__ */ jsx(Button.Primary, { type: "submit", size: "large", disabled: !isValid || busy, className: "w-full shrink-0", children: isEditing ? "Save" : "Add" })
235
251
  ] })
236
252
  ] })
237
253
  }
@@ -247,7 +263,7 @@ var AUTH_TYPE_LABELS = {
247
263
  };
248
264
 
249
265
  // src/containers/SettingsBuilder/ConnectorDetails.tsx
250
- import { useEffect, useLayoutEffect, useRef, useState as useState2 } from "react";
266
+ import { useEffect as useEffect2, useLayoutEffect, useRef, useState as useState2 } from "react";
251
267
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
252
268
  function ExpandableDescription({ text }) {
253
269
  const contentRef = useRef(null);
@@ -321,6 +337,7 @@ var ConnectorDetails = ({
321
337
  connector,
322
338
  onBack,
323
339
  onConnectorRefreshed,
340
+ onEdit,
324
341
  onDisconnect,
325
342
  busy = false
326
343
  }) => {
@@ -330,7 +347,7 @@ var ConnectorDetails = ({
330
347
  const [toolsLoading, setToolsLoading] = useState2(true);
331
348
  const [toolsError, setToolsError] = useState2(null);
332
349
  const [refreshingAfterAuth, setRefreshingAfterAuth] = useState2(false);
333
- useEffect(() => {
350
+ useEffect2(() => {
334
351
  let cancelled = false;
335
352
  setTools([]);
336
353
  setToolsError(null);
@@ -385,13 +402,14 @@ var ConnectorDetails = ({
385
402
  }
386
403
  ),
387
404
  /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
388
- /* @__PURE__ */ jsx2("h4", { className: "text-lg font-semibold text-text-primary", children: connector.name }),
389
- /* @__PURE__ */ jsxs2("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-sm", children: [
405
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
406
+ /* @__PURE__ */ jsx2("h4", { className: "text-lg font-semibold text-text-primary", children: connector.name }),
407
+ /* @__PURE__ */ jsx2("span", { className: "inline-flex items-center rounded-full border border-border bg-secondary-bg/40 px-2 py-0.5 text-xs font-medium text-text-secondary", children: AUTH_TYPE_LABELS[connector.auth.type] ?? AUTH_TYPE_LABELS.none }),
390
408
  /* @__PURE__ */ jsxs2(
391
409
  "span",
392
410
  {
393
411
  className: cn(
394
- "flex items-center gap-1.5 text-xs font-medium",
412
+ "flex items-center gap-1.5 rounded-full border border-border bg-secondary-bg/40 px-2 py-0.5 text-xs font-medium",
395
413
  connector.authenticated ? "text-success-bg" : "text-text-primary"
396
414
  ),
397
415
  children: [
@@ -407,29 +425,30 @@ var ConnectorDetails = ({
407
425
  connector.authenticated ? "Connected" : "Not authenticated"
408
426
  ]
409
427
  }
410
- ),
411
- /* @__PURE__ */ jsxs2("span", { className: "text-text-secondary", children: [
412
- "\xB7 ",
413
- connector.description
414
- ] })
428
+ )
415
429
  ] }),
416
- /* @__PURE__ */ jsx2("span", { className: "mt-2 inline-flex items-center rounded-full border border-border bg-secondary-bg/40 px-2 py-0.5 text-xs font-medium text-text-secondary", children: AUTH_TYPE_LABELS[connector.auth.type] ?? AUTH_TYPE_LABELS.none })
430
+ /* @__PURE__ */ jsx2("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-sm", children: /* @__PURE__ */ jsx2("span", { className: "text-text-secondary", children: connector.description }) })
417
431
  ] }),
418
- connector.auth.type === "dcr" && !connector.authenticated ? /* @__PURE__ */ jsx2(
419
- Button,
420
- {
421
- variant: "outline",
422
- size: "sm",
423
- type: "button",
424
- disabled: busy || connecting,
425
- onClick: () => {
426
- void handleAuthorize(connector.id, (isSuccess) => {
427
- if (isSuccess) void refreshAfterAuthentication();
428
- });
429
- },
430
- children: connecting ? "Connecting\u2026" : "Connect"
431
- }
432
- ) : connector.auth.type === "dcr" && !connector.requiresAuth ? /* @__PURE__ */ jsx2(Button, { variant: "outline", size: "sm", type: "button", disabled: busy, onClick: onDisconnect, children: "Disconnect" }) : null
432
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
433
+ /* @__PURE__ */ jsxs2(Button.Secondary, { size: "small", type: "button", disabled: busy, onClick: onEdit, children: [
434
+ /* @__PURE__ */ jsx2(Icon, { name: "pencil", className: "size-3" }),
435
+ "Edit"
436
+ ] }),
437
+ connector.auth.type === "dcr" && !connector.authenticated ? /* @__PURE__ */ jsx2(
438
+ Button.Secondary,
439
+ {
440
+ size: "small",
441
+ type: "button",
442
+ disabled: busy || connecting,
443
+ onClick: () => {
444
+ void handleAuthorize(connector.id, (isSuccess) => {
445
+ if (isSuccess) void refreshAfterAuthentication();
446
+ });
447
+ },
448
+ children: connecting ? "Connecting\u2026" : "Connect"
449
+ }
450
+ ) : connector.auth.type === "dcr" && !connector.requiresAuth ? /* @__PURE__ */ jsx2(Button.Secondary, { size: "small", type: "button", disabled: busy, onClick: onDisconnect, children: "Disconnect" }) : null
451
+ ] })
433
452
  ] }),
434
453
  /* @__PURE__ */ jsx2("section", { className: "mt-6", "aria-labelledby": "connector-tools-heading", children: toolsLoading ? /* @__PURE__ */ jsx2("div", { className: "rounded-xl border border-dashed border-border p-6 text-center text-sm text-text-secondary", children: "Loading tools\u2026" }) : toolsError ? /* @__PURE__ */ jsxs2("div", { className: "rounded-xl border border-failure-bg/30 bg-failure-bg/10 p-6 text-center text-sm text-failure-bg", children: [
435
454
  toolsError,
@@ -475,6 +494,7 @@ var ConnectorSettings = () => {
475
494
  const [busy, setBusy] = useState3(false);
476
495
  const [catalog, setCatalog] = useState3([]);
477
496
  const [addMcpServerFormOpen, setAddMcpServerFormOpen] = useState3(false);
497
+ const [editingConnector, setEditingConnector] = useState3(null);
478
498
  const [connectorAwaitingKey, setConnectorAwaitingKey] = useState3(null);
479
499
  const [selectedConnector, setSelectedConnector] = useState3(null);
480
500
  const [apiKey, setApiKey] = useState3("");
@@ -515,7 +535,7 @@ var ConnectorSettings = () => {
515
535
  setLoading(false);
516
536
  }
517
537
  }, [connectorCatalog]);
518
- useEffect2(() => {
538
+ useEffect3(() => {
519
539
  void refresh();
520
540
  }, [refresh]);
521
541
  const normalizedQuery = query.trim().toLowerCase();
@@ -597,35 +617,27 @@ var ConnectorSettings = () => {
597
617
  apiKey: apiKey.trim(),
598
618
  ...entry.auth.type === "header" && entry.auth.headerName ? { headerName: entry.auth.headerName } : {}
599
619
  };
600
- const existing = connectors.ordered.find(({ connector }) => connector.id === entry.id);
601
- const existingConnector = existing?.isConfigured ? existing.connector : void 0;
602
- if (existingConnector) {
603
- await connectorCatalog.updateConnector({
604
- id: existingConnector.id,
605
- name: existingConnector.name,
606
- description: existingConnector.description,
607
- url: existingConnector.url,
608
- auth
609
- });
610
- } else {
611
- await createFromCatalog(entry, auth);
612
- }
620
+ await createFromCatalog(entry, auth);
613
621
  closeApiKeyModal();
614
622
  setTimeout(() => {
615
623
  toaster?.showSuccess({
616
- title: `${entry.name} ${existingConnector ? "updated" : "connected"}`
624
+ title: `${entry.name} connected`
617
625
  });
618
626
  }, 100);
619
627
  }, setFormError).catch(() => {
620
628
  });
621
629
  };
622
- const handleAddMcpServer = async (draft) => {
630
+ const handleMcpServerSubmit = async (draft) => {
623
631
  setFormError(null);
624
632
  await runMutation(async () => {
625
- await connectorCatalog.createConnector({ ...draft });
633
+ if (editingConnector) {
634
+ await connectorCatalog.updateConnector({ id: editingConnector.id, ...draft });
635
+ } else {
636
+ await connectorCatalog.createConnector({ ...draft });
637
+ }
626
638
  }, setFormError);
627
639
  setTimeout(() => {
628
- toaster?.showSuccess({ title: `${draft.name} added` });
640
+ toaster?.showSuccess({ title: `${draft.name} ${editingConnector ? "updated" : "added"}` });
629
641
  }, 0);
630
642
  };
631
643
  const handleDisconnect = (connector) => {
@@ -660,7 +672,30 @@ var ConnectorSettings = () => {
660
672
  }
661
673
  ),
662
674
  /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
663
- /* @__PURE__ */ jsx3("h5", { className: "truncate text-sm font-medium text-text-primary", children: connector.name }),
675
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
676
+ /* @__PURE__ */ jsx3("h5", { className: "truncate text-sm font-medium text-text-primary", children: connector.name }),
677
+ /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs3(
678
+ "span",
679
+ {
680
+ className: cn(
681
+ "flex items-center gap-1.5 rounded-full border border-border bg-secondary-bg/40 px-2 py-0.5 text-xs font-medium",
682
+ connector.authenticated ? "text-success-bg" : "text-text-primary"
683
+ ),
684
+ children: [
685
+ /* @__PURE__ */ jsx3(
686
+ "span",
687
+ {
688
+ className: cn(
689
+ "h-1.5 w-1.5 rounded-full",
690
+ connector.authenticated ? "bg-success-bg" : "bg-primary-button-bg"
691
+ )
692
+ }
693
+ ),
694
+ connector.authenticated ? "Connected" : "Added"
695
+ ]
696
+ }
697
+ ) })
698
+ ] }),
664
699
  /* @__PURE__ */ jsx3("p", { className: "mt-0.5 line-clamp-2 text-sm text-text-secondary sm:truncate", children: connector.description })
665
700
  ] })
666
701
  ] });
@@ -676,45 +711,24 @@ var ConnectorSettings = () => {
676
711
  children: [
677
712
  /* @__PURE__ */ jsx3("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: content }),
678
713
  /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
679
- /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs3(
680
- "span",
714
+ /* @__PURE__ */ jsxs3(
715
+ Button.Secondary,
681
716
  {
682
- className: cn(
683
- "flex items-center gap-1.5 rounded-full border border-border bg-secondary-bg/40 px-2 py-0.5 text-xs font-medium",
684
- connector.authenticated ? "text-success-bg" : "text-text-primary"
685
- ),
686
- children: [
687
- /* @__PURE__ */ jsx3(
688
- "span",
689
- {
690
- className: cn(
691
- "h-1.5 w-1.5 rounded-full",
692
- connector.authenticated ? "bg-success-bg" : "bg-primary-button-bg"
693
- )
694
- }
695
- ),
696
- connector.authenticated ? "Connected" : "Added"
697
- ]
698
- }
699
- ) }),
700
- connector.auth.type === "header" ? /* @__PURE__ */ jsxs3(
701
- Button,
702
- {
703
- variant: "secondary",
704
- size: "sm",
717
+ size: "small",
705
718
  type: "button",
706
719
  disabled: busy,
707
720
  onClick: (event) => {
708
721
  event.stopPropagation();
709
- setApiKey("");
710
- setConnectorAwaitingKey(connector);
722
+ setFormError(null);
723
+ setEditingConnector(connector);
724
+ setAddMcpServerFormOpen(true);
711
725
  },
712
726
  children: [
713
- /* @__PURE__ */ jsx3(Icon, { name: "wrench", className: "size-3" }),
714
- "Replace Key"
727
+ /* @__PURE__ */ jsx3(Icon, { name: "pencil", className: "size-3" }),
728
+ "Edit"
715
729
  ]
716
730
  }
717
- ) : null,
731
+ ),
718
732
  /* @__PURE__ */ jsx3(Icon, { name: "chevron-right", className: "size-4" })
719
733
  ] })
720
734
  ]
@@ -746,10 +760,9 @@ var ConnectorSettings = () => {
746
760
  /* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 items-center gap-2", children: [
747
761
  /* @__PURE__ */ jsx3("span", { className: "hidden text-xs text-text-secondary sm:inline", children: AUTH_TYPE_LABELS[entry.auth.type] ?? AUTH_TYPE_LABELS.none }),
748
762
  /* @__PURE__ */ jsx3(
749
- Button,
763
+ Button.Secondary,
750
764
  {
751
- variant: "secondary",
752
- size: "sm",
765
+ size: "small",
753
766
  type: "button",
754
767
  disabled: busy,
755
768
  onClick: () => {
@@ -764,26 +777,45 @@ var ConnectorSettings = () => {
764
777
  entry.id
765
778
  );
766
779
  };
767
- const isReplacingKey = useMemo(() => {
768
- return connectorAwaitingKey !== null && connectors.ordered.some(
769
- (item) => item.isConfigured && item.connector.id === connectorAwaitingKey.id
770
- );
771
- }, [connectorAwaitingKey, connectors.ordered]);
772
780
  if (selectedConnector) {
773
- return /* @__PURE__ */ jsx3(
774
- ConnectorDetails_default,
775
- {
776
- connector: selectedConnector,
777
- busy,
778
- onBack: () => {
779
- setSelectedConnector(null);
780
- },
781
- onConnectorRefreshed: handleConnectorRefreshed,
782
- onDisconnect: () => {
783
- handleDisconnect(selectedConnector);
781
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
782
+ /* @__PURE__ */ jsx3(
783
+ ConnectorDetails_default,
784
+ {
785
+ connector: selectedConnector,
786
+ busy,
787
+ onBack: () => {
788
+ setSelectedConnector(null);
789
+ },
790
+ onConnectorRefreshed: handleConnectorRefreshed,
791
+ onEdit: () => {
792
+ setFormError(null);
793
+ setEditingConnector(selectedConnector);
794
+ setAddMcpServerFormOpen(true);
795
+ },
796
+ onDisconnect: () => {
797
+ handleDisconnect(selectedConnector);
798
+ }
784
799
  }
785
- }
786
- );
800
+ ),
801
+ /* @__PURE__ */ jsx3(
802
+ AddMcpServerForm_default,
803
+ {
804
+ open: addMcpServerFormOpen,
805
+ onOpenChange: (open) => {
806
+ setAddMcpServerFormOpen(open);
807
+ if (!open) {
808
+ setEditingConnector(null);
809
+ setFormError(null);
810
+ }
811
+ },
812
+ onSubmit: handleMcpServerSubmit,
813
+ connector: editingConnector ?? void 0,
814
+ busy,
815
+ error: formError
816
+ }
817
+ )
818
+ ] });
787
819
  }
788
820
  const hasMatches = matchingConnected.length > 0 || availableConnectors.length > 0;
789
821
  return /* @__PURE__ */ jsxs3(Fragment3, { children: [
@@ -794,12 +826,12 @@ var ConnectorSettings = () => {
794
826
  /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
795
827
  /* @__PURE__ */ jsx3("div", { className: "flex-1", children: /* @__PURE__ */ jsx3(SearchInput_default, { query, setQuery, placeholder: "Search connectors" }) }),
796
828
  /* @__PURE__ */ jsxs3(
797
- Button,
829
+ Button.Secondary,
798
830
  {
799
- variant: "secondary",
800
831
  type: "button",
801
832
  onClick: () => {
802
833
  setFormError(null);
834
+ setEditingConnector(null);
803
835
  setAddMcpServerFormOpen(true);
804
836
  },
805
837
  children: [
@@ -848,7 +880,7 @@ var ConnectorSettings = () => {
848
880
  onOpenChange: (open) => {
849
881
  if (!open) closeApiKeyModal();
850
882
  },
851
- title: `${isReplacingKey ? "Replace key for" : "Connect"} ${connectorAwaitingKey?.name ?? "connector"}`,
883
+ title: `Connect ${connectorAwaitingKey?.name ?? "connector"}`,
852
884
  description: connectorAwaitingKey?.url,
853
885
  contentSized: true,
854
886
  className: "md:max-w-xl",
@@ -896,8 +928,8 @@ var ConnectorSettings = () => {
896
928
  formError ? /* @__PURE__ */ jsx3("p", { className: "text-failure-bg text-sm", children: formError }) : null
897
929
  ] }),
898
930
  /* @__PURE__ */ jsxs3("footer", { className: "flex justify-end gap-2 border-t border-border px-5 py-4", children: [
899
- /* @__PURE__ */ jsx3(Button, { variant: "ghost", type: "button", onClick: closeApiKeyModal, disabled: busy, children: "Cancel" }),
900
- /* @__PURE__ */ jsx3(Button, { type: "submit", disabled: !apiKey.trim() || busy, children: isReplacingKey ? "Replace Key" : "Connect" })
931
+ /* @__PURE__ */ jsx3(Button.Ghost, { type: "button", onClick: closeApiKeyModal, disabled: busy, children: "Cancel" }),
932
+ /* @__PURE__ */ jsx3(Button.Primary, { type: "submit", disabled: !apiKey.trim() || busy, children: "Connect" })
901
933
  ] })
902
934
  ] })
903
935
  }
@@ -908,9 +940,13 @@ var ConnectorSettings = () => {
908
940
  open: addMcpServerFormOpen,
909
941
  onOpenChange: (open) => {
910
942
  setAddMcpServerFormOpen(open);
911
- if (!open) setFormError(null);
943
+ if (!open) {
944
+ setEditingConnector(null);
945
+ setFormError(null);
946
+ }
912
947
  },
913
- onAdd: handleAddMcpServer,
948
+ onSubmit: handleMcpServerSubmit,
949
+ connector: editingConnector ?? void 0,
914
950
  busy,
915
951
  error: formError
916
952
  }
@@ -922,4 +958,4 @@ var ConnectorSettings_default = ConnectorSettings;
922
958
  export {
923
959
  ConnectorSettings_default as default
924
960
  };
925
- //# sourceMappingURL=ConnectorSettings-MXFRWWR6.js.map
961
+ //# sourceMappingURL=ConnectorSettings-R5VEP7BO.js.map