vzcode 1.59.0 → 1.61.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 (32) hide show
  1. package/dist/assets/bootstrap-icons-BeopsB42.woff +0 -0
  2. package/dist/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
  3. package/dist/assets/{index-afP-wJTZ.css → index-Br76WttW.css} +5 -1
  4. package/dist/assets/{index-BJI4JLx9.js → index-EWyCE9d7.js} +142 -142
  5. package/dist/index.html +2 -2
  6. package/package.json +7 -6
  7. package/src/client/Icons/AdjustmentSVG.tsx +19 -0
  8. package/src/client/Icons/index.tsx +1 -0
  9. package/src/client/VZCodeContext/index.tsx +29 -0
  10. package/src/client/VZCodeContext/types.ts +247 -0
  11. package/src/client/{VZCodeContext.tsx → VZCodeContext/useVZCodeState.ts} +115 -294
  12. package/src/client/VZRight.tsx +6 -3
  13. package/src/client/VZSidebar/AIChat/ChatInput.tsx +45 -2
  14. package/src/client/VZSidebar/AIChat/MessageList.tsx +2 -0
  15. package/src/client/VZSidebar/AIChat/index.tsx +13 -1
  16. package/src/client/VZSidebar/AIChat/styles.scss +2 -0
  17. package/src/client/VZSidebar/EmptyState.tsx +11 -0
  18. package/src/client/VZSidebar/VisualEditor.tsx +284 -0
  19. package/src/client/VZSidebar/index.tsx +64 -0
  20. package/src/client/VZSidebar/styles.scss +213 -1
  21. package/src/client/bootstrap.ts +3 -0
  22. package/src/client/useActions.ts +12 -0
  23. package/src/client/vzReducer/closeTabReducer.test.ts +33 -21
  24. package/src/client/vzReducer/createInitialState.ts +1 -0
  25. package/src/client/vzReducer/index.ts +9 -0
  26. package/src/client/vzReducer/searchReducer.test.ts +1 -1
  27. package/src/client/vzReducer/visualEditorReducer.ts +9 -0
  28. package/src/server/aiChatHandler/chatOperations.ts +22 -0
  29. package/src/server/aiChatHandler/errorHandling.ts +17 -4
  30. package/src/server/aiChatHandler/index.ts +131 -67
  31. package/src/server/aiChatHandler/llmStreaming.ts +76 -27
  32. package/src/types.ts +12 -0
package/dist/index.html CHANGED
@@ -20,8 +20,8 @@
20
20
  href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
21
21
  rel="stylesheet"
22
22
  />
23
- <script type="module" crossorigin src="/assets/index-BJI4JLx9.js"></script>
24
- <link rel="stylesheet" crossorigin href="/assets/index-afP-wJTZ.css">
23
+ <script type="module" crossorigin src="/assets/index-EWyCE9d7.js"></script>
24
+ <link rel="stylesheet" crossorigin href="/assets/index-Br76WttW.css">
25
25
  </head>
26
26
  <body>
27
27
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "1.59.0",
3
+ "version": "1.61.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "test": "vitest run",
14
- "test-interactive": "cd test/sampleDirectories/kitchenSink && node --import \"data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));\" ../../../src/server/index.ts",
14
+ "test-interactive": "cd test/sampleDirectories/visualEditor && node --import \"data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));\" ../../../src/server/index.ts",
15
15
  "prettier": "prettier {*.*,**/*.*} --write",
16
16
  "typecheck": "tsc --noEmit",
17
17
  "dev": "cross-env EDITOR_PORT=5173 concurrently \"npm run test-interactive\" \"vite\"",
@@ -117,8 +117,8 @@
117
117
  "@codemirror/state": "^6.5.2",
118
118
  "@codemirror/theme-one-dark": "^6.1.3",
119
119
  "@codemirror/view": "^6.38.1",
120
- "@langchain/core": "^0.3.67",
121
- "@langchain/openai": "^0.6.4",
120
+ "@langchain/core": "^0.3.68",
121
+ "@langchain/openai": "^0.6.7",
122
122
  "@lezer/highlight": "^1.2.1",
123
123
  "@livekit/components-react": "^2.9.14",
124
124
  "@replit/codemirror-indentation-markers": "^6.5.3",
