@jini-ai/ui 0.5.4 → 0.5.6

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 (270) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/core/theme/validation.js +40 -38
  3. package/dist/features/a2ui/renderer.js +15 -13
  4. package/dist/features/about/react/components/AboutTab.js +64 -34
  5. package/dist/features/about/rules.d.ts +2 -2
  6. package/dist/features/about/rules.js +156 -129
  7. package/dist/features/admin-widgets/components/ImagePreviewModal.d.ts +4 -3
  8. package/dist/features/admin-widgets/components/ImagePreviewModal.js +6 -10
  9. package/dist/features/admin-widgets/components/InfoTip.d.ts +3 -2
  10. package/dist/features/admin-widgets/components/InfoTip.hooks.js +2 -0
  11. package/dist/features/admin-widgets/components/InfoTip.js +34 -7
  12. package/dist/features/admin-widgets/components/InfoTip.rules.d.ts +13 -0
  13. package/dist/features/admin-widgets/components/InfoTip.rules.js +43 -10
  14. package/dist/features/admin-widgets/components/Lightbox/Lightbox.d.ts +30 -0
  15. package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.d.ts +40 -0
  16. package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.js +128 -0
  17. package/dist/features/admin-widgets/components/Lightbox/Lightbox.js +18 -0
  18. package/dist/features/admin-widgets/components/MiddleTruncate.d.ts +14 -0
  19. package/dist/features/admin-widgets/components/MiddleTruncate.js +12 -0
  20. package/dist/features/admin-widgets/components/MiddleTruncate.rules.d.ts +20 -0
  21. package/dist/features/admin-widgets/components/MiddleTruncate.rules.js +21 -0
  22. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.d.ts +18 -0
  23. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.d.ts +16 -0
  24. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.js +45 -0
  25. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.js +18 -0
  26. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.d.ts +32 -0
  27. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.js +26 -0
  28. package/dist/features/admin-widgets/components/Select/Select.hooks.d.ts +21 -0
  29. package/dist/features/admin-widgets/components/Select/Select.hooks.js +24 -2
  30. package/dist/features/admin-widgets/components/Select/Select.js +4 -3
  31. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.hooks.js +29 -14
  32. package/dist/features/admin-widgets/index.d.ts +14 -2
  33. package/dist/features/admin-widgets/index.js +7 -1
  34. package/dist/features/admin-widgets/styles/admin-widgets.css +1 -0
  35. package/dist/features/asset-grid/react/components/AssetCard.js +7 -1
  36. package/dist/features/asset-grid/react/components/AssetGrid.d.ts +1 -1
  37. package/dist/features/asset-grid/react/components/AssetGrid.js +38 -18
  38. package/dist/features/asset-grid/react/components/useAssetGridFilters.d.ts +21 -0
  39. package/dist/features/asset-grid/react/components/useAssetGridFilters.js +19 -0
  40. package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +16 -11
  41. package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.d.ts +2 -0
  42. package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +35 -11
  43. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.d.ts +6 -6
  44. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.js +10 -129
  45. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.d.ts +50 -0
  46. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.js +95 -0
  47. package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.d.ts +56 -0
  48. package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.js +80 -0
  49. package/dist/features/asset-tree-browser/rules.js +40 -22
  50. package/dist/features/browser-chrome/rules.js +74 -70
  51. package/dist/features/charts/browser.js +11 -5
  52. package/dist/features/charts/react.js +2 -2
  53. package/dist/features/charts/table.js +2 -2
  54. package/dist/features/command-palette/react/hooks/useCommandPalette.js +3 -9
  55. package/dist/features/connectors/ConnectorsBrowser.d.ts +4 -4
  56. package/dist/features/connectors/ConnectorsBrowser.js +26 -14
  57. package/dist/features/connectors/components/ConnectorCard.js +67 -38
  58. package/dist/features/connectors/components/ConnectorDetailDrawer.js +62 -31
  59. package/dist/features/connectors/components/ConnectorGrid.js +11 -6
  60. package/dist/features/connectors/hooks/useConnectorAuthorization.js +6 -0
  61. package/dist/features/connectors/hooks/useConnectorCatalog.d.ts +2 -0
  62. package/dist/features/connectors/hooks/useConnectorCatalog.js +32 -13
  63. package/dist/features/connectors/hooks/useWiredConnectorsBrowser.d.ts +3 -3
  64. package/dist/features/connectors/rules.d.ts +8 -1
  65. package/dist/features/connectors/rules.js +42 -20
  66. package/dist/features/connectors/types.d.ts +11 -0
  67. package/dist/features/execution/constants.d.ts +4 -10
  68. package/dist/features/execution/constants.js +9 -94
  69. package/dist/features/execution/react/components/ByokProviderForm.d.ts +2 -4
  70. package/dist/features/execution/react/components/ByokProviderForm.js +140 -43
  71. package/dist/features/execution/react/components/ExecutionTab.d.ts +1 -2
  72. package/dist/features/execution/react/components/ExecutionTab.js +52 -30
  73. package/dist/features/execution/react/components/LocalCliAgentCard.js +12 -3
  74. package/dist/features/execution/react/components/LocalCliAgentList.js +14 -3
  75. package/dist/features/execution/react/components/LocalCliAgentSettings.js +14 -3
  76. package/dist/features/execution/react/hooks/useLocalCliAgentCard.js +54 -36
  77. package/dist/features/execution/react/hooks/useReasoningControl.d.ts +1 -1
  78. package/dist/features/execution/react/hooks/useReasoningControl.js +116 -75
  79. package/dist/features/execution/rules.d.ts +13 -2
  80. package/dist/features/execution/rules.js +51 -11
  81. package/dist/features/execution/types.d.ts +6 -42
  82. package/dist/features/execution/types.js +0 -17
  83. package/dist/features/external-mcp/react/components/ExternalMcpTab.d.ts +6 -2
  84. package/dist/features/external-mcp/react/components/ExternalMcpTab.js +9 -2
  85. package/dist/features/file-dropzone/react/components/FileDropzone.js +24 -25
  86. package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.d.ts +2 -2
  87. package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.js +35 -30
  88. package/dist/features/file-dropzone/react/components/FileDropzoneThumbnailGrid.js +30 -24
  89. package/dist/features/file-dropzone/react/components/FileDropzoneZone.d.ts +14 -0
  90. package/dist/features/file-dropzone/react/components/FileDropzoneZone.js +26 -0
  91. package/dist/features/html-editor/canvas-content-wrapper.js +13 -13
  92. package/dist/features/html-editor/canvas-embed-placeholders.js +46 -37
  93. package/dist/features/html-editor/css.js +76 -69
  94. package/dist/features/html-editor/editor-blocks.js +47 -33
  95. package/dist/features/html-editor/editor-serialization.js +6 -5
  96. package/dist/features/html-editor/protected-elements.js +39 -28
  97. package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.js +4 -4
  98. package/dist/features/html-editor/source-splice.js +51 -30
  99. package/dist/features/i18n/dictionaries/settings-dialog.ja.js +1 -0
  100. package/dist/features/i18n/dictionaries/settings-dialog.zh-CN.js +1 -0
  101. package/dist/features/i18n/dictionaries/settings-dialog.zh-TW.js +1 -0
  102. package/dist/features/i18n/locale.js +20 -16
  103. package/dist/features/iframe-pool/react/dom-sync.js +8 -6
  104. package/dist/features/integrations/react/components/CodexInstallToggleButton.js +19 -4
  105. package/dist/features/integrations/react/components/IntegrationsTab.js +60 -14
  106. package/dist/features/interactive-ui/interactive-ui.css +1 -1
  107. package/dist/features/interactive-ui/providers/native/data-table.manifest.d.ts +6 -6
  108. package/dist/features/interactive-ui/providers/shadcn/data-table.js +10 -7
  109. package/dist/features/interactive-ui/providers/shadcn/data-table.manifest.d.ts +6 -6
  110. package/dist/features/lexical-rich-text-editor/mention-parser.js +60 -57
  111. package/dist/features/lexical-rich-text-editor/react/hooks/useKeyboardCommands.js +33 -38
  112. package/dist/features/lexical-rich-text-editor/rules.js +87 -74
  113. package/dist/features/lexical-rich-text-editor/serialize.js +27 -25
  114. package/dist/features/mcp-ui/secret-card.js +111 -61
  115. package/dist/features/mcp-ui/surfaces/confirmation.js +39 -21
  116. package/dist/features/mcp-ui/surfaces/document.d.ts +1 -1
  117. package/dist/features/mcp-ui/surfaces/document.js +10 -2
  118. package/dist/features/mcp-ui/surfaces/fields.js +30 -50
  119. package/dist/features/mcp-ui/surfaces/form.d.ts +6 -0
  120. package/dist/features/mcp-ui/surfaces/form.js +43 -21
  121. package/dist/features/mcp-ui/surfaces/outcome.js +30 -20
  122. package/dist/features/mcp-ui/surfaces/text-input.js +33 -21
  123. package/dist/features/mcp-ui/surfaces/tokens.d.ts +6 -1
  124. package/dist/features/mcp-ui/surfaces/tokens.js +5 -2
  125. package/dist/features/media-providers/constants.d.ts +1 -0
  126. package/dist/features/media-providers/constants.js +2 -81
  127. package/dist/features/media-providers/index.d.ts +1 -1
  128. package/dist/features/media-providers/ports.d.ts +2 -0
  129. package/dist/features/media-providers/react/components/MediaProviderCard.d.ts +22 -0
  130. package/dist/features/media-providers/react/components/MediaProviderCard.js +50 -0
  131. package/dist/features/media-providers/react/components/MediaProvidersTab.d.ts +5 -6
  132. package/dist/features/media-providers/react/components/MediaProvidersTab.js +40 -72
  133. package/dist/features/media-providers/react/components/media-providers-tab-labels.d.ts +11 -0
  134. package/dist/features/media-providers/react/components/media-providers-tab-labels.js +57 -0
  135. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.d.ts +4 -2
  136. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +37 -23
  137. package/dist/features/media-providers/rules.js +17 -10
  138. package/dist/features/media-providers/types.d.ts +4 -22
  139. package/dist/features/media-providers/types.js +3 -8
  140. package/dist/features/memory/formatters.js +127 -92
  141. package/dist/features/memory/react/components/MemoryConnectedPanel.js +92 -36
  142. package/dist/features/memory/react/components/MemoryList.js +37 -18
  143. package/dist/features/memory/react/hooks/useMemoryExtractions.store.js +42 -36
  144. package/dist/features/notifications/react/components/NotificationsTab.js +28 -28
  145. package/dist/features/observability/long-task.d.ts +0 -12
  146. package/dist/features/observability/long-task.js +15 -19
  147. package/dist/features/observability/resource-error.d.ts +0 -10
  148. package/dist/features/observability/resource-error.js +18 -13
  149. package/dist/features/observability/stuck-run.js +10 -6
  150. package/dist/features/observability/telemetry-url.d.ts +6 -0
  151. package/dist/features/observability/telemetry-url.js +16 -0
  152. package/dist/features/observability/white-screen.js +12 -24
  153. package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +2 -2
  154. package/dist/features/panel-kit/fetch-query/adapter.react.js +4 -2
  155. package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +46 -33
  156. package/dist/features/panel-kit/helpers/standing-draft-local-backup.js +3 -1
  157. package/dist/features/panel-kit/hooks/use-settings-slice.hooks.js +3 -1
  158. package/dist/features/privacy/react/components/PrivacyTab.js +24 -13
  159. package/dist/features/progress-card/components/ProgressCard.js +7 -3
  160. package/dist/features/progress-card/reference-adapters.js +59 -54
  161. package/dist/features/project-locations/react/components/ProjectLocationsTab.js +24 -15
  162. package/dist/features/project-locations/react/hooks/useProjectLocationsTab.d.ts +8 -0
  163. package/dist/features/project-locations/react/hooks/useProjectLocationsTab.js +31 -23
  164. package/dist/features/resource-dashboard/react/components/ResourceBoard.js +6 -47
  165. package/dist/features/resource-dashboard/react/components/ResourceBoardView.d.ts +2 -2
  166. package/dist/features/resource-dashboard/react/components/ResourceBoardView.js +3 -6
  167. package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.d.ts +15 -0
  168. package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.js +35 -0
  169. package/dist/features/resource-dashboard/react/components/ResourceCard.js +5 -16
  170. package/dist/features/resource-dashboard/react/components/ResourceCardParts.d.ts +34 -0
  171. package/dist/features/resource-dashboard/react/components/ResourceCardParts.js +34 -0
  172. package/dist/features/resource-dashboard/react/components/ResourceRowList.js +3 -1
  173. package/dist/features/resource-dashboard/react/components/ResourceRowListItem.js +2 -2
  174. package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.d.ts +19 -0
  175. package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.js +11 -0
  176. package/dist/features/resource-dashboard/react/components/ResourceRowListView.d.ts +1 -1
  177. package/dist/features/resource-dashboard/react/components/ResourceRowListView.js +4 -4
  178. package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.d.ts +10 -0
  179. package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.js +20 -0
  180. package/dist/features/resource-dashboard/react/components/resourceBoardProps.d.ts +48 -0
  181. package/dist/features/resource-dashboard/react/components/resourceBoardProps.js +70 -0
  182. package/dist/features/resource-dashboard/react/components/resourceRowListProps.d.ts +19 -0
  183. package/dist/features/resource-dashboard/react/components/resourceRowListProps.js +14 -0
  184. package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.d.ts +16 -0
  185. package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.js +13 -0
  186. package/dist/features/resource-dashboard/rules.js +2 -8
  187. package/dist/features/sketch-editor/dom.js +150 -99
  188. package/dist/features/sketch-editor/react/components/SketchEditor.js +26 -15
  189. package/dist/features/skills/react/components/SkillDraftForm.js +13 -19
  190. package/dist/features/skills/react/components/SkillDraftForm.labels.d.ts +31 -0
  191. package/dist/features/skills/react/components/SkillDraftForm.labels.js +54 -0
  192. package/dist/features/skills/react/components/SkillRow.js +38 -18
  193. package/dist/features/skills/react/components/SkillRow.labels.d.ts +7 -0
  194. package/dist/features/skills/react/components/SkillRow.labels.js +18 -0
  195. package/dist/features/skills/react/components/SkillsTab.js +24 -14
  196. package/dist/features/skills/react/components/SkillsTab.labels.d.ts +7 -0
  197. package/dist/features/skills/react/components/SkillsTab.labels.js +11 -0
  198. package/dist/features/skills/rules.js +32 -23
  199. package/dist/features/source-config-list/agent-handles.js +2 -1
  200. package/dist/features/source-config-list/dependencies.js +53 -49
  201. package/dist/features/source-config-list/index.d.ts +3 -3
  202. package/dist/features/source-config-list/react/components/SourceConfigAddForm.d.ts +6 -5
  203. package/dist/features/source-config-list/react/components/SourceConfigAddForm.js +38 -7
  204. package/dist/features/source-config-list/react/components/SourceConfigField.js +69 -25
  205. package/dist/features/source-config-list/react/components/SourceConfigItemCard.d.ts +6 -5
  206. package/dist/features/source-config-list/react/components/SourceConfigItemCard.js +76 -20
  207. package/dist/features/source-config-list/react/components/SourceConfigListView.d.ts +5 -3
  208. package/dist/features/source-config-list/react/components/SourceConfigListView.js +33 -3
  209. package/dist/features/source-config-list/react/components/SourceConfigTestControl.js +17 -1
  210. package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.d.ts +11 -0
  211. package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.js +12 -0
  212. package/dist/features/source-config-list/types.d.ts +14 -0
  213. package/dist/features/tab-launcher-menu/react/components/TabLauncherMenu.js +25 -1
  214. package/dist/features/tab-launcher-menu/react/hooks/useTabLauncherMenu.js +15 -16
  215. package/dist/features/tab-strip/react/components/TabBar.js +8 -1
  216. package/dist/features/tabbed-dialog/react/components/TabbedDialog.js +8 -30
  217. package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.d.ts +15 -0
  218. package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.js +8 -0
  219. package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.d.ts +12 -0
  220. package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.js +6 -0
  221. package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.d.ts +27 -0
  222. package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.js +12 -0
  223. package/dist/features/tabbed-dialog/react/components/tabbedDialogView.d.ts +43 -0
  224. package/dist/features/tabbed-dialog/react/components/tabbedDialogView.js +59 -0
  225. package/dist/features/version-manager/dependencies.d.ts +3 -1
  226. package/dist/features/version-manager/dependencies.js +3 -2
  227. package/dist/features/version-manager/react/components/VersionManagerModal.js +10 -6
  228. package/dist/features/version-manager/react/hooks/useVersionManager.js +7 -4
  229. package/dist/features/viewer-shell/react/components/CommentSidePanel.js +103 -50
  230. package/dist/features/viewer-shell/react/components/MarkdownSplitPane.js +28 -8
  231. package/dist/features/viewer-shell/react/hooks/useCommentReorder.js +22 -16
  232. package/dist/features/viewer-shell/rules.js +19 -23
  233. package/dist/react/components/CustomSelect.d.ts +38 -1
  234. package/dist/react/components/CustomSelect.js +94 -38
  235. package/dist/react/components/OnboardingDropdown.js +20 -8
  236. package/dist/react/components/RemixIcon.stylesheet.js +3 -1
  237. package/dist/react/components/Toast.js +13 -2
  238. package/dist/react/components/TooltipLayer.js +5 -14
  239. package/dist/react/components/WorkingDirPicker.js +78 -50
  240. package/dist/react/components/remixicon-font-recovery.js +38 -30
  241. package/dist/react/components/select-popover.d.ts +8 -6
  242. package/dist/react/components/select-popover.js +33 -29
  243. package/dist/react/mcp-ui/McpUiHost.d.ts +1 -1
  244. package/dist/react/mcp-ui/McpUiHost.js +10 -11
  245. package/dist/react/mcp-ui/host-message-source.d.ts +14 -2
  246. package/dist/react/mcp-ui/host-message-source.js +15 -5
  247. package/dist/react/mcp-ui/mcp-ui-host-frame.d.ts +41 -0
  248. package/dist/react/mcp-ui/mcp-ui-host-frame.js +39 -0
  249. package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +97 -69
  250. package/dist/renderers/preview-modal-shell/react/components/PreviewModalShell.js +59 -30
  251. package/dist/renderers/preview-modal-shell/react/components/icons.js +4 -1
  252. package/dist/renderers/react/components/ArtifactView.js +9 -6
  253. package/dist/renderers/srcdoc/build.d.ts +4 -1
  254. package/dist/renderers/srcdoc/build.js +62 -48
  255. package/dist/styles/admin.css +29 -14
  256. package/dist/styles/lightbox.css +142 -0
  257. package/dist/styles/variables.css +128 -0
  258. package/dist/theme/apply.js +9 -5
  259. package/dist/utils/auto-open-file.d.ts +2 -1
  260. package/dist/utils/auto-open-file.js +69 -85
  261. package/dist/utils/markdown-scroll-sync.js +108 -87
  262. package/dist/utils/polygon-selection.js +25 -26
  263. package/dist/utils/smooth-scroll-to-top.d.ts +1 -1
  264. package/dist/utils/smooth-scroll-to-top.js +2 -32
  265. package/dist/utils/sse.js +26 -26
  266. package/dist/utils/unit-bezier.d.ts +7 -0
  267. package/dist/utils/unit-bezier.js +38 -0
  268. package/package.json +7 -10
  269. package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.d.ts +0 -13
  270. package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.js +0 -46
