vzcode 1.49.0 → 1.51.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/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-DrUY_A13.js"></script>
23
+ <script type="module" crossorigin src="/assets/index-DkCXnCvn.js"></script>
24
24
  <link rel="stylesheet" crossorigin href="/assets/index-BXyJ2hMf.css">
25
25
  </head>
26
26
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "1.49.0",
3
+ "version": "1.51.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -195,6 +195,18 @@ export type VZCodeContextValue = {
195
195
  setVoiceChatModalOpen: (state: boolean) => void;
196
196
  aiChatMessage: string;
197
197
  setAIChatMessage: (message: string) => void;
198
+
199
+ // Auto-fork functions for VizHub integration
200
+ autoForkAndRetryAI?: (
201
+ prompt: string,
202
+ modelName: string,
203
+ commitId?: string,
204
+ ) => Promise<void>;
205
+ clearStoredAIPrompt?: () => void;
206
+ getStoredAIPrompt?: () => {
207
+ prompt: string;
208
+ modelName: string;
209
+ } | null;
198
210
  };
199
211
 
200
212
  export const VZCodeProvider = ({
@@ -218,6 +230,9 @@ export const VZCodeProvider = ({
218
230
  aiChatEndpoint,
219
231
  aiChatUndoEndpoint,
220
232
  aiChatOptions,
233
+ autoForkAndRetryAI,
234
+ clearStoredAIPrompt,
235
+ getStoredAIPrompt,
221
236
  }: {
222
237
  content: VizContent;
223
238
  shareDBDoc: ShareDBDoc<VizContent>;
@@ -239,6 +254,16 @@ export const VZCodeProvider = ({
239
254
  aiChatEndpoint?: string;
240
255
  aiChatUndoEndpoint?: string;
241
256
  aiChatOptions?: { [key: string]: any };
257
+ autoForkAndRetryAI?: (
258
+ prompt: string,
259
+ modelName: string,
260
+ commitId?: string,
261
+ ) => Promise<void>;
262
+ clearStoredAIPrompt?: () => void;
263
+ getStoredAIPrompt?: () => {
264
+ prompt: string;
265
+ modelName: string;
266
+ } | null;
242
267
  }) => {
243
268
  // Auto-run Pretter after local changes.
244
269
  const { prettierError, runPrettierRef } = usePrettier({
@@ -564,6 +589,11 @@ export const VZCodeProvider = ({
564
589
 
565
590
  aiChatMessage,
566
591
  setAIChatMessage,
592
+
593
+ // Auto-fork functions for VizHub integration
594
+ autoForkAndRetryAI,
595
+ clearStoredAIPrompt,
596
+ getStoredAIPrompt,
567
597
  };
568
598
 
569
599
  return (
@@ -25,7 +25,8 @@ export const DiffView: React.FC<DiffViewProps> = ({
25
25
  canUndo = false,
26
26
  }) => {
27
27
  const [isUndoing, setIsUndoing] = useState(false);
28
- const { aiChatUndoEndpoint } = useContext(VZCodeContext);
28
+ const { aiChatUndoEndpoint, aiChatOptions = {} } =
29
+ useContext(VZCodeContext);
29
30
 
30
31
  const unifiedDiffs = Object.values(diffData).filter(
31
32
  (diff) => diff.length > 0,
@@ -54,6 +55,7 @@ export const DiffView: React.FC<DiffViewProps> = ({
54
55
  'Content-Type': 'application/json',
55
56
  },
56
57
  body: JSON.stringify({
58
+ vizId: aiChatOptions.vizId,
57
59
  chatId,
58
60
  messageId,
59
61
  }),
@@ -3,6 +3,7 @@ import {
3
3
  useState,
4
4
  useCallback,
5
5
  useMemo,
6
+ useEffect,
6
7
  } from 'react';
7
8
  import { VZCodeContext } from '../../VZCodeContext';
8
9
  import { v4 as uuidv4 } from 'uuid';
@@ -29,6 +30,9 @@ export const AIChat = () => {
29
30
  aiChatOptions = {},
30
31
  aiChatMode,
31
32
  setAIChatMode,
33
+ autoForkAndRetryAI,
34
+ clearStoredAIPrompt,
35
+ getStoredAIPrompt,
32
36
  } = useContext(VZCodeContext);
33
37
 
34
38
  // Get current chat data from content
@@ -53,6 +57,7 @@ export const AIChat = () => {
53
57
  const handleSendMessage = useCallback(async () => {
54
58
  if (!aiChatMessage.trim() || isLoading) return;
55
59
 
60
+ const currentPrompt = aiChatMessage.trim();
56
61
  setAIChatMessage('');
57
62
  setIsLoading(true);
58
63
  setErrorMessage(null); // Clear any previous errors
@@ -68,7 +73,7 @@ export const AIChat = () => {
68
73
  body: JSON.stringify({
69
74
  ...aiChatOptions,
70
75
  vizId: aiChatOptions.vizId,
71
- content: aiChatMessage.trim(),
76
+ content: currentPrompt,
72
77
  chatId: currentChatId,
73
78
  mode: aiChatMode,
74
79
  }),
@@ -88,7 +93,32 @@ export const AIChat = () => {
88
93
  responseData.outcome === 'failure' &&
89
94
  responseData.error
90
95
  ) {
91
- setErrorMessage(responseData.error.message);
96
+ const errorMessage = responseData.error.message;
97
+
98
+ // Check if this is the specific permission error that should trigger auto-fork
99
+ if (
100
+ errorMessage ===
101
+ '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.'
102
+ ) {
103
+ // Trigger auto-fork instead of showing error
104
+ try {
105
+ await autoForkAndRetryAI?.(
106
+ currentPrompt,
107
+ aiChatMode,
108
+ );
109
+ // If we reach here, the fork was successful and redirect should happen
110
+ return;
111
+ } catch (forkError) {
112
+ console.error('Auto-fork failed:', forkError);
113
+ setErrorMessage(
114
+ 'Failed to fork visualization. Please try forking manually.',
115
+ );
116
+ return;
117
+ }
118
+ }
119
+
120
+ // For other errors, show the error message
121
+ setErrorMessage(errorMessage);
92
122
  return;
93
123
  }
94
124
 
@@ -107,6 +137,34 @@ export const AIChat = () => {
107
137
  aiChatEndpoint,
108
138
  aiChatOptions,
109
139
  currentChatId,
140
+ aiChatMode,
141
+ autoForkAndRetryAI,
142
+ ]);
143
+
144
+ // Check for stored AI prompt on component mount (post-fork restoration)
145
+ useEffect(() => {
146
+ const storedPrompt = getStoredAIPrompt();
147
+ if (storedPrompt) {
148
+ // Restore the prompt and mode
149
+ setAIChatMessage(storedPrompt.prompt);
150
+ setAIChatMode(
151
+ storedPrompt.modelName === 'ask' ? 'ask' : 'edit',
152
+ );
153
+
154
+ // Clear the stored prompt
155
+ clearStoredAIPrompt();
156
+
157
+ // Auto-submit the restored prompt after a short delay
158
+ setTimeout(() => {
159
+ handleSendMessage();
160
+ }, 100);
161
+ }
162
+ }, [
163
+ getStoredAIPrompt,
164
+ clearStoredAIPrompt,
165
+ setAIChatMessage,
166
+ setAIChatMode,
167
+ handleSendMessage,
110
168
  ]);
111
169
 
112
170
  return (