vzcode 2.3.0 → 2.4.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 (196) hide show
  1. package/package.json +3 -2
  2. package/src/cli.ts +208 -0
  3. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +42 -0
  4. package/src/client/AIAssist/AIAssistWidget/index.tsx +135 -0
  5. package/src/client/AIAssist/AIAssistWidget/style.scss +47 -0
  6. package/src/client/AIAssist/Spinner.jsx +76 -0
  7. package/src/client/AIAssist/formatFile.ts +27 -0
  8. package/src/client/AIAssist/generateFilesContext.ts +25 -0
  9. package/src/client/AIAssist/index.ts +2 -0
  10. package/src/client/AIAssist/startAIAssist.ts +95 -0
  11. package/src/client/App/index.tsx +152 -0
  12. package/src/client/App/style.scss +82 -0
  13. package/src/client/App/usePending.ts +51 -0
  14. package/src/client/App/useShareDB.ts +161 -0
  15. package/src/client/CodeEditor/Copilot/index.ts +74 -0
  16. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +12 -0
  17. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +68 -0
  18. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +174 -0
  19. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +79 -0
  20. package/src/client/CodeEditor/InteractiveWidgets/index.ts +44 -0
  21. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +12 -0
  22. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +20 -0
  23. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +143 -0
  24. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +48 -0
  25. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +12 -0
  26. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +25 -0
  27. package/src/client/CodeEditor/basicSetup.ts +73 -0
  28. package/src/client/CodeEditor/getOrCreateEditor.tsx +615 -0
  29. package/src/client/CodeEditor/index.tsx +202 -0
  30. package/src/client/CodeEditor/json1PresenceBroadcast.ts +41 -0
  31. package/src/client/CodeEditor/json1PresenceDisplay.ts +350 -0
  32. package/src/client/CodeEditor/rainbowBrackets.ts +122 -0
  33. package/src/client/CodeEditor/style.scss +156 -0
  34. package/src/client/CodeEditor/typescriptExtension/worker.ts +32 -0
  35. package/src/client/CodeErrorOverlay/index.tsx +77 -0
  36. package/src/client/CodeErrorOverlay/style.scss +33 -0
  37. package/src/client/Fonts/fonts.ts +8 -0
  38. package/src/client/Icons/AdjustmentSVG.tsx +19 -0
  39. package/src/client/Icons/BugSVG.tsx +20 -0
  40. package/src/client/Icons/CloseSVG.tsx +19 -0
  41. package/src/client/Icons/CssSVG.tsx +16 -0
  42. package/src/client/Icons/DirectoryArrowSVG.tsx +19 -0
  43. package/src/client/Icons/EditSVG.tsx +19 -0
  44. package/src/client/Icons/FileSVG.tsx +19 -0
  45. package/src/client/Icons/FolderSVG.tsx +20 -0
  46. package/src/client/Icons/GearSVG.tsx +16 -0
  47. package/src/client/Icons/HtmlSVG.tsx +16 -0
  48. package/src/client/Icons/JavaScriptSVG.tsx +16 -0
  49. package/src/client/Icons/JsonSVG.tsx +16 -0
  50. package/src/client/Icons/MarkdownSVG.tsx +16 -0
  51. package/src/client/Icons/MicOffSVG.tsx +35 -0
  52. package/src/client/Icons/MicSVG.tsx +25 -0
  53. package/src/client/Icons/NewSVG.tsx +19 -0
  54. package/src/client/Icons/PinSVG.tsx +14 -0
  55. package/src/client/Icons/PlaySVG.tsx +16 -0
  56. package/src/client/Icons/QuestionMarkSVG.tsx +18 -0
  57. package/src/client/Icons/ReactSVG.tsx +16 -0
  58. package/src/client/Icons/SearchSVG.tsx +20 -0
  59. package/src/client/Icons/SparklesSVG.tsx +23 -0
  60. package/src/client/Icons/SplitEditorSVG.tsx +34 -0
  61. package/src/client/Icons/StopSVG.tsx +15 -0
  62. package/src/client/Icons/SvelteSVG.tsx +16 -0
  63. package/src/client/Icons/TrashSVG.tsx +19 -0
  64. package/src/client/Icons/TypeScriptSVG.tsx +16 -0
  65. package/src/client/Icons/index.tsx +26 -0
  66. package/src/client/ImageViewer/index.tsx +91 -0
  67. package/src/client/ImageViewer/style.scss +41 -0
  68. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
  69. package/src/client/PresenceNotifications/index.tsx +158 -0
  70. package/src/client/PresenceNotifications/style.scss +17 -0
  71. package/src/client/RunCodeWidget/index.tsx +117 -0
  72. package/src/client/RunCodeWidget/style.scss +24 -0
  73. package/src/client/SplitPaneResizeContext.tsx +159 -0
  74. package/src/client/TabList/Tab.tsx +73 -0
  75. package/src/client/TabList/index.tsx +35 -0
  76. package/src/client/TabList/style.scss +51 -0
  77. package/src/client/VZCodeContext/index.tsx +29 -0
  78. package/src/client/VZCodeContext/types.ts +248 -0
  79. package/src/client/VZCodeContext/useVZCodeState.ts +602 -0
  80. package/src/client/VZKeyboardShortcutsDoc.tsx +148 -0
  81. package/src/client/VZLeft.tsx +28 -0
  82. package/src/client/VZMiddle.tsx +172 -0
  83. package/src/client/VZResizer/index.tsx +128 -0
  84. package/src/client/VZResizer/styles.scss +33 -0
  85. package/src/client/VZRight.tsx +113 -0
  86. package/src/client/VZSettings.tsx +275 -0
  87. package/src/client/VZSidebar/AIChat/ChatInput.tsx +243 -0
  88. package/src/client/VZSidebar/AIChat/DiffView.scss +136 -0
  89. package/src/client/VZSidebar/AIChat/DiffView.tsx +176 -0
  90. package/src/client/VZSidebar/AIChat/Message.tsx +79 -0
  91. package/src/client/VZSidebar/AIChat/MessageList.tsx +190 -0
  92. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +35 -0
  93. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +156 -0
  94. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +19 -0
  95. package/src/client/VZSidebar/AIChat/index.tsx +357 -0
  96. package/src/client/VZSidebar/AIChat/styles.scss +646 -0
  97. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +117 -0
  98. package/src/client/VZSidebar/CreateDirModal.tsx +111 -0
  99. package/src/client/VZSidebar/CreateFileModal.tsx +111 -0
  100. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +76 -0
  101. package/src/client/VZSidebar/DirectoryListing.tsx +89 -0
  102. package/src/client/VZSidebar/EmptyState.tsx +11 -0
  103. package/src/client/VZSidebar/FileListing.tsx +91 -0
  104. package/src/client/VZSidebar/FileTypeIcon.tsx +49 -0
  105. package/src/client/VZSidebar/Item.tsx +237 -0
  106. package/src/client/VZSidebar/Listing.tsx +47 -0
  107. package/src/client/VZSidebar/Search.tsx +527 -0
  108. package/src/client/VZSidebar/VisualEditor.tsx +282 -0
  109. package/src/client/VZSidebar/VoiceChatModal.tsx +121 -0
  110. package/src/client/VZSidebar/aiCopyPaste.ts +199 -0
  111. package/src/client/VZSidebar/index.tsx +728 -0
  112. package/src/client/VZSidebar/styles.scss +612 -0
  113. package/src/client/VZSidebar/useDragAndDrop.tsx +408 -0
  114. package/src/client/bootstrap.ts +26 -0
  115. package/src/client/buildWorker.ts +3 -0
  116. package/src/client/featureFlags.ts +8 -0
  117. package/src/client/generateRequestId.ts +6 -0
  118. package/src/client/getFileTree.ts +53 -0
  119. package/src/client/index.ts +19 -0
  120. package/src/client/main.jsx +10 -0
  121. package/src/client/presenceColor.ts +8 -0
  122. package/src/client/shouldTriggerRun.ts +31 -0
  123. package/src/client/sortFileTree.ts +21 -0
  124. package/src/client/tabsSearchParameters.test.ts +79 -0
  125. package/src/client/tabsSearchParameters.ts +137 -0
  126. package/src/client/themes/index.ts +7 -0
  127. package/src/client/themes/themes.ts +77 -0
  128. package/src/client/themes/uiwImports.ts +32 -0
  129. package/src/client/themes/useDynamicTheme.ts +29 -0
  130. package/src/client/themes/vizhubTheme/colors.ts +80 -0
  131. package/src/client/themes/vizhubTheme/index.ts +193 -0
  132. package/src/client/useActions.ts +288 -0
  133. package/src/client/useESLint/index.ts +72 -0
  134. package/src/client/useESLint/worker.ts +113 -0
  135. package/src/client/useEditorCache.ts +35 -0
  136. package/src/client/useFileCRUD.ts +228 -0
  137. package/src/client/useKeyboardShortcuts.ts +451 -0
  138. package/src/client/useOpenDirectories.ts +99 -0
  139. package/src/client/usePresenceAutoFollow.ts +85 -0
  140. package/src/client/usePrettier/index.ts +178 -0
  141. package/src/client/usePrettier/worker.ts +109 -0
  142. package/src/client/useRunCode.tsx +15 -0
  143. package/src/client/useRuntimeError.ts +32 -0
  144. package/src/client/useSubmitOperation.ts +15 -0
  145. package/src/client/useURLSync.ts +137 -0
  146. package/src/client/usernameLocalStorage.ts +43 -0
  147. package/src/client/utils/fileExtension.ts +10 -0
  148. package/src/client/utils/isImageFile.ts +12 -0
  149. package/src/client/vzReducer/aiChatReducer.ts +44 -0
  150. package/src/client/vzReducer/closeTabReducer.test.ts +205 -0
  151. package/src/client/vzReducer/closeTabsReducer.ts +96 -0
  152. package/src/client/vzReducer/createInitialState.ts +38 -0
  153. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
  154. package/src/client/vzReducer/findPane.ts +19 -0
  155. package/src/client/vzReducer/index.ts +250 -0
  156. package/src/client/vzReducer/openTabReducer.test.ts +127 -0
  157. package/src/client/vzReducer/openTabReducer.ts +74 -0
  158. package/src/client/vzReducer/searchReducer.test.ts +292 -0
  159. package/src/client/vzReducer/searchReducer.ts +181 -0
  160. package/src/client/vzReducer/setActiveFileIdReducer.ts +28 -0
  161. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +76 -0
  162. package/src/client/vzReducer/setIsDocOpenReducer.ts +9 -0
  163. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
  164. package/src/client/vzReducer/setThemeReducer.ts +9 -0
  165. package/src/client/vzReducer/setUsernameReducer.ts +9 -0
  166. package/src/client/vzReducer/splitCurrentPaneReducer.ts +66 -0
  167. package/src/client/vzReducer/toggleAutoFollowReducer.ts +12 -0
  168. package/src/client/vzReducer/updatePane.ts +40 -0
  169. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +30 -0
  170. package/src/client/vzReducer/visualEditorReducer.ts +9 -0
  171. package/src/ot.ts +24 -0
  172. package/src/randomId.ts +15 -0
  173. package/src/reactRouterExports.ts +15 -0
  174. package/src/runCode.ts +27 -0
  175. package/src/server/aiChatHandler/aiEditing.ts +151 -0
  176. package/src/server/aiChatHandler/chatOperations.ts +476 -0
  177. package/src/server/aiChatHandler/errorHandling.ts +66 -0
  178. package/src/server/aiChatHandler/index.ts +199 -0
  179. package/src/server/aiChatHandler/llmStreaming.ts +419 -0
  180. package/src/server/aiChatHandler/validation.ts +24 -0
  181. package/src/server/computeInitialDocument.ts +220 -0
  182. package/src/server/config.ts +24 -0
  183. package/src/server/featureFlags.ts +8 -0
  184. package/src/server/generateAIResponse.ts +188 -0
  185. package/src/server/handleAIAssist.ts +53 -0
  186. package/src/server/handleAIChatMessage.ts +2 -0
  187. package/src/server/handleAICopilot.ts +97 -0
  188. package/src/server/index.ts +379 -0
  189. package/src/server/isDirectory.ts +1 -0
  190. package/src/server/livekit.ts +24 -0
  191. package/src/server/prettier.ts +115 -0
  192. package/src/server/setupEnv.ts +8 -0
  193. package/src/submitOperation.ts +25 -0
  194. package/src/types.ts +205 -0
  195. package/src/utils/fileDiff.ts +117 -0
  196. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,40 @@
