vzcode 2.0.0 → 2.3.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.
Files changed (218) hide show
  1. package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
  2. package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
  3. package/dist/assets/{index-BgqNq-ww.js → index-DuUjtrt6.js} +107 -107
  4. package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
  5. package/dist/cli.js +113 -0
  6. package/dist/index.html +2 -2
  7. package/{src/ot.ts → dist/ot.js} +2 -14
  8. package/{src/randomId.ts → dist/randomId.js} +5 -6
  9. package/dist/runCode.js +20 -0
  10. package/dist/server/aiChatHandler/aiEditing.js +89 -0
  11. package/dist/server/aiChatHandler/chatOperations.js +360 -0
  12. package/dist/server/aiChatHandler/errorHandling.js +49 -0
  13. package/dist/server/aiChatHandler/index.js +112 -0
  14. package/dist/server/aiChatHandler/llmStreaming.js +284 -0
  15. package/dist/server/aiChatHandler/validation.js +19 -0
  16. package/dist/server/computeInitialDocument.js +146 -0
  17. package/{src/server/config.ts → dist/server/config.js} +4 -7
  18. package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
  19. package/dist/server/generateAIResponse.js +129 -0
  20. package/dist/server/handleAIAssist.js +39 -0
  21. package/dist/server/handleAICopilot.js +81 -0
  22. package/dist/server/index.js +297 -0
  23. package/dist/server/livekit.js +17 -0
  24. package/dist/server/prettier.js +90 -0
  25. package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
  26. package/dist/submitOperation.js +14 -0
  27. package/dist/types.js +1 -0
  28. package/dist/utils/fileDiff.js +66 -0
  29. package/package.json +23 -22
  30. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
  31. package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
  32. package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
  33. package/src/client/AIAssist/Spinner.jsx +0 -76
  34. package/src/client/AIAssist/formatFile.ts +0 -27
  35. package/src/client/AIAssist/generateFilesContext.ts +0 -25
  36. package/src/client/AIAssist/index.ts +0 -2
  37. package/src/client/AIAssist/startAIAssist.ts +0 -95
  38. package/src/client/App/index.tsx +0 -153
  39. package/src/client/App/style.scss +0 -82
  40. package/src/client/App/usePending.ts +0 -51
  41. package/src/client/App/useShareDB.ts +0 -161
  42. package/src/client/CodeEditor/Copilot/index.ts +0 -74
  43. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
  44. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
  45. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
  46. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
  47. package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
  48. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
  49. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
  50. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
  51. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
  52. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
  53. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
  54. package/src/client/CodeEditor/basicSetup.ts +0 -73
  55. package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
  56. package/src/client/CodeEditor/index.tsx +0 -202
  57. package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
  58. package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
  59. package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
  60. package/src/client/CodeEditor/style.scss +0 -156
  61. package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
  62. package/src/client/CodeErrorOverlay/index.tsx +0 -77
  63. package/src/client/CodeErrorOverlay/style.scss +0 -33
  64. package/src/client/Fonts/fonts.ts +0 -8
  65. package/src/client/Icons/AdjustmentSVG.tsx +0 -19
  66. package/src/client/Icons/BugSVG.tsx +0 -20
  67. package/src/client/Icons/CloseSVG.tsx +0 -19
  68. package/src/client/Icons/CssSVG.tsx +0 -16
  69. package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
  70. package/src/client/Icons/EditSVG.tsx +0 -19
  71. package/src/client/Icons/FileSVG.tsx +0 -19
  72. package/src/client/Icons/FolderSVG.tsx +0 -20
  73. package/src/client/Icons/GearSVG.tsx +0 -16
  74. package/src/client/Icons/HtmlSVG.tsx +0 -16
  75. package/src/client/Icons/JavaScriptSVG.tsx +0 -16
  76. package/src/client/Icons/JsonSVG.tsx +0 -16
  77. package/src/client/Icons/MarkdownSVG.tsx +0 -16
  78. package/src/client/Icons/MicSVG.tsx +0 -25
  79. package/src/client/Icons/NewSVG.tsx +0 -19
  80. package/src/client/Icons/PinSVG.tsx +0 -14
  81. package/src/client/Icons/PlaySVG.tsx +0 -16
  82. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  83. package/src/client/Icons/ReactSVG.tsx +0 -16
  84. package/src/client/Icons/SearchSVG.tsx +0 -20
  85. package/src/client/Icons/SparklesSVG.tsx +0 -23
  86. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  87. package/src/client/Icons/StopSVG.tsx +0 -15
  88. package/src/client/Icons/SvelteSVG.tsx +0 -16
  89. package/src/client/Icons/TrashSVG.tsx +0 -19
  90. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  91. package/src/client/Icons/index.tsx +0 -24
  92. package/src/client/ImageViewer/index.tsx +0 -91
  93. package/src/client/ImageViewer/style.scss +0 -41
  94. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  95. package/src/client/PresenceNotifications/index.tsx +0 -158
  96. package/src/client/PresenceNotifications/style.scss +0 -17
  97. package/src/client/RunCodeWidget/index.tsx +0 -117
  98. package/src/client/RunCodeWidget/style.scss +0 -24
  99. package/src/client/SplitPaneResizeContext.tsx +0 -159
  100. package/src/client/TabList/Tab.tsx +0 -73
  101. package/src/client/TabList/index.tsx +0 -35
  102. package/src/client/TabList/style.scss +0 -51
  103. package/src/client/VZCodeContext/index.tsx +0 -29
  104. package/src/client/VZCodeContext/types.ts +0 -249
  105. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  106. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  107. package/src/client/VZLeft.tsx +0 -28
  108. package/src/client/VZMiddle.tsx +0 -172
  109. package/src/client/VZResizer/index.tsx +0 -128
  110. package/src/client/VZResizer/styles.scss +0 -33
  111. package/src/client/VZRight.tsx +0 -113
  112. package/src/client/VZSettings.tsx +0 -275
  113. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -196
  114. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  115. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  116. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  117. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  118. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  119. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  120. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  121. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  122. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  123. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  124. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  125. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  126. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  127. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  128. package/src/client/VZSidebar/FileListing.tsx +0 -91
  129. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  130. package/src/client/VZSidebar/Item.tsx +0 -237
  131. package/src/client/VZSidebar/Listing.tsx +0 -47
  132. package/src/client/VZSidebar/Search.tsx +0 -527
  133. package/src/client/VZSidebar/VisualEditor.tsx +0 -295
  134. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  135. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  136. package/src/client/VZSidebar/index.tsx +0 -728
  137. package/src/client/VZSidebar/styles.scss +0 -612
  138. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  139. package/src/client/bootstrap.ts +0 -26
  140. package/src/client/buildWorker.ts +0 -3
  141. package/src/client/featureFlags.ts +0 -8
  142. package/src/client/generateRequestId.ts +0 -6
  143. package/src/client/getFileTree.ts +0 -53
  144. package/src/client/index.ts +0 -19
  145. package/src/client/main.jsx +0 -10
  146. package/src/client/presenceColor.ts +0 -8
  147. package/src/client/shouldTriggerRun.ts +0 -31
  148. package/src/client/sortFileTree.ts +0 -21
  149. package/src/client/tabsSearchParameters.test.ts +0 -79
  150. package/src/client/tabsSearchParameters.ts +0 -137
  151. package/src/client/themes/index.ts +0 -7
  152. package/src/client/themes/themes.ts +0 -77
  153. package/src/client/themes/uiwImports.ts +0 -32
  154. package/src/client/themes/useDynamicTheme.ts +0 -29
  155. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  156. package/src/client/themes/vizhubTheme/index.ts +0 -193
  157. package/src/client/useActions.ts +0 -288
  158. package/src/client/useESLint/index.ts +0 -72
  159. package/src/client/useESLint/worker.ts +0 -113
  160. package/src/client/useEditorCache.ts +0 -35
  161. package/src/client/useFileCRUD.ts +0 -228
  162. package/src/client/useKeyboardShortcuts.ts +0 -451
  163. package/src/client/useOpenDirectories.ts +0 -99
  164. package/src/client/usePresenceAutoFollow.ts +0 -85
  165. package/src/client/usePrettier/index.ts +0 -178
  166. package/src/client/usePrettier/worker.ts +0 -109
  167. package/src/client/useRunCode.tsx +0 -15
  168. package/src/client/useRuntimeError.ts +0 -32
  169. package/src/client/useSubmitOperation.ts +0 -15
  170. package/src/client/useURLSync.ts +0 -137
  171. package/src/client/usernameLocalStorage.ts +0 -43
  172. package/src/client/utils/fileExtension.ts +0 -10
  173. package/src/client/utils/isImageFile.ts +0 -12
  174. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  175. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  176. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  177. package/src/client/vzReducer/createInitialState.ts +0 -38
  178. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  179. package/src/client/vzReducer/findPane.ts +0 -19
  180. package/src/client/vzReducer/index.ts +0 -250
  181. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  182. package/src/client/vzReducer/openTabReducer.ts +0 -74
  183. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  184. package/src/client/vzReducer/searchReducer.ts +0 -181
  185. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  186. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  187. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  188. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  189. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  190. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  191. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  192. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  193. package/src/client/vzReducer/updatePane.ts +0 -40
  194. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  195. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  196. package/src/reactRouterExports.ts +0 -15
  197. package/src/runCode.ts +0 -27
  198. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  199. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  200. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  201. package/src/server/aiChatHandler/index.ts +0 -200
  202. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  203. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  204. package/src/server/aiChatHandler/validation.ts +0 -24
  205. package/src/server/computeInitialDocument.ts +0 -220
  206. package/src/server/generateAIResponse.ts +0 -188
  207. package/src/server/handleAIAssist.ts +0 -53
  208. package/src/server/handleAIChatUndo.ts +0 -2
  209. package/src/server/handleAICopilot.ts +0 -97
  210. package/src/server/index.ts +0 -388
  211. package/src/server/livekit.ts +0 -24
  212. package/src/server/prettier.ts +0 -115
  213. package/src/submitOperation.ts +0 -25
  214. package/src/types.ts +0 -205
  215. package/src/utils/fileDiff.ts +0 -117
  216. package/src/vite-env.d.ts +0 -10
  217. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  218. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -1,584 +0,0 @@