@@ -9,14 +9,9 @@
9
9
  * None of that is product-bound — it is the same problem any host has once
10
10
  * credentials can live in two places at once.
11
11
  *
12
- * What is NOT ported verbatim: the origin's full `MEDIA_PROVIDERS` catalog
13
- * (`media/models.ts`, 761 lines of concrete image/video vendors with their
14
- * endpoints and model lists). Instead this feature ships a small, curated
15
- * `DEFAULT_MEDIA_PROVIDER_CATALOG` (see `constants.ts`) as a starting point,
16
- * not a fixed list — same convention as `execution/constants.ts`'s
17
- * `DEFAULT_PROVIDER_PRESETS`. A host with its own provider roster (or a
18
- * larger/different one) passes its own `catalog` to `MediaProvidersTab` to
19
- * replace this wholesale.
12
+ * The host supplies the provider catalog and its identity policy. Vendor identities,
13
+ * endpoint defaults and alias rules belong to the integrations catalog, so importing
14
+ * generic UI never selects or initializes a vendor roster.
20
15
  *
21
16
  * Also not ported: the origin's functions take and return its whole
22
17
  * `AppConfig`. Here they take and return the providers RECORD alone. Threading
@@ -51,20 +46,7 @@ export interface MediaProviderCredentials {
51
46
  }
