@workbench-kit/react 0.0.2-prototype.0.2.4 → 0.0.2-prototype.0.2.41
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/README.md +172 -0
- package/package.json +38 -21
- package/src/index.ts +74 -34
- package/src/jdw/JsonCodeEditorPane.tsx +7 -6
- package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +1 -3
- package/src/jdw/createBuiltinJdwRegistry.ts +1 -4
- package/src/jdw/cssRenderBackend.tsx +1 -4
- package/src/jdw/fixtures/jdw-fixtures.ts +0 -15
- package/src/json-config/JsonConfigWorkbench.tsx +1 -1
- package/src/layout/index.ts +11 -2
- package/src/layout/panel/Panel.tsx +0 -3
- package/src/layout/panel/index.ts +0 -2
- package/src/layout/sidebar/SideBarTree.tsx +301 -0
- package/src/layout/sidebar/SidebarActionIconBar.tsx +3 -3
- package/src/layout/sidebar/WorkbenchSidebarActions.tsx +1 -1
- package/src/layout/sidebar/index.ts +13 -0
- package/src/modal/Modal.tsx +55 -25
- package/src/modal/ModalTitlebar.tsx +8 -8
- package/src/modal/modalPosition.ts +3 -6
- package/src/modal/useModalFocusTrap.ts +142 -0
- package/src/modal/useModalWindowFrame.ts +2 -2
- package/src/overlay/ContextMenu.tsx +133 -21
- package/src/overlay/context-menu-density.css +22 -0
- package/src/overlay/context-menu-item.ts +17 -0
- package/src/overlay/context-menu.css +6 -2
- package/src/overlay/index.ts +6 -1
- package/src/overlay/measureAnchoredOverlayPanel.ts +4 -6
- package/src/overlay/pointerPassthroughRegion.ts +17 -1
- package/src/overlay/usePointerPassthroughRegion.ts +35 -6
- package/src/primitives/absolute-box/AbsoluteBox.tsx +4 -4
- package/src/primitives/app-icon/AppIcon.tsx +33 -0
- package/src/primitives/app-icon/app-icon.css +28 -0
- package/src/primitives/button/Button.tsx +4 -4
- package/src/primitives/catalog-browse-card/CatalogBrowseCard.tsx +6 -6
- package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +39 -32
- package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +4 -0
- package/src/primitives/catalog-filter-overlay/CatalogFilterOverlay.tsx +2 -2
- package/src/primitives/checkbox/Checkbox.tsx +1 -1
- package/src/primitives/chip/Chip.tsx +3 -12
- package/src/primitives/chip/index.ts +2 -2
- package/src/primitives/codicon/Codicon.tsx +1 -1
- package/src/primitives/file-icon/FileIcon.tsx +1 -1
- package/src/primitives/icon-button/IconButton.tsx +1 -1
- package/src/primitives/index.ts +7 -2
- package/src/primitives/library-detail-layout/LibraryDetailLayout.tsx +123 -9
- package/src/primitives/library-detail-layout/library-detail-layout.css +57 -0
- package/src/primitives/library-detail-layout/resolve-hero-cover-media.ts +80 -0
- package/src/primitives/library-facet-filter-panel/LibraryFacetFilterPanel.tsx +12 -12
- package/src/primitives/library-facet-filter-strip/LibraryFacetFilterStrip.tsx +4 -4
- package/src/primitives/number-input/NumberInput.tsx +5 -5
- package/src/primitives/primitives.css +1 -0
- package/src/primitives/record-media-hero/RecordMediaHero.tsx +10 -6
- package/src/primitives/scroll-area/ScrollArea.tsx +5 -5
- package/src/primitives/scroll-area-infinite-load/useScrollAreaInfiniteLoad.ts +5 -5
- package/src/primitives/searchable-multi-select/SearchableMultiSelect.tsx +7 -7
- package/src/primitives/select/Select.tsx +1 -13
- package/src/primitives/text-area/TextArea.tsx +1 -1
- package/src/primitives/text-input/TextInput.tsx +1 -1
- package/src/primitives/workbench-media-slot/WorkbenchMediaPlaceholder.tsx +2 -2
- package/src/primitives/workbench-media-slot/WorkbenchMediaSlot.tsx +16 -10
- package/src/primitives/workbench-thumbnail/WorkbenchThumbnail.tsx +4 -4
- package/src/scrollbars.css +2 -6
- package/src/styles/core.css +16 -0
- package/src/styles/foundation.css +4 -0
- package/src/styles/overlay.css +2 -0
- package/src/styles.css +1 -15
- package/src/utils/clamp.ts +4 -0
- package/src/utils/normalizeKeyToken.ts +13 -0
- package/src/utils/readNumber.ts +4 -0
- package/src/widget-tree/WidgetSourceEditor.tsx +0 -14
- package/src/widget-tree/WidgetTreeCanvasPreview.tsx +3 -10
- package/src/widget-tree/WidgetTreeLab.tsx +2 -23
- package/src/widget-tree/WidgetTreeSidePanel.tsx +0 -5
- package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +2 -2
- package/src/widget-tree/index.ts +1 -5
- package/src/workbench/auth/WorkbenchLoginView.tsx +1 -2
- package/src/workbench/auth/auth-flows.css +14 -0
- package/src/workbench/chat/ChatCommandProposalCard.tsx +4 -4
- package/src/workbench/chat/ChatConversationBar.tsx +3 -3
- package/src/workbench/chat/ChatHistoryMenu.tsx +1 -1
- package/src/workbench/chat/ChatMessageCollapsible.tsx +4 -0
- package/src/workbench/chat/ChatMessageItem.tsx +68 -10
- package/src/workbench/chat/ChatMessageList.tsx +1 -1
- package/src/workbench/chat/ChatPanel.tsx +32 -23
- package/src/workbench/chat/ChatPhasedRunProgress.tsx +86 -13
- package/src/workbench/chat/ChatRenameDialog.tsx +1 -1
- package/src/workbench/chat/chat-conversation.css +2 -2
- package/src/workbench/chat/chat-ui.css +8 -0
- package/src/workbench/chat/chatConversation.ts +2 -2
- package/src/workbench/chat/chatMessageMeta.tsx +4 -4
- package/src/workbench/chat/index.ts +1 -0
- package/src/workbench/chat/types.ts +7 -7
- package/src/workbench/chat/useCancelRuntimeOnUnmount.ts +4 -4
- package/src/workbench/chat/useChatPrependPagination.ts +10 -10
- package/src/workbench/chat/useSlashCommandSuggest.ts +1 -1
- package/src/workbench/{WorkbenchModalPortal.tsx → chrome/WorkbenchModalPortal.tsx} +1 -1
- package/src/workbench/chrome/workbench-chrome.css +4 -0
- package/src/workbench/chrome/workbench-layout-regions.css +13 -0
- package/src/workbench/chrome/workbench-shell-titlebar.css +0 -8
- package/src/workbench/{CommandGroupShell.tsx → commands/CommandGroupShell.tsx} +2 -2
- package/src/workbench/{CommandList.tsx → commands/CommandList.tsx} +6 -5
- package/src/workbench/{CommandPalette.tsx → commands/CommandPalette.tsx} +16 -42
- package/src/workbench/{ConfirmationFlow.tsx → commands/ConfirmationFlow.tsx} +5 -5
- package/src/workbench/{ShortcutCommandBridge.tsx → commands/ShortcutCommandBridge.tsx} +17 -13
- package/src/workbench/commands/WorkbenchQuickOpen.tsx +462 -0
- package/src/workbench/{command-model.ts → commands/command-model.ts} +5 -1
- package/src/workbench/commands/command-ui.ts +3 -0
- package/src/workbench/{commands.ts → commands/commands.ts} +45 -1
- package/src/workbench/commands/createWorkspaceFilesQuickOpenProvider.ts +86 -0
- package/src/workbench/commands/quick-open-model.ts +66 -0
- package/src/workbench/{WorkbenchEditorTabs.tsx → editor/WorkbenchEditorTabs.tsx} +13 -3
- package/src/workbench/{editor-tabs-dnd.ts → editor/editor-tabs-dnd.ts} +1 -1
- package/src/workbench/{editorTabContextMenu.ts → editor/editorTabContextMenu.ts} +43 -4
- package/src/workbench/{useEditorTabsStripDnd.ts → editor/useEditorTabsStripDnd.ts} +1 -1
- package/src/workbench/{useWorkbenchEditorTabContextMenu.tsx → editor/useWorkbenchEditorTabContextMenu.tsx} +16 -2
- package/src/workbench/editor-tabs/index.ts +10 -9
- package/src/workbench/index.ts +114 -74
- package/src/workbench/management/CommandManagementSidebar.tsx +16 -30
- package/src/workbench/management/ExtensionManagementPanel.tsx +84 -46
- package/src/workbench/management/ExtensionManagementSidebar.tsx +79 -45
- package/src/workbench/management/IntegrationCommandActions.tsx +8 -1
- package/src/workbench/management/IntegrationSettingsSurface.tsx +2 -5
- package/src/workbench/management/IntegrationsShell.tsx +1 -1
- package/src/workbench/management/KeybindingCaptureField.tsx +1 -9
- package/src/workbench/management/WorkbenchDialogFrame.tsx +2 -2
- package/src/workbench/management/WorkbenchNotice.tsx +17 -12
- package/src/workbench/management/createWorkbenchNotify.tsx +88 -0
- package/src/workbench/management/extension-install-approval.ts +72 -0
- package/src/workbench/management/extension-management-filters.ts +38 -0
- package/src/workbench/management/index.ts +18 -3
- package/src/workbench/management/management.css +28 -0
- package/src/workbench/management/types.ts +23 -1
- package/src/workbench/management/useWorkbenchNotify.ts +10 -0
- package/src/workbench/{MarkdownPreview.tsx → markdown/MarkdownPreview.tsx} +22 -7
- package/src/workbench/markdown/markdownRemarkPlugins.ts +12 -0
- package/src/workbench/markdown/sanitizeMarkdownHref.ts +29 -0
- package/src/workbench/schema/workbenchDocumentRenderer.tsx +48 -121
- package/src/workbench/settings/StructuredDataForm.tsx +1 -4
- package/src/workbench/settings/StructuredDataSchemaPanel.tsx +39 -44
- package/src/workbench/settings/sectionedPanelScrollSpy.ts +0 -81
- package/src/workbench/settings/structuredDataFormModel.ts +2 -1
- package/src/workbench/settings/structuredDataSchema.ts +24 -13
- package/src/workbench/settings/structuredDataSchemaSection.ts +4 -0
- package/src/workbench/settings/structuredDataSchemaTable.ts +5 -2
- package/src/workbench/{ActivityBar.tsx → shell/ActivityBar.tsx} +8 -12
- package/src/workbench/{ArtifactShell.tsx → shell/ArtifactShell.tsx} +25 -25
- package/src/workbench/{SplitView.tsx → shell/SplitView.tsx} +3 -3
- package/src/workbench/{StatusBar.tsx → shell/StatusBar.tsx} +8 -8
- package/src/workbench/{StructuredArtifactEditor.tsx → shell/StructuredArtifactEditor.tsx} +9 -9
- package/src/workbench/{Timeline.tsx → shell/Timeline.tsx} +77 -20
- package/src/workbench/{WorkbenchCanvasShell.defaults.ts → shell/WorkbenchCanvasShell.defaults.ts} +1 -1
- package/src/workbench/{WorkbenchCanvasShell.model.ts → shell/WorkbenchCanvasShell.model.ts} +5 -5
- package/src/workbench/{WorkbenchCanvasShell.tsx → shell/WorkbenchCanvasShell.tsx} +6 -6
- package/src/workbench/{WorkbenchDesktopTitleBar.tsx → shell/WorkbenchDesktopTitleBar.tsx} +15 -15
- package/src/workbench/{WorkbenchShell.tsx → shell/WorkbenchShell.tsx} +45 -6
- package/src/workbench/{WorkbenchShellTitleBarLayoutControls.tsx → shell/WorkbenchShellTitleBarLayoutControls.tsx} +16 -19
- package/src/workbench/{WorkbenchStandaloneShell.tsx → shell/WorkbenchStandaloneShell.tsx} +15 -22
- package/src/workbench/{WorkbenchViewEditor.tsx → shell/WorkbenchViewEditor.tsx} +7 -7
- package/src/workbench/{WorkbenchViewSidebar.tsx → shell/WorkbenchViewSidebar.tsx} +7 -7
- package/src/workbench/{WorkbenchWindowChromeControls.tsx → shell/WorkbenchWindowChromeControls.tsx} +18 -15
- package/src/workbench/shell/activity-bar.css +47 -0
- package/src/workbench/{activityBarOrder.ts → shell/activityBarOrder.ts} +2 -1
- package/src/workbench/{shell.ts → shell/shell.ts} +20 -13
- package/src/workbench/{shellViewModel.ts → shell/shellViewModel.ts} +3 -3
- package/src/workbench/{standalone.ts → shell/standalone.ts} +14 -2
- package/src/workbench/{useDeferredWorkbenchMount.ts → shell/useDeferredWorkbenchMount.ts} +3 -3
- package/src/workbench/{useWorkbenchAppearanceDocumentSync.tsx → shell/useWorkbenchAppearanceDocumentSync.tsx} +1 -1
- package/src/workbench/{useWorkbenchSidebarActionBarDnd.ts → shell/useWorkbenchSidebarActionBarDnd.ts} +1 -1
- package/src/workbench/{useWorkbenchSidebarViewPlacementDropZone.ts → shell/useWorkbenchSidebarViewPlacementDropZone.ts} +2 -2
- package/src/workbench/{workbenchSidebarLayoutContext.ts → shell/workbenchSidebarLayoutContext.ts} +0 -6
- package/src/workbench/{workbenchViewRouteState.ts → shell/workbenchViewRouteState.ts} +4 -4
- package/src/workbench/{WorkbenchThemeProvider.tsx → theme/WorkbenchThemeProvider.tsx} +4 -4
- package/src/workbench/{theme.ts → theme/theme.ts} +1 -1
- package/src/workbench/{themePresets.ts → theme/themePresets.ts} +39 -64
- package/src/workbench/views/command-list-density.css +36 -0
- package/src/workbench/views/command-list.css +2 -0
- package/src/workbench/views/extensions-sidebar.css +2 -0
- package/src/workbench/views/view-hosts.css +3 -3
- package/src/workbench/workspace/WorkspaceEditorPanel.tsx +1 -1
- package/src/workbench/workspace/WorkspaceExplorer.tsx +105 -4
- package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +1 -14
- package/src/workbench/workspace/workspaceExplorerKeyboard.ts +109 -0
- package/src/workbench/workspace/workspaceJsonDiagnostics.ts +6 -5
- package/src/workbench-menu-surfaces.css +3 -57
- package/src/brand/TilepaperAppIcon.tsx +0 -181
- package/src/brand/index.ts +0 -2
- package/src/brand/tilepaper-app-icon-geometry.ts +0 -201
- package/src/primitives/absolute-box/index.ts +0 -1
- package/src/primitives/catalog-browse-card/index.ts +0 -1
- package/src/primitives/catalog-browse-pane/index.ts +0 -3
- package/src/primitives/catalog-filter-overlay/index.ts +0 -1
- package/src/primitives/codicon/index.ts +0 -1
- package/src/primitives/external-link-button/index.ts +0 -1
- package/src/primitives/library-detail-layout/index.ts +0 -1
- package/src/primitives/library-facet-filter-panel/index.ts +0 -1
- package/src/primitives/library-facet-filter-strip/index.ts +0 -1
- package/src/primitives/panel-loading/index.ts +0 -1
- package/src/primitives/scroll-area-infinite-load/index.ts +0 -2
- package/src/primitives/workbench-thumbnail/index.ts +0 -1
- package/src/test-utils/workbenchMonacoMock.tsx +0 -37
- package/src/workbench/jdw/jdw-editors.css +0 -4
- package/src/workbench/jdw/jdw.css +0 -2
- package/src/workbench/management/integration-command-action.ts +0 -25
- package/src/workbench/markdownRemarkPlugins.ts +0 -4
- package/src/workbench/workbench-chrome.css +0 -4
- /package/src/workbench/{WorkbenchPlatformContext.tsx → chrome/WorkbenchPlatformContext.tsx} +0 -0
- /package/src/workbench/{workbenchModalViewState.ts → chrome/workbenchModalViewState.ts} +0 -0
- /package/src/workbench/{workbenchOverlaysContext.tsx → chrome/workbenchOverlaysContext.tsx} +0 -0
- /package/src/workbench/{workbenchPlatformChrome.ts → chrome/workbenchPlatformChrome.ts} +0 -0
- /package/src/workbench/{command-execution-policy.ts → commands/command-execution-policy.ts} +0 -0
- /package/src/workbench/{keyboard.ts → commands/keyboard.ts} +0 -0
- /package/src/workbench/{workbenchContextMenu.ts → commands/workbenchContextMenu.ts} +0 -0
- /package/src/workbench/{appearanceLabels.ts → shell/appearanceLabels.ts} +0 -0
- /package/src/workbench/{hardReset.ts → shell/hardReset.ts} +0 -0
- /package/src/workbench/{shellPresets.ts → shell/shellPresets.ts} +0 -0
- /package/src/workbench/{shellState.ts → shell/shellState.ts} +0 -0
- /package/src/workbench/{sidebarViewPlacementDnd.ts → shell/sidebarViewPlacementDnd.ts} +0 -0
- /package/src/workbench/{status.ts → shell/status.ts} +0 -0
- /package/src/workbench/{useWorkbenchSidebarLayout.tsx → shell/useWorkbenchSidebarLayout.tsx} +0 -0
- /package/src/workbench/{useWorkbenchStandaloneShellStateSync.tsx → shell/useWorkbenchStandaloneShellStateSync.tsx} +0 -0
- /package/src/workbench/{workbenchStandaloneShellReactContext.tsx → shell/workbenchStandaloneShellReactContext.tsx} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Badge } from '../../primitives/badge';
|
|
2
2
|
import { Button } from '../../primitives/button';
|
|
3
3
|
import { cx } from '../../utils/cx';
|
|
4
|
-
import { getWorkbenchCommandExecutionPolicyLabel } from '../command-execution-policy';
|
|
5
|
-
import type { WorkbenchCommandExecutionPolicy } from '../command-model';
|
|
4
|
+
import { getWorkbenchCommandExecutionPolicyLabel } from '../commands/command-execution-policy';
|
|
5
|
+
import type { WorkbenchCommandExecutionPolicy } from '../commands/command-model';
|
|
6
6
|
import type { ChatCommandProposal, ChatCommandProposalStatus } from './types';
|
|
7
7
|
|
|
8
8
|
export interface ChatCommandProposalCardProps {
|
|
9
|
-
onAllow?: (
|
|
10
|
-
onDeny?: (
|
|
9
|
+
onAllow?: (proposal: ChatCommandProposal) => void;
|
|
10
|
+
onDeny?: (proposal: ChatCommandProposal) => void;
|
|
11
11
|
proposal: ChatCommandProposal;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -12,14 +12,14 @@ import { defaultWorkbenchChatConversationLabels } from './chatConversation';
|
|
|
12
12
|
export interface ChatConversationBarProps {
|
|
13
13
|
activeConversationId: string;
|
|
14
14
|
conversations: readonly WorkbenchChatConversation[];
|
|
15
|
-
labels?: Partial<WorkbenchChatConversationLabels
|
|
16
|
-
moreMenuItems?: readonly ContextMenuItem[]
|
|
15
|
+
labels?: Partial<WorkbenchChatConversationLabels>;
|
|
16
|
+
moreMenuItems?: readonly ContextMenuItem[];
|
|
17
17
|
onActivate: (conversationId: string) => void;
|
|
18
18
|
onCreate: () => void;
|
|
19
19
|
onDelete: (conversationId: string) => void;
|
|
20
20
|
onRename: (conversationId: string, title: string) => void;
|
|
21
21
|
/** Optional slot for a second pill next to the active conversation control. */
|
|
22
|
-
secondaryPill?: ReactNode
|
|
22
|
+
secondaryPill?: ReactNode;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function ChatConversationBar({
|
|
@@ -15,7 +15,7 @@ import { buildChatHistoryRowMenuItems } from './chatHistoryRowMenuItems';
|
|
|
15
15
|
export interface ChatHistoryMenuProps {
|
|
16
16
|
activeConversationId: string;
|
|
17
17
|
conversations: readonly WorkbenchChatConversation[];
|
|
18
|
-
labels?: Partial<WorkbenchChatConversationLabels
|
|
18
|
+
labels?: Partial<WorkbenchChatConversationLabels>;
|
|
19
19
|
x: number;
|
|
20
20
|
y: number;
|
|
21
21
|
onActivate: (conversationId: string) => void;
|
|
@@ -5,6 +5,8 @@ import { cx } from '../../utils/cx';
|
|
|
5
5
|
export const CHAT_MESSAGE_COLLAPSE_MAX_LINES = 8;
|
|
6
6
|
|
|
7
7
|
export interface ChatMessageCollapsibleProps {
|
|
8
|
+
/** In-bubble region after message body (file chips, etc.). */
|
|
9
|
+
attachments?: ReactNode;
|
|
8
10
|
children: ReactNode;
|
|
9
11
|
className?: string;
|
|
10
12
|
content: string;
|
|
@@ -26,6 +28,7 @@ function measureChatMessageNeedsCollapse(body: HTMLElement, maxLines: number): b
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
export function ChatMessageCollapsible({
|
|
31
|
+
attachments,
|
|
29
32
|
children,
|
|
30
33
|
className,
|
|
31
34
|
content,
|
|
@@ -99,6 +102,7 @@ export function ChatMessageCollapsible({
|
|
|
99
102
|
>
|
|
100
103
|
{children}
|
|
101
104
|
</div>
|
|
105
|
+
{attachments ? <div className="message__attachments">{attachments}</div> : null}
|
|
102
106
|
{needsCollapse && !isStreaming ? (
|
|
103
107
|
<Button
|
|
104
108
|
aria-expanded={expanded}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import Markdown from 'react-markdown';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import { cx } from '../../utils/cx';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
workbenchMarkdownRemarkPlugins,
|
|
6
|
+
workbenchMarkdownRehypePlugins,
|
|
7
|
+
} from '../markdown/markdownRemarkPlugins';
|
|
8
|
+
import { sanitizeMarkdownHref } from '../markdown/sanitizeMarkdownHref';
|
|
5
9
|
import { ChatCommandProposalCard } from './ChatCommandProposalCard';
|
|
6
10
|
import { ChatMessageCollapsible } from './ChatMessageCollapsible';
|
|
7
11
|
import { ChatMessageTime, resolveChatMessageTimestamp } from './chatMessageMeta';
|
|
@@ -16,26 +20,38 @@ import type {
|
|
|
16
20
|
export interface ChatMessageItemProps {
|
|
17
21
|
/**
|
|
18
22
|
* Rendered after the bubble (and before command proposals). Use for
|
|
19
|
-
*
|
|
23
|
+
* host chrome that should stay outside the collapsible surface.
|
|
24
|
+
* Prefer `attachments` for in-bubble file chips.
|
|
20
25
|
*/
|
|
21
|
-
afterMessage?: ReactNode
|
|
26
|
+
afterMessage?: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* In-bubble attachment region (file chips, etc.). Renders inside the bubble
|
|
29
|
+
* surface after the message body. Prefer this over `afterMessage` when chips
|
|
30
|
+
* must stay end-aligned with user bubbles.
|
|
31
|
+
*/
|
|
32
|
+
attachments?: ReactNode;
|
|
22
33
|
assistantLabel?: string;
|
|
23
34
|
/** Overrides `message.contentMode` when set. */
|
|
24
|
-
contentMode?: ChatMessageContentMode
|
|
35
|
+
contentMode?: ChatMessageContentMode;
|
|
25
36
|
/**
|
|
26
37
|
* Forwarded into `ChatMessageCollapsible` in-bubble footer (progress, actions).
|
|
27
38
|
*/
|
|
28
|
-
footer?: ReactNode
|
|
39
|
+
footer?: ReactNode;
|
|
29
40
|
isStreaming?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Assistant-layout label icon. Defaults to sparkle; error/warning tones use
|
|
43
|
+
* status icons. Pass a custom node to override, or `false` to hide.
|
|
44
|
+
*/
|
|
45
|
+
labelIcon?: ReactNode | false;
|
|
30
46
|
layout?: ChatMessageLayout;
|
|
31
47
|
message: ChatMessage;
|
|
32
|
-
onCommandProposalAllow?: (
|
|
33
|
-
onCommandProposalDeny?: (
|
|
48
|
+
onCommandProposalAllow?: (messageId: string, proposal: ChatCommandProposal) => void;
|
|
49
|
+
onCommandProposalDeny?: (messageId: string, proposal: ChatCommandProposal) => void;
|
|
34
50
|
showSenderLabel?: boolean;
|
|
35
51
|
/** When true, keeps the inline timestamp visible without hover. */
|
|
36
52
|
showTimestamp?: boolean;
|
|
37
53
|
/** Overrides `message.tone` when set. */
|
|
38
|
-
tone?: ChatMessageTone
|
|
54
|
+
tone?: ChatMessageTone;
|
|
39
55
|
userLabel?: string;
|
|
40
56
|
}
|
|
41
57
|
|
|
@@ -151,6 +167,25 @@ function resolveChatMessageToneClass(
|
|
|
151
167
|
return undefined;
|
|
152
168
|
}
|
|
153
169
|
|
|
170
|
+
function resolveAssistantLabelIcon(
|
|
171
|
+
labelIcon: ReactNode | false | undefined,
|
|
172
|
+
tone: ChatMessageTone | undefined,
|
|
173
|
+
): ReactNode | null {
|
|
174
|
+
if (labelIcon === false) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
if (labelIcon !== undefined) {
|
|
178
|
+
return labelIcon;
|
|
179
|
+
}
|
|
180
|
+
if (tone === 'error') {
|
|
181
|
+
return <i className="codicon codicon-error message__label-icon" />;
|
|
182
|
+
}
|
|
183
|
+
if (tone === 'warning') {
|
|
184
|
+
return <i className="codicon codicon-warning message__label-icon" />;
|
|
185
|
+
}
|
|
186
|
+
return <i className="codicon codicon-sparkle message__label-icon" />;
|
|
187
|
+
}
|
|
188
|
+
|
|
154
189
|
function ChatMessageBody({
|
|
155
190
|
content,
|
|
156
191
|
contentMode,
|
|
@@ -165,7 +200,23 @@ function ChatMessageBody({
|
|
|
165
200
|
<div className="md-content">
|
|
166
201
|
<Markdown
|
|
167
202
|
remarkPlugins={workbenchMarkdownRemarkPlugins}
|
|
203
|
+
rehypePlugins={workbenchMarkdownRehypePlugins}
|
|
168
204
|
components={{
|
|
205
|
+
a: ({ children, href }) => {
|
|
206
|
+
const safeHref = sanitizeMarkdownHref(href);
|
|
207
|
+
if (!safeHref) {
|
|
208
|
+
return <span>{children}</span>;
|
|
209
|
+
}
|
|
210
|
+
return (
|
|
211
|
+
<a
|
|
212
|
+
href={safeHref}
|
|
213
|
+
rel="noreferrer"
|
|
214
|
+
target={safeHref.startsWith('#') ? undefined : '_blank'}
|
|
215
|
+
>
|
|
216
|
+
{children}
|
|
217
|
+
</a>
|
|
218
|
+
);
|
|
219
|
+
},
|
|
169
220
|
code: ({ children, className }) => (
|
|
170
221
|
<code className={cx('ui-workbench-scrollbar', className)}>{children}</code>
|
|
171
222
|
),
|
|
@@ -188,10 +239,12 @@ function ChatMessageBody({
|
|
|
188
239
|
|
|
189
240
|
export function ChatMessageItem({
|
|
190
241
|
afterMessage,
|
|
242
|
+
attachments,
|
|
191
243
|
assistantLabel = 'Assistant',
|
|
192
244
|
contentMode: contentModeProp,
|
|
193
245
|
footer,
|
|
194
246
|
isStreaming = false,
|
|
247
|
+
labelIcon,
|
|
195
248
|
layout = 'assistant',
|
|
196
249
|
message,
|
|
197
250
|
onCommandProposalAllow,
|
|
@@ -204,7 +257,9 @@ export function ChatMessageItem({
|
|
|
204
257
|
const timestamp = renderMessageTimestamp(message, showTimestamp);
|
|
205
258
|
const bubbleAlign = message.source === 'user' ? 'end' : 'start';
|
|
206
259
|
const contentMode = resolveChatMessageContentMode(message, layout, contentModeProp);
|
|
207
|
-
const
|
|
260
|
+
const resolvedTone = toneProp ?? message.tone;
|
|
261
|
+
const toneClass = resolveChatMessageToneClass(resolvedTone);
|
|
262
|
+
const assistantLabelIcon = resolveAssistantLabelIcon(labelIcon, resolvedTone);
|
|
208
263
|
const body = (
|
|
209
264
|
<ChatMessageBody
|
|
210
265
|
content={message.content}
|
|
@@ -234,6 +289,7 @@ export function ChatMessageItem({
|
|
|
234
289
|
) : null}
|
|
235
290
|
<MessageBubbleLine align={bubbleAlign} timestamp={timestamp}>
|
|
236
291
|
<ChatMessageCollapsible
|
|
292
|
+
attachments={attachments}
|
|
237
293
|
content={message.content}
|
|
238
294
|
footer={footer}
|
|
239
295
|
isStreaming={isStreaming}
|
|
@@ -266,6 +322,7 @@ export function ChatMessageItem({
|
|
|
266
322
|
{peerLabel ? <div className="message__peer-label">{peerLabel}</div> : null}
|
|
267
323
|
<MessageBubbleLine align={bubbleAlign} timestamp={timestamp}>
|
|
268
324
|
<ChatMessageCollapsible
|
|
325
|
+
attachments={attachments}
|
|
269
326
|
content={message.content}
|
|
270
327
|
footer={footer}
|
|
271
328
|
isStreaming={isStreaming}
|
|
@@ -291,11 +348,12 @@ export function ChatMessageItem({
|
|
|
291
348
|
<div className="message__row">
|
|
292
349
|
<div className="message__main">
|
|
293
350
|
<div className="message__label message__label--assistant">
|
|
294
|
-
|
|
351
|
+
{assistantLabelIcon}
|
|
295
352
|
{message.label ?? assistantLabel}
|
|
296
353
|
</div>
|
|
297
354
|
<MessageBubbleLine align={bubbleAlign} timestamp={timestamp}>
|
|
298
355
|
<ChatMessageCollapsible
|
|
356
|
+
attachments={attachments}
|
|
299
357
|
className="message__assistant-collapsible"
|
|
300
358
|
content={message.content}
|
|
301
359
|
footer={footer}
|
|
@@ -23,7 +23,7 @@ export interface ChatMessageListProps {
|
|
|
23
23
|
* Host slot rendered inside the message list area after messages, or as a
|
|
24
24
|
* sibling before the empty state when there are no messages.
|
|
25
25
|
*/
|
|
26
|
-
messageListAddon?: ReactNode
|
|
26
|
+
messageListAddon?: ReactNode;
|
|
27
27
|
messages: ChatMessage[];
|
|
28
28
|
onCommandProposalAllow?: ChatMessageItemProps['onCommandProposalAllow'];
|
|
29
29
|
onCommandProposalDeny?: ChatMessageItemProps['onCommandProposalDeny'];
|
|
@@ -22,18 +22,23 @@ export interface ChatPanelProps
|
|
|
22
22
|
| 'showTools'
|
|
23
23
|
| 'value'
|
|
24
24
|
> {
|
|
25
|
-
className?: string
|
|
26
|
-
composerRef?: Ref<HTMLTextAreaElement
|
|
25
|
+
className?: string;
|
|
26
|
+
composerRef?: Ref<HTMLTextAreaElement>;
|
|
27
27
|
/** Label shown on the file-drop overlay. Defaults to "Drop files to attach". */
|
|
28
|
-
filesDropLabel?: string
|
|
29
|
-
headerAddon?: ReactNode
|
|
28
|
+
filesDropLabel?: string;
|
|
29
|
+
headerAddon?: ReactNode;
|
|
30
30
|
/** Called when files are dropped onto the panel (disabled while `disabled` or `isRunning`). */
|
|
31
|
-
onFilesDrop?: (
|
|
31
|
+
onFilesDrop?: (files: File[]) => void;
|
|
32
32
|
/**
|
|
33
33
|
* Wrap or replace the default `<ChatMessageList />` so hosts can inject
|
|
34
34
|
* hybrid timelines around the kit list.
|
|
35
35
|
*/
|
|
36
|
-
renderMessageList?: (
|
|
36
|
+
renderMessageList?: (defaultList: ReactNode) => ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Wrap or replace the default `<ChatComposer />` while keeping panel chrome
|
|
39
|
+
* and file-drop overlay behavior.
|
|
40
|
+
*/
|
|
41
|
+
renderComposer?: (defaultComposer: ReactNode) => ReactNode;
|
|
37
42
|
title?: string;
|
|
38
43
|
}
|
|
39
44
|
|
|
@@ -53,6 +58,7 @@ export function ChatPanel({
|
|
|
53
58
|
filesDropLabel = 'Drop files to attach',
|
|
54
59
|
headerAddon,
|
|
55
60
|
onFilesDrop,
|
|
61
|
+
renderComposer,
|
|
56
62
|
renderMessageList,
|
|
57
63
|
title = 'Chat',
|
|
58
64
|
value,
|
|
@@ -125,6 +131,25 @@ export function ChatPanel({
|
|
|
125
131
|
? renderMessageList(defaultMessageList)
|
|
126
132
|
: defaultMessageList;
|
|
127
133
|
|
|
134
|
+
const defaultComposer = (
|
|
135
|
+
<ChatComposer
|
|
136
|
+
ref={composerRef}
|
|
137
|
+
commandLabel={commandLabel}
|
|
138
|
+
commandSuggestPopover={commandSuggestPopover}
|
|
139
|
+
disabled={disabled}
|
|
140
|
+
isRunning={isRunning}
|
|
141
|
+
placeholder={placeholder}
|
|
142
|
+
showTools={showTools}
|
|
143
|
+
value={value}
|
|
144
|
+
onCancel={onCancel}
|
|
145
|
+
onCommandClick={onCommandClick}
|
|
146
|
+
onKeyDown={onKeyDown}
|
|
147
|
+
onSubmit={onSubmit}
|
|
148
|
+
onValueChange={onValueChange}
|
|
149
|
+
/>
|
|
150
|
+
);
|
|
151
|
+
const composer = renderComposer ? renderComposer(defaultComposer) : defaultComposer;
|
|
152
|
+
|
|
128
153
|
return (
|
|
129
154
|
<div
|
|
130
155
|
className={cx('chat-panel-drop-target', isFileDragActive && 'chat-panel-drop-target--active')}
|
|
@@ -135,23 +160,7 @@ export function ChatPanel({
|
|
|
135
160
|
>
|
|
136
161
|
<SideBarViewFrame
|
|
137
162
|
className={cx('chat-sidebar-view', className)}
|
|
138
|
-
footer={
|
|
139
|
-
<ChatComposer
|
|
140
|
-
ref={composerRef}
|
|
141
|
-
commandLabel={commandLabel}
|
|
142
|
-
commandSuggestPopover={commandSuggestPopover}
|
|
143
|
-
disabled={disabled}
|
|
144
|
-
isRunning={isRunning}
|
|
145
|
-
placeholder={placeholder}
|
|
146
|
-
showTools={showTools}
|
|
147
|
-
value={value}
|
|
148
|
-
onCancel={onCancel}
|
|
149
|
-
onCommandClick={onCommandClick}
|
|
150
|
-
onKeyDown={onKeyDown}
|
|
151
|
-
onSubmit={onSubmit}
|
|
152
|
-
onValueChange={onValueChange}
|
|
153
|
-
/>
|
|
154
|
-
}
|
|
163
|
+
footer={composer}
|
|
155
164
|
footerPlacement="overlay"
|
|
156
165
|
headerAddon={headerAddon}
|
|
157
166
|
title={title}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getWorkbenchStatusDescriptor,
|
|
8
8
|
type WorkbenchStatus,
|
|
9
9
|
type WorkbenchStatusVariant,
|
|
10
|
-
} from '../status';
|
|
10
|
+
} from '../shell/status';
|
|
11
11
|
|
|
12
12
|
/** Product-neutral phase lifecycle for run-progress UIs. */
|
|
13
13
|
export type ChatRunPhaseStatus =
|
|
@@ -29,6 +29,20 @@ export interface ChatPhasedRunProgressAction {
|
|
|
29
29
|
readonly variant?: 'default' | 'primary' | 'danger';
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Overridable chrome strings for locale-aware hosts. Unset keys keep English defaults.
|
|
34
|
+
*/
|
|
35
|
+
export interface ChatPhasedRunProgressLabels {
|
|
36
|
+
readonly expand?: string;
|
|
37
|
+
readonly collapse?: string;
|
|
38
|
+
readonly noPhases?: string;
|
|
39
|
+
readonly phasesComplete?: (completed: number, total: number) => string;
|
|
40
|
+
/** Summary badge label for the aggregate run status. */
|
|
41
|
+
readonly summaryStatus?: (status: ChatRunPhaseStatus) => string;
|
|
42
|
+
/** Per-phase status badge label (also used when `summaryStatus` is omitted). */
|
|
43
|
+
readonly getStatusLabel?: (status: ChatRunPhaseStatus) => string;
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
function toBadgeVariant(variant: WorkbenchStatusVariant): 'accent' | 'muted' | 'danger' {
|
|
33
47
|
if (variant === 'danger' || variant === 'warning') {
|
|
34
48
|
return 'danger';
|
|
@@ -50,6 +64,8 @@ export interface ChatPhasedRunProgressProps {
|
|
|
50
64
|
/** Extra footer content (host-owned). */
|
|
51
65
|
readonly footer?: ReactNode;
|
|
52
66
|
readonly className?: string;
|
|
67
|
+
/** Locale-aware chrome labels; defaults preserve English copy. */
|
|
68
|
+
readonly labels?: ChatPhasedRunProgressLabels;
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
function mapPhaseStatusToWorkbenchStatus(status: ChatRunPhaseStatus): WorkbenchStatus {
|
|
@@ -73,26 +89,73 @@ function mapPhaseStatusToWorkbenchStatus(status: ChatRunPhaseStatus): WorkbenchS
|
|
|
73
89
|
}
|
|
74
90
|
}
|
|
75
91
|
|
|
76
|
-
|
|
92
|
+
const DEFAULT_SUMMARY_STATUS_LABELS: Record<ChatRunPhaseStatus, string> = {
|
|
93
|
+
pending: 'Pending',
|
|
94
|
+
running: 'Running',
|
|
95
|
+
completed: 'Completed',
|
|
96
|
+
failed: 'Failed',
|
|
97
|
+
skipped: 'Idle',
|
|
98
|
+
cancelled: 'Cancelled',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function resolveStatusLabel(
|
|
102
|
+
status: ChatRunPhaseStatus,
|
|
103
|
+
labels: ChatPhasedRunProgressLabels | undefined,
|
|
104
|
+
prefer: 'summary' | 'phase' = 'summary',
|
|
105
|
+
): string {
|
|
106
|
+
const primary =
|
|
107
|
+
prefer === 'summary'
|
|
108
|
+
? (labels?.summaryStatus?.(status) ?? labels?.getStatusLabel?.(status))
|
|
109
|
+
: (labels?.getStatusLabel?.(status) ?? labels?.summaryStatus?.(status));
|
|
110
|
+
if (primary) {
|
|
111
|
+
return primary;
|
|
112
|
+
}
|
|
113
|
+
if (status === 'skipped') {
|
|
114
|
+
return getWorkbenchStatusDescriptor(mapPhaseStatusToWorkbenchStatus(status)).label;
|
|
115
|
+
}
|
|
116
|
+
return (
|
|
117
|
+
DEFAULT_SUMMARY_STATUS_LABELS[status] ??
|
|
118
|
+
getWorkbenchStatusDescriptor(mapPhaseStatusToWorkbenchStatus(status)).label
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function summarizePhases(
|
|
123
|
+
phases: readonly ChatRunPhase[],
|
|
124
|
+
labels: ChatPhasedRunProgressLabels | undefined,
|
|
125
|
+
): {
|
|
77
126
|
label: string;
|
|
78
127
|
status: ChatRunPhaseStatus;
|
|
79
128
|
} {
|
|
80
129
|
if (phases.some((phase) => phase.status === 'failed')) {
|
|
81
|
-
return { label: '
|
|
130
|
+
return { label: resolveStatusLabel('failed', labels, 'summary'), status: 'failed' };
|
|
82
131
|
}
|
|
83
132
|
if (phases.some((phase) => phase.status === 'running')) {
|
|
84
|
-
return { label: '
|
|
133
|
+
return { label: resolveStatusLabel('running', labels, 'summary'), status: 'running' };
|
|
85
134
|
}
|
|
86
135
|
if (phases.some((phase) => phase.status === 'cancelled')) {
|
|
87
|
-
return { label: '
|
|
136
|
+
return { label: resolveStatusLabel('cancelled', labels, 'summary'), status: 'cancelled' };
|
|
88
137
|
}
|
|
89
138
|
if (
|
|
90
139
|
phases.length > 0 &&
|
|
91
140
|
phases.every((phase) => phase.status === 'completed' || phase.status === 'skipped')
|
|
92
141
|
) {
|
|
93
|
-
return { label: '
|
|
142
|
+
return { label: resolveStatusLabel('completed', labels, 'summary'), status: 'completed' };
|
|
143
|
+
}
|
|
144
|
+
return { label: resolveStatusLabel('pending', labels, 'summary'), status: 'pending' };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function resolvePhaseBadgeLabel(
|
|
148
|
+
status: ChatRunPhaseStatus,
|
|
149
|
+
labels: ChatPhasedRunProgressLabels | undefined,
|
|
150
|
+
): string {
|
|
151
|
+
if (labels?.getStatusLabel) {
|
|
152
|
+
return labels.getStatusLabel(status);
|
|
153
|
+
}
|
|
154
|
+
// Pending maps to workbench "waiting" / "Waiting"; keep summary vocabulary ("Pending").
|
|
155
|
+
if (status === 'pending') {
|
|
156
|
+
return resolveStatusLabel('pending', labels, 'summary');
|
|
94
157
|
}
|
|
95
|
-
return
|
|
158
|
+
return getWorkbenchStatusDescriptor(mapPhaseStatusToWorkbenchStatus(status)).label;
|
|
96
159
|
}
|
|
97
160
|
|
|
98
161
|
/**
|
|
@@ -108,14 +171,24 @@ export function ChatPhasedRunProgress({
|
|
|
108
171
|
actions,
|
|
109
172
|
footer,
|
|
110
173
|
className,
|
|
174
|
+
labels,
|
|
111
175
|
}: ChatPhasedRunProgressProps) {
|
|
112
176
|
const panelId = useId();
|
|
113
177
|
const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);
|
|
114
178
|
const isExpanded = expanded ?? uncontrolledExpanded;
|
|
115
|
-
const summary = summarizePhases(phases);
|
|
179
|
+
const summary = summarizePhases(phases, labels);
|
|
116
180
|
const summaryDescriptor = getWorkbenchStatusDescriptor(
|
|
117
181
|
mapPhaseStatusToWorkbenchStatus(summary.status),
|
|
118
182
|
);
|
|
183
|
+
const expandLabel = labels?.expand ?? 'Expand';
|
|
184
|
+
const collapseLabel = labels?.collapse ?? 'Collapse';
|
|
185
|
+
const noPhasesLabel = labels?.noPhases ?? 'No phases';
|
|
186
|
+
const completedCount = phases.filter(
|
|
187
|
+
(phase) => phase.status === 'completed' || phase.status === 'skipped',
|
|
188
|
+
).length;
|
|
189
|
+
const phasesCompleteLabel =
|
|
190
|
+
labels?.phasesComplete?.(completedCount, phases.length) ??
|
|
191
|
+
`${completedCount}/${phases.length} phases complete`;
|
|
119
192
|
|
|
120
193
|
const setExpanded = (next: boolean) => {
|
|
121
194
|
if (expanded === undefined) {
|
|
@@ -143,7 +216,7 @@ export function ChatPhasedRunProgress({
|
|
|
143
216
|
aria-controls={panelId}
|
|
144
217
|
onClick={() => setExpanded(!isExpanded)}
|
|
145
218
|
>
|
|
146
|
-
{isExpanded ?
|
|
219
|
+
{isExpanded ? collapseLabel : expandLabel}
|
|
147
220
|
</Button>
|
|
148
221
|
</header>
|
|
149
222
|
|
|
@@ -162,7 +235,9 @@ export function ChatPhasedRunProgress({
|
|
|
162
235
|
>
|
|
163
236
|
<div className="chat-phased-run-progress__phase-main">
|
|
164
237
|
<span className="chat-phased-run-progress__phase-label">{phase.label}</span>
|
|
165
|
-
<Badge variant={toBadgeVariant(descriptor.variant)}>
|
|
238
|
+
<Badge variant={toBadgeVariant(descriptor.variant)}>
|
|
239
|
+
{resolvePhaseBadgeLabel(phase.status, labels)}
|
|
240
|
+
</Badge>
|
|
166
241
|
</div>
|
|
167
242
|
{phase.detail ? (
|
|
168
243
|
<p className="chat-phased-run-progress__phase-detail">{phase.detail}</p>
|
|
@@ -173,9 +248,7 @@ export function ChatPhasedRunProgress({
|
|
|
173
248
|
</ol>
|
|
174
249
|
) : (
|
|
175
250
|
<p className="chat-phased-run-progress__summary" id={panelId}>
|
|
176
|
-
{phases.length === 0
|
|
177
|
-
? 'No phases'
|
|
178
|
-
: `${phases.filter((phase) => phase.status === 'completed' || phase.status === 'skipped').length}/${phases.length} phases complete`}
|
|
251
|
+
{phases.length === 0 ? noPhasesLabel : phasesCompleteLabel}
|
|
179
252
|
</p>
|
|
180
253
|
)}
|
|
181
254
|
|
|
@@ -10,7 +10,7 @@ import { defaultWorkbenchChatConversationLabels } from './chatConversation';
|
|
|
10
10
|
|
|
11
11
|
export interface ChatRenameDialogProps {
|
|
12
12
|
conversation: WorkbenchChatConversation;
|
|
13
|
-
labels?: Partial<WorkbenchChatConversationLabels
|
|
13
|
+
labels?: Partial<WorkbenchChatConversationLabels>;
|
|
14
14
|
onCancel: () => void;
|
|
15
15
|
onRename: (title: string) => void;
|
|
16
16
|
}
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
.chat-conversation-bar__pill-wrap {
|
|
66
66
|
position: relative;
|
|
67
67
|
flex: 1 1 auto;
|
|
68
|
-
min-width: 7.5rem;
|
|
68
|
+
min-width: var(--workbench-chat-conversation-pill-min-width, 7.5rem);
|
|
69
69
|
max-width: min(160px, 100%);
|
|
70
70
|
overflow: visible;
|
|
71
71
|
z-index: 1;
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
.chat-conversation-bar__pill--session {
|
|
79
79
|
flex: 0 1 auto;
|
|
80
80
|
flex-shrink: 1;
|
|
81
|
-
min-width: 5.5rem;
|
|
81
|
+
min-width: var(--workbench-chat-conversation-session-pill-min-width, 5.5rem);
|
|
82
82
|
max-width: min(108px, 100%);
|
|
83
83
|
color: var(--color-text-subtle);
|
|
84
84
|
}
|
|
@@ -4,9 +4,9 @@ export interface WorkbenchChatConversation {
|
|
|
4
4
|
id: string;
|
|
5
5
|
title: string;
|
|
6
6
|
/** Short secondary line shown in history menu rows. */
|
|
7
|
-
metaSummary?: string
|
|
7
|
+
metaSummary?: string;
|
|
8
8
|
/** Tooltip content for the active conversation pill. */
|
|
9
|
-
metaTooltip?: ReactNode
|
|
9
|
+
metaTooltip?: ReactNode;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface WorkbenchChatConversationLabels {
|
|
@@ -118,8 +118,8 @@ export function toChatMessageTimeDateTime(value: ChatMessageTimestampInput): str
|
|
|
118
118
|
export function getPeerChatSenderKey(
|
|
119
119
|
message: ChatMessage,
|
|
120
120
|
options: {
|
|
121
|
-
assistantLabel?: string
|
|
122
|
-
userLabel?: string
|
|
121
|
+
assistantLabel?: string;
|
|
122
|
+
userLabel?: string;
|
|
123
123
|
} = {},
|
|
124
124
|
): string {
|
|
125
125
|
if (message.source === 'user') {
|
|
@@ -133,8 +133,8 @@ export function shouldShowPeerChatSenderLabel(
|
|
|
133
133
|
messages: readonly ChatMessage[],
|
|
134
134
|
index: number,
|
|
135
135
|
options: {
|
|
136
|
-
assistantLabel?: string
|
|
137
|
-
userLabel?: string
|
|
136
|
+
assistantLabel?: string;
|
|
137
|
+
userLabel?: string;
|
|
138
138
|
} = {},
|
|
139
139
|
): boolean {
|
|
140
140
|
const message = messages[index];
|
|
@@ -5,6 +5,7 @@ export type { ChatCommandProposalCardProps } from './ChatCommandProposalCard';
|
|
|
5
5
|
export { ChatPhasedRunProgress } from './ChatPhasedRunProgress';
|
|
6
6
|
export type {
|
|
7
7
|
ChatPhasedRunProgressAction,
|
|
8
|
+
ChatPhasedRunProgressLabels,
|
|
8
9
|
ChatPhasedRunProgressProps,
|
|
9
10
|
ChatRunPhase,
|
|
10
11
|
ChatRunPhaseStatus,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
-
import type { WorkbenchCommandExecutionPolicy } from '../command-model';
|
|
3
|
+
import type { WorkbenchCommandExecutionPolicy } from '../commands/command-model';
|
|
4
4
|
|
|
5
5
|
export type ChatMessageSource = 'assistant' | 'user';
|
|
6
6
|
|
|
@@ -15,11 +15,11 @@ export type ChatCommandProposalStatus =
|
|
|
15
15
|
'pending' | 'running' | 'allowed' | 'denied' | 'blocked' | 'executed' | 'failed';
|
|
16
16
|
|
|
17
17
|
export interface ChatCommandProposal {
|
|
18
|
-
args?: readonly unknown[]
|
|
18
|
+
args?: readonly unknown[];
|
|
19
19
|
commandId: string;
|
|
20
|
-
description?: string
|
|
20
|
+
description?: string;
|
|
21
21
|
id: string;
|
|
22
|
-
label?: string
|
|
22
|
+
label?: string;
|
|
23
23
|
policy: WorkbenchCommandExecutionPolicy;
|
|
24
24
|
status: ChatCommandProposalStatus;
|
|
25
25
|
}
|
|
@@ -27,13 +27,13 @@ export interface ChatCommandProposal {
|
|
|
27
27
|
export type ChatMessageTimestamp = number | Date | string;
|
|
28
28
|
|
|
29
29
|
export interface ChatMessage {
|
|
30
|
-
commandProposals?: readonly ChatCommandProposal[]
|
|
30
|
+
commandProposals?: readonly ChatCommandProposal[];
|
|
31
31
|
content: string;
|
|
32
32
|
/**
|
|
33
33
|
* How `content` is rendered. Defaults to markdown for assistant-layout
|
|
34
34
|
* assistant messages; otherwise plain text.
|
|
35
35
|
*/
|
|
36
|
-
contentMode?: ChatMessageContentMode
|
|
36
|
+
contentMode?: ChatMessageContentMode;
|
|
37
37
|
createdAt?: string;
|
|
38
38
|
id: string;
|
|
39
39
|
label?: ReactNode;
|
|
@@ -41,5 +41,5 @@ export interface ChatMessage {
|
|
|
41
41
|
/** Preferred timestamp for display; falls back to `createdAt` when omitted. */
|
|
42
42
|
timestamp?: ChatMessageTimestamp;
|
|
43
43
|
/** Optional visual tone for host-driven status / error messages. */
|
|
44
|
-
tone?: ChatMessageTone
|
|
44
|
+
tone?: ChatMessageTone;
|
|
45
45
|
}
|
|
@@ -5,10 +5,10 @@ export const DEFAULT_RUNTIME_UNMOUNT_CANCELLABLE_STATUSES = ['running'] as const
|
|
|
5
5
|
|
|
6
6
|
export interface UseCancelRuntimeOnUnmountOptions<TStatus extends string = RuntimeStatus> {
|
|
7
7
|
cancel: () => void;
|
|
8
|
-
cancellableStatuses?: readonly TStatus[]
|
|
9
|
-
enabled?: boolean
|
|
10
|
-
getStatus?: (
|
|
11
|
-
status?: TStatus
|
|
8
|
+
cancellableStatuses?: readonly TStatus[];
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
getStatus?: () => TStatus;
|
|
11
|
+
status?: TStatus;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function shouldCancelRuntimeOnUnmount(
|