1
+ import { Pane, PaneId, TabState } from '../../types';
2
+ import { VizFileId } from '@vizhub/viz-types';
3
+
4
+ // Immutable update pattern for updating a pane's tab list.
5
+ export const updatePane = ({
6
+ pane,
7
+ activePaneId,
8
+ newTabList,
9
+ newActiveFileId,
10
+ }: {
11
+ pane: Pane;
12
+ activePaneId: PaneId;
13
+ newTabList?: Array<TabState>;
14
+ newActiveFileId?: VizFileId | null;
15
+ }): Pane =>
16
+ pane.type === 'splitPane'
17
+ ? {
18
+ ...pane,
19
+ children: pane.children.map((child) =>
20
+ updatePane({
21
+ pane: child,
22
+ activePaneId,
23
+ newTabList,
24
+ newActiveFileId,
25
+ }),
26
+ ),
27
+ }
28
+ : pane.id === activePaneId
29
+ ? {
30
+ ...pane,
31
+ tabList:
32
+ newTabList !== undefined
33
+ ? newTabList
34
+ : pane.tabList,
35
+ activeFileId:
36
+ newActiveFileId !== undefined
37
+ ? newActiveFileId
38
+ : pane.activeFileId,
39
+ }
40
+ : pane;
@@ -0,0 +1,30 @@
1
+ import { VZAction, VZState } from '.';
2
+
3
+ export const updatePresenceIndicatorReducer = (
4
+ state: VZState,
5
+ action: VZAction,
6
+ ): VZState => {
7
+ if (action.type === 'update_presence_indicator') {
8
+ // True if there's already an entry for this user.
9
+ const needsUpdate =
10
+ state.sidebarPresenceIndicators.find(
11
+ (d) =>
12
+ d.username === action.presenceIndicator.username,
13
+ );
14
+
15
+ return {
16
+ ...state,
17
+ sidebarPresenceIndicators: needsUpdate
18
+ ? state.sidebarPresenceIndicators.map((d) =>
19
+ d.username === action.presenceIndicator.username
20
+ ? action.presenceIndicator
21
+ : d,
22
+ )
23
+ : [
24
+ ...state.sidebarPresenceIndicators,
25
+ action.presenceIndicator,
26
+ ],
27
+ };
28
+ }
29
+ return state;
30
+ };
@@ -0,0 +1,9 @@
1
+ import { VZAction, VZState } from '.';
2
+
3
+ export const setIsVisualEditorOpenReducer = (
4
+ state: VZState,
5
+ action: VZAction,
6
+ ): VZState =>
7
+ action.type === 'set_is_visual_editor_open'
8
+ ? { ...state, isVisualEditorOpen: action.value }
9
+ : state;
package/src/ot.ts ADDED
@@ -0,0 +1,24 @@
1
+ // Operational Transformation (OT) utilities.
2
+ // This file is the central point where the OT types are imported.
3
+ // Localized to one file so it's easy to change it in future.
4
+ import OTJSON1Presence from 'sharedb-client-browser/dist/ot-json1-presence-umd.cjs';
5
+ import jsondiff from 'json0-ot-diff';
6
+ import diffMatchPatch from 'diff-match-patch';
7
+
8
+ export const { json1Presence, textUnicode } =
9
+ OTJSON1Presence;
10
+
11
+ // The OT type used throughout the codebase.
12
+ export const otType = json1Presence.type;
13
+
14
+ // Applies an OT op to an object.
15
+ export const apply = otType.apply;
16
+
17
+ export const diff = (a, b) =>
18
+ jsondiff(
19
+ a,
20
+ b,
21
+ diffMatchPatch,
22
+ json1Presence,
23
+ textUnicode,
24
+ );
@@ -0,0 +1,15 @@
1
+ // Generate a random ID string consisting of digits.
2
+ const numDigits = 8;
3
+ export const randomId = () => {
4
+ let randomString = '';
5
+ for (let i = 0; i < numDigits; i++) {
6
+ randomString += Math.floor(Math.random() * 10);
7
+ }
8
+ return randomString;
9
+ };
10
+
11
+ // const probabilityOfCollision =
12
+ // 1 - Math.pow(1 - 1 / Math.pow(10, numDigits), numRuns);
13
+ // Using this formula, the probability of generating the same ID twice
14
+ // when using 8 digits and running the code 1000 times is approximately
15
+ // 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
@@ -0,0 +1,15 @@
1
+ // The React Router exports have been a pain to deal with.
2
+ // After upgrading Node and React Router, there were random errors.
3
+ // And we want to migrate soon from `react-router-dom` to `react-router`,
4
+ // so the exports are centralized here.
5
+ import * as reactRouterDOM from 'react-router-dom';
6
+
7
+ export const {
8
+ useSearchParams,
9
+
10
+ // This actually is the only thing that works.
11
+ // It looks crazy, but it works.
12
+ // - reactRouterDOM.default works for Vite SSR build
13
+ // - reactRouterDOM works for Vite frontend build
14
+ // @ts-ignore
15
+ } = reactRouterDOM.default || reactRouterDOM;
package/src/runCode.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { generateRunId } from '@vizhub/viz-utils';
2
+ import { SubmitOperation } from './types';
3
+ import { VizContent } from '@vizhub/viz-types';
4
+
5
+ /**
6
+ * Creates a runCode function that triggers code execution by changing the `runId` in the content.
7
+ * This works for both client-side (with submitOperation) and server-side (with ShareDB document).
8
+ */
9
+ export const createRunCodeFunction =
10
+ (submitOperation: SubmitOperation) => () => {
11
+ submitOperation((content: VizContent) => ({
12
+ ...content,
13
+ runId: generateRunId(),
14
+ }));
15
+ };
16
+
17
+ /**
18
+ * Creates a runCodeRef object compatible with React refs.
19
+ * This is useful for maintaining compatibility with existing code that expects a ref.
20
+ */
21
+ export const createRunCodeRef = (
22
+ submitOperation: SubmitOperation,
23
+ ) => {
24
+ return {
25
+ current: createRunCodeFunction(submitOperation),
26
+ };
27
+ };
@@ -0,0 +1,151 @@
1
+ import {
2
+ assembleFullPrompt,
3
+ prepareFilesForPrompt,
4
+ } from 'editcodewithai';
5
+ import { formatMarkdownFiles } from 'llm-code-format';
6
+ import {
7
+ createFilesSnapshot,
8
+ generateFilesUnifiedDiff,
9
+ } from '../../utils/fileDiff.js';
10
+ import { formatFiles } from '../prettier.js';
11
+ import { createSubmitOperation } from '../../submitOperation.js';
12
+ import { VizContent } from '@vizhub/viz-types';
13
+
14
+ // Dev flag for waiting 1 second before starting the LLM function.
15
+ // Useful for debugging and testing purposes, e.g. checking the typing indicator.
16
+ const delayStart = false;
17
+
18
+ /**
19
+ * Performs AI chat without editing - just generates a response
20
+ */
21
+ export const performAIChat = async ({
22
+ prompt,
23
+ shareDBDoc,
24
+ llmFunction,
25
+ }) => {
26
+ const preparedFiles = prepareFilesForPrompt(
27
+ shareDBDoc.data.files,
28
+ );
29
+ const filesContext = formatMarkdownFiles(preparedFiles);
30
+
31
+ // 2. Assemble the final prompt for Q&A mode
32
+ const fullPrompt = assembleFullPrompt({
33
+ filesContext,
34
+ prompt,
35
+ editFormat: 'whole',
36
+ });
37
+
38
+ if (delayStart) {
39
+ await new Promise((resolve) =>
40
+ setTimeout(resolve, 1000),
41
+ );
42
+ }
43
+
44
+ // Call the LLM function which will handle streaming but won't edit files
45
+ const result = await llmFunction(fullPrompt);
46
+
47
+ return {
48
+ content: result.content,
49
+ generationId: result.generationId,
50
+ diffData: {}, // No file changes in ask mode
51
+ };
52
+ };
53
+
54
+ /**
55
+ * Performs AI editing operations using streaming with incremental OT operations
56
+ */
57
+ export const performAIEditing = async ({
58
+ prompt,
59
+ shareDBDoc,
60
+ llmFunction,
61
+ runCode,
62
+ }) => {
63
+ // 1. Capture the current state of files before editing
64
+ const beforeFiles = createFilesSnapshot(
65
+ shareDBDoc.data.files,
66
+ );
67
+
68
+ const preparedFiles = prepareFilesForPrompt(
69
+ shareDBDoc.data.files,
70
+ );
71
+ const filesContext = formatMarkdownFiles(preparedFiles);
72
+
73
+ // 2. Assemble the final prompt
74
+ const fullPrompt = assembleFullPrompt({
75
+ filesContext,
76
+ prompt,
77
+ editFormat: 'whole',
78
+ });
79
+
80
+ if (delayStart) {
81
+ await new Promise((resolve) =>
82
+ setTimeout(resolve, 1000),
83
+ );
84
+ }
85
+
86
+ // Call the LLM function which will handle streaming and incremental file updates
87
+ const result = await llmFunction(fullPrompt);
88
+
89
+ // 3. Run Prettier on changed files before running code
90
+ const afterLLMFiles = createFilesSnapshot(
91
+ shareDBDoc.data.files,
92
+ );
93
+
94
+ // Find files that were changed by the AI
95
+ const changedFileIds = Object.keys(afterLLMFiles).filter(
96
+ (fileId) =>
97
+ beforeFiles[fileId]?.text !==
98
+ afterLLMFiles[fileId]?.text,
99
+ );
100
+
101
+ if (changedFileIds.length > 0) {
102
+ // Format the changed files
103
+ const formattedFiles = await formatFiles(
104
+ shareDBDoc.data.files,
105
+ changedFileIds,
106
+ );
107
+
108
+ // Apply formatted versions to shareDBDoc if formatting succeeded
109
+ if (Object.keys(formattedFiles).length > 0) {
110
+ const submitOperation =
111
+ createSubmitOperation(shareDBDoc);
112
+ submitOperation((document: VizContent) => {
113
+ const updatedFiles = { ...document.files };
114
+
115
+ // Apply each formatted file
116
+ Object.entries(formattedFiles).forEach(
117
+ ([fileId, formattedText]) => {
118
+ if (updatedFiles[fileId]) {
119
+ updatedFiles[fileId] = {
120
+ ...updatedFiles[fileId],
121
+ text: formattedText,
122
+ };
123
+ }
124
+ },
125
+ );
126
+
127
+ return {
128
+ ...document,
129
+ files: updatedFiles,
130
+ };
131
+ });
132
+ }
133
+ }
134
+
135
+ runCode();
136
+
137
+ // 4. Capture the state of files after editing and formatting, then generate diff
138
+ const afterFiles = createFilesSnapshot(
139
+ shareDBDoc.data.files,
140
+ );
141
+ const diffData = generateFilesUnifiedDiff(
142
+ beforeFiles,
143
+ afterFiles,
144
+ );
145
+
146
+ return {
147
+ content: result.content,
148
+ generationId: result.generationId,
149
+ diffData,
150
+ };
151
+ };