vzcode 2.6.0 → 2.8.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-Bfp1zhR4.js → index-CCjGlbxJ.js} +175 -176
- package/dist/cli.js +0 -2
- package/dist/index.html +1 -1
- package/dist/server/aiChatHandler/chatOperations.js +1 -1
- package/dist/server/computeInitialDocument.js +1 -1
- package/dist/server/index.js +2 -2
- package/package.json +10 -3
- package/src/cli.ts +0 -3
- package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +4 -4
- package/src/client/AIAssist/startAIAssist.ts +1 -7
- package/src/client/App/useShareDB.ts +1 -1
- package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +1 -1
- package/src/client/CodeEditor/getOrCreateEditor.tsx +5 -15
- package/src/client/CodeEditor/index.tsx +4 -3
- package/src/client/CodeEditor/rainbowBrackets.ts +0 -1
- package/src/client/CodeErrorOverlay/index.tsx +1 -1
- package/src/client/RunCodeWidget/index.tsx +1 -1
- package/src/client/SplitPaneResizeContext.tsx +0 -1
- package/src/client/VZCodeContext/types.ts +8 -4
- package/src/client/VZCodeContext/useVZCodeState.ts +6 -6
- package/src/client/VZKeyboardShortcutsDoc.tsx +3 -18
- package/src/client/VZMiddle.tsx +0 -6
- package/src/client/VZSidebar/AIChat/DiffView.tsx +6 -28
- package/src/client/VZSidebar/AIChat/Message.tsx +2 -7
- package/src/client/VZSidebar/AIChat/MessageList.tsx +1 -3
- package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +1 -2
- package/src/client/VZSidebar/DirectoryListing.tsx +0 -1
- package/src/client/VZSidebar/VisualEditor.tsx +3 -3
- package/src/client/VZSidebar/VoiceChatModal.tsx +0 -1
- package/src/client/VZSidebar/aiCopyPaste.ts +0 -2
- package/src/client/useFileCRUD.ts +0 -1
- package/src/client/useKeyboardShortcuts.ts +6 -2
- package/src/client/vzReducer/closeTabsReducer.ts +1 -1
- package/src/client/vzReducer/createInitialState.test.ts +25 -0
- package/src/client/vzReducer/createInitialState.ts +1 -1
- package/src/client/vzReducer/searchReducer.test.ts +16 -16
- package/src/client/vzReducer/searchReducer.ts +2 -2
- package/src/server/aiChatHandler/chatOperations.ts +1 -4
- package/src/server/computeInitialDocument.ts +1 -1
- package/src/server/index.ts +2 -2
package/dist/cli.js
CHANGED
|
@@ -75,8 +75,6 @@ function startServerInBackground(workingDirectory) {
|
|
|
75
75
|
}
|
|
76
76
|
// Fallback function to launch the browser version
|
|
77
77
|
async function launchBrowserVersion(workingDirectory) {
|
|
78
|
-
const { default: open } = await import('open');
|
|
79
|
-
const serverModule = await import('./server/index.js');
|
|
80
78
|
// Note: The server/index.js will use process.cwd() automatically
|
|
81
79
|
// and we're already in the correct working directory
|
|
82
80
|
console.log(`Starting VZCode server from: ${workingDirectory}`);
|
package/dist/index.html
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
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-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-CCjGlbxJ.js"></script>
|
|
24
24
|
<link rel="stylesheet" crossorigin href="/assets/index-Bjj9VRMn.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
|
@@ -65,7 +65,7 @@ export const computeInitialDocument = ({ fullPath }) => {
|
|
|
65
65
|
* Stack for recursively traversing directories.
|
|
66
66
|
* @type {string[]}
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
const files = [];
|
|
69
69
|
const ignoreFileMatcher = createIgnore().add(ignoreFilePattern);
|
|
70
70
|
const isIgnoreFile = (fileName) => ignoreFileMatcher.ignores(fileName);
|
|
71
71
|
const unsearchedDirectories = [
|
package/dist/server/index.js
CHANGED
|
@@ -191,7 +191,7 @@ const save = () => {
|
|
|
191
191
|
}
|
|
192
192
|
// handle deleting files and directories.
|
|
193
193
|
if (previous && !current) {
|
|
194
|
-
|
|
194
|
+
const stats = fs.statSync(previous.name);
|
|
195
195
|
//Check if the file path we are trying to delete is a directory
|
|
196
196
|
if (!stats.isDirectory()) {
|
|
197
197
|
fs.unlinkSync(previous.name);
|
|
@@ -290,7 +290,7 @@ server.listen(port, async () => {
|
|
|
290
290
|
// Note: ngrok support can be added when the package is properly installed
|
|
291
291
|
// Sets the port to the one specified in the environment
|
|
292
292
|
// variable (for development) or the default port.
|
|
293
|
-
|
|
293
|
+
const livePort = process.env.EDITOR_PORT || port;
|
|
294
294
|
console.log(`EDITOR_PORT: ${process.env.EDITOR_PORT}`);
|
|
295
295
|
console.log(`Editor is live at http://localhost:${livePort}`);
|
|
296
296
|
open(`http://localhost:${livePort}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
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
|
+
"lint": "eslint . --ext .js,.ts,.tsx",
|
|
18
|
+
"lint:fix": "eslint . --ext .js,.ts,.tsx --fix",
|
|
17
19
|
"dev": "cross-env EDITOR_PORT=5173 concurrently \"npm run test-interactive\" \"vite\"",
|
|
18
20
|
"build": "vite build && npm run build:server",
|
|
19
21
|
"build:server": "tsc --project tsconfig.server.json",
|
|
@@ -118,7 +120,7 @@
|
|
|
118
120
|
"@codemirror/state": "^6.5.2",
|
|
119
121
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
120
122
|
"@codemirror/view": "^6.38.1",
|
|
121
|
-
"@langchain/core": "^0.3.
|
|
123
|
+
"@langchain/core": "^0.3.71",
|
|
122
124
|
"@langchain/openai": "^0.6.7",
|
|
123
125
|
"@lezer/highlight": "^1.2.1",
|
|
124
126
|
"@livekit/components-react": "^2.9.14",
|
|
@@ -169,7 +171,7 @@
|
|
|
169
171
|
"react-bootstrap": "^2.10.10",
|
|
170
172
|
"react-dom": "^18",
|
|
171
173
|
"react-markdown": "^10.1.0",
|
|
172
|
-
"react-router-dom": "^7.8.
|
|
174
|
+
"react-router-dom": "^7.8.1",
|
|
173
175
|
"remark-gfm": "^4.0.1",
|
|
174
176
|
"sharedb": "^5.2.2",
|
|
175
177
|
"sharedb-client-browser": "^5.2.2",
|
|
@@ -182,10 +184,15 @@
|
|
|
182
184
|
"@tauri-apps/cli": "^2.7.1",
|
|
183
185
|
"@types/react": "^18",
|
|
184
186
|
"@types/react-dom": "^18",
|
|
187
|
+
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
|
188
|
+
"@typescript-eslint/parser": "^8.39.1",
|
|
185
189
|
"@vitejs/plugin-react": "^5.0.0",
|
|
186
190
|
"concurrently": "^9.2.0",
|
|
187
191
|
"cross-env": "^10.0.0",
|
|
188
192
|
"eslint": "^9.33.0",
|
|
193
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
194
|
+
"eslint-plugin-react": "^7.37.5",
|
|
195
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
189
196
|
"globals": "^16.3.0",
|
|
190
197
|
"npm-check-updates": "^18.0.2",
|
|
191
198
|
"prettier": "^3.6.2",
|
package/src/cli.ts
CHANGED
|
@@ -153,9 +153,6 @@ function startServerInBackground(
|
|
|
153
153
|
async function launchBrowserVersion(
|
|
154
154
|
workingDirectory: string,
|
|
155
155
|
): Promise<void> {
|
|
156
|
-
const { default: open } = await import('open');
|
|
157
|
-
const serverModule = await import('./server/index.js');
|
|
158
|
-
|
|
159
156
|
// Note: The server/index.js will use process.cwd() automatically
|
|
160
157
|
// and we're already in the correct working directory
|
|
161
158
|
console.log(
|
|
@@ -3,9 +3,9 @@ import { ShareDBDoc, TabState } from '../../types';
|
|
|
3
3
|
import { VizContent } from '@vizhub/viz-types';
|
|
4
4
|
|
|
5
5
|
export const AIAssistCodeMirrorKeyMap = ({
|
|
6
|
-
shareDBDoc,
|
|
7
|
-
fileId,
|
|
8
|
-
tabList,
|
|
6
|
+
shareDBDoc: _shareDBDoc,
|
|
7
|
+
fileId: _fileId,
|
|
8
|
+
tabList: _tabList,
|
|
9
9
|
}: {
|
|
10
10
|
shareDBDoc: ShareDBDoc<VizContent>;
|
|
11
11
|
fileId: string;
|
|
@@ -14,7 +14,7 @@ export const AIAssistCodeMirrorKeyMap = ({
|
|
|
14
14
|
keymap.of([
|
|
15
15
|
{
|
|
16
16
|
key: 'control-m',
|
|
17
|
-
run: (
|
|
17
|
+
run: (_view: EditorView) => {
|
|
18
18
|
// if (
|
|
19
19
|
// shareDBDoc.data.aiStreams === undefined ||
|
|
20
20
|
// shareDBDoc.data.aiStreams[mostRecentStreamId] ===
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { EditorView } from 'codemirror';
|
|
2
2
|
import { ShareDBDoc, TabState } from '../../types';
|
|
3
|
-
import {
|
|
4
|
-
VizFile,
|
|
5
|
-
VizFileId,
|
|
6
|
-
VizContent,
|
|
7
|
-
} from '@vizhub/viz-types';
|
|
3
|
+
import { VizFileId, VizContent } from '@vizhub/viz-types';
|
|
8
4
|
import { RequestId } from '../generateRequestId';
|
|
9
5
|
import { formatFile } from './formatFile';
|
|
10
6
|
|
|
11
|
-
const debug = false;
|
|
12
|
-
|
|
13
7
|
// Enables inclusion of code from open tabs as context.
|
|
14
8
|
const enableTabContext = false;
|
|
15
9
|
|
|
@@ -94,7 +94,7 @@ class RotationCircle extends WidgetType {
|
|
|
94
94
|
this.angle = angle;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
toDOM(
|
|
97
|
+
toDOM(_view: EditorView): HTMLElement {
|
|
98
98
|
const parent = document.createElement('div');
|
|
99
99
|
|
|
100
100
|
parent.setAttribute('style', 'width:20px;height:20px');
|
|
@@ -24,12 +24,7 @@ import {
|
|
|
24
24
|
} from '@codemirror/lint';
|
|
25
25
|
|
|
26
26
|
import { json1Presence, textUnicode } from '../../ot';
|
|
27
|
-
import {
|
|
28
|
-
PaneId,
|
|
29
|
-
ShareDBDoc,
|
|
30
|
-
TabState,
|
|
31
|
-
Username,
|
|
32
|
-
} from '../../types';
|
|
27
|
+
import { PaneId, ShareDBDoc, Username } from '../../types';
|
|
33
28
|
import { VizFileId, VizContent } from '@vizhub/viz-types';
|
|
34
29
|
import { json1PresenceBroadcast } from './json1PresenceBroadcast';
|
|
35
30
|
import { json1PresenceDisplay } from './json1PresenceDisplay';
|
|
@@ -72,9 +67,6 @@ import {
|
|
|
72
67
|
} from '@valtown/codemirror-ts';
|
|
73
68
|
import { getFileExtension } from '../utils/fileExtension';
|
|
74
69
|
import { SparklesSVG } from '../Icons/SparklesSVG';
|
|
75
|
-
import { VZCodeContext } from '../VZCodeContext';
|
|
76
|
-
import { useContext, useMemo } from 'react';
|
|
77
|
-
import { handleAIChatMessage } from '../../server/aiChatHandler';
|
|
78
70
|
|
|
79
71
|
const DEBUG = false;
|
|
80
72
|
|
|
@@ -83,7 +75,7 @@ const DEBUG = false;
|
|
|
83
75
|
export const fileNameStateField = StateField.define<string>(
|
|
84
76
|
{
|
|
85
77
|
create: () => '', // Default initial value
|
|
86
|
-
update: (value,
|
|
78
|
+
update: (value, _tr) => value, // Typically set once at creation for a given editor instance
|
|
87
79
|
},
|
|
88
80
|
);
|
|
89
81
|
|
|
@@ -194,7 +186,6 @@ export const getOrCreateEditor = async ({
|
|
|
194
186
|
esLintSource,
|
|
195
187
|
rainbowBracketsEnabled = true,
|
|
196
188
|
setIsAIChatOpen,
|
|
197
|
-
setAIChatMessage,
|
|
198
189
|
handleSendMessage,
|
|
199
190
|
}: {
|
|
200
191
|
// TODO pass this in from the outside
|
|
@@ -232,7 +223,6 @@ export const getOrCreateEditor = async ({
|
|
|
232
223
|
) => Promise<readonly Diagnostic[]>;
|
|
233
224
|
rainbowBracketsEnabled?: boolean; // New parameter type
|
|
234
225
|
setIsAIChatOpen: (isAIChatOpen: boolean) => void;
|
|
235
|
-
setAIChatMessage: (message: string) => void;
|
|
236
226
|
handleSendMessage: any; // TODO fix types
|
|
237
227
|
}): Promise<ExtendedEditorCacheValue> => {
|
|
238
228
|
// Cache hit
|
|
@@ -258,10 +248,10 @@ export const getOrCreateEditor = async ({
|
|
|
258
248
|
|
|
259
249
|
// Create a compartment for the theme so that it can be changed dynamically.
|
|
260
250
|
// Inspired by: https://github.com/craftzdog/cm6-themes/blob/main/example/index.ts
|
|
261
|
-
|
|
251
|
+
const themeCompartment = new Compartment();
|
|
262
252
|
|
|
263
253
|
// Create a compartment for rainbow brackets so that it can be enabled/disabled dynamically.
|
|
264
|
-
|
|
254
|
+
const rainbowBracketsCompartment = new Compartment();
|
|
265
255
|
|
|
266
256
|
// The CodeMirror extensions to use.
|
|
267
257
|
// const extensions = [autocompletion(), html(htmlConfig)]
|
|
@@ -485,7 +475,7 @@ export const getOrCreateEditor = async ({
|
|
|
485
475
|
super();
|
|
486
476
|
}
|
|
487
477
|
|
|
488
|
-
eq(
|
|
478
|
+
eq(_other: ToDoWidget) {
|
|
489
479
|
return false;
|
|
490
480
|
}
|
|
491
481
|
|
|
@@ -44,7 +44,6 @@ export const CodeEditor = ({
|
|
|
44
44
|
codeEditorRef,
|
|
45
45
|
enableAutoFollow,
|
|
46
46
|
setIsAIChatOpen,
|
|
47
|
-
setAIChatMessage,
|
|
48
47
|
handleSendMessage,
|
|
49
48
|
} = useContext(VZCodeContext);
|
|
50
49
|
|
|
@@ -71,7 +70,10 @@ export const CodeEditor = ({
|
|
|
71
70
|
|
|
72
71
|
// This logic deletes the `isInteracting` property from the document
|
|
73
72
|
submitOperation(
|
|
74
|
-
({
|
|
73
|
+
({
|
|
74
|
+
isInteracting: _isInteracting,
|
|
75
|
+
...newDocument
|
|
76
|
+
}) => ({
|
|
75
77
|
...newDocument,
|
|
76
78
|
}),
|
|
77
79
|
);
|
|
@@ -116,7 +118,6 @@ export const CodeEditor = ({
|
|
|
116
118
|
aiCopilotEndpoint,
|
|
117
119
|
esLintSource,
|
|
118
120
|
setIsAIChatOpen,
|
|
119
|
-
setAIChatMessage,
|
|
120
121
|
handleSendMessage,
|
|
121
122
|
});
|
|
122
123
|
|
|
@@ -29,7 +29,7 @@ export const RunCodeWidget = ({
|
|
|
29
29
|
const [isRunning, setIsRunning] = useState(false);
|
|
30
30
|
|
|
31
31
|
const handleClick = useCallback(
|
|
32
|
-
(
|
|
32
|
+
(_event?: React.MouseEvent) => {
|
|
33
33
|
setIsRunning(true); // Set the running state to true
|
|
34
34
|
|
|
35
35
|
// Run Prettier
|
|
@@ -199,14 +199,14 @@ export type VZCodeContextValue = {
|
|
|
199
199
|
} | null;
|
|
200
200
|
|
|
201
201
|
// Additional widgets that can be rendered in AI chat messages
|
|
202
|
-
additionalWidgets?:
|
|
202
|
+
additionalWidgets?: (props: {
|
|
203
203
|
messageId: string;
|
|
204
204
|
chatId: string;
|
|
205
205
|
handleSendMessage?: (
|
|
206
206
|
messageToSend?: string,
|
|
207
207
|
options?: Record<string, string>,
|
|
208
208
|
) => void;
|
|
209
|
-
}
|
|
209
|
+
}) => React.ReactNode;
|
|
210
210
|
};
|
|
211
211
|
|
|
212
212
|
export interface VZCodeProviderProps {
|
|
@@ -239,10 +239,14 @@ export interface VZCodeProviderProps {
|
|
|
239
239
|
prompt: string;
|
|
240
240
|
modelName: string;
|
|
241
241
|
} | null;
|
|
242
|
-
additionalWidgets?:
|
|
242
|
+
additionalWidgets?: (props: {
|
|
243
243
|
messageId: string;
|
|
244
244
|
chatId: string;
|
|
245
|
-
|
|
245
|
+
handleSendMessage?: (
|
|
246
|
+
messageToSend?: string,
|
|
247
|
+
options?: Record<string, string>,
|
|
248
|
+
) => void;
|
|
249
|
+
}) => React.ReactNode;
|
|
246
250
|
iframeRef?: React.MutableRefObject<HTMLIFrameElement>;
|
|
247
251
|
handleChatError?: (
|
|
248
252
|
error: string,
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
useRef,
|
|
7
7
|
useState,
|
|
8
8
|
} from 'react';
|
|
9
|
-
import { VizContent } from '@vizhub/viz-types';
|
|
10
9
|
import { defaultTheme, useDynamicTheme } from '../themes';
|
|
11
10
|
import { useActions } from '../useActions';
|
|
12
11
|
import { useEditorCache } from '../useEditorCache';
|
|
@@ -77,9 +76,10 @@ export const useVZCodeState = ({
|
|
|
77
76
|
const sidebarRef = useRef(null);
|
|
78
77
|
|
|
79
78
|
const codeEditorRef = useRef(null);
|
|
79
|
+
const internalIframeRef = useRef(null);
|
|
80
80
|
|
|
81
|
-
// Use external iframeRef if provided, otherwise
|
|
82
|
-
const iframeRef = externalIframeRef ||
|
|
81
|
+
// Use external iframeRef if provided, otherwise use internal one
|
|
82
|
+
const iframeRef = externalIframeRef || internalIframeRef;
|
|
83
83
|
|
|
84
84
|
// The error message shows errors in order of priority:
|
|
85
85
|
// * `runtimeError` - errors from runtime execution, highest priority
|
|
@@ -492,7 +492,7 @@ export const useVZCodeState = ({
|
|
|
492
492
|
let newConfigData;
|
|
493
493
|
try {
|
|
494
494
|
newConfigData = JSON.parse(files[configFileId].text);
|
|
495
|
-
} catch
|
|
495
|
+
} catch {
|
|
496
496
|
// If config is invalid JSON, we can't process changes
|
|
497
497
|
return;
|
|
498
498
|
}
|
|
@@ -543,10 +543,10 @@ export const useVZCodeState = ({
|
|
|
543
543
|
iframeRef.current?.contentWindow?.postMessage(
|
|
544
544
|
changedProperties,
|
|
545
545
|
);
|
|
546
|
-
} catch (
|
|
546
|
+
} catch (_error_) {
|
|
547
547
|
console.error(
|
|
548
548
|
'Failed to send config changes to iframe:',
|
|
549
|
-
|
|
549
|
+
_error_,
|
|
550
550
|
);
|
|
551
551
|
}
|
|
552
552
|
}
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
2
|
import { Button, Modal, Form } from './bootstrap';
|
|
3
|
-
import { ThemeLabel, themes } from './themes';
|
|
4
3
|
import { VZCodeContext } from './VZCodeContext';
|
|
5
4
|
|
|
6
5
|
export const VZKeyboardShortcutsDoc = ({
|
|
7
|
-
enableUsernameField = true,
|
|
6
|
+
enableUsernameField: _enableUsernameField = true,
|
|
8
7
|
}: {
|
|
9
8
|
// Feature flag to enable/disable username field
|
|
10
9
|
enableUsernameField?: boolean;
|
|
11
10
|
}) => {
|
|
12
|
-
const {
|
|
13
|
-
isDocOpen,
|
|
14
|
-
closeDoc,
|
|
15
|
-
|
|
16
|
-
setTheme,
|
|
17
|
-
|
|
18
|
-
setUsername,
|
|
19
|
-
} = useContext(VZCodeContext);
|
|
20
|
-
|
|
21
|
-
const handleThemeChange = useCallback(
|
|
22
|
-
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
23
|
-
setTheme(event.target.value as ThemeLabel);
|
|
24
|
-
},
|
|
25
|
-
[],
|
|
26
|
-
);
|
|
11
|
+
const { isDocOpen, closeDoc } = useContext(VZCodeContext);
|
|
27
12
|
|
|
28
13
|
return isDocOpen ? (
|
|
29
14
|
<Modal
|
package/src/client/VZMiddle.tsx
CHANGED
|
@@ -11,8 +11,6 @@ import { RunCodeWidget } from './RunCodeWidget';
|
|
|
11
11
|
import { InteractRule } from '@replit/codemirror-interact';
|
|
12
12
|
import { EditorView } from '@codemirror/view';
|
|
13
13
|
import { Diagnostic } from '@codemirror/lint';
|
|
14
|
-
import { VizContent } from '@vizhub/viz-types';
|
|
15
|
-
import { LeafPane } from '../types';
|
|
16
14
|
import { isImageFile } from './utils/isImageFile';
|
|
17
15
|
|
|
18
16
|
// TODO modify this to handle the SplitPane type
|
|
@@ -104,8 +102,6 @@ export const VZMiddle = ({
|
|
|
104
102
|
aiAssistTooltipText,
|
|
105
103
|
aiAssistClickOverride,
|
|
106
104
|
aiCopilotEndpoint,
|
|
107
|
-
aiChatEndpoint,
|
|
108
|
-
aiChatOptions,
|
|
109
105
|
customInteractRules,
|
|
110
106
|
esLintSource,
|
|
111
107
|
}: {
|
|
@@ -115,8 +111,6 @@ export const VZMiddle = ({
|
|
|
115
111
|
aiAssistTooltipText?: string;
|
|
116
112
|
aiAssistClickOverride?: () => void;
|
|
117
113
|
aiCopilotEndpoint?: string;
|
|
118
|
-
aiChatEndpoint?: string;
|
|
119
|
-
aiChatOptions?: { [key: string]: any };
|
|
120
114
|
customInteractRules?: Array<InteractRule>;
|
|
121
115
|
esLintSource: (
|
|
122
116
|
view: EditorView,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
useContext,
|
|
3
3
|
useEffect,
|
|
4
|
-
useMemo,
|
|
5
4
|
useRef,
|
|
6
5
|
} from 'react';
|
|
7
6
|
import {
|
|
@@ -13,7 +12,7 @@ import * as Diff2Html from 'diff2html';
|
|
|
13
12
|
import 'diff2html/bundles/css/diff2html.min.css';
|
|
14
13
|
import './DiffView.scss';
|
|
15
14
|
import { VZCodeContext } from '../../VZCodeContext';
|
|
16
|
-
import {
|
|
15
|
+
import { VizFiles } from '@vizhub/viz-types';
|
|
17
16
|
|
|
18
17
|
interface DiffViewProps {
|
|
19
18
|
diffData: UnifiedFilesDiff;
|
|
@@ -30,10 +29,6 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|
|
30
29
|
(diff) => diff.length > 0,
|
|
31
30
|
);
|
|
32
31
|
|
|
33
|
-
if (unifiedDiffs.length === 0) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
// Calculate statistics from all unified diffs
|
|
38
33
|
let totalAdditions = 0;
|
|
39
34
|
let totalDeletions = 0;
|
|
@@ -53,27 +48,6 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|
|
53
48
|
outputFormat: 'line-by-line',
|
|
54
49
|
});
|
|
55
50
|
|
|
56
|
-
// Create a mapping from file name to file ID for click handling
|
|
57
|
-
const fileNameToIdMap = useMemo(() => {
|
|
58
|
-
const map = new Map<string, VizFileId>();
|
|
59
|
-
Object.entries(diffData).forEach(([fileId, diff]) => {
|
|
60
|
-
// Extract file name from the unified diff
|
|
61
|
-
// The diff contains lines like "--- a/filename" and "+++ b/filename"
|
|
62
|
-
const lines = diff.split('\n');
|
|
63
|
-
for (const line of lines) {
|
|
64
|
-
if (
|
|
65
|
-
line.startsWith('--- a/') ||
|
|
66
|
-
line.startsWith('+++ b/')
|
|
67
|
-
) {
|
|
68
|
-
const fileName = line.substring(6); // Remove "--- a/" or "+++ b/"
|
|
69
|
-
map.set(fileName, fileId as VizFileId);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return map;
|
|
75
|
-
}, [diffData]);
|
|
76
|
-
|
|
77
51
|
// Add click handlers to file names after HTML is rendered
|
|
78
52
|
useEffect(() => {
|
|
79
53
|
if (!diffContainerRef.current) return;
|
|
@@ -103,7 +77,7 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|
|
103
77
|
|
|
104
78
|
// TODO get fileId from content.files
|
|
105
79
|
const fileId = Object.entries(files).find(
|
|
106
|
-
([
|
|
80
|
+
([_id, file]) => file.name === fileName,
|
|
107
81
|
)?.[0];
|
|
108
82
|
console.log('Mapped file ID:', fileId);
|
|
109
83
|
|
|
@@ -145,6 +119,10 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|
|
145
119
|
};
|
|
146
120
|
}, [diffHtml, content, openTab, setIsAIChatOpen]);
|
|
147
121
|
|
|
122
|
+
if (unifiedDiffs.length === 0) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
148
126
|
return (
|
|
149
127
|
<div className="diff-view">
|
|
150
128
|
<div className="diff-summary">
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { timestampToDate } from '@vizhub/viz-utils';
|
|
2
2
|
import Markdown from 'react-markdown';
|
|
3
3
|
import remarkGfm from 'remark-gfm';
|
|
4
|
-
import React, {
|
|
5
|
-
useMemo,
|
|
6
|
-
memo,
|
|
7
|
-
useState,
|
|
8
|
-
useContext,
|
|
9
|
-
} from 'react';
|
|
4
|
+
import React, { useMemo, memo, useContext } from 'react';
|
|
10
5
|
import { DiffView } from './DiffView';
|
|
11
6
|
import { UnifiedFilesDiff } from '../../../utils/fileDiff';
|
|
12
7
|
import { enableDiffView } from '../../featureFlags';
|
|
@@ -63,7 +58,7 @@ const MessageComponent = ({
|
|
|
63
58
|
)}
|
|
64
59
|
{additionalWidgets &&
|
|
65
60
|
chatId &&
|
|
66
|
-
|
|
61
|
+
additionalWidgets({
|
|
67
62
|
messageId: id,
|
|
68
63
|
chatId: chatId,
|
|
69
64
|
handleSendMessage,
|
|
@@ -15,13 +15,11 @@ const MessageListComponent = ({
|
|
|
15
15
|
isLoading,
|
|
16
16
|
chatId, // Add chatId prop
|
|
17
17
|
aiScratchpad, // Add aiScratchpad prop
|
|
18
|
-
aiStatus, // Add aiStatus prop
|
|
19
18
|
}: {
|
|
20
19
|
messages: VizChatMessage[];
|
|
21
20
|
isLoading: boolean;
|
|
22
21
|
chatId?: string; // Add chatId to the type
|
|
23
22
|
aiScratchpad?: string; // Add aiScratchpad to the type
|
|
24
|
-
aiStatus?: string; // Add aiStatus to the type
|
|
25
23
|
}) => {
|
|
26
24
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
|
27
25
|
const messagesContainerRef = useRef<HTMLDivElement>(null);
|
|
@@ -160,7 +158,7 @@ const MessageListComponent = ({
|
|
|
160
158
|
ref={messagesContainerRef}
|
|
161
159
|
onScroll={handleScroll}
|
|
162
160
|
>
|
|
163
|
-
{messages.map((msg,
|
|
161
|
+
{messages.map((msg, _index) => {
|
|
164
162
|
return (
|
|
165
163
|
<Message
|
|
166
164
|
key={msg.id}
|
|
@@ -20,8 +20,7 @@ export const useSpeechRecognition = (
|
|
|
20
20
|
const [recognition, setRecognition] =
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
useState<SpeechRecognition | null>(null);
|
|
23
|
-
const [
|
|
24
|
-
useState<string>('');
|
|
23
|
+
const [, setFinalTranscript] = useState<string>('');
|
|
25
24
|
|
|
26
25
|
// Speech recognition setup
|
|
27
26
|
useEffect(() => {
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
useCallback,
|
|
3
3
|
useContext,
|
|
4
4
|
useState,
|
|
5
|
-
useRef,
|
|
6
5
|
useEffect,
|
|
7
6
|
useMemo,
|
|
8
7
|
} from 'react';
|
|
@@ -60,7 +59,8 @@ export const VisualEditor = () => {
|
|
|
60
59
|
const configData = useMemo(() => {
|
|
61
60
|
try {
|
|
62
61
|
return JSON.parse(files[configFileId].text);
|
|
63
|
-
} catch (
|
|
62
|
+
} catch (_error) {
|
|
63
|
+
console.error('Error parsing config.json:', _error);
|
|
64
64
|
return null;
|
|
65
65
|
}
|
|
66
66
|
}, [files?.[configFileId]?.text]);
|
|
@@ -301,7 +301,7 @@ export const VisualEditor = () => {
|
|
|
301
301
|
|
|
302
302
|
return (
|
|
303
303
|
<div className="visual-editor">
|
|
304
|
-
{visualEditorWidgets.map((widgetConfig,
|
|
304
|
+
{visualEditorWidgets.map((widgetConfig, _index) => {
|
|
305
305
|
if (widgetConfig.type === 'slider') {
|
|
306
306
|
// Use local value if available, otherwise fall back to config value
|
|
307
307
|
const currentValue =
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
vizFilesToFileCollection,
|
|
13
13
|
} from '@vizhub/viz-utils';
|
|
14
14
|
import JSZip from 'jszip';
|
|
15
|
-
import { generate } from '@langchain/core/dist/utils/fast-json-patch';
|
|
16
15
|
|
|
17
16
|
export const createAICopyPasteHandlers = (
|
|
18
17
|
files: VizFiles,
|
|
@@ -113,7 +112,6 @@ export const createAICopyPasteHandlers = (
|
|
|
113
112
|
runId: generateRunId(),
|
|
114
113
|
}));
|
|
115
114
|
|
|
116
|
-
const fileCount = Object.keys(parsed.files).length;
|
|
117
115
|
setPasteButtonText('Pasted!');
|
|
118
116
|
setTimeout(
|
|
119
117
|
() => setPasteButtonText('Paste for AI'),
|
|
@@ -5,7 +5,6 @@ import { randomId } from '../randomId';
|
|
|
5
5
|
import { EditorCache } from './useEditorCache';
|
|
6
6
|
import { getFileExtension } from './utils/fileExtension';
|
|
7
7
|
import { getLanguageExtension } from './CodeEditor/getOrCreateEditor';
|
|
8
|
-
import { editorCacheKey } from './useEditorCache';
|
|
9
8
|
|
|
10
9
|
// CRUD operations for files and directories
|
|
11
10
|
// CRUD = Create, Read, Update, Delete
|