vzcode 2.2.0 → 2.3.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 (220) hide show
  1. package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
  2. package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
  3. package/dist/assets/{index-CpxqGhXj.js → index-DuUjtrt6.js} +150 -150
  4. package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
  5. package/dist/cli.js +113 -0
  6. package/dist/index.html +2 -2
  7. package/{src/ot.ts → dist/ot.js} +2 -14
  8. package/{src/randomId.ts → dist/randomId.js} +5 -6
  9. package/dist/runCode.js +20 -0
  10. package/dist/server/aiChatHandler/aiEditing.js +89 -0
  11. package/dist/server/aiChatHandler/chatOperations.js +360 -0
  12. package/dist/server/aiChatHandler/errorHandling.js +49 -0
  13. package/dist/server/aiChatHandler/index.js +112 -0
  14. package/dist/server/aiChatHandler/llmStreaming.js +284 -0
  15. package/dist/server/aiChatHandler/validation.js +19 -0
  16. package/dist/server/computeInitialDocument.js +146 -0
  17. package/{src/server/config.ts → dist/server/config.js} +4 -7
  18. package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
  19. package/dist/server/generateAIResponse.js +129 -0
  20. package/dist/server/handleAIAssist.js +39 -0
  21. package/dist/server/handleAICopilot.js +81 -0
  22. package/dist/server/index.js +297 -0
  23. package/dist/server/livekit.js +17 -0
  24. package/dist/server/prettier.js +90 -0
  25. package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
  26. package/dist/submitOperation.js +14 -0
  27. package/dist/types.js +1 -0
  28. package/dist/utils/fileDiff.js +66 -0
  29. package/package.json +22 -22
  30. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
  31. package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
  32. package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
  33. package/src/client/AIAssist/Spinner.jsx +0 -76
  34. package/src/client/AIAssist/formatFile.ts +0 -27
  35. package/src/client/AIAssist/generateFilesContext.ts +0 -25
  36. package/src/client/AIAssist/index.ts +0 -2
  37. package/src/client/AIAssist/startAIAssist.ts +0 -95
  38. package/src/client/App/index.tsx +0 -153
  39. package/src/client/App/style.scss +0 -82
  40. package/src/client/App/usePending.ts +0 -51
  41. package/src/client/App/useShareDB.ts +0 -161
  42. package/src/client/CodeEditor/Copilot/index.ts +0 -74
  43. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
  44. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
  45. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
  46. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
  47. package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
  48. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
  49. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
  50. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
  51. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
  52. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
  53. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
  54. package/src/client/CodeEditor/basicSetup.ts +0 -73
  55. package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
  56. package/src/client/CodeEditor/index.tsx +0 -202
  57. package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
  58. package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
  59. package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
  60. package/src/client/CodeEditor/style.scss +0 -156
  61. package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
  62. package/src/client/CodeErrorOverlay/index.tsx +0 -77
  63. package/src/client/CodeErrorOverlay/style.scss +0 -33
  64. package/src/client/Fonts/fonts.ts +0 -8
  65. package/src/client/Icons/AdjustmentSVG.tsx +0 -19
  66. package/src/client/Icons/BugSVG.tsx +0 -20
  67. package/src/client/Icons/CloseSVG.tsx +0 -19
  68. package/src/client/Icons/CssSVG.tsx +0 -16
  69. package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
  70. package/src/client/Icons/EditSVG.tsx +0 -19
  71. package/src/client/Icons/FileSVG.tsx +0 -19
  72. package/src/client/Icons/FolderSVG.tsx +0 -20
  73. package/src/client/Icons/GearSVG.tsx +0 -16
  74. package/src/client/Icons/HtmlSVG.tsx +0 -16
  75. package/src/client/Icons/JavaScriptSVG.tsx +0 -16
  76. package/src/client/Icons/JsonSVG.tsx +0 -16
  77. package/src/client/Icons/MarkdownSVG.tsx +0 -16
  78. package/src/client/Icons/MicOffSVG.tsx +0 -35
  79. package/src/client/Icons/MicSVG.tsx +0 -25
  80. package/src/client/Icons/NewSVG.tsx +0 -19
  81. package/src/client/Icons/PinSVG.tsx +0 -14
  82. package/src/client/Icons/PlaySVG.tsx +0 -16
  83. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  84. package/src/client/Icons/ReactSVG.tsx +0 -16
  85. package/src/client/Icons/SearchSVG.tsx +0 -20
  86. package/src/client/Icons/SparklesSVG.tsx +0 -23
  87. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  88. package/src/client/Icons/StopSVG.tsx +0 -15
  89. package/src/client/Icons/SvelteSVG.tsx +0 -16
  90. package/src/client/Icons/TrashSVG.tsx +0 -19
  91. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  92. package/src/client/Icons/index.tsx +0 -26
  93. package/src/client/ImageViewer/index.tsx +0 -91
  94. package/src/client/ImageViewer/style.scss +0 -41
  95. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  96. package/src/client/PresenceNotifications/index.tsx +0 -158
  97. package/src/client/PresenceNotifications/style.scss +0 -17
  98. package/src/client/RunCodeWidget/index.tsx +0 -117
  99. package/src/client/RunCodeWidget/style.scss +0 -24
  100. package/src/client/SplitPaneResizeContext.tsx +0 -159
  101. package/src/client/TabList/Tab.tsx +0 -73
  102. package/src/client/TabList/index.tsx +0 -35
  103. package/src/client/TabList/style.scss +0 -51
  104. package/src/client/VZCodeContext/index.tsx +0 -29
  105. package/src/client/VZCodeContext/types.ts +0 -249
  106. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  107. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  108. package/src/client/VZLeft.tsx +0 -28
  109. package/src/client/VZMiddle.tsx +0 -172
  110. package/src/client/VZResizer/index.tsx +0 -128
  111. package/src/client/VZResizer/styles.scss +0 -33
  112. package/src/client/VZRight.tsx +0 -113
  113. package/src/client/VZSettings.tsx +0 -275
  114. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -239
  115. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  116. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  117. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  118. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  119. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  120. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  121. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  122. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  123. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  124. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -117
  125. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  126. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  127. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  128. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  129. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  130. package/src/client/VZSidebar/FileListing.tsx +0 -91
  131. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  132. package/src/client/VZSidebar/Item.tsx +0 -237
  133. package/src/client/VZSidebar/Listing.tsx +0 -47
  134. package/src/client/VZSidebar/Search.tsx +0 -527
  135. package/src/client/VZSidebar/VisualEditor.tsx +0 -282
  136. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  137. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  138. package/src/client/VZSidebar/index.tsx +0 -728
  139. package/src/client/VZSidebar/styles.scss +0 -612
  140. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  141. package/src/client/bootstrap.ts +0 -26
  142. package/src/client/buildWorker.ts +0 -3
  143. package/src/client/featureFlags.ts +0 -8
  144. package/src/client/generateRequestId.ts +0 -6
  145. package/src/client/getFileTree.ts +0 -53
  146. package/src/client/index.ts +0 -19
  147. package/src/client/main.jsx +0 -10
  148. package/src/client/presenceColor.ts +0 -8
  149. package/src/client/shouldTriggerRun.ts +0 -31
  150. package/src/client/sortFileTree.ts +0 -21
  151. package/src/client/tabsSearchParameters.test.ts +0 -79
  152. package/src/client/tabsSearchParameters.ts +0 -137
  153. package/src/client/themes/index.ts +0 -7
  154. package/src/client/themes/themes.ts +0 -77
  155. package/src/client/themes/uiwImports.ts +0 -32
  156. package/src/client/themes/useDynamicTheme.ts +0 -29
  157. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  158. package/src/client/themes/vizhubTheme/index.ts +0 -193
  159. package/src/client/useActions.ts +0 -288
  160. package/src/client/useESLint/index.ts +0 -72
  161. package/src/client/useESLint/worker.ts +0 -113
  162. package/src/client/useEditorCache.ts +0 -35
  163. package/src/client/useFileCRUD.ts +0 -228
  164. package/src/client/useKeyboardShortcuts.ts +0 -451
  165. package/src/client/useOpenDirectories.ts +0 -99
  166. package/src/client/usePresenceAutoFollow.ts +0 -85
  167. package/src/client/usePrettier/index.ts +0 -178
  168. package/src/client/usePrettier/worker.ts +0 -109
  169. package/src/client/useRunCode.tsx +0 -15
  170. package/src/client/useRuntimeError.ts +0 -32
  171. package/src/client/useSubmitOperation.ts +0 -15
  172. package/src/client/useURLSync.ts +0 -137
  173. package/src/client/usernameLocalStorage.ts +0 -43
  174. package/src/client/utils/fileExtension.ts +0 -10
  175. package/src/client/utils/isImageFile.ts +0 -12
  176. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  177. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  178. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  179. package/src/client/vzReducer/createInitialState.ts +0 -38
  180. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  181. package/src/client/vzReducer/findPane.ts +0 -19
  182. package/src/client/vzReducer/index.ts +0 -250
  183. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  184. package/src/client/vzReducer/openTabReducer.ts +0 -74
  185. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  186. package/src/client/vzReducer/searchReducer.ts +0 -181
  187. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  188. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  189. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  190. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  191. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  192. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  193. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  194. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  195. package/src/client/vzReducer/updatePane.ts +0 -40
  196. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  197. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  198. package/src/reactRouterExports.ts +0 -15
  199. package/src/runCode.ts +0 -27
  200. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  201. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  202. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  203. package/src/server/aiChatHandler/index.ts +0 -200
  204. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  205. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  206. package/src/server/aiChatHandler/validation.ts +0 -24
  207. package/src/server/computeInitialDocument.ts +0 -220
  208. package/src/server/generateAIResponse.ts +0 -188
  209. package/src/server/handleAIAssist.ts +0 -53
  210. package/src/server/handleAIChatUndo.ts +0 -2
  211. package/src/server/handleAICopilot.ts +0 -97
  212. package/src/server/index.ts +0 -388
  213. package/src/server/livekit.ts +0 -24
  214. package/src/server/prettier.ts +0 -115
  215. package/src/submitOperation.ts +0 -25
  216. package/src/types.ts +0 -205
  217. package/src/utils/fileDiff.ts +0 -117
  218. package/src/vite-env.d.ts +0 -10
  219. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  220. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -1,627 +0,0 @@