52
47
  /** Credentials keyed by provider id. */
53
48
  export type MediaProviderMap = Record<string, MediaProviderCredentials>;
54
- /**
55
- * One selectable provider in the catalog. A host supplies its own catalog —
56
- * this package ships `DEFAULT_MEDIA_PROVIDER_CATALOG` as a starting point,
57
- * not as a fixed list (same convention as `ProviderPreset`).
58
- */
59
- export interface MediaProviderOption {
60
- id: string;
61
- label: string;
62
- /** Prefilled when the operator picks this provider and typed nothing. */
63
- defaultBaseUrl?: string;
64
- /** Model ids this provider advertises. A host that discovers models at
65
- * runtime can leave this empty. */
66
- models?: readonly string[];
67
- }
49
+ export type { MediaProviderOption } from '@jini-ai/core';
68
50
  /**
69
51
  * Result of the tab's daemon read, surfaced while the initial fetch or a
70
52
  * manual reload is in flight. `'unreachable'` mirrors
@@ -9,14 +9,9 @@
9
9
  * None of that is product-bound — it is the same problem any host has once
10
10
  * credentials can live in two places at once.
11
11
  *
12
- * What is NOT ported verbatim: the origin's full `MEDIA_PROVIDERS` catalog
13
- * (`media/models.ts`, 761 lines of concrete image/video vendors with their
14
- * endpoints and model lists). Instead this feature ships a small, curated
15
- * `DEFAULT_MEDIA_PROVIDER_CATALOG` (see `constants.ts`) as a starting point,
16
- * not a fixed list — same convention as `execution/constants.ts`'s
17
- * `DEFAULT_PROVIDER_PRESETS`. A host with its own provider roster (or a
18
- * larger/different one) passes its own `catalog` to `MediaProvidersTab` to
19
- * replace this wholesale.
12
+ * The host supplies the provider catalog and its identity policy. Vendor identities,
13
+ * endpoint defaults and alias rules belong to the integrations catalog, so importing
14
+ * generic UI never selects or initializes a vendor roster.
20
15
  *
21
16
  * Also not ported: the origin's functions take and return its whole
22
17
  * `AppConfig`. Here they take and return the providers RECORD alone. Threading
@@ -45,84 +45,101 @@ export function providerDisplayName(provider) {
45
45
  return 'Memory model';
46
46
  }
47
47
  }
48
- export function parseProviderError(raw) {
48
+ function isString(value) {
49
+ return typeof value === 'string';
50
+ }
51
+ function isNumber(value) {
52
+ return typeof value === 'number';
53
+ }
54
+ // Reads message/code/status out of the first `{...}` in the raw provider
55
+ // error. The nested `error.*` field wins for message/code; the top-level
56
+ // field wins for status.
57
+ function parseJsonErrorFields(raw) {
49
58
  const jsonStart = raw.indexOf('{');
50
- let message = raw.trim();
51
- let code = '';
52
- let status = null;
53
- if (jsonStart >= 0) {
54
- try {
55
- const parsed = JSON.parse(raw.slice(jsonStart));
56
- const error = parsed?.error;
57
- if (typeof error?.message === 'string')
58
- message = error.message;
59
- else if (typeof parsed?.message === 'string')
60
- message = parsed.message;
61
- if (typeof error?.code === 'string')
62
- code = error.code;
63
- else if (typeof parsed?.code === 'string')
64
- code = parsed.code;
65
- if (typeof parsed?.status === 'number')
66
- status = parsed.status;
67
- else if (typeof error?.status === 'number')
68
- status = error.status;
69
- }
70
- catch {
71
- // Fall through to regex parsing below.
72
- }
59
+ if (jsonStart < 0)
60
+ return {};
61
+ try {
62
+ // Text starting at `{` can only parse to an object, so `parsed` is never null.
63
+ const parsed = JSON.parse(raw.slice(jsonStart));
64
+ const error = parsed.error;
65
+ return {
66
+ message: [error?.message, parsed.message].find(isString),
67
+ code: [error?.code, parsed.code].find(isString),
68
+ status: [parsed.status, error?.status].find(isNumber),
69
+ };
70
+ }
71
+ catch {
72
+ // Fall through to regex parsing below.
73
+ return {};
73
74
  }
75
+ }
76
+ export function parseProviderError(raw) {
77
+ const fields = parseJsonErrorFields(raw);
74
78
  const statusMatch = /\b(4\d\d|5\d\d)\b/.exec(raw);
75
- if (status === null && statusMatch?.[1])
76
- status = Number(statusMatch[1]);
77
79
  return {
78
- message: message.replace(/\s+/g, ' ').trim(),
79
- code,
80
- status,
80
+ message: (fields.message ?? raw.trim()).replace(/\s+/g, ' ').trim(),
81
+ code: fields.code ?? '',
82
+ status: fields.status ?? (statusMatch ? Number(statusMatch[1]) : null),
81
83
  };
82
84
  }
85
+ function classifyFailure({ status, haystack }) {
86
+ if (status === 401 || /token[_ -]?expired|authentication token has expired|invalid[_ -]?api[_ -]?key|unauthorized/.test(haystack)) {
87
+ return 'auth';
88
+ }
89
+ if (status === 429 || /rate limit|quota|too many requests|insufficient_quota/.test(haystack))
90
+ return 'quota';
91
+ if (/network|fetch failed|timeout|timed out|econnreset|enotfound/.test(haystack))
92
+ return 'network';
93
+ return 'other';
94
+ }
95
+ function failureCopy({ category, providerName, usesChatCli, source, message, }) {
96
+ switch (category) {
97
+ case 'auth':
98
+ return {
99
+ title: `${providerName} authentication expired`,
100
+ detail: source,
101
+ action: usesChatCli
102
+ ? 'Sign in to the selected local CLI or choose a different memory model.'
103
+ : 'Update the memory extraction model key or sign in again.',
104
+ };
105
+ case 'quota':
106
+ return {
107
+ title: `${providerName} quota or rate limit hit`,
108
+ detail: source,
109
+ action: 'Try again later or switch the memory extraction model.',
110
+ };
111
+ case 'network':
112
+ return {
113
+ title: `${providerName} request failed`,
114
+ detail: source,
115
+ action: usesChatCli
116
+ ? 'Check the selected local CLI and try again.'
117
+ : 'Check the model provider connection and try again.',
118
+ };
119
+ default:
120
+ return {
121
+ title: 'Memory extraction failed',
122
+ detail: message || source,
123
+ action: usesChatCli
124
+ ? 'Try again after checking the selected local CLI.'
125
+ : 'Try again after checking the memory extraction model settings.',
126
+ };
127
+ }
128
+ }
83
129
  export function describeExtractionFailure(record) {
84
130
  if (record.phase !== 'failed' || !record.error)
85
131
  return null;
86
- const providerName = providerDisplayName(record.provider);
87
- const usesChatCli = record.provider?.credentialSource === 'chat-cli';
88
132
  const parsed = parseProviderError(record.error);
89
133
  const haystack = `${parsed.message} ${parsed.code} ${record.error}`.toLowerCase();
90
- const source = record.kind === 'connector'
91
- ? 'Connected apps were read, but the assistant could not turn that context into memory.'
92
- : 'Memory extraction could not run for this chat.';
93
- if (parsed.status === 401
94
- || /token[_ -]?expired|authentication token has expired|invalid[_ -]?api[_ -]?key|unauthorized/.test(haystack)) {
95
- return {
96
- title: `${providerName} authentication expired`,
97
- detail: source,
98
- action: usesChatCli
99
- ? 'Sign in to the selected local CLI or choose a different memory model.'
100
- : 'Update the memory extraction model key or sign in again.',
101
- };
102
- }
103
- if (parsed.status === 429 || /rate limit|quota|too many requests|insufficient_quota/.test(haystack)) {
104
- return {
105
- title: `${providerName} quota or rate limit hit`,
106
- detail: source,
107
- action: 'Try again later or switch the memory extraction model.',
108
- };
109
- }
110
- if (/network|fetch failed|timeout|timed out|econnreset|enotfound/.test(haystack)) {
111
- return {
112
- title: `${providerName} request failed`,
113
- detail: source,
114
- action: usesChatCli
115
- ? 'Check the selected local CLI and try again.'
116
- : 'Check the model provider connection and try again.',
117
- };
118
- }
119
- return {
120
- title: 'Memory extraction failed',
121
- detail: parsed.message || source,
122
- action: usesChatCli
123
- ? 'Try again after checking the selected local CLI.'
124
- : 'Try again after checking the memory extraction model settings.',
125
- };
134
+ return failureCopy({
135
+ category: classifyFailure({ status: parsed.status, haystack }),
136
+ providerName: providerDisplayName(record.provider),
137
+ usesChatCli: record.provider?.credentialSource === 'chat-cli',
138
+ source: record.kind === 'connector'
139
+ ? 'Connected apps were read, but the assistant could not turn that context into memory.'
140
+ : 'Memory extraction could not run for this chat.',
141
+ message: parsed.message,
142
+ });
126
143
  }
127
144
  export function formatConnectorContextBytes(bytes) {
128
145
  if (!Number.isFinite(bytes) || bytes <= 0)
@@ -248,43 +265,55 @@ export function formatRelativeTimeAgo(at, now) {
248
265
  export function memoryCountLabel(count) {
249
266
  return count === 1 ? 'memory' : 'memories';
250
267
  }
268
+ // The record's written count when it is a positive number, else 0.
269
+ function positiveWrittenCount(record) {
270
+ const count = record.writtenCount;
271
+ return typeof count === 'number' && count > 0 ? count : 0;
272
+ }
273
+ function connectorCardTitle({ record, t }) {
274
+ switch (record.phase) {
275
+ case 'running':
276
+ return t('Scanning connected apps');
277
+ case 'failed':
278
+ return t('Connected app scan failed');
279
+ case 'skipped':
280
+ return t('Connected app scan skipped');
281
+ case 'success': {
282
+ const writtenCount = positiveWrittenCount(record);
283
+ if (writtenCount > 0) {
284
+ return t('Saved {count} {label}', { count: writtenCount, label: memoryCountLabel(writtenCount) });
285
+ }
286
+ return t('No new memories found');
287
+ }
288
+ default:
289
+ return t('Connected app scan');
290
+ }
291
+ }
251
292
  export function extractionCardTitle(record, t) {
252
293
  const kind = record.kind ?? 'llm';
253
294
  if (kind !== 'connector') {
254
295
  return record.userMessagePreview || t('Extraction');
255
296
  }
256
- if (record.phase === 'running')
257
- return t('Scanning connected apps');
258
- if (record.phase === 'failed')
259
- return t('Connected app scan failed');
260
- if (record.phase === 'skipped')
261
- return t('Connected app scan skipped');
262
- if (record.phase === 'success') {
263
- const writtenCount = typeof record.writtenCount === 'number' ? record.writtenCount : null;
264
- if (writtenCount && writtenCount > 0) {
265
- return t('Saved {count} {label}', { count: writtenCount, label: memoryCountLabel(writtenCount) });
266
- }
267
- return t('No new memories found');
268
- }
269
- return t('Connected app scan');
297
+ return connectorCardTitle({ record, t });
270
298
  }
271
- export function extractionCardMeta(record, now, t) {
272
- const kind = record.kind ?? 'llm';
299
+ function connectorCardMeta({ record, now, t }) {
300
+ if (record.phase === 'running')
301
+ return t('Checking selected apps');
273
302
  const age = formatRelativeTimeAgo(record.startedAt, now);
274
- if (kind === 'connector') {
275
- if (record.phase === 'running')
276
- return t('Checking selected apps');
277
- if (record.phase === 'failed')
303
+ switch (record.phase) {
304
+ case 'failed':
278
305
  return `${t('Needs attention')} · ${age}`;
279
- if (record.phase === 'skipped')
306
+ case 'skipped':
280
307
  return `${t('Skipped')} · ${age}`;
281
- if (record.phase === 'success') {
282
- const writtenCount = typeof record.writtenCount === 'number' ? record.writtenCount : null;
283
- const result = writtenCount && writtenCount > 0 ? t('From connected apps') : t('Checked selected apps');
308
+ case 'success': {
309
+ const result = positiveWrittenCount(record) > 0 ? t('From connected apps') : t('Checked selected apps');
284
310
  return `${result} · ${age}`;
285
311
  }
286
- return `${t('Connected apps')} · ${age}`;
312
+ default:
313
+ return `${t('Connected apps')} · ${age}`;
287
314
  }
315
+ }
316
+ function modelCardMeta({ record, now, t }) {
288
317
  const duration = formatDuration(record);
289
318
  const parts = [formatAbsoluteTime(record.startedAt, now), formatRelativeTime(record.startedAt, now)];
290
319
  if (duration)
@@ -294,6 +323,12 @@ export function extractionCardMeta(record, now, t) {
294
323
  }
295
324
  return parts.join(' · ');
296
325
  }
326
+ export function extractionCardMeta(record, now, t) {
327
+ const kind = record.kind ?? 'llm';
328
+ if (kind === 'connector')
329
+ return connectorCardMeta({ record, now, t });
330
+ return modelCardMeta({ record, now, t });
331
+ }
297
332
  /** Localized labels for each memory type badge. `t`-only, so callers memoize on
298
333
  * `t` at the call site instead of drilling the map through props. */
