@molecule/app-ide-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +115 -0
- package/dist/chatTimelineOrdering.d.ts +50 -0
- package/dist/chatTimelineOrdering.d.ts.map +1 -0
- package/dist/chatTimelineOrdering.js +46 -0
- package/dist/chatTimelineOrdering.js.map +1 -0
- package/dist/command-metadata.d.ts +78 -0
- package/dist/command-metadata.d.ts.map +1 -0
- package/dist/command-metadata.js +214 -0
- package/dist/command-metadata.js.map +1 -0
- package/dist/components/ActivityCard.d.ts +28 -0
- package/dist/components/ActivityCard.d.ts.map +1 -0
- package/dist/components/ActivityCard.js +62 -0
- package/dist/components/ActivityCard.js.map +1 -0
- package/dist/components/AutoCommitBadge.d.ts +58 -0
- package/dist/components/AutoCommitBadge.d.ts.map +1 -0
- package/dist/components/AutoCommitBadge.js +78 -0
- package/dist/components/AutoCommitBadge.js.map +1 -0
- package/dist/components/ChatPanel.d.ts +184 -0
- package/dist/components/ChatPanel.d.ts.map +1 -0
- package/dist/components/ChatPanel.js +6691 -0
- package/dist/components/ChatPanel.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +18 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +33 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/DeviceFrameSelector.d.ts +60 -0
- package/dist/components/DeviceFrameSelector.d.ts.map +1 -0
- package/dist/components/DeviceFrameSelector.js +230 -0
- package/dist/components/DeviceFrameSelector.js.map +1 -0
- package/dist/components/EditorPanel.d.ts +17 -0
- package/dist/components/EditorPanel.d.ts.map +1 -0
- package/dist/components/EditorPanel.js +241 -0
- package/dist/components/EditorPanel.js.map +1 -0
- package/dist/components/FileExplorer.d.ts +64 -0
- package/dist/components/FileExplorer.d.ts.map +1 -0
- package/dist/components/FileExplorer.js +1111 -0
- package/dist/components/FileExplorer.js.map +1 -0
- package/dist/components/FileExplorerContextMenu.d.ts +37 -0
- package/dist/components/FileExplorerContextMenu.d.ts.map +1 -0
- package/dist/components/FileExplorerContextMenu.js +241 -0
- package/dist/components/FileExplorerContextMenu.js.map +1 -0
- package/dist/components/HelpCard.d.ts +34 -0
- package/dist/components/HelpCard.d.ts.map +1 -0
- package/dist/components/HelpCard.js +28 -0
- package/dist/components/HelpCard.js.map +1 -0
- package/dist/components/Icon.d.ts +50 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +25 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts +19 -0
- package/dist/components/KeyboardShortcutsPanel.d.ts.map +1 -0
- package/dist/components/KeyboardShortcutsPanel.js +187 -0
- package/dist/components/KeyboardShortcutsPanel.js.map +1 -0
- package/dist/components/MarkdownContent.d.ts +52 -0
- package/dist/components/MarkdownContent.d.ts.map +1 -0
- package/dist/components/MarkdownContent.js +303 -0
- package/dist/components/MarkdownContent.js.map +1 -0
- package/dist/components/ModelsTable.d.ts +38 -0
- package/dist/components/ModelsTable.d.ts.map +1 -0
- package/dist/components/ModelsTable.js +96 -0
- package/dist/components/ModelsTable.js.map +1 -0
- package/dist/components/PreviewPanel.d.ts +66 -0
- package/dist/components/PreviewPanel.d.ts.map +1 -0
- package/dist/components/PreviewPanel.js +1752 -0
- package/dist/components/PreviewPanel.js.map +1 -0
- package/dist/components/QuickOpen.d.ts +20 -0
- package/dist/components/QuickOpen.d.ts.map +1 -0
- package/dist/components/QuickOpen.js +72 -0
- package/dist/components/QuickOpen.js.map +1 -0
- package/dist/components/QuickPicker.d.ts +21 -0
- package/dist/components/QuickPicker.d.ts.map +1 -0
- package/dist/components/QuickPicker.js +174 -0
- package/dist/components/QuickPicker.js.map +1 -0
- package/dist/components/RelevantSkillSuggestion.d.ts +41 -0
- package/dist/components/RelevantSkillSuggestion.d.ts.map +1 -0
- package/dist/components/RelevantSkillSuggestion.js +85 -0
- package/dist/components/RelevantSkillSuggestion.js.map +1 -0
- package/dist/components/ReportModal.d.ts +35 -0
- package/dist/components/ReportModal.d.ts.map +1 -0
- package/dist/components/ReportModal.js +112 -0
- package/dist/components/ReportModal.js.map +1 -0
- package/dist/components/ResizeHandle.d.ts +21 -0
- package/dist/components/ResizeHandle.d.ts.map +1 -0
- package/dist/components/ResizeHandle.js +109 -0
- package/dist/components/ResizeHandle.js.map +1 -0
- package/dist/components/ScriptsCard.d.ts +37 -0
- package/dist/components/ScriptsCard.d.ts.map +1 -0
- package/dist/components/ScriptsCard.js +177 -0
- package/dist/components/ScriptsCard.js.map +1 -0
- package/dist/components/SearchPanel.d.ts +18 -0
- package/dist/components/SearchPanel.d.ts.map +1 -0
- package/dist/components/SearchPanel.js +449 -0
- package/dist/components/SearchPanel.js.map +1 -0
- package/dist/components/SettingsCard.d.ts +49 -0
- package/dist/components/SettingsCard.d.ts.map +1 -0
- package/dist/components/SettingsCard.js +59 -0
- package/dist/components/SettingsCard.js.map +1 -0
- package/dist/components/ShareModal.d.ts +32 -0
- package/dist/components/ShareModal.d.ts.map +1 -0
- package/dist/components/ShareModal.js +126 -0
- package/dist/components/ShareModal.js.map +1 -0
- package/dist/components/SidebarTabs.d.ts +18 -0
- package/dist/components/SidebarTabs.d.ts.map +1 -0
- package/dist/components/SidebarTabs.js +20 -0
- package/dist/components/SidebarTabs.js.map +1 -0
- package/dist/components/SkillsCard.d.ts +86 -0
- package/dist/components/SkillsCard.d.ts.map +1 -0
- package/dist/components/SkillsCard.js +227 -0
- package/dist/components/SkillsCard.js.map +1 -0
- package/dist/components/StreamingIndicator.d.ts +50 -0
- package/dist/components/StreamingIndicator.d.ts.map +1 -0
- package/dist/components/StreamingIndicator.js +142 -0
- package/dist/components/StreamingIndicator.js.map +1 -0
- package/dist/components/TabBar.d.ts +37 -0
- package/dist/components/TabBar.d.ts.map +1 -0
- package/dist/components/TabBar.js +187 -0
- package/dist/components/TabBar.js.map +1 -0
- package/dist/components/TipCard.d.ts +22 -0
- package/dist/components/TipCard.d.ts.map +1 -0
- package/dist/components/TipCard.js +73 -0
- package/dist/components/TipCard.js.map +1 -0
- package/dist/components/ToolCallCard.d.ts +18 -0
- package/dist/components/ToolCallCard.d.ts.map +1 -0
- package/dist/components/ToolCallCard.js +716 -0
- package/dist/components/ToolCallCard.js.map +1 -0
- package/dist/components/UserAvatar.d.ts +45 -0
- package/dist/components/UserAvatar.d.ts.map +1 -0
- package/dist/components/UserAvatar.js +80 -0
- package/dist/components/UserAvatar.js.map +1 -0
- package/dist/components/WorkspaceLayout.d.ts +19 -0
- package/dist/components/WorkspaceLayout.d.ts.map +1 -0
- package/dist/components/WorkspaceLayout.js +56 -0
- package/dist/components/WorkspaceLayout.js.map +1 -0
- package/dist/components/activity-utilities.d.ts +107 -0
- package/dist/components/activity-utilities.d.ts.map +1 -0
- package/dist/components/activity-utilities.js +154 -0
- package/dist/components/activity-utilities.js.map +1 -0
- package/dist/components/chat-autocommit-utilities.d.ts +172 -0
- package/dist/components/chat-autocommit-utilities.d.ts.map +1 -0
- package/dist/components/chat-autocommit-utilities.js +185 -0
- package/dist/components/chat-autocommit-utilities.js.map +1 -0
- package/dist/components/chat-card-style.d.ts +64 -0
- package/dist/components/chat-card-style.d.ts.map +1 -0
- package/dist/components/chat-card-style.js +74 -0
- package/dist/components/chat-card-style.js.map +1 -0
- package/dist/components/chat-commands.d.ts +17 -0
- package/dist/components/chat-commands.d.ts.map +1 -0
- package/dist/components/chat-commands.js +17 -0
- package/dist/components/chat-commands.js.map +1 -0
- package/dist/components/chat-commit-utilities.d.ts +29 -0
- package/dist/components/chat-commit-utilities.d.ts.map +1 -0
- package/dist/components/chat-commit-utilities.js +31 -0
- package/dist/components/chat-commit-utilities.js.map +1 -0
- package/dist/components/chat-cost-utilities.d.ts +62 -0
- package/dist/components/chat-cost-utilities.d.ts.map +1 -0
- package/dist/components/chat-cost-utilities.js +66 -0
- package/dist/components/chat-cost-utilities.js.map +1 -0
- package/dist/components/chat-effort-utilities.d.ts +96 -0
- package/dist/components/chat-effort-utilities.d.ts.map +1 -0
- package/dist/components/chat-effort-utilities.js +97 -0
- package/dist/components/chat-effort-utilities.js.map +1 -0
- package/dist/components/chat-help-utilities.d.ts +89 -0
- package/dist/components/chat-help-utilities.d.ts.map +1 -0
- package/dist/components/chat-help-utilities.js +131 -0
- package/dist/components/chat-help-utilities.js.map +1 -0
- package/dist/components/chat-model-mode-utilities.d.ts +143 -0
- package/dist/components/chat-model-mode-utilities.d.ts.map +1 -0
- package/dist/components/chat-model-mode-utilities.js +191 -0
- package/dist/components/chat-model-mode-utilities.js.map +1 -0
- package/dist/components/chat-models-utilities.d.ts +98 -0
- package/dist/components/chat-models-utilities.d.ts.map +1 -0
- package/dist/components/chat-models-utilities.js +136 -0
- package/dist/components/chat-models-utilities.js.map +1 -0
- package/dist/components/chat-report-utilities.d.ts +149 -0
- package/dist/components/chat-report-utilities.d.ts.map +1 -0
- package/dist/components/chat-report-utilities.js +151 -0
- package/dist/components/chat-report-utilities.js.map +1 -0
- package/dist/components/chat-scripts-utilities.d.ts +140 -0
- package/dist/components/chat-scripts-utilities.d.ts.map +1 -0
- package/dist/components/chat-scripts-utilities.js +158 -0
- package/dist/components/chat-scripts-utilities.js.map +1 -0
- package/dist/components/chat-settings-utilities.d.ts +72 -0
- package/dist/components/chat-settings-utilities.d.ts.map +1 -0
- package/dist/components/chat-settings-utilities.js +56 -0
- package/dist/components/chat-settings-utilities.js.map +1 -0
- package/dist/components/chat-share-utilities.d.ts +104 -0
- package/dist/components/chat-share-utilities.d.ts.map +1 -0
- package/dist/components/chat-share-utilities.js +90 -0
- package/dist/components/chat-share-utilities.js.map +1 -0
- package/dist/components/chat-skills-utilities.d.ts +242 -0
- package/dist/components/chat-skills-utilities.d.ts.map +1 -0
- package/dist/components/chat-skills-utilities.js +433 -0
- package/dist/components/chat-skills-utilities.js.map +1 -0
- package/dist/components/chat-stream-utilities.d.ts +74 -0
- package/dist/components/chat-stream-utilities.d.ts.map +1 -0
- package/dist/components/chat-stream-utilities.js +103 -0
- package/dist/components/chat-stream-utilities.js.map +1 -0
- package/dist/components/chat-tips-utilities.d.ts +108 -0
- package/dist/components/chat-tips-utilities.d.ts.map +1 -0
- package/dist/components/chat-tips-utilities.js +137 -0
- package/dist/components/chat-tips-utilities.js.map +1 -0
- package/dist/components/device-cycle.d.ts +84 -0
- package/dist/components/device-cycle.d.ts.map +1 -0
- package/dist/components/device-cycle.js +77 -0
- package/dist/components/device-cycle.js.map +1 -0
- package/dist/components/index.d.ts +36 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +33 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/tool-call-utilities.d.ts +69 -0
- package/dist/components/tool-call-utilities.d.ts.map +1 -0
- package/dist/components/tool-call-utilities.js +368 -0
- package/dist/components/tool-call-utilities.js.map +1 -0
- package/dist/components/user-avatar-utilities.d.ts +41 -0
- package/dist/components/user-avatar-utilities.d.ts.map +1 -0
- package/dist/components/user-avatar-utilities.js +56 -0
- package/dist/components/user-avatar-utilities.js.map +1 -0
- package/dist/components/workspace-layout-utilities.d.ts +37 -0
- package/dist/components/workspace-layout-utilities.d.ts.map +1 -0
- package/dist/components/workspace-layout-utilities.js +58 -0
- package/dist/components/workspace-layout-utilities.js.map +1 -0
- package/dist/customEventCards.d.ts +117 -0
- package/dist/customEventCards.d.ts.map +1 -0
- package/dist/customEventCards.js +36 -0
- package/dist/customEventCards.js.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +48 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.js +112 -0
- package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/hooks/useViewport.d.ts +42 -0
- package/dist/hooks/useViewport.d.ts.map +1 -0
- package/dist/hooks/useViewport.js +61 -0
- package/dist/hooks/useViewport.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/settings-metadata.d.ts +78 -0
- package/dist/settings-metadata.d.ts.map +1 -0
- package/dist/settings-metadata.js +131 -0
- package/dist/settings-metadata.js.map +1 -0
- package/dist/types.d.ts +751 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { t } from '@molecule/app-i18n';
|
|
4
|
+
import { useThemeMode } from '@molecule/app-react';
|
|
5
|
+
/**
|
|
6
|
+
* Groups shortcuts by category, preserving insertion order.
|
|
7
|
+
* @param shortcuts - Flat list of shortcut entries.
|
|
8
|
+
* @returns Map from category name to entries in that category.
|
|
9
|
+
*/
|
|
10
|
+
function groupByCategory(shortcuts) {
|
|
11
|
+
const groups = new Map();
|
|
12
|
+
for (const entry of shortcuts) {
|
|
13
|
+
const cat = entry.category ?? '';
|
|
14
|
+
const list = groups.get(cat);
|
|
15
|
+
if (list) {
|
|
16
|
+
list.push(entry);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
groups.set(cat, [entry]);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return groups;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Renders a single key badge.
|
|
26
|
+
* @param props - Component props.
|
|
27
|
+
* @returns The key badge element.
|
|
28
|
+
*/
|
|
29
|
+
function KeyBadge({ children, isLight }) {
|
|
30
|
+
return (_jsx("kbd", { style: {
|
|
31
|
+
display: 'inline-block',
|
|
32
|
+
padding: '2px 6px',
|
|
33
|
+
fontSize: 11,
|
|
34
|
+
fontFamily: 'system-ui, sans-serif',
|
|
35
|
+
lineHeight: '16px',
|
|
36
|
+
borderRadius: 4,
|
|
37
|
+
border: `1px solid ${isLight ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.15)'}`,
|
|
38
|
+
background: isLight ? 'rgba(0,0,0,0.05)' : 'rgba(255,255,255,0.08)',
|
|
39
|
+
color: 'var(--mol-color-text, currentColor)',
|
|
40
|
+
minWidth: 20,
|
|
41
|
+
textAlign: 'center',
|
|
42
|
+
}, children: children }));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Keyboard shortcuts reference panel.
|
|
46
|
+
*
|
|
47
|
+
* @param props - Component props.
|
|
48
|
+
* @returns The keyboard shortcuts panel element.
|
|
49
|
+
*/
|
|
50
|
+
export function KeyboardShortcutsPanel({ shortcuts, onDismiss, }) {
|
|
51
|
+
const isLight = useThemeMode() === 'light';
|
|
52
|
+
const panelRef = useRef(null);
|
|
53
|
+
const listRef = useRef(null);
|
|
54
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
55
|
+
const groups = useMemo(() => groupByCategory(shortcuts), [shortcuts]);
|
|
56
|
+
// Flat list for keyboard navigation indexing
|
|
57
|
+
const flatEntries = useMemo(() => {
|
|
58
|
+
const entries = [];
|
|
59
|
+
for (const group of groups.values()) {
|
|
60
|
+
entries.push(...group);
|
|
61
|
+
}
|
|
62
|
+
return entries;
|
|
63
|
+
}, [groups]);
|
|
64
|
+
// Scroll selected item into view
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!listRef.current)
|
|
67
|
+
return;
|
|
68
|
+
const buttons = listRef.current.querySelectorAll('[data-shortcut-row]');
|
|
69
|
+
const el = buttons[selectedIndex];
|
|
70
|
+
el?.scrollIntoView({ block: 'nearest' });
|
|
71
|
+
}, [selectedIndex]);
|
|
72
|
+
const handleKeyDown = useCallback((e) => {
|
|
73
|
+
switch (e.key) {
|
|
74
|
+
case 'Escape':
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
onDismiss();
|
|
77
|
+
break;
|
|
78
|
+
case 'ArrowDown':
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
setSelectedIndex((i) => Math.min(i + 1, flatEntries.length - 1));
|
|
81
|
+
break;
|
|
82
|
+
case 'ArrowUp':
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
setSelectedIndex((i) => Math.max(i - 1, 0));
|
|
85
|
+
break;
|
|
86
|
+
case 'Enter': {
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
const entry = flatEntries[selectedIndex];
|
|
89
|
+
if (entry?.execute) {
|
|
90
|
+
entry.execute();
|
|
91
|
+
onDismiss();
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}, [onDismiss, flatEntries, selectedIndex]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
document.addEventListener('keydown', handleKeyDown, true);
|
|
99
|
+
return () => document.removeEventListener('keydown', handleKeyDown, true);
|
|
100
|
+
}, [handleKeyDown]);
|
|
101
|
+
// Focus the panel so keyboard events work immediately
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
panelRef.current?.focus();
|
|
104
|
+
}, []);
|
|
105
|
+
const selectedBg = isLight ? 'rgba(64,112,224,0.12)' : 'rgba(64,112,224,0.25)';
|
|
106
|
+
// Build a flat index counter to map grouped rendering back to flat index
|
|
107
|
+
let flatIndex = -1;
|
|
108
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { onClick: onDismiss, style: {
|
|
109
|
+
position: 'fixed',
|
|
110
|
+
inset: 0,
|
|
111
|
+
zIndex: 1000,
|
|
112
|
+
background: 'rgba(0,0,0,0.4)',
|
|
113
|
+
} }), _jsxs("div", { ref: panelRef, tabIndex: -1, style: {
|
|
114
|
+
position: 'fixed',
|
|
115
|
+
top: '50%',
|
|
116
|
+
left: '50%',
|
|
117
|
+
transform: 'translate(-50%, -50%)',
|
|
118
|
+
width: 480,
|
|
119
|
+
maxWidth: '90vw',
|
|
120
|
+
maxHeight: '70vh',
|
|
121
|
+
zIndex: 1001,
|
|
122
|
+
borderRadius: 8,
|
|
123
|
+
overflow: 'hidden',
|
|
124
|
+
boxShadow: isLight ? '0 8px 32px rgba(0,0,0,0.18)' : '0 8px 32px rgba(0,0,0,0.6)',
|
|
125
|
+
background: isLight ? '#fff' : 'var(--mol-color-background, #1e1e1e)',
|
|
126
|
+
border: '1px solid var(--color-border, #333)',
|
|
127
|
+
display: 'flex',
|
|
128
|
+
flexDirection: 'column',
|
|
129
|
+
outline: 'none',
|
|
130
|
+
}, children: [_jsxs("div", { style: {
|
|
131
|
+
display: 'flex',
|
|
132
|
+
alignItems: 'center',
|
|
133
|
+
justifyContent: 'space-between',
|
|
134
|
+
padding: '14px 16px 10px',
|
|
135
|
+
borderBottom: '1px solid var(--color-border, #333)',
|
|
136
|
+
flexShrink: 0,
|
|
137
|
+
}, children: [_jsx("span", { style: { fontSize: 14, fontWeight: 600 }, children: t('ide.shortcuts.title', undefined, { defaultValue: 'Keyboard Shortcuts' }) }), _jsx("button", { type: "button", onClick: onDismiss, style: {
|
|
138
|
+
padding: '2px 6px',
|
|
139
|
+
border: 'none',
|
|
140
|
+
background: 'transparent',
|
|
141
|
+
color: 'var(--mol-color-text-secondary, #888)',
|
|
142
|
+
cursor: 'pointer',
|
|
143
|
+
fontSize: 16,
|
|
144
|
+
lineHeight: 1,
|
|
145
|
+
}, children: "\u00D7" })] }), _jsx("div", { ref: listRef, style: { flex: 1, overflow: 'auto', padding: '8px 0' }, children: Array.from(groups.entries()).map(([category, entries]) => (_jsxs("div", { children: [category && (_jsx("div", { style: {
|
|
146
|
+
padding: '8px 16px 4px',
|
|
147
|
+
fontSize: 11,
|
|
148
|
+
fontWeight: 600,
|
|
149
|
+
textTransform: 'uppercase',
|
|
150
|
+
letterSpacing: '0.05em',
|
|
151
|
+
color: 'var(--mol-color-text-secondary, #888)',
|
|
152
|
+
}, children: category })), entries.map((entry) => {
|
|
153
|
+
flatIndex++;
|
|
154
|
+
const idx = flatIndex;
|
|
155
|
+
const isSelected = idx === selectedIndex;
|
|
156
|
+
return (_jsxs("button", { type: "button", "data-shortcut-row": true, onClick: () => {
|
|
157
|
+
if (entry.execute) {
|
|
158
|
+
entry.execute();
|
|
159
|
+
onDismiss();
|
|
160
|
+
}
|
|
161
|
+
}, onMouseEnter: () => setSelectedIndex(idx), style: {
|
|
162
|
+
display: 'flex',
|
|
163
|
+
alignItems: 'center',
|
|
164
|
+
justifyContent: 'space-between',
|
|
165
|
+
padding: '6px 16px',
|
|
166
|
+
fontSize: 13,
|
|
167
|
+
width: '100%',
|
|
168
|
+
border: 'none',
|
|
169
|
+
background: isSelected ? selectedBg : 'transparent',
|
|
170
|
+
color: 'var(--mol-color-text, currentColor)',
|
|
171
|
+
cursor: entry.execute ? 'pointer' : 'default',
|
|
172
|
+
textAlign: 'left',
|
|
173
|
+
borderRadius: 0,
|
|
174
|
+
}, children: [_jsx("span", { children: entry.label }), _jsx("span", { style: { display: 'flex', gap: 4, flexShrink: 0, marginLeft: 16 }, children: entry.keys.split(' ').map((part, i) => (_jsx(KeyBadge, { isLight: isLight, children: part }, i))) })] }, entry.label));
|
|
175
|
+
})] }, category))) }), _jsx("div", { style: {
|
|
176
|
+
padding: '8px 16px',
|
|
177
|
+
borderTop: '1px solid var(--color-border, #333)',
|
|
178
|
+
fontSize: 11,
|
|
179
|
+
color: 'var(--mol-color-text-secondary, #888)',
|
|
180
|
+
textAlign: 'center',
|
|
181
|
+
flexShrink: 0,
|
|
182
|
+
}, children: t('ide.shortcuts.hint', undefined, {
|
|
183
|
+
defaultValue: 'Arrow keys to navigate · Enter to run · Esc to close',
|
|
184
|
+
}) })] })] }));
|
|
185
|
+
}
|
|
186
|
+
KeyboardShortcutsPanel.displayName = 'KeyboardShortcutsPanel';
|
|
187
|
+
//# sourceMappingURL=KeyboardShortcutsPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyboardShortcutsPanel.js","sourceRoot":"","sources":["../../src/components/KeyboardShortcutsPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown content renderer for AI chat messages.
|
|
3
|
+
*
|
|
4
|
+
* Handles the subset of Markdown that Claude commonly produces:
|
|
5
|
+
* fenced code blocks, headers, ordered/unordered lists, bold, italic,
|
|
6
|
+
* and inline code. No external dependencies.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { JSX } from 'react';
|
|
11
|
+
/** Props for {@link MarkdownContent}. */
|
|
12
|
+
export interface MarkdownContentProps {
|
|
13
|
+
/** The raw markdown text to render. */
|
|
14
|
+
text: string;
|
|
15
|
+
/** When true, appends a blinking cursor at the end (streaming indicator). */
|
|
16
|
+
isStreaming?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Current activity/status label (e.g. a verification step like "Type-checking
|
|
19
|
+
* the app"). When set WHILE streaming, the trailing indicator switches from a
|
|
20
|
+
* bare inline cursor to a labeled block below the finalized text — so the
|
|
21
|
+
* post-response check phase is never an unlabeled spinner. This is the window
|
|
22
|
+
* after the model's text is done but `isStreaming` is still true because the
|
|
23
|
+
* server is running type-check / lint / runtime probes.
|
|
24
|
+
*/
|
|
25
|
+
statusLabel?: string | null;
|
|
26
|
+
/** Turn start (ms) for the labeled indicator's elapsed timer. */
|
|
27
|
+
statusStartedAt?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Navigates the live preview to a route path. When provided, a `[label](/route)` markdown
|
|
30
|
+
* link renders as a clickable button that jumps the preview to that page (instead of opening
|
|
31
|
+
* a new tab or navigating the IDE) — so the agent's "your app is ready" handoff can list the
|
|
32
|
+
* app's pages as one-click links.
|
|
33
|
+
*/
|
|
34
|
+
onNavigatePreview?: (path: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Suppress this component's OWN trailing streaming indicators (the inline end-of-text cursor
|
|
37
|
+
* and the labeled verification block). The chat owns a single, persistent activity indicator
|
|
38
|
+
* for the whole turn, so the per-message ones here would just duplicate it AND flicker on/off
|
|
39
|
+
* as each message finalizes (the cause of the jumpy scroll). `isStreaming` is still honored
|
|
40
|
+
* for the live throttled parse — only the spinner is hidden.
|
|
41
|
+
*/
|
|
42
|
+
hideStreamingIndicator?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Renders a subset of Markdown as React elements.
|
|
46
|
+
* Handles fenced code blocks (with copy button), headers, lists,
|
|
47
|
+
* bold/italic, and inline code.
|
|
48
|
+
* @param props - Component props (see {@link MarkdownContentProps}).
|
|
49
|
+
* @returns The rendered markdown content element.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MarkdownContent: import("react").MemoExoticComponent<({ text, isStreaming, statusLabel, statusStartedAt, onNavigatePreview, hideStreamingIndicator, }: MarkdownContentProps) => JSX.Element>;
|
|
52
|
+
//# sourceMappingURL=MarkdownContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownContent.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAa,MAAM,OAAO,CAAA;AAoX3C,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;CACjC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,wIAOzB,oBAAoB,KAAG,GAAG,CAAC,OAAO,CAwGnC,CAAA"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { t } from '@molecule/app-i18n';
|
|
4
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
5
|
+
import { useCoarsePointer } from '../hooks/useViewport.js';
|
|
6
|
+
import { StreamingIndicator } from './StreamingIndicator.js';
|
|
7
|
+
/**
|
|
8
|
+
* Renders a single markdown link `[label](href)`. A ROUTE link — any app-internal path, whether
|
|
9
|
+
* written with a leading slash (`/transactions`) or without (`transactions`, `courses/:id`) — is a
|
|
10
|
+
* page in the live preview: when an `onNavigatePreview` handler is wired (the chat context), it
|
|
11
|
+
* renders as a button that navigates the PREVIEW to that route on click (the path is normalized to
|
|
12
|
+
* a leading `/`), so the agent's "your app is ready" handoff can list clickable pages the user
|
|
13
|
+
* jumps straight to. Only a genuinely EXTERNAL link — one with a URL scheme (`http(s):`, `mailto:`)
|
|
14
|
+
* or protocol-relative (`//host`) — opens in a new tab; a bare route must never open a new tab. A
|
|
15
|
+
* route link with no handler (e.g. a help card), or a parameterized route (`/courses/:id`) that has
|
|
16
|
+
* no concrete destination, renders as plain text rather than a broken/IDE-navigating link. A
|
|
17
|
+
* `#anchor` can't address a preview page, so it stays an inert anchor.
|
|
18
|
+
*
|
|
19
|
+
* @param props - Component props (see {@link MarkdownContentProps}).
|
|
20
|
+
* @returns The rendered link node.
|
|
21
|
+
*/
|
|
22
|
+
function LinkToken({ label, href, onNavigatePreview, }) {
|
|
23
|
+
const linkStyle = {
|
|
24
|
+
color: 'var(--mol-color-primary, #4070e0)',
|
|
25
|
+
textDecoration: 'underline',
|
|
26
|
+
textUnderlineOffset: '2px',
|
|
27
|
+
};
|
|
28
|
+
// External = a URL scheme (http:, https:, mailto:, tel:, …) or protocol-relative (//host).
|
|
29
|
+
// Everything else is an app route for the preview — INCLUDING bare paths the agent emits
|
|
30
|
+
// WITHOUT a leading slash (`courses/:id`), which used to fall through to a new-tab anchor (the
|
|
31
|
+
// "opens a new tab instead of the preview" bug). A `#anchor` can't address a preview page.
|
|
32
|
+
const isExternal = /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith('//');
|
|
33
|
+
const isAnchor = href.startsWith('#');
|
|
34
|
+
if (!isExternal && !isAnchor) {
|
|
35
|
+
// Normalize to a root-relative path so the handler always receives a clean `/route`.
|
|
36
|
+
const path = href.startsWith('/') ? href : `/${href}`;
|
|
37
|
+
// A parameterized route (`/courses/:id`, a `*` splat) has no concrete destination — navigating
|
|
38
|
+
// the preview to a literal `:id` just 404s, so it's a useless "get started" link. Render the
|
|
39
|
+
// label as plain text instead. (The handoff prompt also tells the agent to list concrete,
|
|
40
|
+
// parameter-free landing pages — this is the renderer-side safety net.)
|
|
41
|
+
const isParameterized = path.split('/').some((seg) => seg.startsWith(':') || seg === '*');
|
|
42
|
+
if (isParameterized || !onNavigatePreview)
|
|
43
|
+
return _jsx(_Fragment, { children: label });
|
|
44
|
+
return (_jsx("button", { type: "button", "data-mol-id": "chat-preview-link", onClick: () => onNavigatePreview(path), title: t('ide.chat.previewLinkTitle', { path }, { defaultValue: 'Open {{path}} in the preview' }), style: {
|
|
45
|
+
...linkStyle,
|
|
46
|
+
background: 'none',
|
|
47
|
+
border: 'none',
|
|
48
|
+
padding: 0,
|
|
49
|
+
font: 'inherit',
|
|
50
|
+
cursor: 'pointer',
|
|
51
|
+
}, children: label }));
|
|
52
|
+
}
|
|
53
|
+
return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", style: linkStyle, children: label }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Splits raw markdown text into alternating prose and fenced code block segments.
|
|
57
|
+
* @param text - The raw markdown string to split.
|
|
58
|
+
* @returns An array of text and code segments.
|
|
59
|
+
*/
|
|
60
|
+
function splitSegments(text) {
|
|
61
|
+
const out = [];
|
|
62
|
+
const re = /```(\w*)\n?([\s\S]*?)```/g;
|
|
63
|
+
let last = 0;
|
|
64
|
+
let m;
|
|
65
|
+
while ((m = re.exec(text)) !== null) {
|
|
66
|
+
if (m.index > last)
|
|
67
|
+
out.push({ type: 'text', content: text.slice(last, m.index) });
|
|
68
|
+
out.push({ type: 'code', lang: m[1] ?? '', content: m[2].trimEnd() });
|
|
69
|
+
last = m.index + m[0].length;
|
|
70
|
+
}
|
|
71
|
+
if (last < text.length)
|
|
72
|
+
out.push({ type: 'text', content: text.slice(last) });
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Inline rendering — bold, italic, inline code
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Order matters: link `[text](url)` is matched before bold/italic so a label/url containing
|
|
79
|
+
// `*` isn't mis-split. The url stops at whitespace or the closing paren.
|
|
80
|
+
const INLINE_RE = /(`[^`\n]+`|\[[^\]\n]+\]\([^)\s]+\)|\*\*(?:[^*]|\*(?!\*))+\*\*|\*[^*\n]+\*)/g;
|
|
81
|
+
/**
|
|
82
|
+
* Renders inline markdown formatting (bold, italic, inline code, links) as React nodes.
|
|
83
|
+
* @param text - The text containing inline markdown tokens.
|
|
84
|
+
* @param onNavigatePreview - Optional handler so a `[label](/route)` link navigates the preview.
|
|
85
|
+
* @returns A ReactNode with formatted inline elements.
|
|
86
|
+
*/
|
|
87
|
+
function renderInline(text, onNavigatePreview) {
|
|
88
|
+
const parts = [];
|
|
89
|
+
let last = 0;
|
|
90
|
+
let k = 0;
|
|
91
|
+
for (const m of text.matchAll(INLINE_RE)) {
|
|
92
|
+
if (m.index > last)
|
|
93
|
+
parts.push(text.slice(last, m.index));
|
|
94
|
+
const tok = m[0];
|
|
95
|
+
if (tok[0] === '`') {
|
|
96
|
+
parts.push(_jsx("code", { style: {
|
|
97
|
+
fontFamily: 'var(--vscode-editor-font-family, "SF Mono", Consolas, monospace)',
|
|
98
|
+
fontSize: '0.875em',
|
|
99
|
+
background: 'rgba(128,128,128,0.15)',
|
|
100
|
+
borderRadius: '3px',
|
|
101
|
+
padding: '1px 4px',
|
|
102
|
+
}, children: tok.slice(1, -1) }, k++));
|
|
103
|
+
}
|
|
104
|
+
else if (tok[0] === '[') {
|
|
105
|
+
// [label](href)
|
|
106
|
+
const lm = tok.match(/^\[([^\]]+)\]\(([^)\s]+)\)$/);
|
|
107
|
+
if (lm) {
|
|
108
|
+
parts.push(_jsx(LinkToken, { label: lm[1], href: lm[2], onNavigatePreview: onNavigatePreview }, k++));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
parts.push(tok);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (tok.startsWith('**')) {
|
|
115
|
+
parts.push(_jsx("strong", { children: tok.slice(2, -2) }, k++));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
parts.push(_jsx("em", { children: tok.slice(1, -1) }, k++));
|
|
119
|
+
}
|
|
120
|
+
last = m.index + m[0].length;
|
|
121
|
+
}
|
|
122
|
+
if (last < text.length)
|
|
123
|
+
parts.push(text.slice(last));
|
|
124
|
+
if (parts.length === 0)
|
|
125
|
+
return null;
|
|
126
|
+
if (parts.length === 1)
|
|
127
|
+
return parts[0];
|
|
128
|
+
return _jsx(_Fragment, { children: parts });
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Prose block rendering — headers, lists, paragraphs
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
/**
|
|
134
|
+
* Renders a prose text segment as structured HTML (headers, lists, paragraphs).
|
|
135
|
+
* @param props - Component props (see {@link MarkdownContentProps}).
|
|
136
|
+
* @returns The rendered prose block element.
|
|
137
|
+
*/
|
|
138
|
+
function Prose({ content, segIdx, onNavigatePreview, }) {
|
|
139
|
+
const lines = content.split('\n');
|
|
140
|
+
const els = [];
|
|
141
|
+
let k = segIdx * 10000;
|
|
142
|
+
let i = 0;
|
|
143
|
+
while (i < lines.length) {
|
|
144
|
+
const line = lines[i];
|
|
145
|
+
// Blank line — paragraph separator
|
|
146
|
+
if (!line.trim()) {
|
|
147
|
+
i++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Headers
|
|
151
|
+
const hm = line.match(/^(#{1,3}) (.+)/);
|
|
152
|
+
if (hm) {
|
|
153
|
+
const lvl = hm[1].length;
|
|
154
|
+
els.push(_jsx("p", { style: {
|
|
155
|
+
fontWeight: 600,
|
|
156
|
+
fontSize: lvl === 1 ? '1.05em' : '1em',
|
|
157
|
+
marginBottom: '4px',
|
|
158
|
+
marginTop: i > 0 ? '10px' : 0,
|
|
159
|
+
}, children: renderInline(hm[2], onNavigatePreview) }, k++));
|
|
160
|
+
i++;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// Unordered list
|
|
164
|
+
if (/^[-*] /.test(line)) {
|
|
165
|
+
const items = [];
|
|
166
|
+
while (i < lines.length && /^[-*] /.test(lines[i])) {
|
|
167
|
+
items.push(_jsx("li", { children: renderInline(lines[i].replace(/^[-*] /, ''), onNavigatePreview) }, i));
|
|
168
|
+
i++;
|
|
169
|
+
}
|
|
170
|
+
els.push(_jsx("ul", { style: { paddingLeft: '18px', marginBottom: '6px', listStyleType: 'disc' }, children: items }, k++));
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// Ordered list
|
|
174
|
+
if (/^\d+\. /.test(line)) {
|
|
175
|
+
const items = [];
|
|
176
|
+
while (i < lines.length && /^\d+\. /.test(lines[i])) {
|
|
177
|
+
items.push(_jsx("li", { children: renderInline(lines[i].replace(/^\d+\. /, ''), onNavigatePreview) }, i));
|
|
178
|
+
i++;
|
|
179
|
+
}
|
|
180
|
+
els.push(_jsx("ol", { style: { paddingLeft: '18px', marginBottom: '6px', listStyleType: 'decimal' }, children: items }, k++));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// Paragraph — collect consecutive non-special lines
|
|
184
|
+
const para = [];
|
|
185
|
+
while (i < lines.length &&
|
|
186
|
+
lines[i].trim() &&
|
|
187
|
+
!/^#{1,3} /.test(lines[i]) &&
|
|
188
|
+
!/^[-*] /.test(lines[i]) &&
|
|
189
|
+
!/^\d+\. /.test(lines[i])) {
|
|
190
|
+
para.push(lines[i]);
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
if (para.length) {
|
|
194
|
+
els.push(_jsx("p", { style: { whiteSpace: 'pre-wrap', marginBottom: '6px' }, children: renderInline(para.join('\n'), onNavigatePreview) }, k++));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return _jsx(_Fragment, { children: els });
|
|
198
|
+
}
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// Code block with language label + copy button
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
/**
|
|
203
|
+
* Renders a fenced code block with a language label and copy-to-clipboard button.
|
|
204
|
+
* @param props - Component props (see {@link MarkdownContentProps}).
|
|
205
|
+
* @returns The rendered code block element.
|
|
206
|
+
*/
|
|
207
|
+
function CodeBlock({ lang, content }) {
|
|
208
|
+
const cm = getClassMap();
|
|
209
|
+
const isCoarse = useCoarsePointer();
|
|
210
|
+
const [copied, setCopied] = useState(false);
|
|
211
|
+
/** Copies the code block content to clipboard and shows a brief confirmation. */
|
|
212
|
+
function handleCopy() {
|
|
213
|
+
void navigator.clipboard.writeText(content);
|
|
214
|
+
setCopied(true);
|
|
215
|
+
setTimeout(() => setCopied(false), 1500);
|
|
216
|
+
}
|
|
217
|
+
return (_jsxs("div", { className: cm.surfaceSecondary, style: { borderRadius: '6px', marginBottom: '10px', overflow: 'hidden' }, children: [_jsxs("div", { style: {
|
|
218
|
+
display: 'flex',
|
|
219
|
+
justifyContent: 'space-between',
|
|
220
|
+
alignItems: 'center',
|
|
221
|
+
padding: '3px 10px',
|
|
222
|
+
borderBottom: '1px solid rgba(128,128,128,0.15)',
|
|
223
|
+
fontSize: '11px',
|
|
224
|
+
opacity: 0.75,
|
|
225
|
+
}, children: [_jsx("span", { style: {
|
|
226
|
+
fontFamily: 'var(--vscode-editor-font-family, monospace)',
|
|
227
|
+
letterSpacing: '0.3px',
|
|
228
|
+
}, children: lang || 'text' }), _jsx("button", { type: "button", onClick: handleCopy, style: {
|
|
229
|
+
background: 'none',
|
|
230
|
+
border: 'none',
|
|
231
|
+
cursor: 'pointer',
|
|
232
|
+
color: 'inherit',
|
|
233
|
+
fontSize: '11px',
|
|
234
|
+
padding: '2px 6px',
|
|
235
|
+
// Touch: ~17px is untappable — 32px dense-row floor, text unchanged.
|
|
236
|
+
...(isCoarse ? { minHeight: 32 } : {}),
|
|
237
|
+
opacity: 0.75,
|
|
238
|
+
}, children: copied ? '\u2713 Copied' : 'Copy' })] }), _jsx("pre", { style: {
|
|
239
|
+
margin: 0,
|
|
240
|
+
padding: '10px 12px',
|
|
241
|
+
overflowX: 'auto',
|
|
242
|
+
fontSize: '12px',
|
|
243
|
+
lineHeight: 1.6,
|
|
244
|
+
fontFamily: 'var(--vscode-editor-font-family, "SF Mono", Consolas, monospace)',
|
|
245
|
+
whiteSpace: 'pre',
|
|
246
|
+
}, children: _jsx("code", { children: content }) })] }));
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Renders a subset of Markdown as React elements.
|
|
250
|
+
* Handles fenced code blocks (with copy button), headers, lists,
|
|
251
|
+
* bold/italic, and inline code.
|
|
252
|
+
* @param props - Component props (see {@link MarkdownContentProps}).
|
|
253
|
+
* @returns The rendered markdown content element.
|
|
254
|
+
*/
|
|
255
|
+
export const MarkdownContent = memo(function MarkdownContent({ text, isStreaming, statusLabel, statusStartedAt, onNavigatePreview, hideStreamingIndicator, }) {
|
|
256
|
+
// Markdown is parsed + rendered LIVE while streaming (not deferred until the
|
|
257
|
+
// stream finalizes). The page freezes that originally motivated deferring it
|
|
258
|
+
// were caused by stale Vite pre-bundle caches serving a duplicate React, NOT
|
|
259
|
+
// by this parse.
|
|
260
|
+
//
|
|
261
|
+
// One real concern from that era remains: `text` grows on every ~50ms flush, so
|
|
262
|
+
// re-parsing the FULL content on every flush is O(content²) over a long stream
|
|
263
|
+
// (a big plan / file content streamed into chat) — sustained main-thread CPU.
|
|
264
|
+
// We keep it live but THROTTLE the parse input to ~120ms (≈8 renders/sec, still
|
|
265
|
+
// visually live) so the per-flush re-parse work is bounded. On finalize we parse
|
|
266
|
+
// the complete text immediately so the last tokens never lag.
|
|
267
|
+
const PARSE_THROTTLE_MS = 120;
|
|
268
|
+
const [parseText, setParseText] = useState(text);
|
|
269
|
+
const lastParseAtRef = useRef(0);
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
if (!isStreaming) {
|
|
272
|
+
setParseText(text); // finalized (or non-streaming) — parse the full, stable text now
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const elapsed = Date.now() - lastParseAtRef.current;
|
|
276
|
+
if (elapsed >= PARSE_THROTTLE_MS) {
|
|
277
|
+
lastParseAtRef.current = Date.now();
|
|
278
|
+
setParseText(text);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// Leading+trailing throttle: schedule the pending update so continuous
|
|
282
|
+
// streaming still refreshes ~every PARSE_THROTTLE_MS (a plain debounce here
|
|
283
|
+
// would defer ALL rendering to the end — the very bug we're removing).
|
|
284
|
+
const id = setTimeout(() => {
|
|
285
|
+
lastParseAtRef.current = Date.now();
|
|
286
|
+
setParseText(text);
|
|
287
|
+
}, PARSE_THROTTLE_MS - elapsed);
|
|
288
|
+
return () => clearTimeout(id);
|
|
289
|
+
}, [text, isStreaming]);
|
|
290
|
+
const segments = useMemo(() => (parseText ? splitSegments(parseText) : []), [parseText]);
|
|
291
|
+
// A real status label (verification step) makes the trailing indicator a
|
|
292
|
+
// labeled block; otherwise it's the bare end-of-text cursor used during
|
|
293
|
+
// token-by-token streaming.
|
|
294
|
+
const hasStatus = statusLabel != null && statusLabel.trim() !== '';
|
|
295
|
+
if (!text) {
|
|
296
|
+
return (_jsx(_Fragment, { children: isStreaming && !hideStreamingIndicator && (_jsx(StreamingIndicator, { label: hasStatus ? statusLabel : undefined, startedAt: statusStartedAt })) }));
|
|
297
|
+
}
|
|
298
|
+
if (isStreaming) {
|
|
299
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { fontSize: '13px', lineHeight: 1.6, marginTop: '6px', wordBreak: 'break-word' }, children: [segments.map((seg, i) => seg.type === 'code' ? (_jsx(CodeBlock, { lang: seg.lang, content: seg.content }, i)) : (_jsx(Prose, { content: seg.content, segIdx: i, onNavigatePreview: onNavigatePreview }, i))), !hideStreamingIndicator && !hasStatus && _jsx(StreamingIndicator, { inline: true })] }), !hideStreamingIndicator && hasStatus && (_jsx(StreamingIndicator, { label: statusLabel, startedAt: statusStartedAt }))] }));
|
|
300
|
+
}
|
|
301
|
+
return (_jsx("div", { style: { fontSize: '13px', lineHeight: 1.6, marginTop: '6px', wordBreak: 'break-word' }, children: segments.map((seg, i) => seg.type === 'code' ? (_jsx(CodeBlock, { lang: seg.lang, content: seg.content }, i)) : (_jsx(Prose, { content: seg.content, segIdx: i, onNavigatePreview: onNavigatePreview }, i))) }));
|
|
302
|
+
});
|
|
303
|
+
//# sourceMappingURL=MarkdownContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownContent.js","sourceRoot":"","sources":["../../src/components/MarkdownContent.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/models` comparison table.
|
|
3
|
+
*
|
|
4
|
+
* Renders the available models in a sortable table: name, context window,
|
|
5
|
+
* combined cost per 1M tokens, knowledge cutoff, and free-tier availability.
|
|
6
|
+
* Clicking a column header sorts ascending, then toggles to descending; every
|
|
7
|
+
* header carries a neutral SVG sort glyph (`chevrons-up-down`) that resolves to
|
|
8
|
+
* an up/down chevron on the active column — never a unicode arrow or emoji.
|
|
9
|
+
* Free-tier-available models are visually highlighted.
|
|
10
|
+
*
|
|
11
|
+
* The "Cutoff" column replaced a former "Speed" column that was fabricated from
|
|
12
|
+
* input price (it duplicated Cost and could be factually wrong). Knowledge
|
|
13
|
+
* cutoff is a real, factual axis genuinely independent of the price/size axes.
|
|
14
|
+
*
|
|
15
|
+
* Styling uses `getClassMap()` (`cm.*`) for structure/typography/spacing and the
|
|
16
|
+
* `--color-primary` theme token for the active-header accent; the only inline
|
|
17
|
+
* styles are the free-tier highlight tint and the provider accent stripe —
|
|
18
|
+
* things the ClassMap can't express.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import type { JSX } from 'react';
|
|
23
|
+
import type { AppModelDefinition } from '@molecule/app-ai-models';
|
|
24
|
+
/**
|
|
25
|
+
* Sortable comparison table of available AI models.
|
|
26
|
+
*
|
|
27
|
+
* @param root0 - Component props.
|
|
28
|
+
* @param root0.models - Models to display (already filtered to the current catalog).
|
|
29
|
+
* @param root0.currentModelId - The id of the project's active model, badged as "current".
|
|
30
|
+
* @param root0.isLight - Whether the current theme is light mode (drives highlight tints).
|
|
31
|
+
* @returns The rendered models table.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ModelsTable({ models, currentModelId, isLight, }: {
|
|
34
|
+
models: readonly AppModelDefinition[];
|
|
35
|
+
currentModelId?: string;
|
|
36
|
+
isLight: boolean;
|
|
37
|
+
}): JSX.Element;
|
|
38
|
+
//# sourceMappingURL=ModelsTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelsTable.d.ts","sourceRoot":"","sources":["../../src/components/ModelsTable.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AA8BjE;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,cAAc,EACd,OAAO,GACR,EAAE;IACD,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,GAAG,CAAC,OAAO,CAqLd"}
|