vzcode 1.59.0 → 1.60.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/dist/assets/{index-afP-wJTZ.css → index-DMIy-XE4.css} +1 -1
- package/dist/assets/{index-BJI4JLx9.js → index-S-R8oY72.js} +115 -115
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/client/VZCodeContext/index.tsx +29 -0
- package/src/client/VZCodeContext/types.ts +236 -0
- package/src/client/{VZCodeContext.tsx → VZCodeContext/useVZCodeState.ts} +34 -289
- package/src/client/VZSidebar/AIChat/index.tsx +1 -1
- package/src/client/VZSidebar/AIChat/styles.scss +2 -0
|
@@ -1,237 +1,33 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Context,
|
|
3
|
-
createContext,
|
|
4
2
|
useCallback,
|
|
5
3
|
useReducer,
|
|
6
4
|
useRef,
|
|
7
5
|
useState,
|
|
8
6
|
} from 'react';
|
|
7
|
+
import { VizContent } from '@vizhub/viz-types';
|
|
8
|
+
import { defaultTheme, useDynamicTheme } from '../themes';
|
|
9
|
+
import { useActions } from '../useActions';
|
|
10
|
+
import { useEditorCache } from '../useEditorCache';
|
|
11
|
+
import { useFileCRUD } from '../useFileCRUD';
|
|
12
|
+
import { useKeyboardShortcuts } from '../useKeyboardShortcuts';
|
|
13
|
+
import { useOpenDirectories } from '../useOpenDirectories';
|
|
14
|
+
import { usePrettier } from '../usePrettier';
|
|
15
|
+
import { useRunCode } from '../useRunCode';
|
|
16
|
+
import { useRuntimeError } from '../useRuntimeError';
|
|
17
|
+
import { useURLSync } from '../useURLSync';
|
|
9
18
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
SearchFileVisibility,
|
|
16
|
-
SearchResults,
|
|
17
|
-
ShareDBDoc,
|
|
18
|
-
SubmitOperation,
|
|
19
|
-
TabState,
|
|
20
|
-
Username,
|
|
21
|
-
} from '../types';
|
|
22
|
-
import { VizFiles, VizContent } from '@vizhub/viz-types';
|
|
23
|
-
import {
|
|
24
|
-
ThemeLabel,
|
|
25
|
-
defaultTheme,
|
|
26
|
-
useDynamicTheme,
|
|
27
|
-
} from './themes';
|
|
28
|
-
import { useActions } from './useActions';
|
|
29
|
-
import {
|
|
30
|
-
EditorCache,
|
|
31
|
-
useEditorCache,
|
|
32
|
-
} from './useEditorCache';
|
|
33
|
-
import { useFileCRUD } from './useFileCRUD';
|
|
34
|
-
import { useKeyboardShortcuts } from './useKeyboardShortcuts';
|
|
35
|
-
import { useOpenDirectories } from './useOpenDirectories';
|
|
36
|
-
import { usePrettier } from './usePrettier';
|
|
37
|
-
import { useRunCode } from './useRunCode';
|
|
38
|
-
import { useRuntimeError } from './useRuntimeError';
|
|
39
|
-
import { useURLSync } from './useURLSync';
|
|
40
|
-
import { createInitialState, vzReducer } from './vzReducer';
|
|
41
|
-
import { findPane } from './vzReducer/findPane';
|
|
42
|
-
import { usePresenceAutoFollow } from './usePresenceAutoFollow';
|
|
19
|
+
createInitialState,
|
|
20
|
+
vzReducer,
|
|
21
|
+
} from '../vzReducer';
|
|
22
|
+
import { findPane } from '../vzReducer/findPane';
|
|
23
|
+
import { usePresenceAutoFollow } from '../usePresenceAutoFollow';
|
|
43
24
|
import { v4 as uuidv4 } from 'uuid';
|
|
25
|
+
import {
|
|
26
|
+
VZCodeContextValue,
|
|
27
|
+
VZCodeProviderProps,
|
|
28
|
+
} from './types';
|
|
44
29
|
|
|
45
|
-
|
|
46
|
-
// to do with the application state. This includes
|
|
47
|
-
// * Accessing and manipulating ShareDB data
|
|
48
|
-
// * Centralized application state
|
|
49
|
-
export const VZCodeContext =
|
|
50
|
-
createContext<VZCodeContextValue>(null);
|
|
51
|
-
|
|
52
|
-
// The type of the object provided by this context.
|
|
53
|
-
export type VZCodeContextValue = {
|
|
54
|
-
content: VizContent | null;
|
|
55
|
-
shareDBDoc: ShareDBDoc<VizContent> | null;
|
|
56
|
-
submitOperation: (
|
|
57
|
-
next: (content: VizContent) => VizContent,
|
|
58
|
-
) => void;
|
|
59
|
-
// TODO pull in this type from ShareDB if possible
|
|
60
|
-
localPresence: any;
|
|
61
|
-
// TODO pull in this type from ShareDB if possible
|
|
62
|
-
docPresence: any;
|
|
63
|
-
|
|
64
|
-
files: VizFiles | null;
|
|
65
|
-
createFile: (fileName: string, text?: string) => void;
|
|
66
|
-
renameFile: (fileId: string, fileName: string) => void;
|
|
67
|
-
deleteFile: (fileId: string) => void;
|
|
68
|
-
createDirectory: (
|
|
69
|
-
fileName: string,
|
|
70
|
-
text?: string,
|
|
71
|
-
) => void;
|
|
72
|
-
renameDirectory: (
|
|
73
|
-
directoryId: string,
|
|
74
|
-
directoryOldName: string,
|
|
75
|
-
directoryName: string,
|
|
76
|
-
) => void;
|
|
77
|
-
deleteDirectory: (directoryId: string) => void;
|
|
78
|
-
|
|
79
|
-
setActiveFileId: (fileId: string | null) => void;
|
|
80
|
-
setActiveFileLeft: () => void;
|
|
81
|
-
setActiveFileRight: () => void;
|
|
82
|
-
|
|
83
|
-
activePaneId: PaneId;
|
|
84
|
-
pane: Pane;
|
|
85
|
-
activePane: LeafPane;
|
|
86
|
-
|
|
87
|
-
openTab: (tabState: TabState) => void;
|
|
88
|
-
closeTabs: (fileIds: string[]) => void;
|
|
89
|
-
|
|
90
|
-
isSettingsOpen: boolean;
|
|
91
|
-
setIsSettingsOpen: (isSettingsOpen: boolean) => void;
|
|
92
|
-
closeSettings: () => void;
|
|
93
|
-
|
|
94
|
-
isDocOpen: boolean;
|
|
95
|
-
setIsDocOpen: (isDocOpen: boolean) => void;
|
|
96
|
-
closeDoc: () => void;
|
|
97
|
-
|
|
98
|
-
theme: ThemeLabel;
|
|
99
|
-
setTheme: (theme: ThemeLabel) => void;
|
|
100
|
-
|
|
101
|
-
username: Username;
|
|
102
|
-
setUsername: (username: Username) => void;
|
|
103
|
-
|
|
104
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
105
|
-
toggleDirectory: (path: string) => void;
|
|
106
|
-
|
|
107
|
-
editorCache: EditorCache;
|
|
108
|
-
|
|
109
|
-
// Whether the editor should be focused.
|
|
110
|
-
editorWantsFocus: boolean;
|
|
111
|
-
// Signals that the editor no longer wants focus.
|
|
112
|
-
editorNoLongerWantsFocus: () => void;
|
|
113
|
-
|
|
114
|
-
errorMessage: string | null;
|
|
115
|
-
|
|
116
|
-
// Runtime error handling
|
|
117
|
-
handleRuntimeError: (
|
|
118
|
-
formattedErrorMessage: string,
|
|
119
|
-
) => void;
|
|
120
|
-
clearRuntimeError: () => void;
|
|
121
|
-
|
|
122
|
-
search: SearchResults;
|
|
123
|
-
isSearchOpen: boolean;
|
|
124
|
-
setIsSearchOpen: (isSearchOpen: boolean) => void;
|
|
125
|
-
setSearch: (pattern: string) => void;
|
|
126
|
-
|
|
127
|
-
isAIChatOpen: boolean;
|
|
128
|
-
setIsAIChatOpen: (isAIChatOpen: boolean) => void;
|
|
129
|
-
aiChatFocused: boolean;
|
|
130
|
-
toggleAIChatFocused: () => void;
|
|
131
|
-
aiChatMode: 'ask' | 'edit';
|
|
132
|
-
setAIChatMode: (mode: 'ask' | 'edit') => void;
|
|
133
|
-
aiChatEndpoint?: string;
|
|
134
|
-
aiChatUndoEndpoint?: string;
|
|
135
|
-
aiChatOptions?: { [key: string]: any };
|
|
136
|
-
setSearchResults: (files: ShareDBDoc<VizContent>) => void;
|
|
137
|
-
setSearchFileVisibility: (
|
|
138
|
-
files: ShareDBDoc<VizContent>,
|
|
139
|
-
id: string,
|
|
140
|
-
visibility: SearchFileVisibility,
|
|
141
|
-
) => void;
|
|
142
|
-
setSearchLineVisibility: (
|
|
143
|
-
files: ShareDBDoc<VizContent>,
|
|
144
|
-
id: string,
|
|
145
|
-
line: number,
|
|
146
|
-
) => void;
|
|
147
|
-
setSearchFocusedIndex: (
|
|
148
|
-
focusedIndex: number,
|
|
149
|
-
childIndex: number,
|
|
150
|
-
) => void;
|
|
151
|
-
toggleSearchFocused: () => void;
|
|
152
|
-
|
|
153
|
-
isCreateFileModalOpen: boolean;
|
|
154
|
-
handleOpenCreateFileModal: () => void;
|
|
155
|
-
handleCloseCreateFileModal: () => void;
|
|
156
|
-
handleCreateFileClick: (newFileName: string) => void;
|
|
157
|
-
|
|
158
|
-
isCreateDirModalOpen: boolean;
|
|
159
|
-
handleOpenCreateDirModal: () => void;
|
|
160
|
-
handleCloseCreateDirModal: () => void;
|
|
161
|
-
handleCreateDirClick: (newFileName: string) => void;
|
|
162
|
-
|
|
163
|
-
runPrettierRef: React.MutableRefObject<
|
|
164
|
-
null | (() => void)
|
|
165
|
-
>;
|
|
166
|
-
runCodeRef: React.MutableRefObject<
|
|
167
|
-
null | ((hardRerun?: boolean) => void)
|
|
168
|
-
>;
|
|
169
|
-
|
|
170
|
-
sidebarRef: React.RefObject<HTMLDivElement>;
|
|
171
|
-
|
|
172
|
-
codeEditorRef: React.RefObject<HTMLDivElement>;
|
|
173
|
-
|
|
174
|
-
connected: boolean;
|
|
175
|
-
pending: boolean;
|
|
176
|
-
|
|
177
|
-
hoveredItemId: ItemId | null;
|
|
178
|
-
setHoveredItemId: (itemId: ItemId | null) => void;
|
|
179
|
-
|
|
180
|
-
enableAutoFollow: boolean;
|
|
181
|
-
toggleAutoFollow: () => void;
|
|
182
|
-
|
|
183
|
-
updatePresenceIndicator: (
|
|
184
|
-
presenceIndicator: PresenceIndicator,
|
|
185
|
-
) => void;
|
|
186
|
-
|
|
187
|
-
sidebarPresenceIndicators: Array<PresenceIndicator>;
|
|
188
|
-
splitCurrentPane: () => void;
|
|
189
|
-
|
|
190
|
-
liveKitToken: string;
|
|
191
|
-
setLiveKitToken: (state: string) => void;
|
|
192
|
-
liveKitRoomName: string;
|
|
193
|
-
setLiveKitRoom: (state: string) => void;
|
|
194
|
-
liveKitConnection: boolean;
|
|
195
|
-
setLiveKitConnection: (state: boolean) => void;
|
|
196
|
-
voiceChatModalOpen: boolean;
|
|
197
|
-
setVoiceChatModalOpen: (state: boolean) => void;
|
|
198
|
-
aiChatMessage: string;
|
|
199
|
-
setAIChatMessage: (message: string) => void;
|
|
200
|
-
isLoading: boolean;
|
|
201
|
-
setIsLoading: (state: boolean) => void;
|
|
202
|
-
currentChatId: string;
|
|
203
|
-
aiErrorMessage: string | null;
|
|
204
|
-
setAIErrorMessage: (state: string | null) => void;
|
|
205
|
-
handleSendMessage: (
|
|
206
|
-
messageToSend?: string,
|
|
207
|
-
options?: Record<string, string>,
|
|
208
|
-
) => void;
|
|
209
|
-
|
|
210
|
-
// Auto-fork functions for VizHub integration
|
|
211
|
-
autoForkAndRetryAI?: (
|
|
212
|
-
prompt: string,
|
|
213
|
-
modelName: string,
|
|
214
|
-
commitId?: string,
|
|
215
|
-
) => Promise<void>;
|
|
216
|
-
clearStoredAIPrompt?: () => void;
|
|
217
|
-
getStoredAIPrompt?: () => {
|
|
218
|
-
prompt: string;
|
|
219
|
-
modelName: string;
|
|
220
|
-
} | null;
|
|
221
|
-
|
|
222
|
-
// Additional widgets that can be rendered in AI chat messages
|
|
223
|
-
additionalWidgets?: React.ComponentType<{
|
|
224
|
-
messageId: string;
|
|
225
|
-
chatId: string;
|
|
226
|
-
canUndo: boolean;
|
|
227
|
-
handleSendMessage?: (
|
|
228
|
-
messageToSend?: string,
|
|
229
|
-
options?: Record<string, string>,
|
|
230
|
-
) => void;
|
|
231
|
-
}>;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export const VZCodeProvider = ({
|
|
30
|
+
export const useVZCodeState = ({
|
|
235
31
|
content,
|
|
236
32
|
shareDBDoc,
|
|
237
33
|
submitOperation,
|
|
@@ -239,7 +35,6 @@ export const VZCodeProvider = ({
|
|
|
239
35
|
docPresence,
|
|
240
36
|
prettierWorker,
|
|
241
37
|
initialUsername,
|
|
242
|
-
children,
|
|
243
38
|
codeError = null,
|
|
244
39
|
connected,
|
|
245
40
|
pending,
|
|
@@ -256,44 +51,11 @@ export const VZCodeProvider = ({
|
|
|
256
51
|
clearStoredAIPrompt,
|
|
257
52
|
getStoredAIPrompt,
|
|
258
53
|
additionalWidgets,
|
|
259
|
-
}:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
docPresence: any;
|
|
265
|
-
prettierWorker: Worker;
|
|
266
|
-
initialUsername: Username;
|
|
267
|
-
children: React.ReactNode;
|
|
268
|
-
codeError?: string | null;
|
|
269
|
-
connected?: boolean;
|
|
270
|
-
pending?: boolean;
|
|
271
|
-
liveKitToken?: string | undefined;
|
|
272
|
-
setLiveKitToken?: (state: string) => void;
|
|
273
|
-
liveKitRoomName?: string | undefined;
|
|
274
|
-
setLiveKitRoom?: (state: string) => void;
|
|
275
|
-
liveKitConnection?: boolean;
|
|
276
|
-
setLiveKitConnection?: (state: boolean) => void;
|
|
277
|
-
aiChatEndpoint?: string;
|
|
278
|
-
aiChatUndoEndpoint?: string;
|
|
279
|
-
aiChatOptions?: { [key: string]: any };
|
|
280
|
-
autoForkAndRetryAI?: (
|
|
281
|
-
prompt: string,
|
|
282
|
-
modelName: string,
|
|
283
|
-
commitId?: string,
|
|
284
|
-
) => Promise<void>;
|
|
285
|
-
clearStoredAIPrompt?: () => void;
|
|
286
|
-
getStoredAIPrompt?: () => {
|
|
287
|
-
prompt: string;
|
|
288
|
-
modelName: string;
|
|
289
|
-
} | null;
|
|
290
|
-
additionalWidgets?: React.ComponentType<{
|
|
291
|
-
messageId: string;
|
|
292
|
-
chatId: string;
|
|
293
|
-
canUndo: boolean;
|
|
294
|
-
}>;
|
|
295
|
-
}) => {
|
|
296
|
-
// Auto-run Pretter after local changes.
|
|
54
|
+
}: Omit<
|
|
55
|
+
VZCodeProviderProps,
|
|
56
|
+
'children'
|
|
57
|
+
>): VZCodeContextValue => {
|
|
58
|
+
// Auto-run Prettier after local changes.
|
|
297
59
|
const { prettierError, runPrettierRef } = usePrettier({
|
|
298
60
|
shareDBDoc,
|
|
299
61
|
submitOperation,
|
|
@@ -336,8 +98,6 @@ export const VZCodeProvider = ({
|
|
|
336
98
|
);
|
|
337
99
|
|
|
338
100
|
// Unpack state.
|
|
339
|
-
// print the state object to see what it contains
|
|
340
|
-
// console.log('state: ', state);
|
|
341
101
|
const {
|
|
342
102
|
pane,
|
|
343
103
|
activePaneId,
|
|
@@ -355,7 +115,7 @@ export const VZCodeProvider = ({
|
|
|
355
115
|
aiChatMode,
|
|
356
116
|
} = state;
|
|
357
117
|
|
|
358
|
-
const activePane
|
|
118
|
+
const activePane = findPane(pane, activePaneId);
|
|
359
119
|
if (activePane.type !== 'leafPane') {
|
|
360
120
|
// Should never happen
|
|
361
121
|
throw new Error('Expected leafPane');
|
|
@@ -400,12 +160,11 @@ export const VZCodeProvider = ({
|
|
|
400
160
|
});
|
|
401
161
|
|
|
402
162
|
// The set of open directories.
|
|
403
|
-
// TODO move this into reducer/useActions
|
|
404
163
|
const { isDirectoryOpen, toggleDirectory } =
|
|
405
164
|
useOpenDirectories({ activePane, content });
|
|
406
165
|
|
|
407
166
|
// Cache of CodeMirror editors by file id.
|
|
408
|
-
const editorCache
|
|
167
|
+
const editorCache = useEditorCache();
|
|
409
168
|
|
|
410
169
|
// Handle dynamic theme changes.
|
|
411
170
|
useDynamicTheme(editorCache, theme);
|
|
@@ -467,13 +226,10 @@ export const VZCodeProvider = ({
|
|
|
467
226
|
);
|
|
468
227
|
|
|
469
228
|
// Isolate the files object from the document.
|
|
470
|
-
const files
|
|
471
|
-
? content.files
|
|
472
|
-
: null;
|
|
229
|
+
const files = content ? content.files : null;
|
|
473
230
|
|
|
474
231
|
useKeyboardShortcuts({
|
|
475
232
|
closeTabs,
|
|
476
|
-
// TODO verify that this makes sense
|
|
477
233
|
activeFileId: activePane.activeFileId,
|
|
478
234
|
activePaneId,
|
|
479
235
|
handleOpenCreateFileModal,
|
|
@@ -488,12 +244,9 @@ export const VZCodeProvider = ({
|
|
|
488
244
|
});
|
|
489
245
|
|
|
490
246
|
// Track the currently hovered file id.
|
|
491
|
-
const [hoveredItemId, setHoveredItemId] =
|
|
492
|
-
useState<ItemId | null>(null);
|
|
247
|
+
const [hoveredItemId, setHoveredItemId] = useState(null);
|
|
493
248
|
|
|
494
249
|
// Handle presence-based auto-following
|
|
495
|
-
// This hook manages opening tabs when presence is received on files
|
|
496
|
-
// that are not currently open, independent of CodeMirror extensions
|
|
497
250
|
usePresenceAutoFollow({
|
|
498
251
|
docPresence,
|
|
499
252
|
enableAutoFollow,
|
|
@@ -502,7 +255,6 @@ export const VZCodeProvider = ({
|
|
|
502
255
|
});
|
|
503
256
|
|
|
504
257
|
// Livekit Voice Chat Modal
|
|
505
|
-
|
|
506
258
|
const [voiceChatModalOpen, setVoiceChatModalOpen] =
|
|
507
259
|
useState(false);
|
|
508
260
|
|
|
@@ -545,7 +297,6 @@ export const VZCodeProvider = ({
|
|
|
545
297
|
setAIErrorMessage(null); // Clear any previous errors
|
|
546
298
|
|
|
547
299
|
// Call backend endpoint for AI response
|
|
548
|
-
// The server will handle all ShareDB operations including adding the user message
|
|
549
300
|
try {
|
|
550
301
|
const response = await fetch(aiChatEndpoint, {
|
|
551
302
|
method: 'POST',
|
|
@@ -579,7 +330,7 @@ export const VZCodeProvider = ({
|
|
|
579
330
|
|
|
580
331
|
// Check if this is the specific permission error that should trigger auto-fork
|
|
581
332
|
if (
|
|
582
|
-
|
|
333
|
+
errorMessage ===
|
|
583
334
|
'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.'
|
|
584
335
|
) {
|
|
585
336
|
// Trigger auto-fork instead of showing error
|
|
@@ -600,7 +351,7 @@ export const VZCodeProvider = ({
|
|
|
600
351
|
}
|
|
601
352
|
|
|
602
353
|
// For other errors, show the error message
|
|
603
|
-
setAIErrorMessage(
|
|
354
|
+
setAIErrorMessage(errorMessage);
|
|
604
355
|
return;
|
|
605
356
|
}
|
|
606
357
|
|
|
@@ -625,8 +376,8 @@ export const VZCodeProvider = ({
|
|
|
625
376
|
],
|
|
626
377
|
);
|
|
627
378
|
|
|
628
|
-
//
|
|
629
|
-
|
|
379
|
+
// Return the context value
|
|
380
|
+
return {
|
|
630
381
|
content,
|
|
631
382
|
shareDBDoc,
|
|
632
383
|
submitOperation,
|
|
@@ -750,10 +501,4 @@ export const VZCodeProvider = ({
|
|
|
750
501
|
// Additional widgets that can be rendered in AI chat messages
|
|
751
502
|
additionalWidgets,
|
|
752
503
|
};
|
|
753
|
-
|
|
754
|
-
return (
|
|
755
|
-
<VZCodeContext.Provider value={value}>
|
|
756
|
-
{children}
|
|
757
|
-
</VZCodeContext.Provider>
|
|
758
|
-
);
|
|
759
504
|
};
|