299
334
  export function memoryTypeLabels(t) {
@@ -14,43 +14,99 @@ import { ConnectorLogo } from '../../../connectors/index.js';
14
14
  import { Icon } from '../../../../react/components/Icon.js';
15
15
  import { useT } from '../../../i18n/index.js';
16
16
  import { MemoryExtractionCard } from './MemoryExtractionCard.js';
17
- export function MemoryConnectedPanel({ enabled, onOpenConnectors, connectorStatuses, connectorsLoading, connectedCount, selectedConnectorIds, selectedConnectedConnectorIds, connectingConnectorIds, pendingConnectorAuthIds, connectorConnectErrors, connectorIdsWithDetails, connectorExtracting, connectorSaving, connectorScanLabel, connectorSuggestions, selectedSuggestionIds, selectedConnectorSuggestions, connectorStatus, connectorError, connectorLoadError, connectorAttempts, connectorContextBytes, connectorExtractions, memoryConnectors, toggleConnectorSelection, onConnectMemoryConnector, toggleConnectorSuggestion, onSuggestConnectorMemory, onSaveConnectorSuggestions, onDiscardConnectorSuggestions, nowClock, onOpenPreview, onDeleteExtraction, }) {
17
+ function isStatusResolved({ connector, context }) {
18
+ return context.connectorIdsWithDetails.has(connector.id) || context.connectorStatuses[connector.id] !== undefined;
19
+ }
20
+ function connectorRowState({ connector, context }) {
21
+ const connected = connector.status === 'connected';
22
+ const connecting = context.connectingConnectorIds.has(connector.id);
23
+ const authorizationPending = context.pendingConnectorAuthIds.has(connector.id);
24
+ const connectError = context.connectorConnectErrors[connector.id];
25
+ const checkingStatus = context.connectorsLoading && !isStatusResolved({ connector, context }) && !connected && !authorizationPending && !connectError && !connecting;
26
+ return {
27
+ connected,
28
+ selected: context.selectedConnectorIds.has(connector.id) && connected,
29
+ connecting,
30
+ authorizationPending,
31
+ connectError,
32
+ checkingStatus,
33
+ reconnecting: connector.status === 'error',
34
+ busy: connecting || authorizationPending || checkingStatus,
35
+ };
36
+ }
37
+ function connectorHint({ connector, state, t }) {
38
+ if (state.connected)
39
+ return connector.accountLabel || `${connector.tools.length} ${t('read tools')}`;
40
+ if (state.checkingStatus)
41
+ return t('Checking connection status…');
42
+ if (state.authorizationPending)
43
+ return t('Finish authorization in your browser, then return here');
44
+ return connector.lastError?.trim() || state.connectError || t('Connect this app before extraction');
45
+ }
46
+ function connectButtonLabel({ state, t }) {
47
+ if (state.checkingStatus)
48
+ return t('Checking');
49
+ if (state.authorizationPending)
50
+ return t('Waiting');
51
+ if (state.connecting)
52
+ return t('Connecting');
53
+ return state.reconnecting ? t('Reconnect') : t('Connect');
54
+ }
55
+ function MemoryConnectButton({ connector, state, onConnectMemoryConnector, }) {
56
+ const t = useT();
57
+ return (_jsxs("button", { type: "button", className: `memory-connector-connect-button${state.busy ? ' is-loading' : ''}`, disabled: state.busy, "aria-busy": state.busy || undefined, "aria-label": `${state.reconnecting ? t('Reconnect') : t('Connect')} ${connector.name}`, onClick: (event) => {
58
+ event.preventDefault();
59
+ event.stopPropagation();
60
+ void onConnectMemoryConnector(connector.id);
61
+ }, children: [_jsx(Icon, { name: state.busy ? 'refresh' : 'plus', size: 12, className: state.busy ? 'icon-spin' : '' }), _jsx("span", { children: connectButtonLabel({ state, t }) })] }));
62
+ }
63
+ function MemoryConnectorPicker({ selected }) {
64
+ const t = useT();
65
+ return (_jsxs("span", { className: `memory-connector-picker${selected ? ' is-selected' : ''}`, children: [_jsx("span", { className: "memory-connector-picker-box", "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 12 }) : null }), _jsx("span", { children: selected ? t('Selected') : t('Select') })] }));
66
+ }
67
+ function MemoryConnectorRow({ connector, context, toggleConnectorSelection, onConnectMemoryConnector, }) {
68
+ const t = useT();
69
+ const state = connectorRowState({ connector, context });
70
+ const { connected, selected } = state;
71
+ return (_jsxs("label", { className: `memory-connector-row${connected ? '' : ' is-disabled'}${selected ? ' is-selected' : ''}`, "data-memory-connector-id": connector.id, children: [_jsx("input", { className: "memory-connector-input", type: "checkbox", checked: selected, disabled: !connected, "aria-label": `${t('Use')} ${connector.name} ${t('for memory extraction')}`, onChange: () => toggleConnectorSelection(connector.id) }), _jsxs("span", { className: `memory-connector-brand${selected ? ' is-selected' : ''}`, children: [_jsx(ConnectorLogo, { connectorId: connector.id, connectorName: connector.name, logoUrl: connector.logoUrl, size: "sm" }), _jsx("span", { className: "memory-connector-selected-mark", "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 13 }) : null })] }), _jsxs("span", { className: "memory-connector-copy", children: [_jsx("strong", { children: connector.name }), _jsx("small", { children: connectorHint({ connector, state, t }) })] }), connected ? (_jsx(MemoryConnectorPicker, { selected: selected })) : (_jsx(MemoryConnectButton, { connector: connector, state: state, onConnectMemoryConnector: onConnectMemoryConnector }))] }));
72
+ }
73
+ function MemoryConnectedSummary({ connectorsLoading, connectedCount, onOpenConnectors, }) {
74
+ const t = useT();
75
+ return (_jsxs("div", { className: "memory-source-summary memory-connected-summary", children: [_jsx("span", { className: "memory-block-icon", children: _jsx(Icon, { name: "link", size: 15 }) }), _jsxs("div", { children: [_jsx("h4", { children: t('Import from apps') }), _jsx("p", { className: "hint", children: t('Choose apps to scan for design preferences, project context, and visual references. Nothing is scanned until you select an app.') })] }), _jsx("span", { className: "memory-source-badge", children: connectorsLoading ? t('Loading') : `${connectedCount} ${t('connected')}` }), _jsx("button", { type: "button", className: "ghost memory-source-action", onClick: onOpenConnectors, disabled: !onOpenConnectors, children: t('Manage') })] }));
76
+ }
77
+ function MemoryConnectorRunBar({ enabled, connectorExtracting, connectorSaving, connectedCount, selectedCount, connectorScanLabel, onSuggestConnectorMemory, }) {
78
+ const t = useT();
79
+ return (_jsxs("div", { className: "memory-connector-actions memory-connector-runbar", children: [_jsxs("span", { className: "hint", children: [t('Selected'), " ", selectedCount, " ", t('of'), " ", connectedCount, " ", t('connected'), ' ', connectedCount === 1 ? t('app') : t('apps'), "."] }), _jsxs("button", { type: "button", className: "primary memory-source-action", onClick: () => void onSuggestConnectorMemory(), disabled: !enabled || connectorExtracting || connectorSaving || selectedCount === 0, children: [_jsx(Icon, { name: connectorExtracting ? 'refresh' : 'sparkles', size: 14, className: connectorExtracting ? 'icon-spin' : '' }), _jsx("span", { children: t(connectorScanLabel) })] })] }));
80
+ }
81
+ function MemorySuggestionCard({ suggestion, selected, typeLabel, toggleConnectorSuggestion, }) {
82
+ const t = useT();
83
+ const sourceLabel = suggestion.source?.connectorName || suggestion.source?.toolTitle || t('Connected apps');
84
+ return (_jsxs("label", { className: `memory-suggestion-card${selected ? ' is-selected' : ''}`, children: [_jsxs("span", { className: "memory-connector-check", children: [_jsx("input", { type: "checkbox", checked: selected, onChange: () => toggleConnectorSuggestion(suggestion.id) }), _jsx("span", { "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 13 }) : null })] }), _jsxs("span", { className: "memory-suggestion-copy", children: [_jsxs("span", { className: "memory-suggestion-title", children: [_jsx("strong", { children: suggestion.name }), _jsx("span", { className: "memory-type-badge", children: typeLabel })] }), suggestion.description ? _jsx("small", { children: suggestion.description }) : null, _jsx("span", { className: "memory-suggestion-body", children: suggestion.body })] }), _jsx("span", { className: "memory-connector-state is-connected", children: sourceLabel })] }));
85
+ }
86
+ function MemorySuggestionPanel({ connectorSuggestions, selectedSuggestionIds, selectedConnectorSuggestions, connectorSaving, toggleConnectorSuggestion, onSaveConnectorSuggestions, onDiscardConnectorSuggestions, }) {
18
87
  const t = useT();
19
88
  const typeLabel = useMemo(() => memoryTypeLabels(t), [t]);
20
- return (_jsxs("div", { className: "memory-tab-panel memory-connected-panel", children: [_jsxs("div", { className: "memory-source-summary memory-connected-summary", children: [_jsx("span", { className: "memory-block-icon", children: _jsx(Icon, { name: "link", size: 15 }) }), _jsxs("div", { children: [_jsx("h4", { children: t('Import from apps') }), _jsx("p", { className: "hint", children: t('Choose apps to scan for design preferences, project context, and visual references. Nothing is scanned until you select an app.') })] }), _jsx("span", { className: "memory-source-badge", children: connectorsLoading ? t('Loading') : `${connectedCount} ${t('connected')}` }), _jsx("button", { type: "button", className: "ghost memory-source-action", onClick: onOpenConnectors, disabled: !onOpenConnectors, children: t('Manage') })] }), _jsxs("div", { className: "memory-connector-workbench", children: [connectorLoadError ? (_jsx("div", { role: "alert", className: "memory-connector-result is-error", children: connectorLoadError })) : null, _jsxs("div", { className: "memory-connector-picker-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Choose sources') }), _jsx("p", { className: "hint", children: t('Select connected apps first. Only the apps you choose are scanned.') })] }), _jsxs("span", { className: "memory-source-badge", children: [selectedConnectedConnectorIds.length, " ", t('selected')] })] }), _jsx("div", { className: "memory-connector-list", "aria-label": t('Connected memory apps'), children: memoryConnectors.map((connector) => {
21
- const connected = connector.status === 'connected';
22
- const selected = selectedConnectorIds.has(connector.id) && connected;
23
- const connecting = connectingConnectorIds.has(connector.id);
24
- const authorizationPending = pendingConnectorAuthIds.has(connector.id);
25
- const connectError = connectorConnectErrors[connector.id];
26
- const statusResolved = connectorIdsWithDetails.has(connector.id) || connectorStatuses[connector.id] !== undefined;
27
- const checkingStatus = connectorsLoading && !statusResolved && !connected && !authorizationPending && !connectError && !connecting;
28
- const connectorLastError = connector.lastError?.trim();
29
- const reconnecting = connector.status === 'error';
30
- const connectorHint = connected
31
- ? connector.accountLabel || `${connector.tools.length} ${t('read tools')}`
32
- : checkingStatus
33
- ? t('Checking connection status…')
34
- : authorizationPending
35
- ? t('Finish authorization in your browser, then return here')
36
- : connectorLastError || connectError || t('Connect this app before extraction');
37
- return (_jsxs("label", { className: `memory-connector-row${connected ? '' : ' is-disabled'}${selected ? ' is-selected' : ''}`, "data-memory-connector-id": connector.id, children: [_jsx("input", { className: "memory-connector-input", type: "checkbox", checked: selected, disabled: !connected, "aria-label": `${t('Use')} ${connector.name} ${t('for memory extraction')}`, onChange: () => toggleConnectorSelection(connector.id) }), _jsxs("span", { className: `memory-connector-brand${selected ? ' is-selected' : ''}`, children: [_jsx(ConnectorLogo, { connectorId: connector.id, connectorName: connector.name, logoUrl: connector.logoUrl, size: "sm" }), _jsx("span", { className: "memory-connector-selected-mark", "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 13 }) : null })] }), _jsxs("span", { className: "memory-connector-copy", children: [_jsx("strong", { children: connector.name }), _jsx("small", { children: connectorHint })] }), connected ? (_jsxs("span", { className: `memory-connector-picker${selected ? ' is-selected' : ''}`, children: [_jsx("span", { className: "memory-connector-picker-box", "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 12 }) : null }), _jsx("span", { children: selected ? t('Selected') : t('Select') })] })) : (_jsxs("button", { type: "button", className: `memory-connector-connect-button${connecting || authorizationPending || checkingStatus ? ' is-loading' : ''}`, disabled: connecting || authorizationPending || checkingStatus, "aria-busy": connecting || authorizationPending || checkingStatus || undefined, "aria-label": `${reconnecting ? t('Reconnect') : t('Connect')} ${connector.name}`, onClick: (event) => {
38
- event.preventDefault();
39
- event.stopPropagation();
40
- void onConnectMemoryConnector(connector.id);
41
- }, children: [_jsx(Icon, { name: connecting || authorizationPending || checkingStatus ? 'refresh' : 'plus', size: 12, className: connecting || authorizationPending || checkingStatus ? 'icon-spin' : '' }), _jsx("span", { children: checkingStatus
42
- ? t('Checking')
43
- : authorizationPending
44
- ? t('Waiting')
45
- : connecting
46
- ? t('Connecting')
47
- : reconnecting
48
- ? t('Reconnect')
49
- : t('Connect') })] }))] }, connector.id));
50
- }) }), _jsxs("div", { className: "memory-connector-actions memory-connector-runbar", children: [_jsxs("span", { className: "hint", children: [t('Selected'), " ", selectedConnectedConnectorIds.length, " ", t('of'), " ", connectedCount, " ", t('connected'), ' ', connectedCount === 1 ? t('app') : t('apps'), "."] }), _jsxs("button", { type: "button", className: "primary memory-source-action", onClick: () => void onSuggestConnectorMemory(), disabled: !enabled || connectorExtracting || connectorSaving || selectedConnectedConnectorIds.length === 0, children: [_jsx(Icon, { name: connectorExtracting ? 'refresh' : 'sparkles', size: 14, className: connectorExtracting ? 'icon-spin' : '' }), _jsx("span", { children: t(connectorScanLabel) })] })] })] }), connectorSuggestions.length > 0 ? (_jsxs("div", { className: "memory-suggestion-panel", children: [_jsxs("div", { className: "memory-subsection-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Suggested memories') }), _jsx("p", { className: "hint", children: t('Review design-related memories before saving them.') })] }), _jsxs("span", { className: "memory-source-badge", children: [selectedConnectorSuggestions.length, " ", t('selected')] })] }), _jsx("div", { className: "memory-suggestion-list", children: connectorSuggestions.map((suggestion) => {
51
- const selected = selectedSuggestionIds.has(suggestion.id);
52
- const sourceLabel = suggestion.source?.connectorName || suggestion.source?.toolTitle || t('Connected apps');
53
- return (_jsxs("label", { className: `memory-suggestion-card${selected ? ' is-selected' : ''}`, children: [_jsxs("span", { className: "memory-connector-check", children: [_jsx("input", { type: "checkbox", checked: selected, onChange: () => toggleConnectorSuggestion(suggestion.id) }), _jsx("span", { "aria-hidden": "true", children: selected ? _jsx(Icon, { name: "check", size: 13 }) : null })] }), _jsxs("span", { className: "memory-suggestion-copy", children: [_jsxs("span", { className: "memory-suggestion-title", children: [_jsx("strong", { children: suggestion.name }), _jsx("span", { className: "memory-type-badge", children: typeLabel[suggestion.type] })] }), suggestion.description ? _jsx("small", { children: suggestion.description }) : null, _jsx("span", { className: "memory-suggestion-body", children: suggestion.body })] }), _jsx("span", { className: "memory-connector-state is-connected", children: sourceLabel })] }, suggestion.id));
54
- }) }), _jsxs("div", { className: "memory-connector-actions", children: [_jsxs("button", { type: "button", className: "primary memory-source-action", onClick: () => void onSaveConnectorSuggestions(), disabled: connectorSaving || selectedConnectorSuggestions.length === 0, children: [_jsx(Icon, { name: connectorSaving ? 'refresh' : 'check', size: 14, className: connectorSaving ? 'icon-spin' : '' }), _jsx("span", { children: connectorSaving ? t('Saving') : t('Save selected') })] }), _jsx("button", { type: "button", className: "ghost memory-source-action", onClick: onDiscardConnectorSuggestions, disabled: connectorSaving, children: t('Discard') })] })] })) : null, connectorStatus ? (_jsx("div", { role: "status", className: "memory-connector-result is-success", children: connectorStatus })) : null, connectorError ? (_jsx("div", { role: "alert", className: "memory-connector-result is-error", children: connectorError })) : null, connectorAttempts.length > 0 ? (_jsxs("div", { className: "memory-connector-diagnostics", "aria-label": t('Connected app read status'), children: [_jsxs("div", { className: "memory-connector-diagnostics-head", children: [_jsx("strong", { children: t('Last scan') }), _jsxs("span", { children: [formatConnectorContextBytes(connectorContextBytes), " ", t('read')] })] }), _jsx("div", { className: "memory-connector-diagnostics-list", children: connectorAttempts.map((attempt) => (_jsxs("div", { className: `memory-connector-diagnostic-row is-${attempt.status}`, children: [_jsx("span", { className: "memory-connector-diagnostic-dot", "aria-hidden": "true" }), _jsxs("span", { className: "memory-connector-diagnostic-copy", children: [_jsx("strong", { children: connectorAttemptTitle(attempt) }), _jsx("small", { children: connectorAttemptDetail(attempt) })] })] }, `${attempt.connectorId}-${attempt.status}-${attempt.toolName ?? 'none'}`))) })] })) : null, connectorExtractions.length > 0 ? (_jsxs("details", { className: "memory-scan-history", children: [_jsxs("summary", { children: [_jsx("span", { children: t('Recent scans') }), _jsx("span", { children: connectorExtractions.length })] }), _jsx("div", { className: "memory-connector-run-history", "aria-label": t('Connected app memory run status'), children: connectorExtractions.slice(0, 4).map((record) => (_jsx(MemoryExtractionCard, { record: record, nowClock: nowClock, onOpenPreview: onOpenPreview, onDelete: onDeleteExtraction }, record.id))) })] })) : null] }));
89
+ return (_jsxs("div", { className: "memory-suggestion-panel", children: [_jsxs("div", { className: "memory-subsection-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Suggested memories') }), _jsx("p", { className: "hint", children: t('Review design-related memories before saving them.') })] }), _jsxs("span", { className: "memory-source-badge", children: [selectedConnectorSuggestions.length, " ", t('selected')] })] }), _jsx("div", { className: "memory-suggestion-list", children: connectorSuggestions.map((suggestion) => (_jsx(MemorySuggestionCard, { suggestion: suggestion, selected: selectedSuggestionIds.has(suggestion.id), typeLabel: typeLabel[suggestion.type], toggleConnectorSuggestion: toggleConnectorSuggestion }, suggestion.id))) }), _jsxs("div", { className: "memory-connector-actions", children: [_jsxs("button", { type: "button", className: "primary memory-source-action", onClick: () => void onSaveConnectorSuggestions(), disabled: connectorSaving || selectedConnectorSuggestions.length === 0, children: [_jsx(Icon, { name: connectorSaving ? 'refresh' : 'check', size: 14, className: connectorSaving ? 'icon-spin' : '' }), _jsx("span", { children: connectorSaving ? t('Saving') : t('Save selected') })] }), _jsx("button", { type: "button", className: "ghost memory-source-action", onClick: onDiscardConnectorSuggestions, disabled: connectorSaving, children: t('Discard') })] })] }));
90
+ }
91
+ function MemoryConnectorDiagnostics({ connectorAttempts, connectorContextBytes, }) {
92
+ const t = useT();
93
+ return (_jsxs("div", { className: "memory-connector-diagnostics", "aria-label": t('Connected app read status'), children: [_jsxs("div", { className: "memory-connector-diagnostics-head", children: [_jsx("strong", { children: t('Last scan') }), _jsxs("span", { children: [formatConnectorContextBytes(connectorContextBytes), " ", t('read')] })] }), _jsx("div", { className: "memory-connector-diagnostics-list", children: connectorAttempts.map((attempt) => (_jsxs("div", { className: `memory-connector-diagnostic-row is-${attempt.status}`, children: [_jsx("span", { className: "memory-connector-diagnostic-dot", "aria-hidden": "true" }), _jsxs("span", { className: "memory-connector-diagnostic-copy", children: [_jsx("strong", { children: connectorAttemptTitle(attempt) }), _jsx("small", { children: connectorAttemptDetail(attempt) })] })] }, `${attempt.connectorId}-${attempt.status}-${attempt.toolName ?? 'none'}`))) })] }));
94
+ }
95
+ function MemoryScanHistory({ connectorExtractions, nowClock, onOpenPreview, onDeleteExtraction, }) {
96
+ const t = useT();
97
+ return (_jsxs("details", { className: "memory-scan-history", children: [_jsxs("summary", { children: [_jsx("span", { children: t('Recent scans') }), _jsx("span", { children: connectorExtractions.length })] }), _jsx("div", { className: "memory-connector-run-history", "aria-label": t('Connected app memory run status'), children: connectorExtractions.slice(0, 4).map((record) => (_jsx(MemoryExtractionCard, { record: record, nowClock: nowClock, onOpenPreview: onOpenPreview, onDelete: onDeleteExtraction }, record.id))) })] }));
98
+ }
99
+ export function MemoryConnectedPanel({ enabled, onOpenConnectors, connectorStatuses, connectorsLoading, connectedCount, selectedConnectorIds, selectedConnectedConnectorIds, connectingConnectorIds, pendingConnectorAuthIds, connectorConnectErrors, connectorIdsWithDetails, connectorExtracting, connectorSaving, connectorScanLabel, connectorSuggestions, selectedSuggestionIds, selectedConnectorSuggestions, connectorStatus, connectorError, connectorLoadError, connectorAttempts, connectorContextBytes, connectorExtractions, memoryConnectors, toggleConnectorSelection, onConnectMemoryConnector, toggleConnectorSuggestion, onSuggestConnectorMemory, onSaveConnectorSuggestions, onDiscardConnectorSuggestions, nowClock, onOpenPreview, onDeleteExtraction, }) {
100
+ const t = useT();
101
+ const rowContext = {
102
+ connectorStatuses,
103
+ connectorsLoading,
104
+ selectedConnectorIds,
105
+ connectingConnectorIds,
106
+ pendingConnectorAuthIds,
107
+ connectorConnectErrors,
108
+ connectorIdsWithDetails,
109
+ };
110
+ return (_jsxs("div", { className: "memory-tab-panel memory-connected-panel", children: [_jsx(MemoryConnectedSummary, { connectorsLoading: connectorsLoading, connectedCount: connectedCount, onOpenConnectors: onOpenConnectors }), _jsxs("div", { className: "memory-connector-workbench", children: [connectorLoadError ? (_jsx("div", { role: "alert", className: "memory-connector-result is-error", children: connectorLoadError })) : null, _jsxs("div", { className: "memory-connector-picker-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Choose sources') }), _jsx("p", { className: "hint", children: t('Select connected apps first. Only the apps you choose are scanned.') })] }), _jsxs("span", { className: "memory-source-badge", children: [selectedConnectedConnectorIds.length, " ", t('selected')] })] }), _jsx("div", { className: "memory-connector-list", "aria-label": t('Connected memory apps'), children: memoryConnectors.map((connector) => (_jsx(MemoryConnectorRow, { connector: connector, context: rowContext, toggleConnectorSelection: toggleConnectorSelection, onConnectMemoryConnector: onConnectMemoryConnector }, connector.id))) }), _jsx(MemoryConnectorRunBar, { enabled: enabled, connectorExtracting: connectorExtracting, connectorSaving: connectorSaving, connectedCount: connectedCount, selectedCount: selectedConnectedConnectorIds.length, connectorScanLabel: connectorScanLabel, onSuggestConnectorMemory: onSuggestConnectorMemory })] }), connectorSuggestions.length > 0 ? (_jsx(MemorySuggestionPanel, { connectorSuggestions: connectorSuggestions, selectedSuggestionIds: selectedSuggestionIds, selectedConnectorSuggestions: selectedConnectorSuggestions, connectorSaving: connectorSaving, toggleConnectorSuggestion: toggleConnectorSuggestion, onSaveConnectorSuggestions: onSaveConnectorSuggestions, onDiscardConnectorSuggestions: onDiscardConnectorSuggestions })) : null, connectorStatus ? (_jsx("div", { role: "status", className: "memory-connector-result is-success", children: connectorStatus })) : null, connectorError ? (_jsx("div", { role: "alert", className: "memory-connector-result is-error", children: connectorError })) : null, connectorAttempts.length > 0 ? (_jsx(MemoryConnectorDiagnostics, { connectorAttempts: connectorAttempts, connectorContextBytes: connectorContextBytes })) : null, connectorExtractions.length > 0 ? (_jsx(MemoryScanHistory, { connectorExtractions: connectorExtractions, nowClock: nowClock, onOpenPreview: onOpenPreview, onDeleteExtraction: onDeleteExtraction })) : null] }));
55
111
  }
56
112
  //# sourceMappingURL=MemoryConnectedPanel.js.map
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  // Dumb panel for the saved-memory records: counts, the type-filter pills, the
3
3
  // extraction clear/refresh toolbar, and the unified list (saved entries + the
4
4
  // visible extraction rows). Rendering only — every list, count, and handler is
@@ -11,24 +11,43 @@ import { TYPES } from '../../constants.js';
11
11
  import { memoryTypeLabels } from '../../formatters.js';
12
12
  import { MemoryEntryCard } from './MemoryEntryCard.js';
13
13
  import { MemoryExtractionCard } from './MemoryExtractionCard.js';
14
- export function MemoryList({ sectionRef, entries, filtered, visibleExtractions, filter, onFilterChange, unifiedMemoryCount, onClearExtractions, onRefreshExtractions, isRefreshing, previewId, previewBody, nowClock, onOpenPreview, onStartEdit, onDeleteEntry, onDeleteExtraction, agentHandle, }) {
14
+ /** Per-row agent handles under `<agentHandle>-<action>`, or undefined when unpublished. */
15
+ function rowHandles({ agentHandle, action, ids }) {
16
+ return agentHandle ? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action }), ids }) : undefined;
17
+ }
18
+ function MemoryListCounts({ savedCount, extractionCount }) {
19
+ const t = useT();
20
+ return (_jsxs("div", { className: "memory-management-counts", children: [_jsxs("span", { className: "memory-source-badge", children: [savedCount, " ", t('saved')] }), extractionCount > 0 ? (_jsxs("span", { className: "memory-source-badge", children: [extractionCount, " ", extractionCount === 1 ? t('extraction') : t('extractions')] })) : null] }));
21
+ }
22
+ function MemoryFilterPills({ entries, extractionCount, filter, onFilterChange, agentHandle, }) {
15
23
  const t = useT();
16
24
  const typeLabel = useMemo(() => memoryTypeLabels(t), [t]);
17
- const entryHandles = agentHandle
18
- ? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'entry' }), ids: filtered.map((e) => e.id) })
19
- : undefined;
20
- const extractionHandles = agentHandle
21
- ? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'extraction' }), ids: visibleExtractions.map((r) => r.id) })
22
- : undefined;
23
- return (_jsx("section", { ref: sectionRef, className: "settings-section settings-section-card memory-records-section", children: _jsxs("div", { className: "memory-management-panel", children: [_jsxs("div", { className: "memory-subsection-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Saved memory') }), _jsx("p", { className: "hint", children: t('Saved facts, preferences, and project context available to future chats.') })] }), _jsxs("div", { className: "memory-management-counts", children: [_jsxs("span", { className: "memory-source-badge", children: [entries.length, " ", t('saved')] }), visibleExtractions.length > 0 ? (_jsxs("span", { className: "memory-source-badge", children: [visibleExtractions.length, " ", visibleExtractions.length === 1 ? t('extraction') : t('extractions')] })) : null] })] }), _jsxs("div", { className: "library-toolbar is-row", children: [_jsxs("div", { className: "library-filters", children: [_jsxs("button", { type: "button", className: `filter-pill${filter === 'all' ? ' active' : ''}`, onClick: () => onFilterChange('all'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'filter-all', role: 'button', label: t('All') }) }), children: [t('All'), _jsx("span", { className: "filter-pill-count", children: entries.length + visibleExtractions.length })] }), TYPES.map((type) => {
24
- const count = entries.filter((e) => e.type === type).length;
25
- if (count === 0 && filter !== type)
26
- return null;
27
- return (_jsxs("button", { type: "button", className: `filter-pill${filter === type ? ' active' : ''}`, onClick: () => onFilterChange(type), ...agentHandleProps({}, { base: agentHandle, ...({ action: `filter-${type}`, role: 'button', label: typeLabel[type] }) }), children: [typeLabel[type], _jsx("span", { className: "filter-pill-count", children: count })] }, type));
28
- })] }), _jsxs("div", { className: "memory-management-actions", children: [visibleExtractions.length > 0 ? (_jsxs("button", { type: "button", className: "ghost memory-clear-extractions", onClick: () => onClearExtractions(), title: t('Clear extraction history'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'clear-extractions', role: 'button', label: t('Clear extraction history') }) }), children: [_jsx(Icon, { name: "close", size: 12 }), _jsx("span", { children: t('Clear') })] })) : null, visibleExtractions.length > 0 ? (_jsxs("button", { type: "button", className: "ghost memory-refresh-extractions", onClick: () => onRefreshExtractions(), disabled: isRefreshing, title: t('Refresh'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'refresh-extractions', role: 'button', label: t('Refresh') }) }), children: [_jsx(Icon, { name: "refresh", size: 12, className: isRefreshing ? 'icon-spin' : '' }), _jsx("span", { children: isRefreshing ? t('Refreshing') : t('Refresh') })] })) : null] })] }), _jsx("div", { className: "library-content memory-unified-list", children: unifiedMemoryCount === 0 ? (
29
- // Empty state: one clear "no rows yet" line and a one-sentence
30
- // primer that explains the mechanism (talk in chat, fact gets
31
- // extracted) with a single example.
32
- _jsxs("div", { className: "library-empty", children: [_jsx("p", { className: "library-empty-title", children: t('No saved memories yet') }), _jsxs("p", { className: "library-empty-hint", children: [t('Tell the assistant a fact in chat — e.g.'), " ", _jsx("code", { children: t('I prefer dark mode') }), ' ', t('— and it will be saved here automatically.')] })] })) : (_jsxs(_Fragment, { children: [filtered.map((entry, index) => (_jsx(MemoryEntryCard, { entry: entry, previewId: previewId, previewBody: previewBody, onOpenPreview: onOpenPreview, onStartEdit: onStartEdit, onDelete: onDeleteEntry, ...(entryHandles?.[index] ? { agentHandle: entryHandles[index] } : {}) }, entry.id))), visibleExtractions.map((record, index) => (_jsx(MemoryExtractionCard, { record: record, nowClock: nowClock, onOpenPreview: onOpenPreview, onDelete: onDeleteExtraction, ...(extractionHandles?.[index] ? { agentHandle: extractionHandles[index] } : {}) }, record.id)))] })) })] }) }));
25
+ return (_jsxs("div", { className: "library-filters", children: [_jsxs("button", { type: "button", className: `filter-pill${filter === 'all' ? ' active' : ''}`, onClick: () => onFilterChange('all'), ...agentHandleProps({}, { base: agentHandle, action: 'filter-all', role: 'button', label: t('All') }), children: [t('All'), _jsx("span", { className: "filter-pill-count", children: entries.length + extractionCount })] }), TYPES.map((type) => {
26
+ const count = entries.filter((e) => e.type === type).length;
27
+ if (count === 0 && filter !== type)
28
+ return null;
29
+ return (_jsxs("button", { type: "button", className: `filter-pill${filter === type ? ' active' : ''}`, onClick: () => onFilterChange(type), ...agentHandleProps({}, { base: agentHandle, action: `filter-${type}`, role: 'button', label: typeLabel[type] }), children: [typeLabel[type], _jsx("span", { className: "filter-pill-count", children: count })] }, type));
30
+ })] }));
31
+ }
32
+ function MemoryExtractionActions({ onClearExtractions, onRefreshExtractions, isRefreshing, agentHandle, }) {
33
+ const t = useT();
34
+ return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "ghost memory-clear-extractions", onClick: () => onClearExtractions(), title: t('Clear extraction history'), ...agentHandleProps({}, { base: agentHandle, action: 'clear-extractions', role: 'button', label: t('Clear extraction history') }), children: [_jsx(Icon, { name: "close", size: 12 }), _jsx("span", { children: t('Clear') })] }), _jsxs("button", { type: "button", className: "ghost memory-refresh-extractions", onClick: () => onRefreshExtractions(), disabled: isRefreshing, title: t('Refresh'), ...agentHandleProps({}, { base: agentHandle, action: 'refresh-extractions', role: 'button', label: t('Refresh') }), children: [_jsx(Icon, { name: "refresh", size: 12, className: isRefreshing ? 'icon-spin' : '' }), _jsx("span", { children: isRefreshing ? t('Refreshing') : t('Refresh') })] })] }));
35
+ }
36
+ function MemoryListEmpty() {
37
+ const t = useT();
38
+ return (
39
+ // Empty state: one clear "no rows yet" line and a one-sentence
40
+ // primer that explains the mechanism (talk in chat, fact gets
41
+ // extracted) with a single example.
42
+ _jsxs("div", { className: "library-empty", children: [_jsx("p", { className: "library-empty-title", children: t('No saved memories yet') }), _jsxs("p", { className: "library-empty-hint", children: [t('Tell the assistant a fact in chat — e.g.'), " ", _jsx("code", { children: t('I prefer dark mode') }), ' ', t('— and it will be saved here automatically.')] })] }));
43
+ }
44
+ function MemoryListRows({ filtered, visibleExtractions, previewId, previewBody, nowClock, onOpenPreview, onStartEdit, onDeleteEntry, onDeleteExtraction, agentHandle, }) {
45
+ const entryHandles = rowHandles({ agentHandle, action: 'entry', ids: filtered.map((e) => e.id) });
46
+ const extractionHandles = rowHandles({ agentHandle, action: 'extraction', ids: visibleExtractions.map((r) => r.id) });
47
+ return (_jsxs(_Fragment, { children: [filtered.map((entry, index) => (_jsx(MemoryEntryCard, { entry: entry, previewId: previewId, previewBody: previewBody, onOpenPreview: onOpenPreview, onStartEdit: onStartEdit, onDelete: onDeleteEntry, ...(entryHandles?.[index] ? { agentHandle: entryHandles[index] } : {}) }, entry.id))), visibleExtractions.map((record, index) => (_jsx(MemoryExtractionCard, { record: record, nowClock: nowClock, onOpenPreview: onOpenPreview, onDelete: onDeleteExtraction, ...(extractionHandles?.[index] ? { agentHandle: extractionHandles[index] } : {}) }, record.id)))] }));
48
+ }
49
+ export function MemoryList({ sectionRef, entries, filtered, visibleExtractions, filter, onFilterChange, unifiedMemoryCount, onClearExtractions, onRefreshExtractions, isRefreshing, previewId, previewBody, nowClock, onOpenPreview, onStartEdit, onDeleteEntry, onDeleteExtraction, agentHandle, }) {
50
+ const t = useT();
51
+ return (_jsx("section", { ref: sectionRef, className: "settings-section settings-section-card memory-records-section", children: _jsxs("div", { className: "memory-management-panel", children: [_jsxs("div", { className: "memory-subsection-head", children: [_jsxs("div", { children: [_jsx("h4", { children: t('Saved memory') }), _jsx("p", { className: "hint", children: t('Saved facts, preferences, and project context available to future chats.') })] }), _jsx(MemoryListCounts, { savedCount: entries.length, extractionCount: visibleExtractions.length })] }), _jsxs("div", { className: "library-toolbar is-row", children: [_jsx(MemoryFilterPills, { entries: entries, extractionCount: visibleExtractions.length, filter: filter, onFilterChange: onFilterChange, agentHandle: agentHandle }), _jsx("div", { className: "memory-management-actions", children: visibleExtractions.length > 0 ? (_jsx(MemoryExtractionActions, { onClearExtractions: onClearExtractions, onRefreshExtractions: onRefreshExtractions, isRefreshing: isRefreshing, agentHandle: agentHandle })) : null })] }), _jsx("div", { className: "library-content memory-unified-list", children: unifiedMemoryCount === 0 ? (_jsx(MemoryListEmpty, {})) : (_jsx(MemoryListRows, { filtered: filtered, visibleExtractions: visibleExtractions, previewId: previewId, previewBody: previewBody, nowClock: nowClock, onOpenPreview: onOpenPreview, onStartEdit: onStartEdit, onDeleteEntry: onDeleteEntry, onDeleteExtraction: onDeleteExtraction, agentHandle: agentHandle })) })] }) }));
33
52
  }
34
53
  //# sourceMappingURL=MemoryList.js.map