1
- .ai-chat-container {
2
- height: 100%;
3
- display: flex;
4
- flex-direction: column;
5
- padding: 0;
6
- }
7
-
8
- .ai-chat-content {
9
- flex: 1;
10
- overflow: hidden;
11
- display: flex;
12
- flex-direction: column;
13
- }
14
-
15
- .ai-chat-messages-container {
16
- flex: 1;
17
- overflow-y: auto;
18
- padding: 10px;
19
- padding-bottom: 0;
20
- display: flex;
21
- flex-direction: column;
22
- }
23
-
24
- .ai-chat-input-fixed {
25
- flex-shrink: 0;
26
- padding: 10px;
27
- padding-top: 0;
28
- }
29
-
30
- .ai-chat-empty {
31
- flex: 1;
32
- display: flex;
33
- flex-direction: column;
34
- align-items: center;
35
- justify-content: center;
36
- text-align: center;
37
- padding: 20px;
38
- overflow-y: auto;
39
-
40
- .ai-chat-empty-icon {
41
- font-size: 42px;
42
- margin-bottom: 15px;
43
- }
44
-
45
- .ai-chat-empty-title {
46
- font-size: 18px;
47
- font-weight: 600;
48
- color: var(--vh-color-neutral-04);
49
- margin-bottom: 15px;
50
- }
51
-
52
- .ai-chat-empty-text {
53
- font-size: 14px;
54
- color: var(--vh-color-neutral-04);
55
- margin-bottom: 20px;
56
- line-height: 1.5;
57
- }
58
-
59
- .ai-chat-empty-examples {
60
- background: var(--vh-color-neutral-02);
61
- border-radius: 8px;
62
- padding: 15px;
63
- margin-bottom: 20px;
64
- text-align: left;
65
- width: 100%;
66
-
67
- h4 {
68
- font-size: 15px;
69
- font-weight: 600;
70
- color: var(--vh-color-neutral-04);
71
- margin-bottom: 10px;
72
- }
73
-
74
- .ai-chat-suggested-prompts {
75
- display: flex;
76
- flex-direction: column;
77
- gap: 8px;
78
- margin: 0;
79
-
80
- .ai-chat-suggested-prompt {
81
- background: var(--vh-color-neutral-03);
82
- border: 1px solid var(--vh-color-neutral-04);
83
- border-radius: 6px;
84
- padding: 8px 12px;
85
- font-size: 13px;
86
- color: var(--vh-color-neutral-04);
87
- text-align: left;
88
- cursor: pointer;
89
- transition: all 0.2s ease;
90
- line-height: 1.4;
91
-
92
- &:hover {
93
- background: var(--vh-color-neutral-04);
94
- color: var(--vh-color-neutral-01);
95
- border-color: var(--vh-color-primary-01);
96
- }
97
-
98
- &:active {
99
- background: var(--vh-color-primary-01);
100
- color: white;
101
- border-color: var(--vh-color-primary-01);
102
- }
103
- }
104
- }
105
- }
106
- }
107
-
108
- .ai-chat-messages {
109
- flex: 1;
110
- overflow-y: auto;
111
- margin-bottom: 10px;
112
- padding-right: 5px;
113
- scroll-behavior: smooth;
114
-
115
- &::-webkit-scrollbar {
116
- width: 6px;
117
- }
118
-
119
- &::-webkit-scrollbar-track {
120
- background: var(--vh-color-neutral-02);
121
- border-radius: 3px;
122
- }
123
-
124
- &::-webkit-scrollbar-thumb {
125
- background: var(--vh-color-neutral-04);
126
- border-radius: 3px;
127
- }
128
- }
129
-
130
- .ai-chat-message {
131
- margin-bottom: 15px;
132
-
133
- &.user {
134
- .ai-chat-message-content {
135
- background: var(--vh-color-primary-01);
136
- color: white;
137
- margin-left: 20px;
138
- border-radius: 12px 12px 4px 12px;
139
- }
140
-
141
- .ai-chat-message-time {
142
- text-align: right;
143
- margin-right: 5px;
144
- }
145
- }
146
-
147
- &.assistant {
148
- .ai-chat-message-content {
149
- background: var(--vh-color-neutral-02);
150
- color: white;
151
- margin-right: 20px;
152
- border-radius: 12px 12px 12px 4px;
153
- }
154
-
155
- .ai-chat-message-time {
156
- text-align: left;
157
- margin-left: 5px;
158
- }
159
-
160
- &.streaming {
161
- .ai-chat-message-content {
162
- background: var(--vh-color-neutral-02);
163
- color: white;
164
- border-radius: 12px 12px 12px 4px;
165
- }
166
- }
167
- }
168
- }
169
-
170
- .ai-chat-message-content {
171
- .diff-view .diff-files .d2h-code-linenumber {
172
- display: none !important;
173
- }
174
-
175
- .d2h-code-line {
176
- padding: 0 1em;
177
- }
178
-
179
- padding: 10px 12px;
180
- font-size: 14px;
181
- line-height: 1.4;
182
- word-wrap: break-word;
183
-
184
- .undo-button-container {
185
- display: flex;
186
- justify-content: flex-end;
187
- gap: 8px;
188
- margin-top: 16px;
189
- }
190
-
191
- .undo-button {
192
- background-color: #dc3545;
193
- color: white;
194
- border: none;
195
- border-radius: 4px;
196
- padding: 4px 8px;
197
- font-size: 12px;
198
- cursor: pointer;
199
- transition: background-color 0.2s;
200
-
201
- &:hover:not(:disabled) {
202
- background-color: #c82333;
203
- }
204
-
205
- &:disabled {
206
- background-color: #6c757d;
207
- cursor: not-allowed;
208
- }
209
- }
210
-
211
- // Markdown styling for dark backgrounds
212
- pre {
213
- background-color: rgba(0, 0, 0, 0.3);
214
- color: #e6e6e6;
215
- padding: 0.5rem;
216
- border-radius: 0.25rem;
217
- overflow-x: auto;
218
- font-size: 0.875rem;
219
- border: 1px solid rgba(255, 255, 255, 0.1);
220
- }
221
-
222
- code {
223
- background-color: rgba(0, 0, 0, 0.3);
224
- color: #e6e6e6;
225
- padding: 0.125rem 0.25rem;
226
- border-radius: 0.25rem;
227
- font-size: 0.875rem;
228
- border: 1px solid rgba(255, 255, 255, 0.1);
229
- }
230
-
231
- pre code {
232
- background-color: transparent;
233
- padding: 0;
234
- border: none;
235
- }
236
-
237
- blockquote {
238
- border-left: 3px solid var(--vh-color-neutral-03);
239
- padding-left: 1rem;
240
- margin: 0.5rem 0;
241
- color: var(--vh-color-neutral-03);
242
- font-style: italic;
243
- }
244
-
245
- h1,
246
- h2,
247
- h3,
248
- h4,
249
- h5,
250
- h6 {
251
- margin-top: 1rem;
252
- margin-bottom: 0.5rem;
253
- color: inherit;
254
- }
255
-
256
- ul,
257
- ol {
258
- padding-left: 1.5rem;
259
- }
260
-
261
- p {
262
- margin-bottom: 0.5rem;
263
- }
264
-
265
- // Ensure good contrast for assistant messages
266
- .ai-chat-message.assistant & {
267
- color: white;
268
- }
269
-
270
- // Ensure user message text stays white
271
- .ai-chat-message.user & {
272
- color: white;
273
- }
274
- }
275
-
276
- .ai-chat-message-time {
277
- font-size: 11px;
278
- color: var(--vh-color-neutral-03);
279
- margin-top: 4px;
280
- }
281
-
282
- .ai-chat-status {
283
- font-size: 0.75rem;
284
- font-style: italic;
285
- color: var(--vh-color-neutral-03);
286
- margin-bottom: 0.5rem;
287
- margin-left: 20px;
288
- margin-right: 20px;
289
- padding: 0.25rem 0.5rem;
290
- background-color: var(--vh-color-neutral-02);
291
- border-radius: 0.25rem;
292
- border: 1px solid var(--vh-color-neutral-03);
293
- text-align: left;
294
- }
295
-
296
- .ai-chat-typing {
297
- display: flex;
298
- gap: 4px;
299
- align-items: center;
300
-
301
- span {
302
- width: 6px;
303
- height: 6px;
304
- background: var(--vh-color-neutral-03);
305
- border-radius: 50%;
306
- animation: typing 1.4s infinite ease-in-out;
307
-
308
- &:nth-child(1) {
309
- animation-delay: -0.32s;
310
- }
311
- &:nth-child(2) {
312
- animation-delay: -0.16s;
313
- }
314
- &:nth-child(3) {
315
- animation-delay: 0s;
316
- }
317
- }
318
- }
319
-
320
- @keyframes typing {
321
- 0%,
322
- 80%,
323
- 100% {
324
- transform: scale(0.8);
325
- opacity: 0.5;
326
- }
327
- 40% {
328
- transform: scale(1);
329
- opacity: 1;
330
- }
331
- }
332
-
333
- .ai-chat-error {
334
- margin: 10px 0;
335
- padding: 0;
336
- border-radius: 8px;
337
- background: rgba(220, 53, 69, 0.1);
338
- border: 1px solid rgba(220, 53, 69, 0.3);
339
-
340
- .ai-chat-error-content {
341
- display: flex;
342
- align-items: center;
343
- padding: 12px;
344
- gap: 10px;
345
-
346
- .ai-chat-error-icon {
347
- font-size: 16px;
348
- flex-shrink: 0;
349
- }
350
-
351
- .ai-chat-error-message {
352
- flex: 1;
353
- font-size: 14px;
354
- color: #dc3545;
355
- line-height: 1.4;
356
- font-weight: 500;
357
- }
358
-
359
- .ai-chat-error-dismiss {
360
- background: none;
361
- border: none;
362
- color: #dc3545;
363
- font-size: 18px;
364
- font-weight: bold;
365
- cursor: pointer;
366
- padding: 0;
367
- width: 20px;
368
- height: 20px;
369
- display: flex;
370
- align-items: center;
371
- justify-content: center;
372
- border-radius: 50%;
373
- transition: background-color 0.2s ease;
374
- flex-shrink: 0;
375
-
376
- &:hover {
377
- background: rgba(220, 53, 69, 0.1);
378
- }
379
-
380
- &:focus {
381
- outline: 2px solid rgba(220, 53, 69, 0.3);
382
- outline-offset: 1px;
383
- }
384
- }
385
- }
386
- }
387
-
388
- .ai-chat-input-container {
389
- border-top: 1px solid var(--vh-color-neutral-02);
390
- padding-top: 10px;
391
- background: var(--vh-color-neutral-01);
392
- }
393
-
394
- .ai-chat-mode-toggle {
395
- display: flex;
396
- flex-direction: column;
397
- gap: 4px;
398
-
399
- .btn-group {
400
- justify-content: center;
401
- }
402
-
403
- .btn-group .btn {
404
- font-size: 12px;
405
- font-weight: 500;
406
- padding: 4px 12px;
407
- border: 1px solid var(--vh-color-neutral-03);
408
- background: var(--vh-color-neutral-02);
409
- color: var(--vh-color-neutral-04);
410
- transition: all 0.2s ease;
411
-
412
- &:hover {
413
- background: var(--vh-color-neutral-03);
414
- border-color: var(--vh-color-neutral-04);
415
- }
416
-
417
- &.btn-primary {
418
- background: var(--vh-color-primary-01);
419
- border-color: var(--vh-color-primary-01);
420
- color: white;
421
-
422
- &:hover {
423
- background: var(--vh-color-primary-02);
424
- border-color: var(--vh-color-primary-02);
425
- }
426
- }
427
-
428
- &:disabled {
429
- opacity: 0.6;
430
- cursor: not-allowed;
431
- }
432
- }
433
-
434
- .ai-chat-mode-description {
435
- font-size: 11px;
436
- color: var(--vh-color-neutral-03);
437
- text-align: center;
438
- font-style: italic;
439
- }
440
- }
441
-
442
- .ai-chat-input-group {
443
- display: flex;
444
- flex-direction: column;
445
- gap: 8px;
446
- margin-bottom: 0;
447
-
448
- textarea {
449
- flex: 1;
450
- background: var(--vh-color-neutral-02) !important;
451
- border: 1px solid var(--vh-color-neutral-03) !important;
452
- color: var(--vh-color-neutral-04) !important;
453
- border-radius: 8px;
454
- padding: 10px 12px;
455
- font-size: 14px;
456
- font-family: var(--vzcode-font-family);
457
- resize: none;
458
- min-height: 48px;
459
- line-height: 1.4;
460
-
461
- &:focus {
462
- outline: none !important;
463
- border-color: var(--vh-color-primary-01) !important;
464
- box-shadow: 0 0 0 2px rgba(38, 67, 153, 0.2) !important;
465
- color: var(--vh-color-neutral-04) !important;
466
- }
467
-
468
- &::placeholder {
469
- color: var(--vh-color-neutral-03) !important;
470
- }
471
-
472
- &:disabled {
473
- opacity: 0.6;
474
- cursor: not-allowed;
475
- }
476
- }
477
-
478
- .ai-chat-input-footer {
479
- display: flex;
480
- justify-content: space-between;
481
- align-items: center;
482
- font-size: 12px;
483
- color: var(--vh-color-neutral-03);
484
- min-height: 40px; // Prevent layout jumping
485
-
486
- .ai-chat-hint {
487
- font-style: italic;
488
- flex: 1;
489
- }
490
- }
491
-
492
- .ai-chat-send-button {
493
- border-radius: 8px;
494
- padding: 8px 16px;
495
- font-size: 14px;
496
- font-weight: 500;
497
- cursor: pointer;
498
- transition: all 0.2s ease;
499
- min-width: 80px;
500
- flex-shrink: 0;
501
-
502
- &.btn-primary {
503
- background: var(--vh-color-primary-01);
504
- border-color: var(--vh-color-primary-01);
505
- color: white;
506
-
507
- &:hover:not(:disabled) {
508
- background: var(--vh-color-primary-02);
509
- border-color: var(--vh-color-primary-02);
510
- }
511
- }
512
-
513
- &.btn-outline-secondary {
514
- background: transparent;
515
- border-color: var(--vh-color-neutral-03);
516
- color: var(--vh-color-neutral-03);
517
-
518
- &:hover:not(:disabled) {
519
- background: var(--vh-color-neutral-03);
520
- color: var(--vh-color-neutral-01);
521
- }
522
- }
523
-
524
- &:disabled {
525
- background: var(--vh-color-neutral-03);
526
- border-color: var(--vh-color-neutral-03);
527
- color: var(--vh-color-neutral-02);
528
- cursor: not-allowed;
529
- }
530
- }
531
- }
532
-
533
- // Thinking scratchpad styles
534
- .thinking-scratchpad {
535
- background: var(--vh-color-neutral-02);
536
- border: 1px solid var(--vh-color-neutral-03);
537
- border-radius: 8px;
538
- margin: 10px 0;
539
- padding: 0;
540
- overflow: hidden;
541
- font-size: 13px;
542
-
543
- .thinking-scratchpad-header {
544
- background: var(--vh-color-neutral-03);
545
- color: var(--vh-color-neutral-04);
546
- padding: 8px 12px;
547
- font-weight: 600;
548
- display: flex;
549
- align-items: center;
550
- gap: 8px;
551
-
552
- .thinking-scratchpad-icon {
553
- font-size: 16px;
554
- }
555
-
556
- .thinking-scratchpad-title {
557
- font-size: 13px;
558
- }
559
- }
560
-
561
- .thinking-scratchpad-content {
562
- padding: 12px;
563
- max-height: 200px;
564
- overflow-y: auto;
565
- background: var(--vh-color-neutral-02);
566
- scroll-behavior: smooth;
567
-
568
- &::-webkit-scrollbar {
569
- width: 6px;
570
- }
571
-
572
- &::-webkit-scrollbar-track {
573
- background: var(--vh-color-neutral-02);
574
- border-radius: 3px;
575
- }
576
-
577
- &::-webkit-scrollbar-thumb {
578
- background: var(--vh-color-neutral-04);
579
- border-radius: 3px;
580
- }
581
-
582
- // Style markdown content in thinking scratchpad
583
- p {
584
- margin: 0 0 8px 0;
585
- line-height: 1.4;
586
- color: var(--vh-color-neutral-04);
587
-
588
- &:last-child {
589
- margin-bottom: 0;
590
- }
591
- }
592
-
593
- code {
594
- background: rgba(0, 0, 0, 0.3);
595
- color: #e6e6e6;
596
- padding: 1px 4px;
597
- border-radius: 3px;
598
- font-size: 12px;
599
- border: 1px solid rgba(255, 255, 255, 0.1);
600
- }
601
-
602
- ul,
603
- ol {
604
- margin: 0 0 8px 0;
605
- padding-left: 20px;
606
-
607
- li {
608
- margin-bottom: 4px;
609
- color: var(--vh-color-neutral-04);
610
- }
611
- }
612
-
613
- h1,
614
- h2,
615
- h3,
616
- h4,
617
- h5,
618
- h6 {
619
- margin: 8px 0 6px 0;
620
- color: var(--vh-color-neutral-04);
621
-
622
- &:first-child {
623
- margin-top: 0;
624
- }
625
- }
626
- }
627
- }
@@ -1,117 +0,0 @@
1
- import {
2
- useState,
3
- useEffect,
4
- useCallback,
5
- Dispatch,
6
- SetStateAction,
7
- } from 'react';
8
-
9
- export interface UseSpeechRecognitionResult {
10
- isSpeaking: boolean;
11
- toggleSpeechRecognition: () => void;
12
- stopSpeaking: () => void;
13
- }
14
-
15
- export const useSpeechRecognition = (
16
- onTranscriptChange: Dispatch<SetStateAction<string>>,
17
- ): UseSpeechRecognitionResult => {
18
- const [isSpeaking, setIsSpeaking] =
19
- useState<boolean>(false);
20
- const [recognition, setRecognition] =
21
- // @ts-ignore
22
- useState<SpeechRecognition | null>(null);
23
- const [finalTranscript, setFinalTranscript] =
24
- useState<string>('');
25
-
26
- // Speech recognition setup
27
- useEffect(() => {
28
- // Check if browser supports SpeechRecognition
29
- const SpeechRecognition =
30
- // @ts-ignore
31
- window.SpeechRecognition ||
32
- // @ts-ignore
33
- window.webkitSpeechRecognition;
34
-
35
- if (SpeechRecognition) {
36
- const recognitionInstance = new SpeechRecognition();
37
- recognitionInstance.continuous = true;
38
- recognitionInstance.interimResults = true;
39
-
40
- recognitionInstance.onresult = (event) => {
41
- let finalText = '';
42
- let interimText = '';
43
-
44
- // Process all results to separate final and interim text
45
- for (let i = 0; i < event.results.length; i++) {
46
- const result = event.results[i];
47
- if (result.isFinal) {
48
- finalText += result[0].transcript;
49
- } else {
50
- interimText += result[0].transcript;
51
- }
52
- }
53
-
54
- // Update our final transcript state
55
- setFinalTranscript(finalText);
56
-
57
- // Combine final and interim text and update the prompt
58
- const fullTranscript = finalText + interimText;
59
- onTranscriptChange(fullTranscript);
60
- };
61
-
62
- recognitionInstance.onerror = (event) => {
63
- console.error(
64
- 'Speech recognition error',
65
- event.error,
66
- );
67
- setIsSpeaking(false);
68
- };
69
-
70
- recognitionInstance.onend = () => {
71
- setIsSpeaking(false);
72
- // Reset final transcript when recognition ends
73
- setFinalTranscript('');
74
- };
75
-
76
- setRecognition(recognitionInstance);
77
-
78
- return () => {
79
- recognitionInstance.abort();
80
- };
81
- }
82
- }, [onTranscriptChange]);
83
-
84
- const toggleSpeechRecognition = useCallback(() => {
85
- if (!recognition) {
86
- console.error(
87
- 'Speech recognition not supported in this browser',
88
- );
89
- return;
90
- }
91
-
92
- if (isSpeaking) {
93
- recognition.stop();
94
- setIsSpeaking(false);
95
- } else {
96
- // Reset final transcript when starting new recognition
97
- setFinalTranscript('');
98
- recognition.start();
99
- setIsSpeaking(true);
100
- }
101
- }, [isSpeaking, recognition]);
102
-
103
- const stopSpeaking = useCallback(() => {
104
- if (recognition && isSpeaking) {
105
- recognition.stop();
106
- setIsSpeaking(false);
107
- // Reset final transcript when manually stopping
108
- setFinalTranscript('');
109
- }
110
- }, [isSpeaking, recognition]);
111
-
112
- return {
113
- isSpeaking,
114
- toggleSpeechRecognition,
115
- stopSpeaking,
116
- };
117
- };