@jini-ai/ui 0.3.13 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +139 -0
- package/README.md +120 -26
- package/dist/browser/index.js +1 -1
- package/dist/browser/useDismissOnOutsideOrEscape.d.ts +10 -1
- package/dist/browser/useDismissOnOutsideOrEscape.js +7 -4
- package/dist/browser/useGlobalKeydown.d.ts +14 -2
- package/dist/browser/useGlobalKeydown.js +8 -17
- package/dist/features/a2ui/catalog-from-registry.d.ts +6 -3
- package/dist/features/a2ui/catalog-from-registry.js +1 -1
- package/dist/features/a2ui/index.d.ts +1 -1
- package/dist/features/a2ui/protocol.d.ts +1 -1
- package/dist/features/a2ui/renderer.js +23 -10
- package/dist/features/a2ui/use-a2ui-surface.d.ts +11 -6
- package/dist/features/a2ui/use-a2ui-surface.js +40 -10
- package/dist/features/admin-widgets/components/ComingSoonNotice.d.ts +11 -0
- package/dist/features/admin-widgets/components/ComingSoonNotice.js +7 -0
- package/dist/features/admin-widgets/components/ComingSoonPanel.d.ts +10 -0
- package/dist/features/admin-widgets/components/ComingSoonPanel.js +10 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.d.ts +16 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.d.ts +13 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.js +46 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.js +13 -0
- package/dist/features/admin-widgets/components/InfoTip.d.ts +18 -0
- package/dist/features/admin-widgets/components/InfoTip.hooks.d.ts +16 -0
- package/dist/features/admin-widgets/components/InfoTip.hooks.js +45 -0
- package/dist/features/admin-widgets/components/InfoTip.js +12 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.d.ts +41 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.hooks.d.ts +14 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.hooks.js +57 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.js +24 -0
- package/dist/features/admin-widgets/components/Select/Select.d.ts +39 -0
- package/dist/features/admin-widgets/components/Select/Select.hooks.d.ts +105 -0
- package/dist/features/admin-widgets/components/Select/Select.hooks.js +359 -0
- package/dist/features/admin-widgets/components/Select/Select.js +46 -0
- package/dist/features/admin-widgets/index.d.ts +20 -0
- package/dist/features/admin-widgets/index.js +11 -0
- package/dist/features/admin-widgets/styles/admin-widgets.css +2 -0
- package/dist/features/appearance/constants.d.ts +2 -2
- package/dist/features/appearance/constants.js +2 -1
- package/dist/features/appearance/react/components/AppearanceTab.js +5 -5
- package/dist/features/appearance/rules.d.ts +10 -4
- package/dist/features/appearance/rules.js +5 -5
- package/dist/features/appearance/types.d.ts +1 -1
- package/dist/features/appearance/types.js +1 -1
- package/dist/features/asset-grid/react/components/AssetGrid.js +1 -1
- package/dist/features/asset-grid/react/components/DeleteConfirmDialog.js +1 -1
- package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +23 -21
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.d.ts +1 -1
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +1 -1
- package/dist/features/asset-tree-browser/ports.d.ts +3 -1
- package/dist/features/asset-tree-browser/react/hooks/useAssetTreeCopyLocalPath.js +1 -1
- package/dist/features/browser-chrome/react/components/BrowserViewportControls.js +1 -1
- package/dist/features/browser-chrome/types.js +1 -1
- package/dist/features/command-palette/ports.js +1 -1
- package/dist/features/connectors/ConnectorsBrowser.js +2 -2
- package/dist/features/connectors/components/ConnectorCard.js +3 -3
- package/dist/features/connectors/components/ConnectorDetailDrawer.js +1 -1
- package/dist/features/connectors/components/ConnectorGrid.js +2 -2
- package/dist/features/connectors/components/ConnectorSearchBar.js +2 -2
- package/dist/features/connectors/components/ProviderTabBar.js +2 -2
- package/dist/features/connectors/constants.d.ts +1 -1
- package/dist/features/connectors/constants.js +1 -1
- package/dist/features/connectors/hooks/useConnectorAuthorization.js +1 -1
- package/dist/features/connectors/rules.d.ts +2 -2
- package/dist/features/connectors/rules.js +1 -1
- package/dist/features/connectors/types.d.ts +2 -2
- package/dist/features/connectors/types.js +1 -1
- package/dist/features/execution/react/components/ByokProviderForm.js +3 -3
- package/dist/features/execution/react/components/ExecutionTab.js +2 -2
- package/dist/features/execution/react/components/LocalCliAgentCard.js +3 -3
- package/dist/features/execution/react/components/LocalCliAgentList.js +2 -2
- package/dist/features/execution/react/components/ProviderChipGroup.js +2 -2
- package/dist/features/execution/react/components/SearchableModelSelect.js +1 -1
- package/dist/features/execution/rules.js +1 -1
- package/dist/features/file-dropzone/react/components/FileDropzone.js +5 -3
- package/dist/features/file-dropzone/react/hooks/useFileDropzone.d.ts +1 -1
- package/dist/features/file-dropzone/react/hooks/useFileDropzone.js +1 -1
- package/dist/features/file-dropzone/types.d.ts +1 -1
- package/dist/features/file-dropzone/types.js +1 -1
- package/dist/features/folder-path-drop/react/hooks/useFolderPathDropCapture.js +6 -4
- package/dist/features/html-editor/canvas-content-wrapper.js +1 -1
- package/dist/features/html-editor/canvas-embed-placeholders.js +7 -7
- package/dist/features/html-editor/canvas-style.d.ts +4 -0
- package/dist/features/html-editor/canvas-style.js +6 -21
- package/dist/features/html-viewer/constants.d.ts +1 -1
- package/dist/features/html-viewer/constants.js +1 -1
- package/dist/features/html-viewer/react/components/PresentMenu.js +1 -1
- package/dist/features/html-viewer/react/components/ZoomMenu.js +1 -1
- package/dist/features/html-viewer/types.d.ts +1 -1
- package/dist/features/html-viewer/types.js +1 -1
- package/dist/features/i18n/dictionaries/index.d.ts +2 -3
- package/dist/features/i18n/dictionaries/settings-dialog.en.d.ts +1 -1
- package/dist/features/i18n/dictionary-translator.d.ts +16 -0
- package/dist/features/i18n/dictionary-translator.js +14 -0
- package/dist/features/i18n/index.d.ts +3 -0
- package/dist/features/i18n/index.js +2 -0
- package/dist/features/i18n/locale.d.ts +1 -1
- package/dist/features/i18n/template-i18n.d.ts +26 -0
- package/dist/features/i18n/template-i18n.js +36 -0
- package/dist/features/iframe-pool/react/components/IframeKeepAliveProvider.d.ts +1 -1
- package/dist/features/iframe-pool/react/components/IframeKeepAliveProvider.js +1 -1
- package/dist/features/instructions/react/components/InstructionsTab.js +1 -1
- package/dist/features/integrations/react/components/ClientPicker.js +4 -4
- package/dist/features/integrations/react/components/CodexInstallToggleButton.js +1 -1
- package/dist/features/integrations/react/components/IntegrationsTab.js +2 -2
- package/dist/features/integrations/react/components/SnippetBlock.js +1 -1
- package/dist/features/integrations/types.d.ts +1 -1
- package/dist/features/integrations/types.js +1 -1
- package/dist/features/interactive-ui/index.js +13 -13
- package/dist/features/interactive-ui/interactive-ui.css +1 -1
- package/dist/features/interactive-ui/providers/recharts/bar-chart.js +1 -1
- package/dist/features/interactive-ui/providers/recharts/line-chart.js +1 -1
- package/dist/features/interactive-ui/providers/recharts/pie-chart.js +2 -2
- package/dist/features/interactive-ui/providers/shadcn/lib/utils.d.ts +1 -1
- package/dist/features/interactive-ui/providers/shadcn/lib/utils.js +1 -1
- package/dist/features/interactive-ui/registry.d.ts +15 -4
- package/dist/features/interactive-ui/registry.js +5 -5
- package/dist/features/language/react/components/LanguageTab.js +2 -2
- package/dist/features/list-detail-panel/types.d.ts +1 -1
- package/dist/features/list-detail-panel/types.js +1 -1
- package/dist/features/mcp-ui/confirmation-store.js +2 -1
- package/dist/features/mcp-ui/surfaces/bridge.d.ts +2 -1
- package/dist/features/mcp-ui/surfaces/bridge.js +17 -7
- package/dist/features/mcp-ui/surfaces/confirmation.d.ts +20 -0
- package/dist/features/mcp-ui/surfaces/confirmation.js +38 -6
- package/dist/features/mcp-ui/surfaces/document.d.ts +7 -1
- package/dist/features/mcp-ui/surfaces/document.js +19 -1
- package/dist/features/mcp-ui/surfaces/text-input.js +4 -4
- package/dist/features/mcp-ui/surfaces/tokens.d.ts +17 -20
- package/dist/features/mcp-ui/surfaces/tokens.js +33 -35
- package/dist/features/media-providers/index.d.ts +1 -1
- package/dist/features/media-providers/index.js +1 -1
- package/dist/features/media-providers/react/components/MediaProvidersTab.js +4 -4
- package/dist/features/media-providers/rules.js +1 -1
- package/dist/features/memory/async-commit-guard.d.ts +1 -1
- package/dist/features/memory/constants.d.ts +1 -1
- package/dist/features/memory/constants.js +1 -1
- package/dist/features/memory/dependencies.d.ts +11 -23
- package/dist/features/memory/dependencies.js +116 -106
- package/dist/features/memory/index.d.ts +1 -1
- package/dist/features/memory/index.js +1 -1
- package/dist/features/memory/react/components/MemoryAdvancedModal.js +2 -2
- package/dist/features/memory/react/components/MemoryEntryCard.js +1 -1
- package/dist/features/memory/react/components/MemoryExtractionCard.js +1 -1
- package/dist/features/memory/react/components/MemoryHooksPanel.js +1 -1
- package/dist/features/memory/react/components/MemoryList.js +5 -5
- package/dist/features/memory/react/components/MemoryManualEditor.js +5 -5
- package/dist/features/memory/react/components/MemorySettingsPanel.js +1 -1
- package/dist/features/memory/react/hooks/useMemoryEntries.hooks.js +1 -1
- package/dist/features/memory/react/hooks/useMemoryNavigation.hooks.js +1 -1
- package/dist/features/memory/react/styles.js +1 -1
- package/dist/features/memory/rules.js +1 -1
- package/dist/features/memory/types.d.ts +1 -1
- package/dist/features/mention-autocomplete/react/hooks/useMentionAutocomplete.js +1 -1
- package/dist/features/notifications/react/components/NotificationsTab.js +7 -7
- package/dist/features/notifications/types.d.ts +1 -1
- package/dist/features/observability/boot-timing.js +2 -2
- package/dist/features/observability/stuck-run.js +1 -1
- package/dist/features/observability/white-screen.js +4 -4
- package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +35 -0
- package/dist/features/panel-kit/fetch-query/adapter.react.js +122 -0
- package/dist/features/panel-kit/fetch-query/cache.d.ts +123 -0
- package/dist/features/panel-kit/fetch-query/cache.js +231 -0
- package/dist/features/panel-kit/fetch-query/environment.browser.d.ts +4 -0
- package/dist/features/panel-kit/fetch-query/environment.browser.js +25 -0
- package/dist/features/panel-kit/fetch-query/index.d.ts +4 -0
- package/dist/features/panel-kit/fetch-query/index.js +2 -0
- package/dist/features/panel-kit/fetch-query/types.d.ts +91 -0
- package/dist/features/panel-kit/fetch-query/types.js +2 -0
- package/dist/features/panel-kit/helpers/format-timestamp.d.ts +18 -0
- package/dist/features/panel-kit/helpers/format-timestamp.js +20 -0
- package/dist/features/panel-kit/helpers/permissions.d.ts +11 -0
- package/dist/features/panel-kit/helpers/permissions.js +10 -0
- package/dist/features/panel-kit/helpers/resolve-active-tab-id.d.ts +13 -0
- package/dist/features/panel-kit/helpers/resolve-active-tab-id.js +13 -0
- package/dist/features/panel-kit/helpers/retry-unreachable.d.ts +20 -0
- package/dist/features/panel-kit/helpers/retry-unreachable.js +39 -0
- package/dist/features/panel-kit/hooks/use-async-action.hooks.d.ts +13 -0
- package/dist/features/panel-kit/hooks/use-async-action.hooks.js +27 -0
- package/dist/features/panel-kit/hooks/use-dirty-guard.hooks.d.ts +18 -0
- package/dist/features/panel-kit/hooks/use-dirty-guard.hooks.js +33 -0
- package/dist/features/panel-kit/hooks/use-focus-trap.hooks.d.ts +8 -0
- package/dist/features/panel-kit/hooks/use-focus-trap.hooks.js +66 -0
- package/dist/features/panel-kit/hooks/use-serial-writes.hooks.d.ts +26 -0
- package/dist/features/panel-kit/hooks/use-serial-writes.hooks.js +41 -0
- package/dist/features/panel-kit/hooks/use-settlement-generation.hooks.d.ts +9 -0
- package/dist/features/panel-kit/hooks/use-settlement-generation.hooks.js +25 -0
- package/dist/features/panel-kit/index.d.ts +19 -0
- package/dist/features/panel-kit/index.js +13 -0
- package/dist/features/privacy/react/components/PrivacyTab.js +2 -2
- package/dist/features/privacy/types.d.ts +1 -1
- package/dist/features/privacy/types.js +1 -1
- package/dist/features/progress-card/reference-adapters.d.ts +1 -1
- package/dist/features/progress-card/rules.d.ts +1 -1
- package/dist/features/progress-card/rules.js +1 -1
- package/dist/features/progress-card/types.d.ts +1 -1
- package/dist/features/progress-card/types.js +1 -1
- package/dist/features/resource-dashboard/dependencies.d.ts +1 -1
- package/dist/features/resource-dashboard/ports.d.ts +1 -1
- package/dist/features/resource-dashboard/react/hooks/useResourceBoard.d.ts +1 -1
- package/dist/features/resource-dashboard/react/hooks/useResourceBoard.js +1 -1
- package/dist/features/resource-dashboard/rules.d.ts +1 -1
- package/dist/features/resource-dashboard/rules.js +2 -2
- package/dist/features/resource-dashboard/types.d.ts +4 -4
- package/dist/features/resource-dashboard/types.js +1 -1
- package/dist/features/schedule-picker/react/hooks/useRecurringSchedulePicker.js +1 -1
- package/dist/features/settings/dialog/styles/settings-dialog.css +62 -60
- package/dist/features/sketch-editor/constants.d.ts +1 -1
- package/dist/features/sketch-editor/constants.js +1 -1
- package/dist/features/sketch-editor/dom.d.ts +1 -1
- package/dist/features/sketch-editor/dom.js +1 -1
- package/dist/features/sketch-editor/react/hooks/useSketchDomEnhancements.d.ts +1 -1
- package/dist/features/sketch-editor/react/hooks/useSketchDomEnhancements.js +11 -9
- package/dist/features/sketch-editor/types.d.ts +1 -1
- package/dist/features/sketch-editor/types.js +1 -1
- package/dist/features/skills/react/components/SkillDraftForm.js +1 -1
- package/dist/features/skills/react/components/SkillRow.js +1 -1
- package/dist/features/skills/react/components/SkillsTab.js +2 -2
- package/dist/features/source-config-list/agent-handles.js +2 -2
- package/dist/features/source-config-list/react/hooks/useSourceConfigAddForm.d.ts +1 -1
- package/dist/features/source-config-list/react/hooks/useSourceConfigAddForm.js +1 -1
- package/dist/features/source-config-list/rules.d.ts +1 -1
- package/dist/features/source-config-list/rules.js +3 -3
- package/dist/features/source-config-list/types.d.ts +1 -1
- package/dist/features/source-config-list/types.js +1 -1
- package/dist/features/tab-launcher-menu/react/hooks/useTabLauncherMenu.js +1 -1
- package/dist/features/tab-strip/index.d.ts +4 -0
- package/dist/features/tab-strip/index.js +2 -0
- package/dist/features/tab-strip/react/components/TabBar.d.ts +23 -0
- package/dist/features/tab-strip/react/components/TabBar.hooks.d.ts +25 -0
- package/dist/features/tab-strip/react/components/TabBar.hooks.js +57 -0
- package/dist/features/tab-strip/react/components/TabBar.js +18 -0
- package/dist/features/tab-strip/react/components/TabStrip.js +2 -1
- package/dist/features/tab-strip/react/components/TabStripFrame.d.ts +3 -0
- package/dist/features/tab-strip/react/components/TabStripFrame.js +7 -0
- package/dist/features/tabbed-dialog/react/hooks/useTabbedDialog.js +1 -1
- package/dist/features/tabbed-dialog/styles/tabbed-dialog.css +8 -141
- package/dist/features/tabbed-dialog/types.d.ts +1 -1
- package/dist/features/tabbed-dialog/types.js +1 -1
- package/dist/features/version-manager/ports.d.ts +1 -1
- package/dist/features/version-manager/react/components/VersionPromptPopover.js +5 -3
- package/dist/features/version-manager/react/components/VersionRestoreControl.js +1 -1
- package/dist/features/version-manager/types.d.ts +1 -1
- package/dist/features/version-manager/types.js +1 -1
- package/dist/features/viewer-shell/dependencies.js +1 -1
- package/dist/features/viewer-shell/ports.d.ts +1 -1
- package/dist/features/viewer-shell/react/components/ViewportSwitcher.js +1 -1
- package/dist/features/viewer-shell/react/hooks/useMarkdownScrollSync.d.ts +1 -1
- package/dist/features/viewer-shell/react/hooks/useMarkdownScrollSync.js +1 -1
- package/dist/features/viewer-shell/types.d.ts +1 -1
- package/dist/features/viewer-shell/types.js +1 -1
- package/dist/index.d.ts +420 -0
- package/dist/index.js +421 -1
- package/dist/react/components/ComponentKitPreview.js +1 -1
- package/dist/react/components/EditorIcon.d.ts +1 -1
- package/dist/react/components/EditorIcon.js +22 -22
- package/dist/react/components/ExportDiagnosticsButton.d.ts +8 -1
- package/dist/react/components/ExportDiagnosticsButton.js +6 -6
- package/dist/react/components/PaletteTweaks.js +5 -5
- package/dist/react/hooks/useBrandFonts.d.ts +19 -4
- package/dist/react/hooks/useBrandFonts.js +11 -7
- package/dist/react/hooks/useDebouncedValue.d.ts +12 -1
- package/dist/react/hooks/useDebouncedValue.js +9 -4
- package/dist/react/hooks/useStableHandler.d.ts +3 -1
- package/dist/react/hooks/useStableHandler.js +1 -1
- package/dist/renderers/annotation-canvas/drawing.d.ts +4 -4
- package/dist/renderers/annotation-canvas/drawing.js +28 -15
- package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +2 -2
- package/dist/renderers/annotation-canvas/react/hooks/useAnnotationCanvas.js +4 -3
- package/dist/renderers/annotation-canvas/rules.d.ts +1 -1
- package/dist/renderers/annotation-canvas/theme.d.ts +13 -0
- package/dist/renderers/annotation-canvas/theme.js +16 -0
- package/dist/renderers/annotation-canvas/types.d.ts +1 -1
- package/dist/renderers/index.d.ts +1 -1
- package/dist/renderers/new-tab-preview.d.ts +3 -0
- package/dist/renderers/new-tab-preview.js +3 -1
- package/dist/renderers/preview-modal-shell/react/hooks/usePreviewModalShell.d.ts +1 -1
- package/dist/renderers/preview-modal-shell/react/hooks/usePreviewModalShell.js +1 -1
- package/dist/renderers/preview-modal-shell/rules.d.ts +1 -1
- package/dist/renderers/preview-modal-shell/types.d.ts +3 -3
- package/dist/renderers/preview-modal-shell/types.js +2 -2
- package/dist/renderers/react/components/ArtifactView.d.ts +1 -1
- package/dist/renderers/react/components/ArtifactView.js +1 -1
- package/dist/renderers/registry.d.ts +12 -6
- package/dist/renderers/registry.js +7 -9
- package/dist/renderers/renderers/html.js +2 -2
- package/dist/renderers/renderers/index.js +1 -1
- package/dist/renderers/renderers/markdown.js +2 -2
- package/dist/renderers/renderers/react-component.js +1 -1
- package/dist/renderers/renderers/svg.js +1 -1
- package/dist/renderers/shiki.js +1 -1
- package/dist/renderers/srcdoc/build.d.ts +1 -1
- package/dist/renderers/srcdoc/build.js +1 -1
- package/dist/renderers/url-load-decision.d.ts +1 -1
- package/dist/renderers/url-load-decision.js +1 -1
- package/dist/styles/admin.css +273 -0
- package/dist/styles/variables.css +117 -0
- package/dist/theme/apply.d.ts +9 -0
- package/dist/theme/apply.js +77 -0
- package/dist/theme/color-scheme.d.ts +8 -0
- package/dist/theme/color-scheme.js +9 -0
- package/dist/theme/default.d.ts +4 -0
- package/dist/theme/default.js +11 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/stylesheet.d.ts +8 -0
- package/dist/theme/stylesheet.js +14 -0
- package/dist/theme/types.d.ts +39 -0
- package/dist/theme/types.js +2 -0
- package/dist/theme/validation.d.ts +15 -0
- package/dist/theme/validation.js +55 -0
- package/dist/utils/appearance.js +1 -1
- package/dist/utils/browser-request.d.ts +12 -0
- package/dist/utils/browser-request.js +10 -0
- package/dist/utils/color-math.d.ts +20 -6
- package/dist/utils/color-math.js +12 -12
- package/dist/utils/copy-to-clipboard.d.ts +19 -8
- package/dist/utils/copy-to-clipboard.js +15 -11
- package/dist/utils/dom-subscriptions.js +1 -1
- package/dist/utils/endpoint-policy.d.ts +9 -3
- package/dist/utils/endpoint-policy.js +5 -5
- package/dist/utils/markdown-scroll-sync.js +3 -3
- package/dist/utils/notifications.d.ts +1 -1
- package/dist/utils/notifications.js +1 -1
- package/dist/utils/polygon-selection.d.ts +1 -1
- package/dist/utils/polygon-selection.js +1 -1
- package/dist/utils/scroll-tabs-with-wheel.d.ts +4 -1
- package/dist/utils/scroll-tabs-with-wheel.js +1 -1
- package/dist/utils/smooth-scroll-to-top.js +1 -1
- package/dist/utils/sse.d.ts +3 -1
- package/dist/utils/sse.js +1 -1
- package/package.json +105 -16
- package/dist/features/lexical-rich-text-editor/react/test-support/lexical-harness.d.ts +0 -11
- package/dist/features/lexical-rich-text-editor/react/test-support/lexical-harness.js +0 -35
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* API shape — this is a generic JSON/REST contract with no vendor coupling,
|
|
13
13
|
* and the pinned source's one open bug (`fetchMemoryList()` trusting an
|
|
14
14
|
* under-validated response — see the fix below and
|
|
15
|
-
* `packages/ui/
|
|
15
|
+
* `packages/ui/archived provenance ledger`) only exists to fix in a real, testable
|
|
16
16
|
* adapter. A host is still free to supply its own binding; this default
|
|
17
17
|
* just isn't a fake.
|
|
18
18
|
* - `memoryConnectorsPort` binds a fake/in-memory connector catalogue (same
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* cluster uses — saving a connector suggestion is an ordinary memory write,
|
|
26
26
|
* not a connector-transport concern.
|
|
27
27
|
*/
|
|
28
|
-
import {
|
|
28
|
+
import { requestWithTimeout } from '../../utils/browser-request.js';
|
|
29
29
|
import { DEFAULT_CONNECTOR_PROVIDER, MEMORY_CONNECTOR_PENDING_AUTH_STORAGE_KEY, } from './constants.js';
|
|
30
30
|
// ─── Shared response-field validators ───────────────────────────────────────
|
|
31
31
|
//
|
|
@@ -52,110 +52,120 @@ function requiredNonNullField(json, field, context) {
|
|
|
52
52
|
}
|
|
53
53
|
return value;
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
55
|
+
/** Build the real REST ports with one native fetch binding; defaults remain browser-owned. */
|
|
56
|
+
export function createMemoryHttpPorts(_required, { fetch } = {}) {
|
|
57
|
+
function request(url, init, { timeoutMs }) {
|
|
58
|
+
return requestWithTimeout({ url, timeoutMs }, { ...(fetch === undefined ? {} : { fetch }), init });
|
|
59
|
+
}
|
|
60
|
+
// ─── Config cluster (real HTTP) ─────────────────────────────────────────────
|
|
61
|
+
async function patchMemoryConfig(patch) {
|
|
62
|
+
const resp = await request('/api/memory/config', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(patch) }, { timeoutMs: 15_000 });
|
|
63
|
+
return resp.ok;
|
|
64
|
+
}
|
|
65
|
+
const memoryConfigPort = {
|
|
66
|
+
patchConfig: patchMemoryConfig,
|
|
67
|
+
};
|
|
68
|
+
// ─── Entries/index cluster (real HTTP) ──────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* `entries` drives the saved-memory list; `rootDir`/`index`/`enabled` are
|
|
71
|
+
* consumed directly (no fallback) by `useMemoryEntries.reload()` and
|
|
72
|
+
* `useMemoryConfig.hydrate()`.
|
|
73
|
+
*
|
|
74
|
+
* BUG FIX (ported from the pinned source with this fix applied — see
|
|
75
|
+
* `packages/ui/archived provenance ledger`): the pinned source validated only `entries`
|
|
76
|
+
* here, even though `hydrate()`/`reload()` read `enabled`/`rootDir`/`index`
|
|
77
|
+
* off this same response with no fallback. A malformed `200` like
|
|
78
|
+
* `{ entries: [] }` passed validation and then silently hydrated those other
|
|
79
|
+
* fields to `undefined`. Fixed the same way `fetchMemoryEntry()` below
|
|
80
|
+
* already handles a missing required field: validate every field this
|
|
81
|
+
* shared read path's callers actually trust unconditionally, and throw
|
|
82
|
+
* instead of returning a response that looks like a legitimate empty state.
|
|
83
|
+
* The four per-hook flags are deliberately NOT added to this list — they
|
|
84
|
+
* keep their own established legacy-default semantics in `hydrate()`
|
|
85
|
+
* (`list.xEnabled !== false`), so their absence is intentionally not a
|
|
86
|
+
* transport failure.
|
|
87
|
+
*/
|
|
88
|
+
async function fetchMemoryList() {
|
|
89
|
+
const resp = await request('/api/memory', {}, { timeoutMs: 15_000 });
|
|
90
|
+
if (!resp.ok)
|
|
91
|
+
throw new Error(`Memory list request failed (${resp.status})`);
|
|
92
|
+
const json = (await resp.json());
|
|
93
|
+
requiredField(json, 'entries', 'Memory list request');
|
|
94
|
+
requiredField(json, 'rootDir', 'Memory list request');
|
|
95
|
+
requiredField(json, 'index', 'Memory list request');
|
|
96
|
+
requiredField(json, 'enabled', 'Memory list request');
|
|
97
|
+
return json;
|
|
98
|
+
}
|
|
99
|
+
async function fetchMemoryTree() {
|
|
100
|
+
const resp = await request('/api/memory/tree', {}, { timeoutMs: 15_000 });
|
|
101
|
+
if (!resp.ok)
|
|
102
|
+
throw new Error(`Memory tree request failed (${resp.status})`);
|
|
103
|
+
const json = (await resp.json());
|
|
104
|
+
return requiredField(json, 'tree', 'Memory tree request');
|
|
105
|
+
}
|
|
106
|
+
async function fetchMemoryEntry(id) {
|
|
107
|
+
const resp = await request(`/api/memory/${encodeURIComponent(id)}`, {}, { timeoutMs: 15_000 });
|
|
108
|
+
// Only a genuine not-found maps to null. A 5xx or other transport failure
|
|
109
|
+
// is not "this entry doesn't exist" — collapsing both into null would let
|
|
110
|
+
// the caller silently render an empty preview or a no-op edit for what is
|
|
111
|
+
// actually a required read that failed.
|
|
112
|
+
if (resp.status === 404)
|
|
113
|
+
return null;
|
|
114
|
+
if (!resp.ok)
|
|
115
|
+
throw new Error(`Memory entry request failed (${resp.status})`);
|
|
116
|
+
const json = (await resp.json());
|
|
117
|
+
return requiredNonNullField(json, 'entry', 'Memory entry request');
|
|
118
|
+
}
|
|
119
|
+
async function saveMemoryEntry(draft) {
|
|
120
|
+
const url = draft.id ? `/api/memory/${encodeURIComponent(draft.id)}` : '/api/memory';
|
|
121
|
+
const resp = await request(url, { method: draft.id ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(draft) }, { timeoutMs: 15_000 });
|
|
122
|
+
if (!resp.ok)
|
|
123
|
+
return null;
|
|
124
|
+
const json = (await resp.json());
|
|
125
|
+
return requiredNonNullField(json, 'entry', 'Memory entry save');
|
|
126
|
+
}
|
|
127
|
+
async function deleteMemoryEntry(id) {
|
|
128
|
+
const resp = await request(`/api/memory/${encodeURIComponent(id)}`, { method: 'DELETE' }, { timeoutMs: 15_000 });
|
|
129
|
+
return resp.ok;
|
|
130
|
+
}
|
|
131
|
+
async function saveMemoryIndex(index) {
|
|
132
|
+
const resp = await request('/api/memory/index', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ index }) }, { timeoutMs: 15_000 });
|
|
133
|
+
return resp.ok;
|
|
134
|
+
}
|
|
135
|
+
const memoryEntriesPort = {
|
|
136
|
+
fetchMemoryList,
|
|
137
|
+
fetchMemoryTree,
|
|
138
|
+
fetchMemoryEntry,
|
|
139
|
+
saveMemoryEntry,
|
|
140
|
+
deleteMemoryEntry,
|
|
141
|
+
saveMemoryIndex,
|
|
142
|
+
};
|
|
143
|
+
// ─── Extraction history cluster (real HTTP) ─────────────────────────────────
|
|
144
|
+
async function fetchExtractions() {
|
|
145
|
+
const resp = await request('/api/memory/extractions', {}, { timeoutMs: 15_000 });
|
|
146
|
+
if (!resp.ok)
|
|
147
|
+
throw new Error(`Memory extractions request failed (${resp.status})`);
|
|
148
|
+
const json = (await resp.json());
|
|
149
|
+
return requiredField(json, 'extractions', 'Memory extractions request');
|
|
150
|
+
}
|
|
151
|
+
async function deleteExtraction(id) {
|
|
152
|
+
const resp = await request(`/api/memory/extractions/${encodeURIComponent(id)}`, { method: 'DELETE' }, { timeoutMs: 15_000 });
|
|
153
|
+
return resp.ok;
|
|
154
|
+
}
|
|
155
|
+
async function clearExtractionHistory() {
|
|
156
|
+
const resp = await request('/api/memory/extractions', { method: 'DELETE' }, { timeoutMs: 15_000 });
|
|
157
|
+
return resp.ok;
|
|
158
|
+
}
|
|
159
|
+
const memoryExtractionsPort = {
|
|
160
|
+
fetchExtractions,
|
|
161
|
+
deleteExtraction,
|
|
162
|
+
clearExtractionHistory,
|
|
163
|
+
};
|
|
164
|
+
return { config: memoryConfigPort, entries: memoryEntriesPort, extractions: memoryExtractionsPort };
|
|
153
165
|
}
|
|
154
|
-
export const memoryExtractionsPort = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
clearExtractionHistory,
|
|
158
|
-
};
|
|
166
|
+
export const { config: memoryConfigPort, entries: memoryEntriesPort, extractions: memoryExtractionsPort } = createMemoryHttpPorts({});
|
|
167
|
+
/** Standalone default read shares the entries port's validated REST implementation. */
|
|
168
|
+
export const fetchMemoryList = memoryEntriesPort.fetchMemoryList;
|
|
159
169
|
/**
|
|
160
170
|
* An in-memory test/demo double for the connector-catalogue transport (same
|
|
161
171
|
* rationale as `features/connectors`' own `createFakeConnectorsPort`). Real
|
|
@@ -197,7 +207,7 @@ export function createFakeMemoryConnectorsPort(options = {}) {
|
|
|
197
207
|
suggestConnectorMemories() {
|
|
198
208
|
return delay(options.suggestionResponse ?? null);
|
|
199
209
|
},
|
|
200
|
-
saveMemoryEntry,
|
|
210
|
+
saveMemoryEntry: memoryEntriesPort.saveMemoryEntry,
|
|
201
211
|
readPendingConnectorAuthIds: readPendingConnectorAuthIdsFromSession,
|
|
202
212
|
writePendingConnectorAuthIds: writePendingConnectorAuthIdsToSession,
|
|
203
213
|
notifyConnectorsChanged,
|
|
@@ -5,7 +5,7 @@ export { connectorAttemptDetail, connectorAttemptName, connectorAttemptTitle, de
|
|
|
5
5
|
export type { MemoryConfigPort, MemoryConnectorsPort, MemoryEntriesPort, MemoryExtractionsPort, } from './ports.js';
|
|
6
6
|
export { applyMemoryConnectorStatus, connectorWithPendingAuthorization, enabledPatch, type MemoryConfigFlagKey, memoryEntryIdForConnectorSuggestion, singleFlagPatch, upsertMemoryConnector, visibleExtractionsFor, } from './rules.js';
|
|
7
7
|
export type { ConnectorMemoryAttempt, ConnectorMemoryAttemptStatus, ConnectorMemorySuggestionResponse, DraftEntry, FlashKind, FriendlyExtractionFailure, MemoryEntry, MemoryEntrySummary, MemoryExtractionEvent, MemoryExtractionPhase, MemoryExtractionProvider, MemoryExtractionRecord, MemoryExtractionSkipReason, MemoryExtractionsResponse, MemoryListResponse, MemorySectionProps, MemorySourceTab, MemorySuggestion, MemoryTab, MemoryTreeListResponse, MemoryTreeNode, MemoryTreeNodeKind, MemoryType, UpdateMemoryConfigRequest, UpsertMemoryRequest, } from './types.js';
|
|
8
|
-
export { createFakeMemoryConnectorsPort, fetchMemoryList, memoryConfigPort, memoryConnectorsPort, memoryEntriesPort, memoryExtractionsPort, } from './dependencies.js';
|
|
8
|
+
export { createFakeMemoryConnectorsPort, createMemoryHttpPorts, fetchMemoryList, memoryConfigPort, memoryConnectorsPort, memoryEntriesPort, memoryExtractionsPort, } from './dependencies.js';
|
|
9
9
|
export type { FakeMemoryConnectorsPortOptions } from './dependencies.js';
|
|
10
10
|
export { useMemoryFlash, type MemoryFlashController, } from './react/hooks/useMemoryFlash.hooks.js';
|
|
11
11
|
export { useMemoryNavigation, type MemoryNavigationController, type MemoryTopTab, } from './react/hooks/useMemoryNavigation.hooks.js';
|
|
@@ -3,7 +3,7 @@ export { createAsyncCommitGuard } from './async-commit-guard.js';
|
|
|
3
3
|
export { CONNECTOR_CALLBACK_MESSAGE_TYPE, connectorAppLabel, DEFAULT_CONNECTOR_PROVIDER, EMPTY_DRAFT, MEMORY_CONNECTOR_APP_IDS, MEMORY_CONNECTOR_APP_LABELS, MEMORY_CONNECTOR_PENDING_AUTH_STORAGE_KEY, STARTERS, TYPES, } from './constants.js';
|
|
4
4
|
export { connectorAttemptDetail, connectorAttemptName, connectorAttemptTitle, describeConnectorReadIssue, describeExtractionFailure, describeRecord, extractionCardMeta, extractionCardTitle, formatAbsoluteTime, formatConnectorContextBytes, formatDuration, formatRelativeTime, formatRelativeTimeAgo, memoryCountLabel, memoryFlashLabels, memorySourceTabs, memoryTypeLabels, parseProviderError, providerDisplayName, } from './formatters.js';
|
|
5
5
|
export { applyMemoryConnectorStatus, connectorWithPendingAuthorization, enabledPatch, memoryEntryIdForConnectorSuggestion, singleFlagPatch, upsertMemoryConnector, visibleExtractionsFor, } from './rules.js';
|
|
6
|
-
export { createFakeMemoryConnectorsPort, fetchMemoryList, memoryConfigPort, memoryConnectorsPort, memoryEntriesPort, memoryExtractionsPort, } from './dependencies.js';
|
|
6
|
+
export { createFakeMemoryConnectorsPort, createMemoryHttpPorts, fetchMemoryList, memoryConfigPort, memoryConnectorsPort, memoryEntriesPort, memoryExtractionsPort, } from './dependencies.js';
|
|
7
7
|
export { useMemoryFlash, } from './react/hooks/useMemoryFlash.hooks.js';
|
|
8
8
|
export { useMemoryNavigation, } from './react/hooks/useMemoryNavigation.hooks.js';
|
|
9
9
|
export { useMemoryConfig, useWiredMemoryConfig, } from './react/hooks/useMemoryConfig.hooks.js';
|
|
@@ -16,7 +16,7 @@ export function MemoryAdvancedModal({ open, modalHost, onClose, index, indexDraf
|
|
|
16
16
|
onMouseDown: onClose, children: _jsxs("div", { className: "memory-action-modal memory-action-modal--advanced", role: "dialog", "aria-modal": "true", "aria-labelledby": "memory-advanced-modal-title", onMouseDown: (event) => event.stopPropagation(), children: [_jsxs("div", { className: "memory-action-modal-head", children: [_jsxs("div", { children: [_jsx("h3", { id: "memory-advanced-modal-title", children: t('Advanced') }), _jsx("p", { children: t('Inspect or edit the underlying memory index.') })] }), _jsx("button", { type: "button", className: "memory-action-modal-close", onClick: onClose, "aria-label": t('Close'), title: t('Close'), children: _jsx(Icon, { name: "close", size: 16 }) })] }), _jsxs("div", { className: "memory-action-modal-body memory-advanced-modal-body", children: [_jsx("p", { className: "memory-advanced-hint", children: t('Inspect or edit the underlying memory index.') }), _jsxs("div", { className: "memory-advanced-stack", children: [_jsxs("details", { className: "library-group memory-advanced-card", children: [_jsx("summary", { className: "memory-details-summary", children: _jsx("span", { className: "memory-details-title", children: t('MEMORY.md index') }) }), _jsx("textarea", { value: indexDraft ?? index, onChange: (e) => onIndexDraftChange(e.target.value), rows: 8, style: {
|
|
17
17
|
width: '100%',
|
|
18
18
|
marginTop: 8,
|
|
19
|
-
fontFamily: '
|
|
19
|
+
fontFamily: 'var(--jini-font-mono)',
|
|
20
20
|
} }), _jsxs("div", { style: {
|
|
21
21
|
display: 'flex',
|
|
22
22
|
gap: 8,
|
|
@@ -27,7 +27,7 @@ export function MemoryAdvancedModal({ open, modalHost, onClose, index, indexDraf
|
|
|
27
27
|
}, children: [_jsx("span", { className: "hint", style: {
|
|
28
28
|
fontSize: 11,
|
|
29
29
|
margin: 0,
|
|
30
|
-
color: indexDraft !== null ? 'var(--
|
|
30
|
+
color: indexDraft !== null ? 'var(--jini-warning)' : 'var(--jini-text-muted)',
|
|
31
31
|
fontWeight: indexDraft !== null ? 600 : 400,
|
|
32
32
|
}, children: indexDraft !== null
|
|
33
33
|
? `● ${t('Unsaved changes')} — ${t('Edits here change how memories are indexed.')}`
|
|
@@ -13,6 +13,6 @@ import { useT } from '../../../i18n/index.js';
|
|
|
13
13
|
import { renderMarkdown } from '../render-markdown.js';
|
|
14
14
|
export function MemoryEntryCard({ entry, previewId, previewBody, onOpenPreview, onStartEdit, onDelete, agentHandle, }) {
|
|
15
15
|
const t = useT();
|
|
16
|
-
return (_jsxs("div", { className: "library-card", children: [_jsxs("div", { className: "library-card-info", children: [_jsx("div", { className: "library-card-title-row", children: _jsx("span", { className: "library-card-name", children: entry.name }) }), _jsx("div", { className: "library-card-desc", children: entry.description || '—' })] }), _jsxs("div", { className: "memory-card-actions", children: [_jsx("button", { type: "button", className: "library-card-expand", onClick: () => onOpenPreview(entry.id), title: t('Preview'), ...agentHandleProps(agentHandle, { action: 'preview', role: 'button', label: t('Preview') }), children: _jsx(Icon, { name: previewId === entry.id ? 'chevron-down' : 'chevron-right', size: 14 }) }), _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onStartEdit(entry.id), title: t('Edit'), ...agentHandleProps(agentHandle, { action: 'edit', role: 'button', label: t('Edit') }), children: _jsx(Icon, { name: "edit", size: 14 }) }), _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onDelete(entry.id), title: t('Delete'), ...agentHandleProps(agentHandle, { action: 'delete', role: 'button', label: t('Delete') }), children: _jsx(Icon, { name: "close", size: 14 }) })] }), previewId === entry.id && (_jsx("div", { className: "library-preview", style: { width: '100%' }, children: previewBody === null ? (_jsx("p", { children: t('Loading…') })) : previewBody ? (_jsx("div", { className: "library-preview-body", children: renderMarkdown(previewBody) })) : (_jsx("p", { className: "hint", children: "\u2014" })) }))] }));
|
|
16
|
+
return (_jsxs("div", { className: "library-card", children: [_jsxs("div", { className: "library-card-info", children: [_jsx("div", { className: "library-card-title-row", children: _jsx("span", { className: "library-card-name", children: entry.name }) }), _jsx("div", { className: "library-card-desc", children: entry.description || '—' })] }), _jsxs("div", { className: "memory-card-actions", children: [_jsx("button", { type: "button", className: "library-card-expand", onClick: () => onOpenPreview(entry.id), title: t('Preview'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'preview', role: 'button', label: t('Preview') }) }), children: _jsx(Icon, { name: previewId === entry.id ? 'chevron-down' : 'chevron-right', size: 14 }) }), _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onStartEdit(entry.id), title: t('Edit'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'edit', role: 'button', label: t('Edit') }) }), children: _jsx(Icon, { name: "edit", size: 14 }) }), _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onDelete(entry.id), title: t('Delete'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'delete', role: 'button', label: t('Delete') }) }), children: _jsx(Icon, { name: "close", size: 14 }) })] }), previewId === entry.id && (_jsx("div", { className: "library-preview", style: { width: '100%' }, children: previewBody === null ? (_jsx("p", { children: t('Loading…') })) : previewBody ? (_jsx("div", { className: "library-preview-body", children: renderMarkdown(previewBody) })) : (_jsx("p", { className: "hint", children: "\u2014" })) }))] }));
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=MemoryEntryCard.js.map
|
|
@@ -16,6 +16,6 @@ export function MemoryExtractionCard({ record, nowClock, onOpenPreview, onDelete
|
|
|
16
16
|
// the record didn't fail), so we render off its result directly instead of
|
|
17
17
|
// duplicating that guard here.
|
|
18
18
|
const failure = describeExtractionFailure(record);
|
|
19
|
-
return (_jsxs("div", { className: `library-card memory-extraction-card is-${desc.tone}`, children: [_jsxs("div", { className: "library-card-info", children: [_jsxs("div", { className: "library-card-title-row", children: [_jsx("span", { className: "library-card-name", children: title }), _jsx("span", { className: `memory-extraction-pill is-${desc.tone}`, children: desc.phaseLabel }), _jsx("span", { className: "library-card-badge", children: desc.kindLabel })] }), _jsx("div", { className: "library-card-desc", children: meta }), desc.reasonLabel ? _jsx("div", { className: "memory-extraction-reason", children: desc.reasonLabel }) : null, failure ? (_jsxs("div", { className: "memory-extraction-failure", children: [_jsx("strong", { children: failure.title }), _jsx("span", { children: failure.detail }), _jsx("span", { children: failure.action })] })) : null, Array.isArray(record.writtenIds) && record.writtenIds.length > 0 ? (_jsxs("div", { className: "memory-extraction-counts", children: [_jsx("span", { children: t('saved') }), _jsx("span", { className: "memory-extraction-ids", children: record.writtenIds.map((id) => (_jsx("button", { type: "button", className: "filter-pill", onClick: () => onOpenPreview(id), title: id, children: id }, id))) })] })) : null] }), _jsx("div", { className: "memory-card-actions", children: _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onDelete(record.id), title: t('Remove'), "aria-label": t('Remove'), ...agentHandleProps(agentHandle, { action: 'delete', role: 'button', label: t('Remove') }), children: _jsx(Icon, { name: "close", size: 14 }) }) })] }));
|
|
19
|
+
return (_jsxs("div", { className: `library-card memory-extraction-card is-${desc.tone}`, children: [_jsxs("div", { className: "library-card-info", children: [_jsxs("div", { className: "library-card-title-row", children: [_jsx("span", { className: "library-card-name", children: title }), _jsx("span", { className: `memory-extraction-pill is-${desc.tone}`, children: desc.phaseLabel }), _jsx("span", { className: "library-card-badge", children: desc.kindLabel })] }), _jsx("div", { className: "library-card-desc", children: meta }), desc.reasonLabel ? _jsx("div", { className: "memory-extraction-reason", children: desc.reasonLabel }) : null, failure ? (_jsxs("div", { className: "memory-extraction-failure", children: [_jsx("strong", { children: failure.title }), _jsx("span", { children: failure.detail }), _jsx("span", { children: failure.action })] })) : null, Array.isArray(record.writtenIds) && record.writtenIds.length > 0 ? (_jsxs("div", { className: "memory-extraction-counts", children: [_jsx("span", { children: t('saved') }), _jsx("span", { className: "memory-extraction-ids", children: record.writtenIds.map((id) => (_jsx("button", { type: "button", className: "filter-pill", onClick: () => onOpenPreview(id), title: id, children: id }, id))) })] })) : null] }), _jsx("div", { className: "memory-card-actions", children: _jsx("button", { type: "button", className: "ghost library-card-action", onClick: () => onDelete(record.id), title: t('Remove'), "aria-label": t('Remove'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'delete', role: 'button', label: t('Remove') }) }), children: _jsx(Icon, { name: "close", size: 14 }) }) })] }));
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=MemoryExtractionCard.js.map
|
|
@@ -48,6 +48,6 @@ const HOOKS = [
|
|
|
48
48
|
];
|
|
49
49
|
export function MemoryHooksPanel({ enabled, flags, onToggle, agentHandle, }) {
|
|
50
50
|
const t = useT();
|
|
51
|
-
return (_jsxs("div", { className: "memory-hooks-panel", "data-testid": "memory-hooks-panel", children: [_jsxs("div", { className: "memory-hooks-panel-head", children: [_jsx("span", { className: "memory-hooks-panel-head-icon", "aria-hidden": "true", children: _jsx(Icon, { name: "sliders", size: 15 }) }), _jsxs("div", { children: [_jsx("h4", { className: "memory-hooks-panel-title", children: t('Memory hooks') }), _jsx("p", { className: "memory-hooks-panel-hint", children: t('Fine-tune how memory is captured and used, without turning it off entirely.') })] })] }), _jsx("ul", { className: "memory-hooks-panel-list", children: HOOKS.map((hook) => (_jsxs("li", { className: "memory-hooks-panel-row", children: [_jsx("span", { className: "memory-hooks-panel-row-icon", "aria-hidden": "true", children: _jsx(Icon, { name: hook.icon, size: 14 }) }), _jsxs("span", { className: "memory-hooks-panel-row-copy", children: [_jsx("span", { className: "memory-hooks-panel-row-label", children: t(hook.label) }), _jsx("small", { className: "memory-hooks-panel-row-desc", children: t(hook.description) })] }), _jsx("label", { className: "memory-hooks-panel-toggle", title: t(hook.label), children: _jsxs("span", { className: "toggle-switch toggle-switch-sm", children: [_jsx("input", { type: "checkbox", "aria-label": t(hook.label), checked: flags[hook.key], disabled: !enabled, onChange: (e) => onToggle(hook.key, e.target.checked), ...agentHandleProps(agentHandle, { action: `hook-${hook.action}`, role: 'checkbox', label: t(hook.label) }) }), _jsx("span", { className: "toggle-slider" })] }) })] }, hook.key))) })] }));
|
|
51
|
+
return (_jsxs("div", { className: "memory-hooks-panel", "data-testid": "memory-hooks-panel", children: [_jsxs("div", { className: "memory-hooks-panel-head", children: [_jsx("span", { className: "memory-hooks-panel-head-icon", "aria-hidden": "true", children: _jsx(Icon, { name: "sliders", size: 15 }) }), _jsxs("div", { children: [_jsx("h4", { className: "memory-hooks-panel-title", children: t('Memory hooks') }), _jsx("p", { className: "memory-hooks-panel-hint", children: t('Fine-tune how memory is captured and used, without turning it off entirely.') })] })] }), _jsx("ul", { className: "memory-hooks-panel-list", children: HOOKS.map((hook) => (_jsxs("li", { className: "memory-hooks-panel-row", children: [_jsx("span", { className: "memory-hooks-panel-row-icon", "aria-hidden": "true", children: _jsx(Icon, { name: hook.icon, size: 14 }) }), _jsxs("span", { className: "memory-hooks-panel-row-copy", children: [_jsx("span", { className: "memory-hooks-panel-row-label", children: t(hook.label) }), _jsx("small", { className: "memory-hooks-panel-row-desc", children: t(hook.description) })] }), _jsx("label", { className: "memory-hooks-panel-toggle", title: t(hook.label), children: _jsxs("span", { className: "toggle-switch toggle-switch-sm", children: [_jsx("input", { type: "checkbox", "aria-label": t(hook.label), checked: flags[hook.key], disabled: !enabled, onChange: (e) => onToggle(hook.key, e.target.checked), ...agentHandleProps({}, { base: agentHandle, ...({ action: `hook-${hook.action}`, role: 'checkbox', label: t(hook.label) }) }) }), _jsx("span", { className: "toggle-slider" })] }) })] }, hook.key))) })] }));
|
|
52
52
|
}
|
|
53
53
|
//# sourceMappingURL=MemoryHooksPanel.js.map
|
|
@@ -15,17 +15,17 @@ export function MemoryList({ sectionRef, entries, filtered, visibleExtractions,
|
|
|
15
15
|
const t = useT();
|
|
16
16
|
const typeLabel = useMemo(() => memoryTypeLabels(t), [t]);
|
|
17
17
|
const entryHandles = agentHandle
|
|
18
|
-
? buildAgentListHandles(agentSubHandle(agentHandle, 'entry'), filtered.map((e) => e.id))
|
|
18
|
+
? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'entry' }), ids: filtered.map((e) => e.id) })
|
|
19
19
|
: undefined;
|
|
20
20
|
const extractionHandles = agentHandle
|
|
21
|
-
? buildAgentListHandles(agentSubHandle(agentHandle, 'extraction'), visibleExtractions.map((r) => r.id))
|
|
21
|
+
? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'extraction' }), ids: visibleExtractions.map((r) => r.id) })
|
|
22
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(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) => {
|
|
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
24
|
const count = entries.filter((e) => e.type === type).length;
|
|
25
25
|
if (count === 0 && filter !== type)
|
|
26
26
|
return null;
|
|
27
|
-
return (_jsxs("button", { type: "button", className: `filter-pill${filter === type ? ' active' : ''}`, onClick: () => onFilterChange(type), ...agentHandleProps(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(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(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 ? (
|
|
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
29
|
// Empty state: one clear "no rows yet" line and a one-sentence
|
|
30
30
|
// primer that explains the mechanism (talk in chat, fact gets
|
|
31
31
|
// extracted) with a single example.
|
|
@@ -18,8 +18,8 @@ export function MemoryManualEditor({ editing, onEditingChange, onStartNew, onCan
|
|
|
18
18
|
alignItems: 'stretch',
|
|
19
19
|
gap: 14,
|
|
20
20
|
padding: 14,
|
|
21
|
-
background: 'var(--
|
|
22
|
-
border: '1px solid var(--border-
|
|
21
|
+
background: 'var(--jini-bg-subtle)',
|
|
22
|
+
border: '1px solid var(--jini-border-soft)',
|
|
23
23
|
borderRadius: 10,
|
|
24
24
|
}, children: [!editing.id ? (_jsxs("div", { style: {
|
|
25
25
|
display: 'flex',
|
|
@@ -27,7 +27,7 @@ export function MemoryManualEditor({ editing, onEditingChange, onStartNew, onCan
|
|
|
27
27
|
alignItems: 'center',
|
|
28
28
|
gap: 6,
|
|
29
29
|
paddingBottom: 10,
|
|
30
|
-
borderBottom: '1px solid var(--border-
|
|
30
|
+
borderBottom: '1px solid var(--jini-border-soft)',
|
|
31
31
|
}, children: [_jsx("span", { style: {
|
|
32
32
|
...FIELD_LABEL_STYLE,
|
|
33
33
|
display: 'inline-block',
|
|
@@ -46,7 +46,7 @@ export function MemoryManualEditor({ editing, onEditingChange, onStartNew, onCan
|
|
|
46
46
|
width: '100%',
|
|
47
47
|
}, children: [_jsxs("div", { style: { display: 'flex', gap: 10, alignItems: 'flex-end' }, children: [_jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("label", { style: FIELD_LABEL_STYLE, children: t('Name') }), _jsx("input", { ref: editorNameRef, type: "text", placeholder: t('e.g. Prefers dark mode'), value: editing.name, onChange: (e) => onEditingChange({ ...editing, name: e.target.value }), style: { width: '100%' } })] }), _jsxs("div", { style: { flex: '0 0 auto', minWidth: 120 }, children: [_jsx("label", { style: FIELD_LABEL_STYLE, children: t('Type') }), _jsx("select", { value: editing.type, onChange: (e) => onEditingChange({ ...editing, type: e.target.value }), style: { width: '100%' }, children: TYPES.map((tt) => (_jsx("option", { value: tt, children: typeLabel[tt] }, tt))) })] })] }), _jsxs("div", { children: [_jsx("label", { style: FIELD_LABEL_STYLE, children: t('Description') }), _jsx("input", { type: "text", placeholder: t('Short description'), value: editing.description, onChange: (e) => onEditingChange({ ...editing, description: e.target.value }), style: { width: '100%' } })] }), _jsxs("div", { children: [_jsx("label", { style: FIELD_LABEL_STYLE, children: t('Details') }), _jsx("textarea", { placeholder: t('What should the assistant remember?'), value: editing.body, onChange: (e) => onEditingChange({ ...editing, body: e.target.value }), rows: 7, style: {
|
|
48
48
|
width: '100%',
|
|
49
|
-
fontFamily: '
|
|
49
|
+
fontFamily: 'var(--jini-font-mono)',
|
|
50
50
|
fontSize: 12,
|
|
51
51
|
lineHeight: 1.5,
|
|
52
52
|
} }), _jsx("p", { className: "hint", style: { fontSize: 11, marginTop: 4 }, children: t('Plain text or Markdown. Keep it concise — this is added to future chat context.') })] })] }), _jsxs("div", { style: {
|
|
@@ -58,7 +58,7 @@ export function MemoryManualEditor({ editing, onEditingChange, onStartNew, onCan
|
|
|
58
58
|
}, children: [_jsx("span", { className: "hint", style: {
|
|
59
59
|
fontSize: 11,
|
|
60
60
|
margin: 0,
|
|
61
|
-
color: 'var(--text-muted
|
|
61
|
+
color: 'var(--jini-text-muted)',
|
|
62
62
|
}, children: t('Saved memories are available to future chats.') }), _jsxs("div", { style: { display: 'flex', gap: 8 }, children: [_jsx("button", { type: "button", className: "ghost", onClick: onCancel, children: t('Cancel') }), _jsx("button", { type: "button", className: "primary", onClick: onSave, disabled: busy || !editing.name.trim(), children: editing.id ? t('Save') : t('Create') })] })] })] })) : null] }));
|
|
63
63
|
}
|
|
64
64
|
//# sourceMappingURL=MemoryManualEditor.js.map
|
|
@@ -26,6 +26,6 @@ export function MemorySettingsPanel({ enabled, onToggleEnabled, topTab, onTopTab
|
|
|
26
26
|
// Scroll target for the saved-memory section; nothing outside this panel
|
|
27
27
|
// needs to reach it, so it's owned here rather than threaded through props.
|
|
28
28
|
const sectionRef = useRef(null);
|
|
29
|
-
return (_jsxs("div", { className: "memory-settings-panel", children: [_jsxs("section", { className: "memory-panel-head-card", children: [_jsxs("div", { className: "memory-panel-head-copy", children: [_jsx("h4", { children: t('Memory') }), _jsx("p", { className: "hint", children: t('Control whether saved facts, preferences, and project context are reused in future chats.') })] }), _jsxs("div", { className: "memory-panel-head-controls", children: [_jsxs("div", { className: "jini-seg-control memory-panel-seg", role: "tablist", "aria-label": t('Memory view'), style: { '--seg-cols': 2 }, children: [_jsx("button", { type: "button", role: "tab", "aria-selected": topTab === 'memories', className: 'jini-seg-btn' + (topTab === 'memories' ? ' active' : ''), onClick: () => onTopTabChange('memories'), ...agentHandleProps(agentHandle, { action: 'view-memories', role: 'button', label: t('Memories') }), children: _jsx("span", { className: "jini-seg-title", children: t('Memories') }) }), _jsx("button", { type: "button", role: "tab", "aria-selected": topTab === 'how', className: 'jini-seg-btn' + (topTab === 'how' ? ' active' : ''), onClick: () => onTopTabChange('how'), ...agentHandleProps(agentHandle, { action: 'view-how', role: 'button', label: t('How it works') }), children: _jsx("span", { className: "jini-seg-title", children: t('How it works') }) })] }), _jsx("button", { type: "button", className: "memory-icon-btn", onClick: onAdd, disabled: !onAdd, "aria-label": t('Add memory'), title: t('Add memory'), ...agentHandleProps(agentHandle, { action: 'add', role: 'button', label: t('Add memory') }), children: _jsx(Icon, { name: "plus", size: 14 }) }), _jsx("button", { type: "button", className: "memory-icon-btn", onClick: onOpenAdvanced, disabled: !onOpenAdvanced, "aria-label": t('Advanced'), title: t('Advanced'), ...agentHandleProps(agentHandle, { action: 'advanced', role: 'button', label: t('Advanced') }), children: _jsx(Icon, { name: "settings", size: 14 }) }), _jsxs("label", { className: "toggle-switch memory-panel-master-toggle", title: enabled ? t('On') : t('Off'), children: [_jsx("input", { type: "checkbox", "aria-label": t('Enable memory'), checked: enabled, onChange: (event) => onToggleEnabled(event.target.checked), ...agentHandleProps(agentHandle, { action: 'enabled', role: 'checkbox', label: t('Enable memory') }) }), _jsx("span", { className: "toggle-slider" })] })] })] }), topTab === 'memories' ? (_jsx(MemoryList, { sectionRef: sectionRef, ...savedMemory, ...(agentHandle ? { agentHandle: agentSubHandle(agentHandle, 'saved') } : {}) })) : (_jsx(MemoryHowPanel, { ...howItWorks, ...(agentHandle ? { agentHandle: agentSubHandle(agentHandle, 'how') } : {}) }))] }));
|
|
29
|
+
return (_jsxs("div", { className: "memory-settings-panel", children: [_jsxs("section", { className: "memory-panel-head-card", children: [_jsxs("div", { className: "memory-panel-head-copy", children: [_jsx("h4", { children: t('Memory') }), _jsx("p", { className: "hint", children: t('Control whether saved facts, preferences, and project context are reused in future chats.') })] }), _jsxs("div", { className: "memory-panel-head-controls", children: [_jsxs("div", { className: "jini-seg-control memory-panel-seg", role: "tablist", "aria-label": t('Memory view'), style: { '--seg-cols': 2 }, children: [_jsx("button", { type: "button", role: "tab", "aria-selected": topTab === 'memories', className: 'jini-seg-btn' + (topTab === 'memories' ? ' active' : ''), onClick: () => onTopTabChange('memories'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'view-memories', role: 'button', label: t('Memories') }) }), children: _jsx("span", { className: "jini-seg-title", children: t('Memories') }) }), _jsx("button", { type: "button", role: "tab", "aria-selected": topTab === 'how', className: 'jini-seg-btn' + (topTab === 'how' ? ' active' : ''), onClick: () => onTopTabChange('how'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'view-how', role: 'button', label: t('How it works') }) }), children: _jsx("span", { className: "jini-seg-title", children: t('How it works') }) })] }), _jsx("button", { type: "button", className: "memory-icon-btn", onClick: onAdd, disabled: !onAdd, "aria-label": t('Add memory'), title: t('Add memory'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'add', role: 'button', label: t('Add memory') }) }), children: _jsx(Icon, { name: "plus", size: 14 }) }), _jsx("button", { type: "button", className: "memory-icon-btn", onClick: onOpenAdvanced, disabled: !onOpenAdvanced, "aria-label": t('Advanced'), title: t('Advanced'), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'advanced', role: 'button', label: t('Advanced') }) }), children: _jsx(Icon, { name: "settings", size: 14 }) }), _jsxs("label", { className: "toggle-switch memory-panel-master-toggle", title: enabled ? t('On') : t('Off'), children: [_jsx("input", { type: "checkbox", "aria-label": t('Enable memory'), checked: enabled, onChange: (event) => onToggleEnabled(event.target.checked), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'enabled', role: 'checkbox', label: t('Enable memory') }) }) }), _jsx("span", { className: "toggle-slider" })] })] })] }), topTab === 'memories' ? (_jsx(MemoryList, { sectionRef: sectionRef, ...savedMemory, ...(agentHandle ? { agentHandle: agentSubHandle({ base: agentHandle, action: 'saved' }) } : {}) })) : (_jsx(MemoryHowPanel, { ...howItWorks, ...(agentHandle ? { agentHandle: agentSubHandle({ base: agentHandle, action: 'how' }) } : {}) }))] }));
|
|
30
30
|
}
|
|
31
31
|
//# sourceMappingURL=MemorySettingsPanel.js.map
|
|
@@ -82,7 +82,7 @@ export function useMemoryEntries(port, coord) {
|
|
|
82
82
|
// BOTH paths fail (e.g. a locked-down document). Check the boolean
|
|
83
83
|
// instead of catching a throw, but preserve the original intent: a total
|
|
84
84
|
// failure must not claim success with a copy flash.
|
|
85
|
-
const copied = await copyToClipboard(rootDir);
|
|
85
|
+
const copied = await copyToClipboard({ text: rootDir });
|
|
86
86
|
if (copied) {
|
|
87
87
|
fireFlash('pathCopied');
|
|
88
88
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Pure UI state with no transport and — deliberately — NO effects: the
|
|
5
5
|
// effects that READ this state (reload-on-`activeTab`, the SSE stream, the
|
|
6
6
|
// OAuth subscriptions) stay in the single-instance host orchestrator per the
|
|
7
|
-
//
|
|
7
|
+
// effect-placement rule, so they can't double-fire. That keeps this. See docs/decisions/DR-001-state-hooks-effect-ownership.md.
|
|
8
8
|
// hook a plain state container a host re-exposes, and it's driveable with
|
|
9
9
|
// `renderHook` to assert the tab/modal transitions in isolation.
|
|
10
10
|
import { useCallback, useRef, useState } from 'react';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// `connectorAuthSnapshotChanged` — generified ports of the exact same
|
|
9
9
|
// reconciliation reducers OD's `connectors-state.ts` module has on
|
|
10
10
|
// its current `main` (confirmed by direct comparison; see
|
|
11
|
-
// `packages/ui/
|
|
11
|
+
// `packages/ui/archived provenance ledger`'s provenance note for this feature). This slice
|
|
12
12
|
// imports and reuses those instead of shipping a third near-duplicate copy,
|
|
13
13
|
// per `ADS-memory/reports/jini-port/god-components-extraction-plan.md`'s Consolidation map,
|
|
14
14
|
// which flags this exact overlap and asks each future extraction to check
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `MemoryExtractionRecord`, `ConnectorMemorySuggestionResponse`, etc.) — that
|
|
5
5
|
* package is not available here, so this file defines the same shapes
|
|
6
6
|
* locally, scoped to exactly what this slice's ported hooks/components/rules
|
|
7
|
-
* consume. See `packages/ui/
|
|
7
|
+
* consume. See `packages/ui/archived provenance ledger` for the full provenance note.
|
|
8
8
|
*
|
|
9
9
|
* Connector-shaped fields reuse `@jini-ai/ui`'s own `features/connectors` types
|
|
10
10
|
* (`Connector`/`ConnectorStatusMap`/`ConnectorActionResult`) instead of a
|
|
@@ -51,7 +51,7 @@ export function useMentionAutocomplete({ value, onValueChange, items, categories
|
|
|
51
51
|
refreshFromTextarea();
|
|
52
52
|
};
|
|
53
53
|
const closeMention = () => setMention(null);
|
|
54
|
-
useDismissOnOutsideOrEscape(closeMention, { enabled: mention !== null, containerRef });
|
|
54
|
+
useDismissOnOutsideOrEscape({ onDismiss: closeMention }, { enabled: mention !== null, containerRef });
|
|
55
55
|
const pickItem = (item) => {
|
|
56
56
|
const token = buildMentionToken(item.label, triggerChar);
|
|
57
57
|
const textarea = textareaRef.current;
|
|
@@ -28,10 +28,10 @@ import { testStatusLabel } from '../../rules.js';
|
|
|
28
28
|
export function NotificationsTab({ preferences, onChange, testNotificationTitle, testNotificationBody, labels, agentHandle, }) {
|
|
29
29
|
const t = useT();
|
|
30
30
|
const successSoundHandles = agentHandle
|
|
31
|
-
? buildAgentListHandles(agentSubHandle(agentHandle, 'success-sound'), SUCCESS_SOUNDS.map((s) => s.id))
|
|
31
|
+
? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'success-sound' }), ids: SUCCESS_SOUNDS.map((s) => s.id) })
|
|
32
32
|
: undefined;
|
|
33
33
|
const failureSoundHandles = agentHandle
|
|
34
|
-
? buildAgentListHandles(agentSubHandle(agentHandle, 'failure-sound'), FAILURE_SOUNDS.map((s) => s.id))
|
|
34
|
+
? buildAgentListHandles({ prefix: agentSubHandle({ base: agentHandle, action: 'failure-sound' }), ids: FAILURE_SOUNDS.map((s) => s.id) })
|
|
35
35
|
: undefined;
|
|
36
36
|
const [permission, setPermission] = useState(() => notificationPermission());
|
|
37
37
|
const [testStatus, setTestStatus] = useState(null);
|
|
@@ -76,16 +76,16 @@ export function NotificationsTab({ preferences, onChange, testNotificationTitle,
|
|
|
76
76
|
// outcome here rather than getting their own dead states.
|
|
77
77
|
setTestStatus(result === 'shown' ? 'sent' : 'failed');
|
|
78
78
|
};
|
|
79
|
-
return (_jsxs("section", { className: "jini-settings-section jini-settings-notifications", children: [_jsxs("div", { className: "jini-settings-subsection", children: [_jsxs("div", { className: "jini-settings-notify-card", children: [_jsxs("div", { className: "jini-settings-notify-card-header", children: [_jsx("h4", { children: completionSoundTitle }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": completionSoundTitle, style: { '--seg-cols': 1 }, children: _jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.soundEnabled ? ' active' : ''), "aria-pressed": preferences.soundEnabled, "aria-label": completionSoundTitle, onClick: toggleSound, ...agentHandleProps(agentHandle, { action: 'sound-toggle', role: 'button', label: completionSoundTitle }), children: _jsx("span", { className: "jini-seg-title", children: preferences.soundEnabled ? activeLabel : offLabel }) }) })] }), _jsx("p", { className: "jini-hint", children: completionSoundHint })] }), preferences.soundEnabled ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "jini-settings-field", children: [_jsx("label", { children: successSoundLabel }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": successSoundLabel, style: { '--seg-cols': SUCCESS_SOUNDS.length }, children: SUCCESS_SOUNDS.map((sound, index) => (_jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.successSoundId === sound.id ? ' active' : ''), "aria-pressed": preferences.successSoundId === sound.id, onClick: () => {
|
|
79
|
+
return (_jsxs("section", { className: "jini-settings-section jini-settings-notifications", children: [_jsxs("div", { className: "jini-settings-subsection", children: [_jsxs("div", { className: "jini-settings-notify-card", children: [_jsxs("div", { className: "jini-settings-notify-card-header", children: [_jsx("h4", { children: completionSoundTitle }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": completionSoundTitle, style: { '--seg-cols': 1 }, children: _jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.soundEnabled ? ' active' : ''), "aria-pressed": preferences.soundEnabled, "aria-label": completionSoundTitle, onClick: toggleSound, ...agentHandleProps({}, { base: agentHandle, ...({ action: 'sound-toggle', role: 'button', label: completionSoundTitle }) }), children: _jsx("span", { className: "jini-seg-title", children: preferences.soundEnabled ? activeLabel : offLabel }) }) })] }), _jsx("p", { className: "jini-hint", children: completionSoundHint })] }), preferences.soundEnabled ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "jini-settings-field", children: [_jsx("label", { children: successSoundLabel }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": successSoundLabel, style: { '--seg-cols': SUCCESS_SOUNDS.length }, children: SUCCESS_SOUNDS.map((sound, index) => (_jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.successSoundId === sound.id ? ' active' : ''), "aria-pressed": preferences.successSoundId === sound.id, onClick: () => {
|
|
80
80
|
onChange({ successSoundId: sound.id });
|
|
81
81
|
playSound(sound.id);
|
|
82
|
-
}, ...agentHandleProps(successSoundHandles?.[index], { role: 'button', label: t(sound.labelKey) }), children: _jsx("span", { className: "jini-seg-title", children: t(sound.labelKey) }) }, sound.id))) })] }), _jsxs("div", { className: "jini-settings-field", children: [_jsx("label", { children: failureSoundLabel }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": failureSoundLabel, style: { '--seg-cols': FAILURE_SOUNDS.length }, children: FAILURE_SOUNDS.map((sound, index) => (_jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.failureSoundId === sound.id ? ' active' : ''), "aria-pressed": preferences.failureSoundId === sound.id, onClick: () => {
|
|
82
|
+
}, ...agentHandleProps({}, { base: successSoundHandles?.[index], ...({ role: 'button', label: t(sound.labelKey) }) }), children: _jsx("span", { className: "jini-seg-title", children: t(sound.labelKey) }) }, sound.id))) })] }), _jsxs("div", { className: "jini-settings-field", children: [_jsx("label", { children: failureSoundLabel }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": failureSoundLabel, style: { '--seg-cols': FAILURE_SOUNDS.length }, children: FAILURE_SOUNDS.map((sound, index) => (_jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.failureSoundId === sound.id ? ' active' : ''), "aria-pressed": preferences.failureSoundId === sound.id, onClick: () => {
|
|
83
83
|
onChange({ failureSoundId: sound.id });
|
|
84
84
|
playSound(sound.id);
|
|
85
|
-
}, ...agentHandleProps(failureSoundHandles?.[index], { role: 'button', label: t(sound.labelKey) }), children: _jsx("span", { className: "jini-seg-title", children: t(sound.labelKey) }) }, sound.id))) })] })] })) : null] }), _jsxs("div", { className: "jini-settings-subsection", children: [_jsxs("div", { className: "jini-settings-notify-card", children: [_jsxs("div", { className: "jini-settings-notify-card-header", children: [_jsx("h4", { children: desktopTitle }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": desktopTitle, style: { '--seg-cols': 1 }, children: _jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.desktopEnabled ? ' active' : ''), "aria-pressed": preferences.desktopEnabled, "aria-label": desktopTitle, disabled: permission === 'unsupported', onClick: () => {
|
|
85
|
+
}, ...agentHandleProps({}, { base: failureSoundHandles?.[index], ...({ role: 'button', label: t(sound.labelKey) }) }), children: _jsx("span", { className: "jini-seg-title", children: t(sound.labelKey) }) }, sound.id))) })] })] })) : null] }), _jsxs("div", { className: "jini-settings-subsection", children: [_jsxs("div", { className: "jini-settings-notify-card", children: [_jsxs("div", { className: "jini-settings-notify-card-header", children: [_jsx("h4", { children: desktopTitle }), _jsx("div", { className: "jini-seg-control", role: "group", "aria-label": desktopTitle, style: { '--seg-cols': 1 }, children: _jsx("button", { type: "button", className: 'jini-seg-btn' + (preferences.desktopEnabled ? ' active' : ''), "aria-pressed": preferences.desktopEnabled, "aria-label": desktopTitle, disabled: permission === 'unsupported', onClick: () => {
|
|
86
86
|
void toggleDesktop();
|
|
87
|
-
}, ...agentHandleProps(agentHandle, { action: 'desktop-toggle', role: 'button', label: desktopTitle }), children: _jsx("span", { className: "jini-seg-title", children: preferences.desktopEnabled ? activeLabel : offLabel }) }) })] }), _jsx("p", { className: "jini-hint", children: desktopHint })] }), permission === 'unsupported' ? _jsx("p", { className: "jini-hint", children: desktopUnsupported }) : null, permission === 'denied' ? _jsx("p", { className: "jini-hint", children: desktopBlocked }) : null, preferences.desktopEnabled && permission === 'granted' ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "jini-button jini-button-ghost", onClick: () => {
|
|
87
|
+
}, ...agentHandleProps({}, { base: agentHandle, ...({ action: 'desktop-toggle', role: 'button', label: desktopTitle }) }), children: _jsx("span", { className: "jini-seg-title", children: preferences.desktopEnabled ? activeLabel : offLabel }) }) })] }), _jsx("p", { className: "jini-hint", children: desktopHint })] }), permission === 'unsupported' ? _jsx("p", { className: "jini-hint", children: desktopUnsupported }) : null, permission === 'denied' ? _jsx("p", { className: "jini-hint", children: desktopBlocked }) : null, preferences.desktopEnabled && permission === 'granted' ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "jini-button jini-button-ghost", onClick: () => {
|
|
88
88
|
void sendTestNotification();
|
|
89
|
-
}, ...agentHandleProps(agentHandle, { action: 'send-test', role: 'button', label: sendTestLabel }), children: sendTestLabel }), testStatus ? (_jsx("p", { className: "jini-hint", role: "status", children: testStatusLabel(testStatus, { testSentLabel, testFailedLabel }) })) : null] })) : null] })] }));
|
|
89
|
+
}, ...agentHandleProps({}, { base: agentHandle, ...({ action: 'send-test', role: 'button', label: sendTestLabel }) }), children: sendTestLabel }), testStatus ? (_jsx("p", { className: "jini-hint", role: "status", children: testStatusLabel(testStatus, { testSentLabel, testFailedLabel }) })) : null] })) : null] })] }));
|
|
90
90
|
}
|
|
91
91
|
//# sourceMappingURL=NotificationsTab.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Origin: `NotificationsSection` in `SettingsDialog.tsx` (completion-sound
|
|
3
3
|
* toggle/picker + browser Notification-permission flow), GENERIC per
|
|
4
4
|
* `ADS-memory/reports/jini-port/recon/r6-god-component-internals.md` §1.3 — browser-API
|
|
5
|
-
* only, zero product-domain coupling. See `packages/ui/
|
|
5
|
+
* only, zero product-domain coupling. See `packages/ui/archived provenance ledger` for
|
|
6
6
|
* the full provenance note.
|
|
7
7
|
*/
|
|
8
8
|
import type { SoundId } from './notifications-catalog.js';
|