1
- import {
2
- useCallback,
3
- useMemo,
4
- useReducer,
5
- useRef,
6
- useState,
7
- } from 'react';
8
- import { VizContent } from '@vizhub/viz-types';
9
- import { defaultTheme, useDynamicTheme } from '../themes';
10
- import { useActions } from '../useActions';
11
- import { useEditorCache } from '../useEditorCache';
12
- import { useFileCRUD } from '../useFileCRUD';
13
- import { useKeyboardShortcuts } from '../useKeyboardShortcuts';
14
- import { useOpenDirectories } from '../useOpenDirectories';
15
- import { usePrettier } from '../usePrettier';
16
- import { useRunCode } from '../useRunCode';
17
- import { useRuntimeError } from '../useRuntimeError';
18
- import { useURLSync } from '../useURLSync';
19
- import {
20
- createInitialState,
21
- vzReducer,
22
- } from '../vzReducer';
23
- import { findPane } from '../vzReducer/findPane';
24
- import { usePresenceAutoFollow } from '../usePresenceAutoFollow';
25
- import { v4 as uuidv4 } from 'uuid';
26
- import {
27
- VZCodeContextValue,
28
- VZCodeProviderProps,
29
- } from './types';
30
-
31
- export const useVZCodeState = ({
32
- content,
33
- shareDBDoc,
34
- submitOperation,
35
- localPresence,
36
- docPresence,
37
- prettierWorker,
38
- initialUsername,
39
- codeError = null,
40
- connected,
41
- pending,
42
- liveKitToken,
43
- setLiveKitToken,
44
- liveKitRoomName,
45
- setLiveKitRoom,
46
- liveKitConnection,
47
- setLiveKitConnection,
48
- aiChatEndpoint,
49
- aiChatUndoEndpoint,
50
- aiChatOptions,
51
- autoForkAndRetryAI,
52
- clearStoredAIPrompt,
53
- getStoredAIPrompt,
54
- additionalWidgets,
55
- iframeRef: externalIframeRef,
56
- }: Omit<
57
- VZCodeProviderProps,
58
- 'children'
59
- >): VZCodeContextValue => {
60
- // Auto-run Prettier after local changes.
61
- const { prettierError, runPrettierRef } = usePrettier({
62
- shareDBDoc,
63
- submitOperation,
64
- prettierWorker,
65
- });
66
-
67
- // Handle runtime errors from the iframe
68
- const {
69
- runtimeError,
70
- handleRuntimeError,
71
- clearRuntimeError,
72
- } = useRuntimeError();
73
-
74
- const runCodeRef = useRunCode(submitOperation);
75
-
76
- const sidebarRef = useRef(null);
77
-
78
- const codeEditorRef = useRef(null);
79
-
80
- // Use external iframeRef if provided, otherwise create our own
81
- const iframeRef = externalIframeRef || useRef(null);
82
-
83
- // The error message shows errors in order of priority:
84
- // * `runtimeError` - errors from runtime execution, highest priority
85
- // * `prettierError` - errors from Prettier, client-side only
86
- // * `codeError` - errors from an external source, such as
87
- // build-time errors or intercepted runtime errors.
88
- // Runtime errors are prioritized since they indicate immediate execution issues.
89
- // Prettier errors are next since they surface syntax errors that are likely
90
- // to be useful to the user.
91
- const errorMessage: string | null = runtimeError
92
- ? runtimeError
93
- : prettierError
94
- ? prettierError
95
- : codeError;
96
-
97
- // Set up the reducer that manages much of the application state.
98
- // See https://react.dev/reference/react/useReducer
99
- const [state, dispatch] = useReducer(
100
- vzReducer,
101
- { defaultTheme, initialUsername },
102
- createInitialState,
103
- );
104
-
105
- // Unpack state.
106
- const {
107
- pane,
108
- activePaneId,
109
- theme,
110
- search,
111
- isSearchOpen,
112
- isVisualEditorOpen,
113
- isAIChatOpen,
114
- aiChatFocused,
115
- isSettingsOpen,
116
- isDocOpen,
117
- editorWantsFocus,
118
- username,
119
- enableAutoFollow,
120
- sidebarPresenceIndicators,
121
- aiChatMode,
122
- } = state;
123
-
124
- const activePane = findPane(pane, activePaneId);
125
- if (activePane.type !== 'leafPane') {
126
- // Should never happen
127
- throw new Error('Expected leafPane');
128
- }
129
-
130
- // Functions for dispatching actions to the reducer.
131
- const {
132
- setActiveFileId,
133
- setActiveFileLeft,
134
- setActiveFileRight,
135
- openTab,
136
- closeTabs,
137
- setTheme,
138
- setIsSearchOpen,
139
- setSearch,
140
- setSearchResults,
141
- setSearchFileVisibility,
142
- setSearchLineVisibility,
143
- setSearchFocusedIndex,
144
- toggleSearchFocused,
145
- setIsVisualEditorOpen,
146
- setIsAIChatOpen,
147
- toggleAIChatFocused,
148
- setAIChatMode,
149
- setIsSettingsOpen,
150
- setIsDocOpen,
151
- closeSettings,
152
- closeDoc,
153
- editorNoLongerWantsFocus,
154
- setUsername,
155
- toggleAutoFollow,
156
- updatePresenceIndicator,
157
- splitCurrentPane,
158
- } = useActions(dispatch);
159
-
160
- // Sync tab state to the URL.
161
- useURLSync({
162
- content,
163
- openTab,
164
- setActiveFileId,
165
- tabList: activePane.tabList,
166
- activeFileId: activePane.activeFileId,
167
- });
168
-
169
- // The set of open directories.
170
- const { isDirectoryOpen, toggleDirectory } =
171
- useOpenDirectories({ activePane, content });
172
-
173
- // Cache of CodeMirror editors by file id.
174
- const editorCache = useEditorCache();
175
-
176
- // Handle dynamic theme changes.
177
- useDynamicTheme(editorCache, theme);
178
-
179
- // Handle file CRUD operations (Create, Read, Update, Delete)
180
- const {
181
- createFile,
182
- renameFile,
183
- deleteFile,
184
- createDirectory,
185
- renameDirectory,
186
- deleteDirectory,
187
- deleteAllFiles,
188
- } = useFileCRUD({
189
- submitOperation,
190
- closeTabs,
191
- openTab,
192
- editorCache,
193
- content,
194
- });
195
-
196
- // State to control the create file modal's visibility
197
- const [isCreateFileModalOpen, setIsCreateFileModalOpen] =
198
- useState(false);
199
-
200
- const handleOpenCreateFileModal = useCallback(() => {
201
- setIsCreateFileModalOpen(true);
202
- }, []);
203
-
204
- const handleCloseCreateFileModal = useCallback(() => {
205
- setIsCreateFileModalOpen(false);
206
- }, []);
207
-
208
- const handleCreateFileClick = useCallback(
209
- (newFileName: string) => {
210
- createFile(newFileName);
211
- setIsCreateFileModalOpen(false);
212
- },
213
- [createFile, setIsCreateFileModalOpen],
214
- );
215
-
216
- // State to control the create directory modal's visibility
217
- const [isCreateDirModalOpen, setIsCreateDirModalOpen] =
218
- useState(false);
219
-
220
- const handleOpenCreateDirModal = useCallback(() => {
221
- setIsCreateDirModalOpen(true);
222
- }, []);
223
-
224
- const handleCloseCreateDirModal = useCallback(() => {
225
- setIsCreateDirModalOpen(false);
226
- }, []);
227
-
228
- const handleCreateDirClick = useCallback(
229
- (newDirName: string) => {
230
- createDirectory(newDirName);
231
- setIsCreateDirModalOpen(false);
232
- },
233
- [createDirectory, setIsCreateDirModalOpen],
234
- );
235
-
236
- // Isolate the files object from the document.
237
- const files = content ? content.files : null;
238
-
239
- useKeyboardShortcuts({
240
- closeTabs,
241
- activeFileId: activePane.activeFileId,
242
- activePaneId,
243
- handleOpenCreateFileModal,
244
- setActiveFileLeft,
245
- setActiveFileRight,
246
- toggleSearchFocused,
247
- runPrettierRef,
248
- runCodeRef,
249
- sidebarRef,
250
- editorCache,
251
- codeEditorRef,
252
- });
253
-
254
- // Track the currently hovered file id.
255
- const [hoveredItemId, setHoveredItemId] = useState(null);
256
-
257
- // Handle presence-based auto-following
258
- usePresenceAutoFollow({
259
- docPresence,
260
- enableAutoFollow,
261
- openTab,
262
- activePane,
263
- });
264
-
265
- // Livekit Voice Chat Modal
266
- const [voiceChatModalOpen, setVoiceChatModalOpen] =
267
- useState(false);
268
-
269
- const [aiChatMessage, setAIChatMessage] = useState('');
270
-
271
- const DEBUG = false;
272
-
273
- // Compute isLoading based on the current chat's aiStatus
274
- const [currentChatId] = useState(() => uuidv4());
275
- const currentChat = content?.chats?.[currentChatId];
276
- const isLoading = currentChat?.aiStatus === 'generating';
277
-
278
- // Message history for up/down arrow navigation - using ShareDB document data
279
- const messageHistory = useMemo(() => {
280
- if (!currentChat?.messages) return [];
281
- // Extract user messages in chronological order for history navigation
282
- return currentChat.messages
283
- .filter((msg) => msg.role === 'user')
284
- .map((msg) => msg.content);
285
- }, [currentChat?.messages]);
286
-
287
- const [historyIndex, setHistoryIndex] = useState(-1);
288
- const [currentDraft, setCurrentDraft] = useState('');
289
-
290
- const [aiErrorMessage, setAIErrorMessage] = useState<
291
- string | null
292
- >(null);
293
-
294
- // Message history navigation functions
295
- const navigateMessageHistoryUp = useCallback(() => {
296
- if (messageHistory.length === 0) return;
297
-
298
- // If we're not navigating history, save current draft
299
- if (historyIndex === -1) {
300
- setCurrentDraft(aiChatMessage);
301
- }
302
-
303
- const newIndex =
304
- historyIndex < messageHistory.length - 1
305
- ? historyIndex + 1
306
- : historyIndex;
307
- setHistoryIndex(newIndex);
308
- setAIChatMessage(
309
- messageHistory[messageHistory.length - 1 - newIndex],
310
- );
311
- }, [messageHistory, historyIndex, aiChatMessage]);
312
-
313
- const navigateMessageHistoryDown = useCallback(() => {
314
- if (historyIndex === -1) return;
315
-
316
- const newIndex = historyIndex - 1;
317
- if (newIndex === -1) {
318
- // Return to draft
319
- setHistoryIndex(-1);
320
- setAIChatMessage(currentDraft);
321
- setCurrentDraft('');
322
- } else {
323
- setHistoryIndex(newIndex);
324
- setAIChatMessage(
325
- messageHistory[
326
- messageHistory.length - 1 - newIndex
327
- ],
328
- );
329
- }
330
- }, [messageHistory, historyIndex, currentDraft]);
331
-
332
- const resetMessageHistoryNavigation = useCallback(() => {
333
- if (historyIndex !== -1) {
334
- setHistoryIndex(-1);
335
- setCurrentDraft('');
336
- }
337
- }, [historyIndex]);
338
-
339
- const handleSendMessage = useCallback(
340
- async (
341
- messageToSend?: string,
342
- options?: Record<string, string>,
343
- ) => {
344
- DEBUG &&
345
- console.log(
346
- 'AIChat: handleSendMessage called with:',
347
- messageToSend,
348
- 'aiChatMessage:',
349
- aiChatMessage,
350
- );
351
- const messageContent = messageToSend || aiChatMessage;
352
-
353
- if (
354
- !messageContent ||
355
- typeof messageContent !== 'string' ||
356
- !messageContent.trim() ||
357
- isLoading
358
- ) {
359
- return;
360
- }
361
-
362
- const currentPrompt = aiChatMessage.trim();
363
- setAIChatMessage('');
364
-
365
- // Reset history navigation when sending a message
366
- setHistoryIndex(-1);
367
- setCurrentDraft('');
368
-
369
- setAIErrorMessage(null); // Clear any previous errors
370
-
371
- // Call backend endpoint for AI response
372
- try {
373
- const response = await fetch(aiChatEndpoint, {
374
- method: 'POST',
375
- headers: {
376
- 'Content-Type': 'application/json',
377
- },
378
- body: JSON.stringify({
379
- ...aiChatOptions,
380
- content: messageContent.trim(),
381
- chatId: currentChatId,
382
- mode: aiChatMode,
383
- ...options,
384
- }),
385
- });
386
-
387
- if (!response.ok) {
388
- throw new Error(
389
- `HTTP error! status: ${response.status}`,
390
- );
391
- }
392
-
393
- // Parse the response to check for errors
394
- const responseData = await response.json();
395
-
396
- // Check if the response contains a VizHub error
397
- if (
398
- responseData.outcome === 'failure' &&
399
- responseData.error
400
- ) {
401
- const errorMessage = responseData.error.message;
402
-
403
- // Check if this is the specific permission error that should trigger auto-fork
404
- if (
405
- errorMessage ===
406
- 'You do not have permission to use AI chat on this visualization. Only users with edit access can use this feature. Fork the viz to edit it.'
407
- ) {
408
- // Trigger auto-fork instead of showing error
409
- try {
410
- await autoForkAndRetryAI?.(
411
- currentPrompt,
412
- aiChatMode,
413
- );
414
- // If we reach here, the fork was successful and redirect should happen
415
- return;
416
- } catch (forkError) {
417
- console.error('Auto-fork failed:', forkError);
418
- setAIErrorMessage(
419
- 'Failed to fork visualization. Please try forking manually.',
420
- );
421
- return;
422
- }
423
- }
424
-
425
- // For other errors, show the error message
426
- setAIErrorMessage(errorMessage);
427
- return;
428
- }
429
-
430
- // The backend handles all ShareDB operations for successful responses
431
- // The loading state is now managed via ShareDB aiStatus
432
- } catch (error) {
433
- console.error('Error getting AI response:', error);
434
- setAIErrorMessage(
435
- 'Failed to send message. Please try again.',
436
- );
437
- }
438
- },
439
- [
440
- aiChatMessage,
441
- isLoading,
442
- aiChatEndpoint,
443
- aiChatOptions,
444
- currentChatId,
445
- aiChatMode,
446
- autoForkAndRetryAI,
447
- ],
448
- );
449
-
450
- // Return the context value
451
- return {
452
- content,
453
- shareDBDoc,
454
- submitOperation,
455
- localPresence,
456
- docPresence,
457
-
458
- files,
459
- createFile,
460
- renameFile,
461
- deleteFile,
462
- createDirectory,
463
- renameDirectory,
464
- deleteDirectory,
465
- deleteAllFiles,
466
-
467
- setActiveFileId,
468
- setActiveFileLeft,
469
- setActiveFileRight,
470
-
471
- activePaneId,
472
- // Root pane
473
- pane,
474
- // Active leaf pane
475
- activePane,
476
-
477
- openTab,
478
- closeTabs,
479
-
480
- search,
481
- isSearchOpen,
482
- setIsSearchOpen,
483
- setSearch,
484
- setSearchResults,
485
- setSearchFileVisibility,
486
- setSearchLineVisibility,
487
- setSearchFocusedIndex,
488
- toggleSearchFocused,
489
-
490
- isVisualEditorOpen,
491
- setIsVisualEditorOpen,
492
-
493
- isAIChatOpen,
494
- setIsAIChatOpen,
495
- aiChatFocused,
496
- toggleAIChatFocused,
497
- aiChatMode: state.aiChatMode,
498
- setAIChatMode,
499
- aiChatEndpoint,
500
- aiChatUndoEndpoint,
501
- aiChatOptions,
502
-
503
- isSettingsOpen,
504
- setIsSettingsOpen,
505
- closeSettings,
506
-
507
- isDocOpen,
508
- setIsDocOpen,
509
- closeDoc,
510
-
511
- theme,
512
- setTheme,
513
-
514
- username,
515
- setUsername,
516
-
517
- isDirectoryOpen,
518
- toggleDirectory,
519
-
520
- editorCache,
521
- editorWantsFocus,
522
- editorNoLongerWantsFocus,
523
-
524
- errorMessage,
525
-
526
- handleRuntimeError,
527
- clearRuntimeError,
528
-
529
- isCreateFileModalOpen,
530
- handleOpenCreateFileModal,
531
- handleCloseCreateFileModal,
532
- handleCreateFileClick,
533
- isCreateDirModalOpen,
534
- handleOpenCreateDirModal,
535
- handleCloseCreateDirModal,
536
- handleCreateDirClick,
537
- runPrettierRef,
538
- runCodeRef,
539
- sidebarRef,
540
- codeEditorRef,
541
- iframeRef,
542
-
543
- connected,
544
- pending,
545
-
546
- hoveredItemId,
547
- setHoveredItemId,
548
-
549
- enableAutoFollow,
550
- toggleAutoFollow,
551
- updatePresenceIndicator,
552
- sidebarPresenceIndicators,
553
- splitCurrentPane,
554
- liveKitRoomName,
555
- setLiveKitRoom,
556
- liveKitToken,
557
- setLiveKitToken,
558
- liveKitConnection,
559
- setLiveKitConnection,
560
- voiceChatModalOpen,
561
- setVoiceChatModalOpen,
562
-
563
- aiChatMessage,
564
- setAIChatMessage,
565
- isLoading,
566
- currentChatId,
567
- aiErrorMessage,
568
- setAIErrorMessage,
569
- handleSendMessage,
570
-
571
- // Message history navigation
572
- navigateMessageHistoryUp,
573
- navigateMessageHistoryDown,
574
- resetMessageHistoryNavigation,
575
-
576
- // Auto-fork functions for VizHub integration
577
- autoForkAndRetryAI,
578
- clearStoredAIPrompt,
579
- getStoredAIPrompt,
580
-
581
- // Additional widgets that can be rendered in AI chat messages
582
- additionalWidgets,
583
- };
584
- };