vzcode 2.2.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 (220) 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-CpxqGhXj.js → index-DuUjtrt6.js} +150 -150
  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 +22 -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/MicOffSVG.tsx +0 -35
  79. package/src/client/Icons/MicSVG.tsx +0 -25
  80. package/src/client/Icons/NewSVG.tsx +0 -19
  81. package/src/client/Icons/PinSVG.tsx +0 -14
  82. package/src/client/Icons/PlaySVG.tsx +0 -16
  83. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  84. package/src/client/Icons/ReactSVG.tsx +0 -16
  85. package/src/client/Icons/SearchSVG.tsx +0 -20
  86. package/src/client/Icons/SparklesSVG.tsx +0 -23
  87. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  88. package/src/client/Icons/StopSVG.tsx +0 -15
  89. package/src/client/Icons/SvelteSVG.tsx +0 -16
  90. package/src/client/Icons/TrashSVG.tsx +0 -19
  91. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  92. package/src/client/Icons/index.tsx +0 -26
  93. package/src/client/ImageViewer/index.tsx +0 -91
  94. package/src/client/ImageViewer/style.scss +0 -41
  95. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  96. package/src/client/PresenceNotifications/index.tsx +0 -158
  97. package/src/client/PresenceNotifications/style.scss +0 -17
  98. package/src/client/RunCodeWidget/index.tsx +0 -117
  99. package/src/client/RunCodeWidget/style.scss +0 -24
  100. package/src/client/SplitPaneResizeContext.tsx +0 -159
  101. package/src/client/TabList/Tab.tsx +0 -73
  102. package/src/client/TabList/index.tsx +0 -35
  103. package/src/client/TabList/style.scss +0 -51
  104. package/src/client/VZCodeContext/index.tsx +0 -29
  105. package/src/client/VZCodeContext/types.ts +0 -249
  106. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  107. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  108. package/src/client/VZLeft.tsx +0 -28
  109. package/src/client/VZMiddle.tsx +0 -172
  110. package/src/client/VZResizer/index.tsx +0 -128
  111. package/src/client/VZResizer/styles.scss +0 -33
  112. package/src/client/VZRight.tsx +0 -113
  113. package/src/client/VZSettings.tsx +0 -275
  114. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -239
  115. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  116. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  117. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  118. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  119. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  120. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  121. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  122. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  123. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  124. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -117
  125. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  126. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  127. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  128. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  129. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  130. package/src/client/VZSidebar/FileListing.tsx +0 -91
  131. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  132. package/src/client/VZSidebar/Item.tsx +0 -237
  133. package/src/client/VZSidebar/Listing.tsx +0 -47
  134. package/src/client/VZSidebar/Search.tsx +0 -527
  135. package/src/client/VZSidebar/VisualEditor.tsx +0 -282
  136. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  137. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  138. package/src/client/VZSidebar/index.tsx +0 -728
  139. package/src/client/VZSidebar/styles.scss +0 -612
  140. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  141. package/src/client/bootstrap.ts +0 -26
  142. package/src/client/buildWorker.ts +0 -3
  143. package/src/client/featureFlags.ts +0 -8
  144. package/src/client/generateRequestId.ts +0 -6
  145. package/src/client/getFileTree.ts +0 -53
  146. package/src/client/index.ts +0 -19
  147. package/src/client/main.jsx +0 -10
  148. package/src/client/presenceColor.ts +0 -8
  149. package/src/client/shouldTriggerRun.ts +0 -31
  150. package/src/client/sortFileTree.ts +0 -21
  151. package/src/client/tabsSearchParameters.test.ts +0 -79
  152. package/src/client/tabsSearchParameters.ts +0 -137
  153. package/src/client/themes/index.ts +0 -7
  154. package/src/client/themes/themes.ts +0 -77
  155. package/src/client/themes/uiwImports.ts +0 -32
  156. package/src/client/themes/useDynamicTheme.ts +0 -29
  157. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  158. package/src/client/themes/vizhubTheme/index.ts +0 -193
  159. package/src/client/useActions.ts +0 -288
  160. package/src/client/useESLint/index.ts +0 -72
  161. package/src/client/useESLint/worker.ts +0 -113
  162. package/src/client/useEditorCache.ts +0 -35
  163. package/src/client/useFileCRUD.ts +0 -228
  164. package/src/client/useKeyboardShortcuts.ts +0 -451
  165. package/src/client/useOpenDirectories.ts +0 -99
  166. package/src/client/usePresenceAutoFollow.ts +0 -85
  167. package/src/client/usePrettier/index.ts +0 -178
  168. package/src/client/usePrettier/worker.ts +0 -109
  169. package/src/client/useRunCode.tsx +0 -15
  170. package/src/client/useRuntimeError.ts +0 -32
  171. package/src/client/useSubmitOperation.ts +0 -15
  172. package/src/client/useURLSync.ts +0 -137
  173. package/src/client/usernameLocalStorage.ts +0 -43
  174. package/src/client/utils/fileExtension.ts +0 -10
  175. package/src/client/utils/isImageFile.ts +0 -12
  176. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  177. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  178. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  179. package/src/client/vzReducer/createInitialState.ts +0 -38
  180. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  181. package/src/client/vzReducer/findPane.ts +0 -19
  182. package/src/client/vzReducer/index.ts +0 -250
  183. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  184. package/src/client/vzReducer/openTabReducer.ts +0 -74
  185. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  186. package/src/client/vzReducer/searchReducer.ts +0 -181
  187. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  188. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  189. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  190. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  191. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  192. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  193. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  194. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  195. package/src/client/vzReducer/updatePane.ts +0 -40
  196. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  197. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  198. package/src/reactRouterExports.ts +0 -15
  199. package/src/runCode.ts +0 -27
  200. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  201. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  202. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  203. package/src/server/aiChatHandler/index.ts +0 -200
  204. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  205. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  206. package/src/server/aiChatHandler/validation.ts +0 -24
  207. package/src/server/computeInitialDocument.ts +0 -220
  208. package/src/server/generateAIResponse.ts +0 -188
  209. package/src/server/handleAIAssist.ts +0 -53
  210. package/src/server/handleAIChatUndo.ts +0 -2
  211. package/src/server/handleAICopilot.ts +0 -97
  212. package/src/server/index.ts +0 -388
  213. package/src/server/livekit.ts +0 -24
  214. package/src/server/prettier.ts +0 -115
  215. package/src/submitOperation.ts +0 -25
  216. package/src/types.ts +0 -205
  217. package/src/utils/fileDiff.ts +0 -117
  218. package/src/vite-env.d.ts +0 -10
  219. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  220. /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
- };