@@ -141,6 +141,7 @@
141
141
  "@vizhub/viz-types": "^0.4.0",
142
142
  "@vizhub/viz-utils": "^1.4.0",
143
143
  "body-parser": "^2.2.0",
144
+ "bootstrap-icons": "^1.13.1",
144
145
  "codemirror": "^6.0.2",
145
146
  "codemirror-copilot": "^0.0.7",
146
147
  "codemirror-ot": "^5.0.0",
@@ -166,7 +167,7 @@
166
167
  "react-bootstrap": "^2.10.10",
167
168
  "react-dom": "^18",
168
169
  "react-markdown": "^10.1.0",
169
- "react-router-dom": "^7.7.1",
170
+ "react-router-dom": "^7.8.0",
170
171
  "remark-gfm": "^4.0.1",
171
172
  "sharedb": "^5.2.2",
172
173
  "sharedb-client-browser": "^5.2.2",
@@ -189,7 +190,7 @@
189
190
  "sass": "^1.90.0",
190
191
  "ts-node": "^10.9.2",
191
192
  "typescript": "^5.9.2",
192
- "vite": "^7.1.0",
193
+ "vite": "^7.1.1",
193
194
  "vitest": "^3.2.4"
194
195
  },
195
196
  "optionalDependencies": {
@@ -0,0 +1,19 @@
1
+ //From Hero Icons
2
+ export const AdjustmentSVG = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ fill="none"
6
+ viewBox="0 0 24 24"
7
+ strokeWidth={1.5}
8
+ stroke="currentColor"
9
+ className="size-6"
10
+ width={32}
11
+ height={32}
12
+ >
13
+ <path
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"
17
+ />
18
+ </svg>
19
+ );
@@ -21,3 +21,4 @@ export { HtmlSVG } from './HtmlSVG';
21
21
  export { CssSVG } from './CssSVG';
22
22
  export { JsonSVG } from './JsonSVG';
23
23
  export { MarkdownSVG } from './MarkdownSVG';
