@flanksource/clicky-ui 0.2.18 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai.cjs +26 -0
- package/dist/ai.cjs.map +1 -0
- package/dist/ai.d.ts +2 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +26 -0
- package/dist/ai.js.map +1 -0
- package/dist/chat.cjs +7 -0
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.js +7 -0
- package/dist/chat.js.map +1 -1
- package/dist/components/FilterBar.cjs +49 -18
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +0 -2
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +50 -19
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/SearchInput.cjs +63 -0
- package/dist/components/SearchInput.cjs.map +1 -0
- package/dist/components/SearchInput.d.ts +31 -0
- package/dist/components/SearchInput.d.ts.map +1 -0
- package/dist/components/SearchInput.js +63 -0
- package/dist/components/SearchInput.js.map +1 -0
- package/dist/components/SegmentedControl.cjs +88 -0
- package/dist/components/SegmentedControl.cjs.map +1 -0
- package/dist/components/SegmentedControl.d.ts +38 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -0
- package/dist/components/SegmentedControl.js +88 -0
- package/dist/components/SegmentedControl.js.map +1 -0
- package/dist/components/Switch.cjs +51 -0
- package/dist/components/Switch.cjs.map +1 -0
- package/dist/components/Switch.d.ts +23 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +51 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/TimeRange.cjs +53 -45
- package/dist/components/TimeRange.cjs.map +1 -1
- package/dist/components/TimeRange.d.ts.map +1 -1
- package/dist/components/TimeRange.js +53 -45
- package/dist/components/TimeRange.js.map +1 -1
- package/dist/components/TreePickerField.cjs +5 -1
- package/dist/components/TreePickerField.cjs.map +1 -1
- package/dist/components/TreePickerField.d.ts.map +1 -1
- package/dist/components/TreePickerField.js +5 -1
- package/dist/components/TreePickerField.js.map +1 -1
- package/dist/components/filter-bar-utils.cjs +5 -0
- package/dist/components/filter-bar-utils.cjs.map +1 -1
- package/dist/components/filter-bar-utils.d.ts +2 -0
- package/dist/components/filter-bar-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.js +5 -0
- package/dist/components/filter-bar-utils.js.map +1 -1
- package/dist/components/json-schema-form-fields.cjs +8 -2
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +8 -2
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +1 -1
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.js +1 -1
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components.cjs +21 -1
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +11 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +21 -1
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +33 -44
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +0 -9
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +31 -42
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +73 -50
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +4 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +73 -50
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Icon.cjs +2 -5
- package/dist/data/Icon.cjs.map +1 -1
- package/dist/data/Icon.d.ts +1 -21
- package/dist/data/Icon.d.ts.map +1 -1
- package/dist/data/Icon.js +3 -6
- package/dist/data/Icon.js.map +1 -1
- package/dist/data/MatrixTable.cjs +4 -4
- package/dist/data/MatrixTable.cjs.map +1 -1
- package/dist/data/MatrixTable.js +4 -4
- package/dist/data/MatrixTable.js.map +1 -1
- package/dist/data/RadialGauge.cjs +76 -0
- package/dist/data/RadialGauge.cjs.map +1 -0
- package/dist/data/RadialGauge.d.ts +24 -0
- package/dist/data/RadialGauge.d.ts.map +1 -0
- package/dist/data/RadialGauge.js +76 -0
- package/dist/data/RadialGauge.js.map +1 -0
- package/dist/data/StatusBreakdown.cjs +0 -4
- package/dist/data/StatusBreakdown.cjs.map +1 -1
- package/dist/data/StatusBreakdown.d.ts +0 -2
- package/dist/data/StatusBreakdown.d.ts.map +1 -1
- package/dist/data/StatusBreakdown.js +1 -5
- package/dist/data/StatusBreakdown.js.map +1 -1
- package/dist/data/TabButton.cjs +17 -2
- package/dist/data/TabButton.cjs.map +1 -1
- package/dist/data/TabButton.d.ts +5 -1
- package/dist/data/TabButton.d.ts.map +1 -1
- package/dist/data/TabButton.js +17 -2
- package/dist/data/TabButton.js.map +1 -1
- package/dist/data/Timeline.cjs +61 -0
- package/dist/data/Timeline.cjs.map +1 -0
- package/dist/data/Timeline.d.ts +36 -0
- package/dist/data/Timeline.d.ts.map +1 -0
- package/dist/data/Timeline.js +61 -0
- package/dist/data/Timeline.js.map +1 -0
- package/dist/data/TimeseriesCoreBars.cjs +2 -25
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts +0 -19
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +2 -25
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.model.cjs +27 -0
- package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -0
- package/dist/data/TimeseriesCoreBars.model.d.ts +20 -0
- package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -0
- package/dist/data/TimeseriesCoreBars.model.js +27 -0
- package/dist/data/TimeseriesCoreBars.model.js.map +1 -0
- package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.axes.d.ts +1 -1
- package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.axes.js.map +1 -1
- package/dist/data/TimeseriesPanel.cjs +4 -54
- package/dist/data/TimeseriesPanel.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.d.ts +2 -138
- package/dist/data/TimeseriesPanel.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.js +2 -52
- package/dist/data/TimeseriesPanel.js.map +1 -1
- package/dist/data/TimeseriesPanel.model.cjs +53 -0
- package/dist/data/TimeseriesPanel.model.cjs.map +1 -0
- package/dist/data/TimeseriesPanel.model.d.ts +88 -0
- package/dist/data/TimeseriesPanel.model.d.ts.map +1 -0
- package/dist/data/TimeseriesPanel.model.js +53 -0
- package/dist/data/TimeseriesPanel.model.js.map +1 -0
- package/dist/data/Tree.cjs +1 -1
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.js +1 -1
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +29 -0
- package/dist/data/ai/ChatFab.cjs.map +1 -0
- package/dist/data/ai/ChatFab.d.ts +12 -0
- package/dist/data/ai/ChatFab.d.ts.map +1 -0
- package/dist/data/ai/ChatFab.js +29 -0
- package/dist/data/ai/ChatFab.js.map +1 -0
- package/dist/data/ai/ChatWindow.cjs +178 -0
- package/dist/data/ai/ChatWindow.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.d.ts +38 -0
- package/dist/data/ai/ChatWindow.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.js +156 -0
- package/dist/data/ai/ChatWindow.js.map +1 -0
- package/dist/data/ai/ChatWindowManager.cjs +139 -0
- package/dist/data/ai/ChatWindowManager.cjs.map +1 -0
- package/dist/data/ai/ChatWindowManager.d.ts +12 -0
- package/dist/data/ai/ChatWindowManager.d.ts.map +1 -0
- package/dist/data/ai/ChatWindowManager.js +139 -0
- package/dist/data/ai/ChatWindowManager.js.map +1 -0
- package/dist/data/ai/ContextBadges.cjs +74 -0
- package/dist/data/ai/ContextBadges.cjs.map +1 -0
- package/dist/data/ai/ContextBadges.d.ts +16 -0
- package/dist/data/ai/ContextBadges.d.ts.map +1 -0
- package/dist/data/ai/ContextBadges.js +74 -0
- package/dist/data/ai/ContextBadges.js.map +1 -0
- package/dist/data/ai/ThreadPicker.cjs +148 -0
- package/dist/data/ai/ThreadPicker.cjs.map +1 -0
- package/dist/data/ai/ThreadPicker.d.ts +37 -0
- package/dist/data/ai/ThreadPicker.d.ts.map +1 -0
- package/dist/data/ai/ThreadPicker.js +148 -0
- package/dist/data/ai/ThreadPicker.js.map +1 -0
- package/dist/data/ai/ToolPreferences.cjs +80 -0
- package/dist/data/ai/ToolPreferences.cjs.map +1 -0
- package/dist/data/ai/ToolPreferences.d.ts +19 -0
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -0
- package/dist/data/ai/ToolPreferences.js +80 -0
- package/dist/data/ai/ToolPreferences.js.map +1 -0
- package/dist/data/ai/chat-window-context.cjs +78 -0
- package/dist/data/ai/chat-window-context.cjs.map +1 -0
- package/dist/data/ai/chat-window-context.d.ts +57 -0
- package/dist/data/ai/chat-window-context.d.ts.map +1 -0
- package/dist/data/ai/chat-window-context.js +78 -0
- package/dist/data/ai/chat-window-context.js.map +1 -0
- package/dist/data/ai/context.cjs +43 -0
- package/dist/data/ai/context.cjs.map +1 -0
- package/dist/data/ai/context.d.ts +35 -0
- package/dist/data/ai/context.d.ts.map +1 -0
- package/dist/data/ai/context.js +43 -0
- package/dist/data/ai/context.js.map +1 -0
- package/dist/data/ai/index.d.ts +10 -0
- package/dist/data/ai/index.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheDetailPanel.cjs +15 -0
- package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -1
- package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
- package/dist/data/cache-browser/CacheDetailPanel.js +15 -0
- package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -1
- package/dist/data/cache-browser/cache-browser.fixtures.d.ts +10 -0
- package/dist/data/cache-browser/cache-browser.fixtures.d.ts.map +1 -0
- package/dist/data/cache-browser/download.cjs +13 -0
- package/dist/data/cache-browser/download.cjs.map +1 -0
- package/dist/data/cache-browser/download.d.ts +3 -0
- package/dist/data/cache-browser/download.d.ts.map +1 -0
- package/dist/data/cache-browser/download.js +13 -0
- package/dist/data/cache-browser/download.js.map +1 -0
- package/dist/data/chat/Chat.cjs +40 -2
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +5 -2
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.cjs +86 -0
- package/dist/data/chat/Chat.fixtures.cjs.map +1 -0
- package/dist/data/chat/Chat.fixtures.d.ts +4 -0
- package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.js +86 -0
- package/dist/data/chat/Chat.fixtures.js.map +1 -0
- package/dist/data/chat/Chat.js +41 -3
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ContextUsage.cjs +99 -0
- package/dist/data/chat/ContextUsage.cjs.map +1 -0
- package/dist/data/chat/ContextUsage.d.ts +19 -0
- package/dist/data/chat/ContextUsage.d.ts.map +1 -0
- package/dist/data/chat/ContextUsage.js +99 -0
- package/dist/data/chat/ContextUsage.js.map +1 -0
- package/dist/data/chat/ModelSelector.cjs +28 -14
- package/dist/data/chat/ModelSelector.cjs.map +1 -1
- package/dist/data/chat/ModelSelector.d.ts +5 -4
- package/dist/data/chat/ModelSelector.d.ts.map +1 -1
- package/dist/data/chat/ModelSelector.js +28 -14
- package/dist/data/chat/ModelSelector.js.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.cjs +21 -1
- package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.d.ts +5 -4
- package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.js +21 -1
- package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
- package/dist/data/chat/index.d.ts +4 -1
- package/dist/data/chat/index.d.ts.map +1 -1
- package/dist/data/chat/provider-icons.cjs +15 -0
- package/dist/data/chat/provider-icons.cjs.map +1 -0
- package/dist/data/chat/provider-icons.d.ts +7 -0
- package/dist/data/chat/provider-icons.d.ts.map +1 -0
- package/dist/data/chat/provider-icons.js +15 -0
- package/dist/data/chat/provider-icons.js.map +1 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +41 -9
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/clicky-parse.cjs +42 -0
- package/dist/data/clicky-parse.cjs.map +1 -0
- package/dist/data/clicky-parse.d.ts +11 -0
- package/dist/data/clicky-parse.d.ts.map +1 -0
- package/dist/data/clicky-parse.js +42 -0
- package/dist/data/clicky-parse.js.map +1 -0
- package/dist/data/diagnostics/FrameSourceWindow.cjs +0 -4
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -11
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +1 -5
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.utils.cjs +7 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +12 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.js +7 -0
- package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -0
- package/dist/data/diagnostics/JvmStackTrace.cjs +2 -1
- package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.js +2 -1
- package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
- package/dist/data/icon-fallback.cjs +12 -0
- package/dist/data/icon-fallback.cjs.map +1 -0
- package/dist/data/icon-fallback.d.ts +19 -0
- package/dist/data/icon-fallback.d.ts.map +1 -0
- package/dist/data/icon-fallback.js +12 -0
- package/dist/data/icon-fallback.js.map +1 -0
- package/dist/data/status-breakdown-utils.cjs +7 -0
- package/dist/data/status-breakdown-utils.cjs.map +1 -0
- package/dist/data/status-breakdown-utils.d.ts +4 -0
- package/dist/data/status-breakdown-utils.d.ts.map +1 -0
- package/dist/data/status-breakdown-utils.js +7 -0
- package/dist/data/status-breakdown-utils.js.map +1 -0
- package/dist/data/test-runner/TestRunSummary.cjs +36 -0
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.d.ts +7 -1
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +36 -0
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +5 -3
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +13 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +5 -3
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +19 -6
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +14 -6
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +18 -5
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +57 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +56 -6
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +332 -0
- package/dist/layout/AppShell.cjs.map +1 -0
- package/dist/layout/AppShell.d.ts +75 -0
- package/dist/layout/AppShell.d.ts.map +1 -0
- package/dist/layout/AppShell.js +332 -0
- package/dist/layout/AppShell.js.map +1 -0
- package/dist/layout/AppSidebar.cjs +239 -0
- package/dist/layout/AppSidebar.cjs.map +1 -0
- package/dist/layout/AppSidebar.d.ts +62 -0
- package/dist/layout/AppSidebar.d.ts.map +1 -0
- package/dist/layout/AppSidebar.js +239 -0
- package/dist/layout/AppSidebar.js.map +1 -0
- package/dist/layout/Panel.cjs +66 -0
- package/dist/layout/Panel.cjs.map +1 -0
- package/dist/layout/Panel.d.ts +34 -0
- package/dist/layout/Panel.d.ts.map +1 -0
- package/dist/layout/Panel.js +66 -0
- package/dist/layout/Panel.js.map +1 -0
- package/dist/layout/Tabs.cjs +36 -0
- package/dist/layout/Tabs.cjs.map +1 -0
- package/dist/layout/Tabs.d.ts +36 -0
- package/dist/layout/Tabs.d.ts.map +1 -0
- package/dist/layout/Tabs.js +36 -0
- package/dist/layout/Tabs.js.map +1 -0
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/Modal.cjs +4 -2
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts +1 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +4 -2
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/Toast.cjs +89 -0
- package/dist/overlay/Toast.cjs.map +1 -0
- package/dist/overlay/Toast.d.ts +14 -0
- package/dist/overlay/Toast.d.ts.map +1 -0
- package/dist/overlay/Toast.js +89 -0
- package/dist/overlay/Toast.js.map +1 -0
- package/dist/overlay/toast-context.cjs +12 -0
- package/dist/overlay/toast-context.cjs.map +1 -0
- package/dist/overlay/toast-context.d.ts +24 -0
- package/dist/overlay/toast-context.d.ts.map +1 -0
- package/dist/overlay/toast-context.js +12 -0
- package/dist/overlay/toast-context.js.map +1 -0
- package/dist/rpc/AcceptPicker.cjs +81 -58
- package/dist/rpc/AcceptPicker.cjs.map +1 -1
- package/dist/rpc/AcceptPicker.d.ts.map +1 -1
- package/dist/rpc/AcceptPicker.js +81 -58
- package/dist/rpc/AcceptPicker.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +5 -35
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.d.ts +0 -3
- package/dist/rpc/CommandForm.d.ts.map +1 -1
- package/dist/rpc/CommandForm.js +2 -32
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/CommandOutput.cjs +2 -1
- package/dist/rpc/CommandOutput.cjs.map +1 -1
- package/dist/rpc/CommandOutput.d.ts.map +1 -1
- package/dist/rpc/CommandOutput.js +2 -1
- package/dist/rpc/CommandOutput.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +28 -83
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.d.ts +1 -4
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +13 -68
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +2 -2
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +1 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +1 -1
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +6 -4
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +3 -1
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/RouterProvider.cjs +10 -0
- package/dist/rpc/RouterProvider.cjs.map +1 -0
- package/dist/rpc/RouterProvider.d.ts +10 -0
- package/dist/rpc/RouterProvider.d.ts.map +1 -0
- package/dist/rpc/RouterProvider.js +10 -0
- package/dist/rpc/RouterProvider.js.map +1 -0
- package/dist/rpc/apiClient.cjs +4 -4
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.js +4 -4
- package/dist/rpc/apiClient.js.map +1 -1
- package/dist/rpc/command-form-utils.cjs +43 -0
- package/dist/rpc/command-form-utils.cjs.map +1 -0
- package/dist/rpc/command-form-utils.d.ts +5 -0
- package/dist/rpc/command-form-utils.d.ts.map +1 -0
- package/dist/rpc/command-form-utils.js +43 -0
- package/dist/rpc/command-form-utils.js.map +1 -0
- package/dist/rpc/commandHref.cjs +62 -0
- package/dist/rpc/commandHref.cjs.map +1 -0
- package/dist/rpc/commandHref.d.ts +7 -0
- package/dist/rpc/commandHref.d.ts.map +1 -0
- package/dist/rpc/commandHref.js +62 -0
- package/dist/rpc/commandHref.js.map +1 -0
- package/dist/rpc/formMetadata.cjs +1 -1
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.js +1 -1
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/router.cjs +83 -0
- package/dist/rpc/router.cjs.map +1 -0
- package/dist/rpc/router.d.ts +24 -0
- package/dist/rpc/router.d.ts.map +1 -0
- package/dist/rpc/router.js +83 -0
- package/dist/rpc/router.js.map +1 -0
- package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts +3 -0
- package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -0
- package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts +3 -0
- package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -0
- package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +24 -0
- package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -0
- package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts +3 -0
- package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -0
- package/dist/rpc/rpc-story.fixtures.d.ts +16 -0
- package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -0
- package/dist/rpc.cjs +17 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +5 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +18 -1
- package/dist/rpc.js.map +1 -1
- package/dist/styles.cjs +1 -0
- package/dist/styles.cjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +1 -0
- package/dist/styles.js.map +1 -1
- package/dist/tailwind-preset.cjs +36 -19
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.d.ts.map +1 -1
- package/dist/tailwind-preset.js +36 -19
- package/dist/tailwind-preset.js.map +1 -1
- package/package.json +11 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Icon } from "../Icon.js";
|
|
4
|
+
import { UiClose } from "../../icons/components/UiClose.js";
|
|
5
|
+
const DEFAULT_STYLE = {
|
|
6
|
+
className: "text-muted-foreground bg-muted"
|
|
7
|
+
};
|
|
8
|
+
function styleFor(type, config) {
|
|
9
|
+
return (config == null ? void 0 : config[type]) ?? DEFAULT_STYLE;
|
|
10
|
+
}
|
|
11
|
+
function detail(item) {
|
|
12
|
+
const fields = item.fields;
|
|
13
|
+
if (!fields) return "";
|
|
14
|
+
return Object.entries(fields).filter(([, v]) => v != null && v !== "").map(([, v]) => v).join(" ");
|
|
15
|
+
}
|
|
16
|
+
function ContextBadges({ items, onRemove, typeConfig, className }) {
|
|
17
|
+
if (items.length === 0) return null;
|
|
18
|
+
const readonly = !onRemove;
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
className: cn(
|
|
23
|
+
readonly ? "flex flex-wrap gap-1" : "flex flex-wrap gap-1.5 px-2 py-1.5",
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
children: items.map((item) => {
|
|
27
|
+
const style = styleFor(item.type, typeConfig);
|
|
28
|
+
const d = detail(item);
|
|
29
|
+
return /* @__PURE__ */ jsxs(
|
|
30
|
+
"span",
|
|
31
|
+
{
|
|
32
|
+
"data-testid": `context-badge-${item.type}`,
|
|
33
|
+
className: cn(
|
|
34
|
+
"inline-flex items-center gap-1.5 rounded-lg border",
|
|
35
|
+
readonly ? "px-1.5 py-0.5 text-[10px]" : "px-2 py-1 text-xs",
|
|
36
|
+
style.className
|
|
37
|
+
),
|
|
38
|
+
children: [
|
|
39
|
+
style.icon && /* @__PURE__ */ jsx(
|
|
40
|
+
Icon,
|
|
41
|
+
{
|
|
42
|
+
...typeof style.icon === "string" ? { name: style.icon } : { icon: style.icon },
|
|
43
|
+
className: "size-3.5 shrink-0"
|
|
44
|
+
}
|
|
45
|
+
),
|
|
46
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium truncate max-w-[180px]", children: item.label }),
|
|
47
|
+
d && /* @__PURE__ */ jsx("span", { className: "opacity-70 truncate max-w-[100px]", children: d }),
|
|
48
|
+
onRemove && /* @__PURE__ */ jsx(
|
|
49
|
+
"button",
|
|
50
|
+
{
|
|
51
|
+
type: "button",
|
|
52
|
+
"data-testid": "context-badge-remove",
|
|
53
|
+
"aria-label": `Remove ${item.label}`,
|
|
54
|
+
onClick: () => onRemove(item.id),
|
|
55
|
+
className: "ml-0.5 opacity-60 hover:opacity-100",
|
|
56
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiClose, className: "size-3" })
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
item.id
|
|
62
|
+
);
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function ContextBadgesReadonly(props) {
|
|
68
|
+
return /* @__PURE__ */ jsx(ContextBadges, { ...props });
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
ContextBadges,
|
|
72
|
+
ContextBadgesReadonly
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=ContextBadges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextBadges.js","sources":["../../../src/data/ai/ContextBadges.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiClose } from \"../../icons\";\nimport type { ChatContextItem, ContextTypeConfig, ContextTypeStyle } from \"./context\";\n\nconst DEFAULT_STYLE: ContextTypeStyle = {\n className: \"text-muted-foreground bg-muted\",\n};\n\nfunction styleFor(type: string, config?: ContextTypeConfig): ContextTypeStyle {\n return config?.[type] ?? DEFAULT_STYLE;\n}\n\nfunction detail(item: ChatContextItem): string {\n const fields = item.fields;\n if (!fields) return \"\";\n return Object.entries(fields)\n .filter(([, v]) => v != null && v !== \"\")\n .map(([, v]) => v)\n .join(\" \");\n}\n\nexport type ContextBadgesProps = {\n items: ChatContextItem[];\n /** Removes the badge with the given id. When omitted the badges are read-only. */\n onRemove?: (id: string) => void;\n /** Maps each item `type` to an icon/colour; falls back to a neutral style. */\n typeConfig?: ContextTypeConfig;\n className?: string;\n};\n\n/** A wrapping row of context chips. Interactive (each removable) when `onRemove`\n * is supplied, otherwise static. The financial type→colour map lives entirely\n * in the caller-supplied `typeConfig`, so this is domain-agnostic. */\nexport function ContextBadges({ items, onRemove, typeConfig, className }: ContextBadgesProps) {\n if (items.length === 0) return null;\n const readonly = !onRemove;\n return (\n <div\n className={cn(\n readonly ? \"flex flex-wrap gap-1\" : \"flex flex-wrap gap-1.5 px-2 py-1.5\",\n className,\n )}\n >\n {items.map((item) => {\n const style = styleFor(item.type, typeConfig);\n const d = detail(item);\n return (\n <span\n key={item.id}\n data-testid={`context-badge-${item.type}`}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-lg border\",\n readonly ? \"px-1.5 py-0.5 text-[10px]\" : \"px-2 py-1 text-xs\",\n style.className,\n )}\n >\n {style.icon && (\n <Icon\n {...(typeof style.icon === \"string\" ? { name: style.icon } : { icon: style.icon })}\n className=\"size-3.5 shrink-0\"\n />\n )}\n <span className=\"font-medium truncate max-w-[180px]\">{item.label}</span>\n {d && <span className=\"opacity-70 truncate max-w-[100px]\">{d}</span>}\n {onRemove && (\n <button\n type=\"button\"\n data-testid=\"context-badge-remove\"\n aria-label={`Remove ${item.label}`}\n onClick={() => onRemove(item.id)}\n className=\"ml-0.5 opacity-60 hover:opacity-100\"\n >\n <Icon icon={UiClose} className=\"size-3\" />\n </button>\n )}\n </span>\n );\n })}\n </div>\n );\n}\n\n/** Convenience alias for static context chips (no remove control). */\nexport function ContextBadgesReadonly(props: Omit<ContextBadgesProps, \"onRemove\">) {\n return <ContextBadges {...props} />;\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAkC;AAAA,EACtC,WAAW;AACb;AAEA,SAAS,SAAS,MAAc,QAA8C;AAC5E,UAAO,iCAAS,UAAS;AAC3B;AAEA,SAAS,OAAO,MAA+B;AAC7C,QAAM,SAAS,KAAK;AACpB,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,QAAQ,MAAM,EACzB,OAAO,CAAC,CAAA,EAAG,CAAC,MAAM,KAAK,QAAQ,MAAM,EAAE,EACvC,IAAI,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,EAChB,KAAK,GAAG;AACb;AAcO,SAAS,cAAc,EAAE,OAAO,UAAU,YAAY,aAAiC;AAC5F,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,WAAW,CAAC;AAClB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT,WAAW,yBAAyB;AAAA,QACpC;AAAA,MAAA;AAAA,MAGD,UAAA,MAAM,IAAI,CAAC,SAAS;AACnB,cAAM,QAAQ,SAAS,KAAK,MAAM,UAAU;AAC5C,cAAM,IAAI,OAAO,IAAI;AACrB,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,eAAa,iBAAiB,KAAK,IAAI;AAAA,YACvC,WAAW;AAAA,cACT;AAAA,cACA,WAAW,8BAA8B;AAAA,cACzC,MAAM;AAAA,YAAA;AAAA,YAGP,UAAA;AAAA,cAAA,MAAM,QACL;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACE,GAAI,OAAO,MAAM,SAAS,WAAW,EAAE,MAAM,MAAM,SAAS,EAAE,MAAM,MAAM,KAAA;AAAA,kBAC3E,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGd,oBAAC,QAAA,EAAK,WAAU,sCAAsC,eAAK,OAAM;AAAA,cAChE,KAAK,oBAAC,QAAA,EAAK,WAAU,qCAAqC,UAAA,GAAE;AAAA,cAC5D,YACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,cAAY,UAAU,KAAK,KAAK;AAAA,kBAChC,SAAS,MAAM,SAAS,KAAK,EAAE;AAAA,kBAC/B,WAAU;AAAA,kBAEV,UAAA,oBAAC,MAAA,EAAK,MAAM,SAAS,WAAU,SAAA,CAAS;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC1C;AAAA,UAAA;AAAA,UAzBG,KAAK;AAAA,QAAA;AAAA,MA6BhB,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;AAGO,SAAS,sBAAsB,OAA6C;AACjF,SAAO,oBAAC,eAAA,EAAe,GAAG,MAAA,CAAO;AACnC;"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const utils = require("../../lib/utils.cjs");
|
|
6
|
+
const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
|
|
7
|
+
const Icon = require("../Icon.cjs");
|
|
8
|
+
const UiAdd = require("../../icons/components/UiAdd.cjs");
|
|
9
|
+
const UiComment = require("../../icons/components/UiComment.cjs");
|
|
10
|
+
const UiTrash = require("../../icons/components/UiTrash.cjs");
|
|
11
|
+
const UiChevronDown = require("../../icons/components/UiChevronDown.cjs");
|
|
12
|
+
function ThreadPicker({
|
|
13
|
+
threadId,
|
|
14
|
+
onSelect,
|
|
15
|
+
onNew,
|
|
16
|
+
api = "/api/chat/threads",
|
|
17
|
+
source,
|
|
18
|
+
query,
|
|
19
|
+
className = ""
|
|
20
|
+
}) {
|
|
21
|
+
const [threads, setThreads] = react.useState([]);
|
|
22
|
+
const [loading, setLoading] = react.useState(false);
|
|
23
|
+
const listUrl = query ? `${api}?${query}` : api;
|
|
24
|
+
const fetchThreads = react.useCallback(async () => {
|
|
25
|
+
setLoading(true);
|
|
26
|
+
try {
|
|
27
|
+
if (source) {
|
|
28
|
+
setThreads(await source.load());
|
|
29
|
+
} else {
|
|
30
|
+
const res = await fetch(listUrl);
|
|
31
|
+
if (res.ok) setThreads(await res.json());
|
|
32
|
+
}
|
|
33
|
+
} catch (err) {
|
|
34
|
+
console.warn("clicky-ui: failed to load threads", err);
|
|
35
|
+
} finally {
|
|
36
|
+
setLoading(false);
|
|
37
|
+
}
|
|
38
|
+
}, [source, listUrl]);
|
|
39
|
+
react.useEffect(() => {
|
|
40
|
+
void fetchThreads();
|
|
41
|
+
}, [fetchThreads]);
|
|
42
|
+
const handleDelete = react.useCallback(
|
|
43
|
+
async (id, e) => {
|
|
44
|
+
var _a;
|
|
45
|
+
e.stopPropagation();
|
|
46
|
+
try {
|
|
47
|
+
if (source) {
|
|
48
|
+
await ((_a = source.remove) == null ? void 0 : _a.call(source, id));
|
|
49
|
+
} else {
|
|
50
|
+
await fetch(`${api}/${id}`, { method: "DELETE" });
|
|
51
|
+
}
|
|
52
|
+
setThreads((prev) => prev.filter((t) => t.id !== id));
|
|
53
|
+
if (id === threadId) onNew();
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.warn("clicky-ui: failed to delete thread", err);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
[source, api, threadId, onNew]
|
|
59
|
+
);
|
|
60
|
+
const current = threads.find((t) => t.id === threadId);
|
|
61
|
+
const label = (current == null ? void 0 : current.title) || "New Chat";
|
|
62
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
+
DropdownMenu.DropdownMenu,
|
|
64
|
+
{
|
|
65
|
+
align: "left",
|
|
66
|
+
className,
|
|
67
|
+
onOpenChange: (open) => {
|
|
68
|
+
if (open) void fetchThreads();
|
|
69
|
+
},
|
|
70
|
+
menuClassName: "min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto",
|
|
71
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
className: "flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted",
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiComment.UiComment, className: "size-3.5 shrink-0" }),
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiChevronDown.UiChevronDown, className: "size-3 shrink-0 opacity-50" })
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
children: (closeMenu) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-1", children: [
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
85
|
+
"button",
|
|
86
|
+
{
|
|
87
|
+
type: "button",
|
|
88
|
+
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent",
|
|
89
|
+
onClick: () => {
|
|
90
|
+
onNew();
|
|
91
|
+
closeMenu();
|
|
92
|
+
},
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiAdd.UiAdd, className: "size-3" }),
|
|
95
|
+
" New Chat"
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-1 border-t border-border" }),
|
|
100
|
+
loading && threads.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "Loading…" }),
|
|
101
|
+
threads.length === 0 && !loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "No previous conversations" }),
|
|
102
|
+
threads.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
role: "button",
|
|
106
|
+
tabIndex: 0,
|
|
107
|
+
className: utils.cn(
|
|
108
|
+
"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent",
|
|
109
|
+
t.id === threadId && "font-semibold"
|
|
110
|
+
),
|
|
111
|
+
onClick: () => {
|
|
112
|
+
onSelect(t.id);
|
|
113
|
+
closeMenu();
|
|
114
|
+
},
|
|
115
|
+
onKeyDown: (e) => {
|
|
116
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
onSelect(t.id);
|
|
119
|
+
closeMenu();
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
children: [
|
|
123
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiComment.UiComment, className: "size-3 shrink-0" }),
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: t.title || "Untitled" }),
|
|
125
|
+
t.totalCostUsd != null && t.totalCostUsd > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: [
|
|
126
|
+
"$",
|
|
127
|
+
t.totalCostUsd.toFixed(2)
|
|
128
|
+
] }),
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
130
|
+
"button",
|
|
131
|
+
{
|
|
132
|
+
type: "button",
|
|
133
|
+
"aria-label": "Delete conversation",
|
|
134
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100",
|
|
135
|
+
onClick: (e) => void handleDelete(t.id, e),
|
|
136
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiTrash.UiTrash, className: "size-3" })
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
t.id
|
|
142
|
+
))
|
|
143
|
+
] })
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
exports.ThreadPicker = ThreadPicker;
|
|
148
|
+
//# sourceMappingURL=ThreadPicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPicker.cjs","sources":["../../../src/data/ai/ThreadPicker.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Icon } from \"../Icon\";\nimport { UiComment, UiAdd, UiTrash, UiChevronDown } from \"../../icons\";\n\n/** One conversation as returned by the threads endpoint. Only `id` is required;\n * `title`/cost are rendered when present so the picker works against minimal\n * backends (e.g. clicky's in-memory ThreadStore, which has no cost). */\nexport interface ThreadSummary {\n id: string;\n title?: string | null;\n totalCostUsd?: number | null;\n updatedAt?: string;\n}\n\n/** An injectable thread data source, for apps that load conversations through\n * their own client (e.g. react-query) rather than a plain `${api}` fetch — and\n * for backend-free stories/demos. When supplied it replaces the `api` calls. */\nexport interface ThreadSource {\n /** Returns the conversation list (re-invoked whenever the menu opens). */\n load: () => Promise<ThreadSummary[]>;\n /** Deletes a conversation. Omit to hide the delete affordance's effect. */\n remove?: (id: string) => Promise<void>;\n}\n\nexport type ThreadPickerProps = {\n /** Currently selected thread, or null for an unsaved/new conversation. */\n threadId: string | null;\n onSelect: (threadId: string) => void;\n onNew: () => void;\n /** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.\n * Defaults to clicky's \"/api/chat/threads\". Ignored when `source` is set. */\n api?: string;\n /** Inject the thread list/delete directly instead of fetching `api`. */\n source?: ThreadSource;\n /** Optional query string appended to the list request (e.g. a scope id). */\n query?: string;\n className?: string;\n};\n\n/** A dropdown to switch between, create, and delete conversation threads. The\n * list is (re)fetched whenever the menu opens, so newly-persisted threads\n * appear without a manual refresh. */\nexport function ThreadPicker({\n threadId,\n onSelect,\n onNew,\n api = \"/api/chat/threads\",\n source,\n query,\n className = \"\",\n}: ThreadPickerProps) {\n const [threads, setThreads] = useState<ThreadSummary[]>([]);\n const [loading, setLoading] = useState(false);\n\n const listUrl = query ? `${api}?${query}` : api;\n\n const fetchThreads = useCallback(async () => {\n setLoading(true);\n try {\n if (source) {\n setThreads(await source.load());\n } else {\n const res = await fetch(listUrl);\n if (res.ok) setThreads(await res.json());\n }\n } catch (err) {\n console.warn(\"clicky-ui: failed to load threads\", err);\n } finally {\n setLoading(false);\n }\n }, [source, listUrl]);\n\n useEffect(() => {\n void fetchThreads();\n }, [fetchThreads]);\n\n const handleDelete = useCallback(\n async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n if (source) {\n await source.remove?.(id);\n } else {\n await fetch(`${api}/${id}`, { method: \"DELETE\" });\n }\n setThreads((prev) => prev.filter((t) => t.id !== id));\n if (id === threadId) onNew();\n } catch (err) {\n console.warn(\"clicky-ui: failed to delete thread\", err);\n }\n },\n [source, api, threadId, onNew],\n );\n\n const current = threads.find((t) => t.id === threadId);\n const label = current?.title || \"New Chat\";\n\n return (\n <DropdownMenu\n align=\"left\"\n className={className}\n onOpenChange={(open) => {\n if (open) void fetchThreads();\n }}\n menuClassName=\"min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto\"\n trigger={\n <button\n type=\"button\"\n className=\"flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted\"\n >\n <Icon icon={UiComment} className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{label}</span>\n <Icon icon={UiChevronDown} className=\"size-3 shrink-0 opacity-50\" />\n </button>\n }\n >\n {(closeMenu) => (\n <div className=\"py-1\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent\"\n onClick={() => {\n onNew();\n closeMenu();\n }}\n >\n <Icon icon={UiAdd} className=\"size-3\" /> New Chat\n </button>\n <div className=\"my-1 border-t border-border\" />\n {loading && threads.length === 0 && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">Loading…</div>\n )}\n {threads.length === 0 && !loading && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">No previous conversations</div>\n )}\n {threads.map((t) => (\n <div\n key={t.id}\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent\",\n t.id === threadId && \"font-semibold\",\n )}\n onClick={() => {\n onSelect(t.id);\n closeMenu();\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(t.id);\n closeMenu();\n }\n }}\n >\n <Icon icon={UiComment} className=\"size-3 shrink-0\" />\n <span className=\"flex-1 truncate\">{t.title || \"Untitled\"}</span>\n {t.totalCostUsd != null && t.totalCostUsd > 0 && (\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n ${t.totalCostUsd.toFixed(2)}\n </span>\n )}\n <button\n type=\"button\"\n aria-label=\"Delete conversation\"\n className=\"shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100\"\n onClick={(e) => void handleDelete(t.id, e)}\n >\n <Icon icon={UiTrash} className=\"size-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":["useState","useCallback","useEffect","jsx","DropdownMenu","jsxs","Icon","UiComment","UiChevronDown","UiAdd","cn","UiTrash"],"mappings":";;;;;;;;;;;AA4CO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAsB;AACpB,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAA0B,CAAA,CAAE;AAC1D,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,KAAK;AAE5C,QAAM,UAAU,QAAQ,GAAG,GAAG,IAAI,KAAK,KAAK;AAE5C,QAAM,eAAeC,MAAAA,YAAY,YAAY;AAC3C,eAAW,IAAI;AACf,QAAI;AACF,UAAI,QAAQ;AACV,mBAAW,MAAM,OAAO,MAAM;AAAA,MAChC,OAAO;AACL,cAAM,MAAM,MAAM,MAAM,OAAO;AAC/B,YAAI,IAAI,GAAI,YAAW,MAAM,IAAI,MAAM;AAAA,MACzC;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,qCAAqC,GAAG;AAAA,IACvD,UAAA;AACE,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AAEpBC,QAAAA,UAAU,MAAM;AACd,SAAK,aAAA;AAAA,EACP,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,eAAeD,MAAAA;AAAAA,IACnB,OAAO,IAAY,MAAwB;;AACzC,QAAE,gBAAA;AACF,UAAI;AACF,YAAI,QAAQ;AACV,kBAAM,YAAO,WAAP,gCAAgB;AAAA,QACxB,OAAO;AACL,gBAAM,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,UAAU;AAAA,QAClD;AACA,mBAAW,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AACpD,YAAI,OAAO,SAAU,OAAA;AAAA,MACvB,SAAS,KAAK;AACZ,gBAAQ,KAAK,sCAAsC,GAAG;AAAA,MACxD;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,KAAK,UAAU,KAAK;AAAA,EAAA;AAG/B,QAAM,UAAU,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AACrD,QAAM,SAAQ,mCAAS,UAAS;AAEhC,SACEE,2BAAAA;AAAAA,IAACC,aAAAA;AAAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN;AAAA,MACA,cAAc,CAAC,SAAS;AACtB,YAAI,WAAW,aAAA;AAAA,MACjB;AAAA,MACA,eAAc;AAAA,MACd,SACEC,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAF,2BAAAA,IAACG,KAAAA,MAAA,EAAK,MAAMC,UAAAA,WAAW,WAAU,qBAAoB;AAAA,YACrDJ,2BAAAA,IAAC,QAAA,EAAK,WAAU,YAAY,UAAA,OAAM;AAAA,YAClCA,2BAAAA,IAACG,KAAAA,MAAA,EAAK,MAAME,cAAAA,eAAe,WAAU,6BAAA,CAA6B;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAIrE,UAAA,CAAC,cACAH,2BAAAA,KAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,QAAAA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAM;AACb,oBAAA;AACA,wBAAA;AAAA,YACF;AAAA,YAEA,UAAA;AAAA,cAAAF,2BAAAA,IAACG,KAAAA,MAAA,EAAK,MAAMG,MAAAA,OAAO,WAAU,UAAS;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAE1CN,2BAAAA,IAAC,OAAA,EAAI,WAAU,8BAAA,CAA8B;AAAA,QAC5C,WAAW,QAAQ,WAAW,oCAC5B,OAAA,EAAI,WAAU,6CAA4C,UAAA,WAAA,CAAQ;AAAA,QAEpE,QAAQ,WAAW,KAAK,CAAC,WACxBA,2BAAAA,IAAC,OAAA,EAAI,WAAU,6CAA4C,UAAA,4BAAA,CAAyB;AAAA,QAErF,QAAQ,IAAI,CAAC,MACZE,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,UAAU;AAAA,YACV,WAAWK,MAAAA;AAAAA,cACT;AAAA,cACA,EAAE,OAAO,YAAY;AAAA,YAAA;AAAA,YAEvB,SAAS,MAAM;AACb,uBAAS,EAAE,EAAE;AACb,wBAAA;AAAA,YACF;AAAA,YACA,WAAW,CAAC,MAAM;AAChB,kBAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,kBAAE,eAAA;AACF,yBAAS,EAAE,EAAE;AACb,0BAAA;AAAA,cACF;AAAA,YACF;AAAA,YAEA,UAAA;AAAA,cAAAP,2BAAAA,IAACG,KAAAA,MAAA,EAAK,MAAMC,UAAAA,WAAW,WAAU,mBAAkB;AAAA,6CAClD,QAAA,EAAK,WAAU,mBAAmB,UAAA,EAAE,SAAS,YAAW;AAAA,cACxD,EAAE,gBAAgB,QAAQ,EAAE,eAAe,KAC1CF,2BAAAA,KAAC,QAAA,EAAK,WAAU,8CAA6C,UAAA;AAAA,gBAAA;AAAA,gBACzD,EAAE,aAAa,QAAQ,CAAC;AAAA,cAAA,GAC5B;AAAA,cAEFF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,cAAW;AAAA,kBACX,WAAU;AAAA,kBACV,SAAS,CAAC,MAAM,KAAK,aAAa,EAAE,IAAI,CAAC;AAAA,kBAEzC,UAAAA,2BAAAA,IAACG,WAAA,EAAK,MAAMK,QAAAA,SAAS,WAAU,SAAA,CAAS;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC1C;AAAA,UAAA;AAAA,UAjCK,EAAE;AAAA,QAAA,CAmCV;AAAA,MAAA,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAIR;;"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** One conversation as returned by the threads endpoint. Only `id` is required;
|
|
2
|
+
* `title`/cost are rendered when present so the picker works against minimal
|
|
3
|
+
* backends (e.g. clicky's in-memory ThreadStore, which has no cost). */
|
|
4
|
+
export interface ThreadSummary {
|
|
5
|
+
id: string;
|
|
6
|
+
title?: string | null;
|
|
7
|
+
totalCostUsd?: number | null;
|
|
8
|
+
updatedAt?: string;
|
|
9
|
+
}
|
|
10
|
+
/** An injectable thread data source, for apps that load conversations through
|
|
11
|
+
* their own client (e.g. react-query) rather than a plain `${api}` fetch — and
|
|
12
|
+
* for backend-free stories/demos. When supplied it replaces the `api` calls. */
|
|
13
|
+
export interface ThreadSource {
|
|
14
|
+
/** Returns the conversation list (re-invoked whenever the menu opens). */
|
|
15
|
+
load: () => Promise<ThreadSummary[]>;
|
|
16
|
+
/** Deletes a conversation. Omit to hide the delete affordance's effect. */
|
|
17
|
+
remove?: (id: string) => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export type ThreadPickerProps = {
|
|
20
|
+
/** Currently selected thread, or null for an unsaved/new conversation. */
|
|
21
|
+
threadId: string | null;
|
|
22
|
+
onSelect: (threadId: string) => void;
|
|
23
|
+
onNew: () => void;
|
|
24
|
+
/** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.
|
|
25
|
+
* Defaults to clicky's "/api/chat/threads". Ignored when `source` is set. */
|
|
26
|
+
api?: string;
|
|
27
|
+
/** Inject the thread list/delete directly instead of fetching `api`. */
|
|
28
|
+
source?: ThreadSource;
|
|
29
|
+
/** Optional query string appended to the list request (e.g. a scope id). */
|
|
30
|
+
query?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
};
|
|
33
|
+
/** A dropdown to switch between, create, and delete conversation threads. The
|
|
34
|
+
* list is (re)fetched whenever the menu opens, so newly-persisted threads
|
|
35
|
+
* appear without a manual refresh. */
|
|
36
|
+
export declare function ThreadPicker({ threadId, onSelect, onNew, api, source, query, className, }: ThreadPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
//# sourceMappingURL=ThreadPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPicker.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ThreadPicker.tsx"],"names":[],"mappings":"AAMA;;yEAEyE;AACzE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;iFAEiF;AACjF,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACrC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;kFAC8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;uCAEuC;AACvC,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,GAAyB,EACzB,MAAM,EACN,KAAK,EACL,SAAc,GACf,EAAE,iBAAiB,2CA+HnB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback, useEffect } from "react";
|
|
3
|
+
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { DropdownMenu } from "../../overlay/DropdownMenu.js";
|
|
5
|
+
import { Icon } from "../Icon.js";
|
|
6
|
+
import { UiAdd } from "../../icons/components/UiAdd.js";
|
|
7
|
+
import { UiComment } from "../../icons/components/UiComment.js";
|
|
8
|
+
import { UiTrash } from "../../icons/components/UiTrash.js";
|
|
9
|
+
import { UiChevronDown } from "../../icons/components/UiChevronDown.js";
|
|
10
|
+
function ThreadPicker({
|
|
11
|
+
threadId,
|
|
12
|
+
onSelect,
|
|
13
|
+
onNew,
|
|
14
|
+
api = "/api/chat/threads",
|
|
15
|
+
source,
|
|
16
|
+
query,
|
|
17
|
+
className = ""
|
|
18
|
+
}) {
|
|
19
|
+
const [threads, setThreads] = useState([]);
|
|
20
|
+
const [loading, setLoading] = useState(false);
|
|
21
|
+
const listUrl = query ? `${api}?${query}` : api;
|
|
22
|
+
const fetchThreads = useCallback(async () => {
|
|
23
|
+
setLoading(true);
|
|
24
|
+
try {
|
|
25
|
+
if (source) {
|
|
26
|
+
setThreads(await source.load());
|
|
27
|
+
} else {
|
|
28
|
+
const res = await fetch(listUrl);
|
|
29
|
+
if (res.ok) setThreads(await res.json());
|
|
30
|
+
}
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.warn("clicky-ui: failed to load threads", err);
|
|
33
|
+
} finally {
|
|
34
|
+
setLoading(false);
|
|
35
|
+
}
|
|
36
|
+
}, [source, listUrl]);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
void fetchThreads();
|
|
39
|
+
}, [fetchThreads]);
|
|
40
|
+
const handleDelete = useCallback(
|
|
41
|
+
async (id, e) => {
|
|
42
|
+
var _a;
|
|
43
|
+
e.stopPropagation();
|
|
44
|
+
try {
|
|
45
|
+
if (source) {
|
|
46
|
+
await ((_a = source.remove) == null ? void 0 : _a.call(source, id));
|
|
47
|
+
} else {
|
|
48
|
+
await fetch(`${api}/${id}`, { method: "DELETE" });
|
|
49
|
+
}
|
|
50
|
+
setThreads((prev) => prev.filter((t) => t.id !== id));
|
|
51
|
+
if (id === threadId) onNew();
|
|
52
|
+
} catch (err) {
|
|
53
|
+
console.warn("clicky-ui: failed to delete thread", err);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
[source, api, threadId, onNew]
|
|
57
|
+
);
|
|
58
|
+
const current = threads.find((t) => t.id === threadId);
|
|
59
|
+
const label = (current == null ? void 0 : current.title) || "New Chat";
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
DropdownMenu,
|
|
62
|
+
{
|
|
63
|
+
align: "left",
|
|
64
|
+
className,
|
|
65
|
+
onOpenChange: (open) => {
|
|
66
|
+
if (open) void fetchThreads();
|
|
67
|
+
},
|
|
68
|
+
menuClassName: "min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto",
|
|
69
|
+
trigger: /* @__PURE__ */ jsxs(
|
|
70
|
+
"button",
|
|
71
|
+
{
|
|
72
|
+
type: "button",
|
|
73
|
+
className: "flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted",
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiComment, className: "size-3.5 shrink-0" }),
|
|
76
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: label }),
|
|
77
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiChevronDown, className: "size-3 shrink-0 opacity-50" })
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
children: (closeMenu) => /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
|
|
82
|
+
/* @__PURE__ */ jsxs(
|
|
83
|
+
"button",
|
|
84
|
+
{
|
|
85
|
+
type: "button",
|
|
86
|
+
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent",
|
|
87
|
+
onClick: () => {
|
|
88
|
+
onNew();
|
|
89
|
+
closeMenu();
|
|
90
|
+
},
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "size-3" }),
|
|
93
|
+
" New Chat"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
|
|
98
|
+
loading && threads.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "Loading…" }),
|
|
99
|
+
threads.length === 0 && !loading && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "No previous conversations" }),
|
|
100
|
+
threads.map((t) => /* @__PURE__ */ jsxs(
|
|
101
|
+
"div",
|
|
102
|
+
{
|
|
103
|
+
role: "button",
|
|
104
|
+
tabIndex: 0,
|
|
105
|
+
className: cn(
|
|
106
|
+
"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent",
|
|
107
|
+
t.id === threadId && "font-semibold"
|
|
108
|
+
),
|
|
109
|
+
onClick: () => {
|
|
110
|
+
onSelect(t.id);
|
|
111
|
+
closeMenu();
|
|
112
|
+
},
|
|
113
|
+
onKeyDown: (e) => {
|
|
114
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
onSelect(t.id);
|
|
117
|
+
closeMenu();
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
children: [
|
|
121
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiComment, className: "size-3 shrink-0" }),
|
|
122
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: t.title || "Untitled" }),
|
|
123
|
+
t.totalCostUsd != null && t.totalCostUsd > 0 && /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: [
|
|
124
|
+
"$",
|
|
125
|
+
t.totalCostUsd.toFixed(2)
|
|
126
|
+
] }),
|
|
127
|
+
/* @__PURE__ */ jsx(
|
|
128
|
+
"button",
|
|
129
|
+
{
|
|
130
|
+
type: "button",
|
|
131
|
+
"aria-label": "Delete conversation",
|
|
132
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100",
|
|
133
|
+
onClick: (e) => void handleDelete(t.id, e),
|
|
134
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiTrash, className: "size-3" })
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
t.id
|
|
140
|
+
))
|
|
141
|
+
] })
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
ThreadPicker
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=ThreadPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPicker.js","sources":["../../../src/data/ai/ThreadPicker.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Icon } from \"../Icon\";\nimport { UiComment, UiAdd, UiTrash, UiChevronDown } from \"../../icons\";\n\n/** One conversation as returned by the threads endpoint. Only `id` is required;\n * `title`/cost are rendered when present so the picker works against minimal\n * backends (e.g. clicky's in-memory ThreadStore, which has no cost). */\nexport interface ThreadSummary {\n id: string;\n title?: string | null;\n totalCostUsd?: number | null;\n updatedAt?: string;\n}\n\n/** An injectable thread data source, for apps that load conversations through\n * their own client (e.g. react-query) rather than a plain `${api}` fetch — and\n * for backend-free stories/demos. When supplied it replaces the `api` calls. */\nexport interface ThreadSource {\n /** Returns the conversation list (re-invoked whenever the menu opens). */\n load: () => Promise<ThreadSummary[]>;\n /** Deletes a conversation. Omit to hide the delete affordance's effect. */\n remove?: (id: string) => Promise<void>;\n}\n\nexport type ThreadPickerProps = {\n /** Currently selected thread, or null for an unsaved/new conversation. */\n threadId: string | null;\n onSelect: (threadId: string) => void;\n onNew: () => void;\n /** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.\n * Defaults to clicky's \"/api/chat/threads\". Ignored when `source` is set. */\n api?: string;\n /** Inject the thread list/delete directly instead of fetching `api`. */\n source?: ThreadSource;\n /** Optional query string appended to the list request (e.g. a scope id). */\n query?: string;\n className?: string;\n};\n\n/** A dropdown to switch between, create, and delete conversation threads. The\n * list is (re)fetched whenever the menu opens, so newly-persisted threads\n * appear without a manual refresh. */\nexport function ThreadPicker({\n threadId,\n onSelect,\n onNew,\n api = \"/api/chat/threads\",\n source,\n query,\n className = \"\",\n}: ThreadPickerProps) {\n const [threads, setThreads] = useState<ThreadSummary[]>([]);\n const [loading, setLoading] = useState(false);\n\n const listUrl = query ? `${api}?${query}` : api;\n\n const fetchThreads = useCallback(async () => {\n setLoading(true);\n try {\n if (source) {\n setThreads(await source.load());\n } else {\n const res = await fetch(listUrl);\n if (res.ok) setThreads(await res.json());\n }\n } catch (err) {\n console.warn(\"clicky-ui: failed to load threads\", err);\n } finally {\n setLoading(false);\n }\n }, [source, listUrl]);\n\n useEffect(() => {\n void fetchThreads();\n }, [fetchThreads]);\n\n const handleDelete = useCallback(\n async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n if (source) {\n await source.remove?.(id);\n } else {\n await fetch(`${api}/${id}`, { method: \"DELETE\" });\n }\n setThreads((prev) => prev.filter((t) => t.id !== id));\n if (id === threadId) onNew();\n } catch (err) {\n console.warn(\"clicky-ui: failed to delete thread\", err);\n }\n },\n [source, api, threadId, onNew],\n );\n\n const current = threads.find((t) => t.id === threadId);\n const label = current?.title || \"New Chat\";\n\n return (\n <DropdownMenu\n align=\"left\"\n className={className}\n onOpenChange={(open) => {\n if (open) void fetchThreads();\n }}\n menuClassName=\"min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto\"\n trigger={\n <button\n type=\"button\"\n className=\"flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted\"\n >\n <Icon icon={UiComment} className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{label}</span>\n <Icon icon={UiChevronDown} className=\"size-3 shrink-0 opacity-50\" />\n </button>\n }\n >\n {(closeMenu) => (\n <div className=\"py-1\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent\"\n onClick={() => {\n onNew();\n closeMenu();\n }}\n >\n <Icon icon={UiAdd} className=\"size-3\" /> New Chat\n </button>\n <div className=\"my-1 border-t border-border\" />\n {loading && threads.length === 0 && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">Loading…</div>\n )}\n {threads.length === 0 && !loading && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">No previous conversations</div>\n )}\n {threads.map((t) => (\n <div\n key={t.id}\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent\",\n t.id === threadId && \"font-semibold\",\n )}\n onClick={() => {\n onSelect(t.id);\n closeMenu();\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(t.id);\n closeMenu();\n }\n }}\n >\n <Icon icon={UiComment} className=\"size-3 shrink-0\" />\n <span className=\"flex-1 truncate\">{t.title || \"Untitled\"}</span>\n {t.totalCostUsd != null && t.totalCostUsd > 0 && (\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n ${t.totalCostUsd.toFixed(2)}\n </span>\n )}\n <button\n type=\"button\"\n aria-label=\"Delete conversation\"\n className=\"shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100\"\n onClick={(e) => void handleDelete(t.id, e)}\n >\n <Icon icon={UiTrash} className=\"size-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const utils = require("../../lib/utils.cjs");
|
|
6
|
+
const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
|
|
7
|
+
const button = require("../../components/button.cjs");
|
|
8
|
+
const Icon = require("../Icon.cjs");
|
|
9
|
+
const UiSliders = require("../../icons/components/UiSliders.cjs");
|
|
10
|
+
const MODE_CYCLE = ["enabled", "ask", "disabled"];
|
|
11
|
+
const MODE_LABEL = { enabled: "Auto", ask: "Ask", disabled: "Off" };
|
|
12
|
+
function ToolRow({
|
|
13
|
+
meta,
|
|
14
|
+
mode,
|
|
15
|
+
onToggle
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18
|
+
"button",
|
|
19
|
+
{
|
|
20
|
+
type: "button",
|
|
21
|
+
className: "flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent",
|
|
22
|
+
onClick: () => onToggle(meta.name),
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("text-xs", mode === "disabled" && "text-muted-foreground line-through"), children: meta.label }),
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26
|
+
"span",
|
|
27
|
+
{
|
|
28
|
+
className: utils.cn(
|
|
29
|
+
"rounded px-1.5 py-0.5 text-[10px] font-medium",
|
|
30
|
+
mode === "enabled" && "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300",
|
|
31
|
+
mode === "ask" && "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
|
|
32
|
+
mode === "disabled" && "bg-muted text-muted-foreground"
|
|
33
|
+
),
|
|
34
|
+
children: MODE_LABEL[mode]
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function ToolPreferences({ tools, value, onChange, className = "" }) {
|
|
42
|
+
const groups = react.useMemo(() => {
|
|
43
|
+
var _a;
|
|
44
|
+
const g = {};
|
|
45
|
+
for (const meta of tools) (g[_a = meta.group ?? "Tools"] ?? (g[_a] = [])).push(meta);
|
|
46
|
+
return g;
|
|
47
|
+
}, [tools]);
|
|
48
|
+
const handleToggle = (name) => {
|
|
49
|
+
const current = value[name] ?? "enabled";
|
|
50
|
+
const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length];
|
|
51
|
+
onChange({ ...value, [name]: next });
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
54
|
+
DropdownMenu.DropdownMenu,
|
|
55
|
+
{
|
|
56
|
+
align: "right",
|
|
57
|
+
className,
|
|
58
|
+
menuClassName: "w-64 max-h-[400px] overflow-y-auto p-3",
|
|
59
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "ghost", size: "icon", title: "Tool preferences", "data-testid": "tool-preferences-btn", children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSliders.UiSliders, className: "size-4" }) }),
|
|
60
|
+
children: () => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold", children: "Tool Preferences" }),
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-[10px] text-muted-foreground", children: "Click to cycle: Auto → Ask → Off" }),
|
|
63
|
+
Object.entries(groups).map(([group, metas]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
|
|
65
|
+
metas.map((meta) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
66
|
+
ToolRow,
|
|
67
|
+
{
|
|
68
|
+
meta,
|
|
69
|
+
mode: value[meta.name] ?? "enabled",
|
|
70
|
+
onToggle: handleToggle
|
|
71
|
+
},
|
|
72
|
+
meta.name
|
|
73
|
+
))
|
|
74
|
+
] }, group))
|
|
75
|
+
] })
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
exports.ToolPreferences = ToolPreferences;
|
|
80
|
+
//# sourceMappingURL=ToolPreferences.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolPreferences.cjs","sources":["../../../src/data/ai/ToolPreferences.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiSliders } from \"../../icons\";\nimport type { ToolMeta } from \"../chat/types\";\n\nexport type { ToolMeta };\n\n/** How a tool may be invoked: run automatically, pause for approval, or be\n * hidden from the model entirely. */\nexport type ToolMode = \"enabled\" | \"ask\" | \"disabled\";\n\nconst MODE_CYCLE: ToolMode[] = [\"enabled\", \"ask\", \"disabled\"];\nconst MODE_LABEL: Record<ToolMode, string> = { enabled: \"Auto\", ask: \"Ask\", disabled: \"Off\" };\n\nexport type ToolPreferencesProps = {\n /** The tools to list. Replaces ai-financials' global registry — callers pass\n * whatever their backend exposes. */\n tools: ToolMeta[];\n /** Current per-tool mode. Missing entries default to \"enabled\". */\n value: Record<string, ToolMode>;\n onChange: (prefs: Record<string, ToolMode>) => void;\n className?: string;\n};\n\nfunction ToolRow({\n meta,\n mode,\n onToggle,\n}: {\n meta: ToolMeta;\n mode: ToolMode;\n onToggle: (name: string) => void;\n}) {\n return (\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent\"\n onClick={() => onToggle(meta.name)}\n >\n <span className={cn(\"text-xs\", mode === \"disabled\" && \"text-muted-foreground line-through\")}>\n {meta.label}\n </span>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-[10px] font-medium\",\n mode === \"enabled\" &&\n \"bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300\",\n mode === \"ask\" && \"bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300\",\n mode === \"disabled\" && \"bg-muted text-muted-foreground\",\n )}\n >\n {MODE_LABEL[mode]}\n </span>\n </button>\n );\n}\n\n/** A popover that cycles each tool through Auto → Ask → Off. The resulting\n * `Record<name, ToolMode>` is meant to be forwarded to the backend (e.g. via\n * `<Chat body={{ toolPreferences }}>`). */\nexport function ToolPreferences({ tools, value, onChange, className = \"\" }: ToolPreferencesProps) {\n const groups = useMemo(() => {\n const g: Record<string, ToolMeta[]> = {};\n for (const meta of tools) (g[meta.group ?? \"Tools\"] ??= []).push(meta);\n return g;\n }, [tools]);\n\n const handleToggle = (name: string) => {\n const current = value[name] ?? \"enabled\";\n const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length]!;\n onChange({ ...value, [name]: next });\n };\n\n return (\n <DropdownMenu\n align=\"right\"\n className={className}\n menuClassName=\"w-64 max-h-[400px] overflow-y-auto p-3\"\n trigger={\n <Button variant=\"ghost\" size=\"icon\" title=\"Tool preferences\" data-testid=\"tool-preferences-btn\">\n <Icon icon={UiSliders} className=\"size-4\" />\n </Button>\n }\n >\n {() => (\n <div>\n <div className=\"mb-2 text-xs font-semibold\">Tool Preferences</div>\n <p className=\"mb-2 text-[10px] text-muted-foreground\">Click to cycle: Auto → Ask → Off</p>\n {Object.entries(groups).map(([group, metas]) => (\n <div key={group} className=\"mb-2\">\n <div className=\"mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {group}\n </div>\n {metas.map((meta) => (\n <ToolRow\n key={meta.name}\n meta={meta}\n mode={value[meta.name] ?? \"enabled\"}\n onToggle={handleToggle}\n />\n ))}\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":["jsxs","jsx","cn","useMemo","DropdownMenu","Button","Icon","UiSliders"],"mappings":";;;;;;;;;AAcA,MAAM,aAAyB,CAAC,WAAW,OAAO,UAAU;AAC5D,MAAM,aAAuC,EAAE,SAAS,QAAQ,KAAK,OAAO,UAAU,MAAA;AAYtF,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAS,MAAM,SAAS,KAAK,IAAI;AAAA,MAEjC,UAAA;AAAA,QAAAC,2BAAAA,IAAC,QAAA,EAAK,WAAWC,MAAAA,GAAG,WAAW,SAAS,cAAc,oCAAoC,GACvF,UAAA,KAAK,MAAA,CACR;AAAA,QACAD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWC,MAAAA;AAAAA,cACT;AAAA,cACA,SAAS,aACP;AAAA,cACF,SAAS,SAAS;AAAA,cAClB,SAAS,cAAc;AAAA,YAAA;AAAA,YAGxB,qBAAW,IAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAClB;AAAA,IAAA;AAAA,EAAA;AAGN;AAKO,SAAS,gBAAgB,EAAE,OAAO,OAAO,UAAU,YAAY,MAA4B;AAChG,QAAM,SAASC,MAAAA,QAAQ,MAAM;;AAC3B,UAAM,IAAgC,CAAA;AACtC,eAAW,QAAQ,MAAO,EAAC,OAAE,KAAK,SAAS,aAAhB,QAA6B,KAAI,KAAK,IAAI;AACrE,WAAO;AAAA,EACT,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,eAAe,CAAC,SAAiB;AACrC,UAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,UAAM,OAAO,YAAY,WAAW,QAAQ,OAAO,IAAI,KAAK,WAAW,MAAM;AAC7E,aAAS,EAAE,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM;AAAA,EACrC;AAEA,SACEF,2BAAAA;AAAAA,IAACG,aAAAA;AAAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN;AAAA,MACA,eAAc;AAAA,MACd,SACEH,2BAAAA,IAACI,OAAAA,QAAA,EAAO,SAAQ,SAAQ,MAAK,QAAO,OAAM,oBAAmB,eAAY,wBACvE,UAAAJ,+BAACK,KAAAA,MAAA,EAAK,MAAMC,UAAAA,WAAW,WAAU,UAAS,GAC5C;AAAA,MAGD,UAAA,sCACE,OAAA,EACC,UAAA;AAAA,QAAAN,2BAAAA,IAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,oBAAgB;AAAA,QAC5DA,2BAAAA,IAAC,KAAA,EAAE,WAAU,0CAAyC,UAAA,oCAAgC;AAAA,QACrF,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,MACxCD,2BAAAA,KAAC,OAAA,EAAgB,WAAU,QACzB,UAAA;AAAA,UAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,wFACZ,UAAA,OACH;AAAA,UACC,MAAM,IAAI,CAAC,SACVA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,MAAM,MAAM,KAAK,IAAI,KAAK;AAAA,cAC1B,UAAU;AAAA,YAAA;AAAA,YAHL,KAAK;AAAA,UAAA,CAKb;AAAA,QAAA,EAAA,GAXO,KAYV,CACD;AAAA,MAAA,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAIR;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ToolMeta } from '../chat/types';
|
|
2
|
+
export type { ToolMeta };
|
|
3
|
+
/** How a tool may be invoked: run automatically, pause for approval, or be
|
|
4
|
+
* hidden from the model entirely. */
|
|
5
|
+
export type ToolMode = "enabled" | "ask" | "disabled";
|
|
6
|
+
export type ToolPreferencesProps = {
|
|
7
|
+
/** The tools to list. Replaces ai-financials' global registry — callers pass
|
|
8
|
+
* whatever their backend exposes. */
|
|
9
|
+
tools: ToolMeta[];
|
|
10
|
+
/** Current per-tool mode. Missing entries default to "enabled". */
|
|
11
|
+
value: Record<string, ToolMode>;
|
|
12
|
+
onChange: (prefs: Record<string, ToolMode>) => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
/** A popover that cycles each tool through Auto → Ask → Off. The resulting
|
|
16
|
+
* `Record<name, ToolMode>` is meant to be forwarded to the backend (e.g. via
|
|
17
|
+
* `<Chat body={{ toolPreferences }}>`). */
|
|
18
|
+
export declare function ToolPreferences({ tools, value, onChange, className }: ToolPreferencesProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=ToolPreferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolPreferences.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ToolPreferences.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB;sCACsC;AACtC,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;AAKtD,MAAM,MAAM,oBAAoB,GAAG;IACjC;0CACsC;IACtC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAmCF;;4CAE4C;AAC5C,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAc,EAAE,EAAE,oBAAoB,2CA+C/F"}
|