vzcode 2.7.0 → 2.9.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/{buildWorker-wLkQ0yz1.js → buildWorker-D4WATavZ.js} +27 -27
- package/dist/assets/{index-DL2VQRps.js → index-C_mFOLqJ.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/useVZCodeState.ts +30 -17
- 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 +1 -6
- 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/index.ts +4 -1
- 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-C_mFOLqJ.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.9.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
|
|
@@ -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
|
|
@@ -423,18 +423,31 @@ export const useVZCodeState = ({
|
|
|
423
423
|
errorMessage ===
|
|
424
424
|
'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.'
|
|
425
425
|
) {
|
|
426
|
-
//
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
426
|
+
// For authenticated users, trigger auto-fork
|
|
427
|
+
if (autoForkAndRetryAI) {
|
|
428
|
+
try {
|
|
429
|
+
await autoForkAndRetryAI(
|
|
430
|
+
currentPrompt,
|
|
431
|
+
aiChatMode,
|
|
432
|
+
);
|
|
433
|
+
// If we reach here, the fork was successful and redirect should happen
|
|
434
|
+
return;
|
|
435
|
+
} catch (forkError) {
|
|
436
|
+
console.error(
|
|
437
|
+
'Auto-fork failed:',
|
|
438
|
+
forkError,
|
|
439
|
+
);
|
|
440
|
+
setAIErrorMessage(
|
|
441
|
+
'Failed to fork visualization. Please try forking manually.',
|
|
442
|
+
);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
} else {
|
|
446
|
+
// For unauthenticated users, store the message and trigger login flow
|
|
447
|
+
// This will be handled by the external error handler
|
|
436
448
|
setAIErrorMessage(
|
|
437
|
-
|
|
449
|
+
errorMessage,
|
|
450
|
+
messageContent.trim(),
|
|
438
451
|
);
|
|
439
452
|
return;
|
|
440
453
|
}
|
|
@@ -492,7 +505,7 @@ export const useVZCodeState = ({
|
|
|
492
505
|
let newConfigData;
|
|
493
506
|
try {
|
|
494
507
|
newConfigData = JSON.parse(files[configFileId].text);
|
|
495
|
-
} catch
|
|
508
|
+
} catch {
|
|
496
509
|
// If config is invalid JSON, we can't process changes
|
|
497
510
|
return;
|
|
498
511
|
}
|
|
@@ -543,10 +556,10 @@ export const useVZCodeState = ({
|
|
|
543
556
|
iframeRef.current?.contentWindow?.postMessage(
|
|
544
557
|
changedProperties,
|
|
545
558
|
);
|
|
546
|
-
} catch (
|
|
559
|
+
} catch (_error_) {
|
|
547
560
|
console.error(
|
|
548
561
|
'Failed to send config changes to iframe:',
|
|
549
|
-
|
|
562
|
+
_error_,
|
|
550
563
|
);
|
|
551
564
|
}
|
|
552
565
|
}
|
|
@@ -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';
|
|
@@ -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'),
|
package/src/client/index.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export type { ThemeLabel, ThemeOption } from './themes';
|
|
2
2
|
export type { EditorCache } from './useEditorCache';
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
VZCodeProvider,
|
|
6
|
+
VZCodeContext,
|
|
7
|
+
} from './VZCodeContext';
|
|
5
8
|
export { VZSidebar } from './VZSidebar';
|
|
6
9
|
export { VZSettings } from './VZSettings';
|
|
7
10
|
export { VZKeyboardShortcutsDoc } from './VZKeyboardShortcutsDoc';
|