24
+ export { AdjustmentSVG } from './AdjustmentSVG';
@@ -0,0 +1,29 @@
1
+ import React, { Context, createContext } from 'react';
2
+ import {
3
+ VZCodeContextValue,
4
+ VZCodeProviderProps,
5
+ } from './types';
6
+ import { useVZCodeState } from './useVZCodeState';
7
+
8
+ // This context centralizes all the "smart" logic
9
+ // to do with the application state. This includes
10
+ // * Accessing and manipulating ShareDB data
11
+ // * Centralized application state
12
+ export const VZCodeContext: Context<VZCodeContextValue | null> =
13
+ createContext<VZCodeContextValue>(null);
14
+
15
+ export const VZCodeProvider: React.FC<
16
+ VZCodeProviderProps
17
+ > = ({ children, ...props }) => {
18
+ // Use the custom hook to get all the context value
19
+ const value = useVZCodeState(props);
20
+
21
+ return (
22
+ <VZCodeContext.Provider value={value}>
23
+ {children}
24
+ </VZCodeContext.Provider>
25
+ );
26
+ };
27
+
28
+ // Re-export types for backward compatibility
29
+ export type { VZCodeContextValue, VZCodeProviderProps };
@@ -0,0 +1,247 @@
1
+ import {
2
+ ItemId,
3
+ LeafPane,
4
+ Pane,
5
+ PaneId,
6
+ PresenceIndicator,
7
+ SearchFileVisibility,
8
+ SearchResults,
9
+ ShareDBDoc,
10
+ SubmitOperation,
11
+ TabState,
12
+ Username,
13
+ } from '../../types';
14
+ import { VizFiles, VizContent } from '@vizhub/viz-types';
15
+ import { ThemeLabel } from '../themes';
16
+ import { EditorCache } from '../useEditorCache';
17
+
18
+ // The type of the object provided by this context.
19
+ export type VZCodeContextValue = {
20
+ content: VizContent | null;
21
+ shareDBDoc: ShareDBDoc<VizContent> | null;
22
+ submitOperation: (
23
+ next: (content: VizContent) => VizContent,
24
+ ) => void;
25
+ // TODO pull in this type from ShareDB if possible
26
+ localPresence: any;
27
+ // TODO pull in this type from ShareDB if possible
28
+ docPresence: any;
29
+
30
+ files: VizFiles | null;
31
+ createFile: (fileName: string, text?: string) => void;
32
+ renameFile: (fileId: string, fileName: string) => void;
33
+ deleteFile: (fileId: string) => void;
34
+ createDirectory: (
35
+ fileName: string,
36
+ text?: string,
37
+ ) => void;
38
+ renameDirectory: (
39
+ directoryId: string,
40
+ directoryOldName: string,
41
+ directoryName: string,
42
+ ) => void;
43
+ deleteDirectory: (directoryId: string) => void;
44
+
45
+ setActiveFileId: (fileId: string | null) => void;
46
+ setActiveFileLeft: () => void;
47
+ setActiveFileRight: () => void;
48
+
49
+ activePaneId: PaneId;
50
+ pane: Pane;
51
+ activePane: LeafPane;
52
+
53
+ openTab: (tabState: TabState) => void;
54
+ closeTabs: (fileIds: string[]) => void;
55
+
56
+ isSettingsOpen: boolean;
57
+ setIsSettingsOpen: (isSettingsOpen: boolean) => void;
58
+ closeSettings: () => void;
59
+
60
+ isDocOpen: boolean;
61
+ setIsDocOpen: (isDocOpen: boolean) => void;
62
+ closeDoc: () => void;
63
+
64
+ theme: ThemeLabel;
65
+ setTheme: (theme: ThemeLabel) => void;
66
+
67
+ username: Username;
68
+ setUsername: (username: Username) => void;
69
+
70
+ isDirectoryOpen: (path: string) => boolean;
71
+ toggleDirectory: (path: string) => void;
72
+
73
+ editorCache: EditorCache;
74
+
75
+ // Whether the editor should be focused.
76
+ editorWantsFocus: boolean;
77
+ // Signals that the editor no longer wants focus.
78
+ editorNoLongerWantsFocus: () => void;
79
+
80
+ errorMessage: string | null;
81
+
82
+ // Runtime error handling
83
+ handleRuntimeError: (
84
+ formattedErrorMessage: string,
85
+ ) => void;
86
+ clearRuntimeError: () => void;
87
+
88
+ search: SearchResults;
89
+ isSearchOpen: boolean;
90
+ setIsSearchOpen: (isSearchOpen: boolean) => void;
91
+ setSearch: (pattern: string) => void;
92
+
93
+ isVisualEditorOpen: boolean;
94
+ setIsVisualEditorOpen: (
95
+ isVisualEditorOpen: boolean,
96
+ ) => void;
97
+
98
+ isAIChatOpen: boolean;
99
+ setIsAIChatOpen: (isAIChatOpen: boolean) => void;
100
+ aiChatFocused: boolean;
101
+ toggleAIChatFocused: () => void;
102
+ aiChatMode: 'ask' | 'edit';
103
+ setAIChatMode: (mode: 'ask' | 'edit') => void;
104
+ aiChatEndpoint?: string;
105
+ aiChatUndoEndpoint?: string;
106
+ aiChatOptions?: { [key: string]: any };
107
+ setSearchResults: (files: ShareDBDoc<VizContent>) => void;
108
+ setSearchFileVisibility: (
109
+ files: ShareDBDoc<VizContent>,
110
+ id: string,
111
+ visibility: SearchFileVisibility,
112
+ ) => void;
113
+ setSearchLineVisibility: (
114
+ files: ShareDBDoc<VizContent>,
115
+ id: string,
116
+ line: number,
117
+ ) => void;
118
+ setSearchFocusedIndex: (
119
+ focusedIndex: number,
120
+ childIndex: number,
121
+ ) => void;
122
+ toggleSearchFocused: () => void;
123
+
124
+ isCreateFileModalOpen: boolean;
125
+ handleOpenCreateFileModal: () => void;
126
+ handleCloseCreateFileModal: () => void;
127
+ handleCreateFileClick: (newFileName: string) => void;
128
+
129
+ isCreateDirModalOpen: boolean;
130
+ handleOpenCreateDirModal: () => void;
131
+ handleCloseCreateDirModal: () => void;
132
+ handleCreateDirClick: (newFileName: string) => void;
133
+
134
+ runPrettierRef: React.MutableRefObject<
135
+ null | (() => void)
136
+ >;
137
+ runCodeRef: React.MutableRefObject<
138
+ null | ((hardRerun?: boolean) => void)
139
+ >;
140
+
141
+ sidebarRef: React.RefObject<HTMLDivElement>;
142
+
143
+ codeEditorRef: React.RefObject<HTMLDivElement>;
144
+
145
+ iframeRef: React.MutableRefObject<HTMLIFrameElement>;
146
+
147
+ connected: boolean;
148
+ pending: boolean;
149
+
150
+ hoveredItemId: ItemId | null;
151
+ setHoveredItemId: (itemId: ItemId | null) => void;
152
+
153
+ enableAutoFollow: boolean;
154
+ toggleAutoFollow: () => void;
155
+
156
+ updatePresenceIndicator: (
157
+ presenceIndicator: PresenceIndicator,
158
+ ) => void;
159
+
160
+ sidebarPresenceIndicators: Array<PresenceIndicator>;
161
+ splitCurrentPane: () => void;
162
+
163
+ liveKitToken: string;
164
+ setLiveKitToken: (state: string) => void;
165
+ liveKitRoomName: string;
166
+ setLiveKitRoom: (state: string) => void;
167
+ liveKitConnection: boolean;
168
+ setLiveKitConnection: (state: boolean) => void;
169
+ voiceChatModalOpen: boolean;
170
+ setVoiceChatModalOpen: (state: boolean) => void;
171
+ aiChatMessage: string;
172
+ setAIChatMessage: (message: string) => void;
173
+ isLoading: boolean;
174
+ currentChatId: string;
175
+ aiErrorMessage: string | null;
176
+ setAIErrorMessage: (state: string | null) => void;
177
+ handleSendMessage: (
178
+ messageToSend?: string,
179
+ options?: Record<string, string>,
180
+ ) => void;
181
+
182
+ // Message history navigation
183
+ navigateMessageHistoryUp: () => void;
184
+ navigateMessageHistoryDown: () => void;
185
+ resetMessageHistoryNavigation: () => void;
186
+
187
+ // Auto-fork functions for VizHub integration
188
+ autoForkAndRetryAI?: (
189
+ prompt: string,
190
+ modelName: string,
191
+ commitId?: string,
192
+ ) => Promise<void>;
193
+ clearStoredAIPrompt?: () => void;
194
+ getStoredAIPrompt?: () => {
195
+ prompt: string;
196
+ modelName: string;
197
+ } | null;
198
+
199
+ // Additional widgets that can be rendered in AI chat messages
200
+ additionalWidgets?: React.ComponentType<{
201
+ messageId: string;
202
+ chatId: string;
203
+ canUndo: boolean;
204
+ handleSendMessage?: (
205
+ messageToSend?: string,
206
+ options?: Record<string, string>,
207
+ ) => void;
208
+ }>;
209
+ };
210
+
211
+ export interface VZCodeProviderProps {
212
+ content: VizContent;
213
+ shareDBDoc: ShareDBDoc<VizContent>;
214
+ submitOperation: SubmitOperation;
215
+ localPresence: any;
216
+ docPresence: any;
217
+ prettierWorker: Worker;
218
+ initialUsername: Username;
219
+ children: React.ReactNode;
220
+ codeError?: string | null;
221
+ connected?: boolean;
222
+ pending?: boolean;
223
+ liveKitToken?: string | undefined;
224
+ setLiveKitToken?: (state: string) => void;
225
+ liveKitRoomName?: string | undefined;
226
+ setLiveKitRoom?: (state: string) => void;
227
+ liveKitConnection?: boolean;
228
+ setLiveKitConnection?: (state: boolean) => void;
229
+ aiChatEndpoint?: string;
230
+ aiChatUndoEndpoint?: string;
231
+ aiChatOptions?: { [key: string]: any };
232
+ autoForkAndRetryAI?: (
233
+ prompt: string,
234
+ modelName: string,
235
+ commitId?: string,
236
+ ) => Promise<void>;
237
+ clearStoredAIPrompt?: () => void;
238
+ getStoredAIPrompt?: () => {
239
+ prompt: string;
240
+ modelName: string;
241
+ } | null;
242
+ additionalWidgets?: React.ComponentType<{
243
+ messageId: string;
244
+ chatId: string;
245
+ canUndo: boolean;
246
+ }>;
247
+ }