Dominic Elm commited on
Commit
621b880
·
1 Parent(s): b4420a2

feat: add first version of workbench, increase token limit, improve system prompt

Browse files
Files changed (49) hide show
  1. eslint.config.mjs +2 -0
  2. packages/bolt/app/components/chat/Artifact.tsx +164 -22
  3. packages/bolt/app/components/chat/BaseChat.tsx +10 -9
  4. packages/bolt/app/components/chat/Chat.client.tsx +3 -3
  5. packages/bolt/app/components/chat/CodeBlock.tsx +57 -58
  6. packages/bolt/app/components/chat/Markdown.module.scss +38 -16
  7. packages/bolt/app/components/chat/Markdown.tsx +10 -4
  8. packages/bolt/app/components/chat/Messages.client.tsx +4 -2
  9. packages/bolt/app/components/editor/codemirror/BinaryContent.tsx +7 -0
  10. packages/bolt/app/components/editor/codemirror/CodeMirrorEditor.tsx +339 -0
  11. packages/bolt/app/components/editor/codemirror/cm-theme.ts +165 -0
  12. packages/bolt/app/components/editor/codemirror/indent.ts +68 -0
  13. packages/bolt/app/components/editor/codemirror/languages.ts +91 -0
  14. packages/bolt/app/components/editor/codemirror/styles.css +133 -0
  15. packages/bolt/app/components/editor/codemirror/themes/vscode-dark.ts +76 -0
  16. packages/bolt/app/components/ui/IconButton.tsx +1 -1
  17. packages/bolt/app/components/workbench/EditorPanel.tsx +21 -0
  18. packages/bolt/app/components/workbench/FileTree.tsx +3 -0
  19. packages/bolt/app/components/workbench/FileTreePanel.tsx +9 -0
  20. packages/bolt/app/components/workbench/Preview.tsx +63 -0
  21. packages/bolt/app/components/{workspace/Workspace.client.tsx → workbench/Workbench.client.tsx} +29 -15
  22. packages/bolt/app/lib/.server/llm/constants.ts +2 -0
  23. packages/bolt/app/lib/.server/llm/prompts.ts +35 -30
  24. packages/bolt/app/lib/.server/llm/stream-text.ts +38 -0
  25. packages/bolt/app/lib/hooks/useMessageParser.ts +16 -11
  26. packages/bolt/app/lib/hooks/usePromptEnhancer.ts +1 -1
  27. packages/bolt/app/lib/runtime/action-runner.ts +68 -0
  28. packages/bolt/app/lib/runtime/message-parser.spec.ts +9 -7
  29. packages/bolt/app/lib/runtime/message-parser.ts +116 -40
  30. packages/bolt/app/lib/stores/previews.ts +42 -0
  31. packages/bolt/app/lib/stores/theme.ts +33 -0
  32. packages/bolt/app/lib/stores/workbench.ts +153 -0
  33. packages/bolt/app/lib/stores/workspace.ts +0 -42
  34. packages/bolt/app/lib/webcontainer/index.ts +2 -1
  35. packages/bolt/app/root.tsx +23 -2
  36. packages/bolt/app/routes/_index.tsx +4 -4
  37. packages/bolt/app/routes/api.chat.ts +3 -28
  38. packages/bolt/app/routes/api.enhancer.ts +14 -23
  39. packages/bolt/app/routes/login.tsx +2 -2
  40. packages/bolt/app/styles/variables.scss +24 -3
  41. packages/bolt/app/types/actions.ts +18 -0
  42. packages/bolt/app/types/artifact.ts +4 -0
  43. packages/bolt/app/types/theme.ts +1 -0
  44. packages/bolt/app/utils/debounce.ts +17 -0
  45. packages/bolt/app/utils/unreachable.ts +3 -0
  46. packages/bolt/package.json +21 -3
  47. packages/bolt/uno.config.ts +3 -0
  48. packages/bolt/vite.config.ts +6 -0
  49. pnpm-lock.yaml +985 -53
eslint.config.mjs CHANGED
@@ -9,6 +9,8 @@ export default [
9
  {
10
  rules: {
11
  '@blitz/catch-error-name': 'off',
 
 
12
  },
13
  },
14
  {
 
9
  {
10
  rules: {
11
  '@blitz/catch-error-name': 'off',
12
+ '@typescript-eslint/no-this-alias': 'off',
13
+ '@typescript-eslint/no-empty-object-type': 'off',
14
  },
15
  },
16
  {
packages/bolt/app/components/chat/Artifact.tsx CHANGED
@@ -1,34 +1,176 @@
1
  import { useStore } from '@nanostores/react';
2
- import { workspaceStore } from '~/lib/stores/workspace';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  interface ArtifactProps {
 
5
  messageId: string;
6
  }
7
 
8
- export function Artifact({ messageId }: ArtifactProps) {
9
- const artifacts = useStore(workspaceStore.artifacts);
10
 
11
- const artifact = artifacts[messageId];
 
 
 
 
 
 
 
12
 
13
  return (
14
- <button
15
- className="flex border rounded-lg overflow-hidden items-stretch bg-gray-50/25 w-full"
16
- onClick={() => {
17
- const showWorkspace = workspaceStore.showWorkspace.get();
18
- workspaceStore.showWorkspace.set(!showWorkspace);
19
- }}
20
- >
21
- <div className="border-r flex items-center px-6 bg-gray-100/50">
22
- {!artifact?.closed ? (
23
- <div className="i-svg-spinners:90-ring-with-bg scale-130"></div>
24
- ) : (
25
- <div className="i-ph:code-bold scale-130 text-gray-600"></div>
26
- )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  </div>
28
- <div className="flex flex-col items-center px-4 p-2.5">
29
- <div className="text-left w-full">{artifact?.title}</div>
30
- <small className="w-full text-left">Click to open code</small>
31
- </div>
32
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  );
34
  }
 
1
  import { useStore } from '@nanostores/react';
2
+ import { AnimatePresence, motion } from 'framer-motion';
3
+ import { computed } from 'nanostores';
4
+ import { useState } from 'react';
5
+ import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki';
6
+ import { getArtifactKey, workbenchStore, type ActionState } from '../../lib/stores/workbench';
7
+ import { classNames } from '../../utils/classNames';
8
+ import { cubicEasingFn } from '../../utils/easings';
9
+ import { IconButton } from '../ui/IconButton';
10
+
11
+ const highlighterOptions = {
12
+ langs: ['shell'],
13
+ themes: ['light-plus', 'dark-plus'],
14
+ };
15
+
16
+ const shellHighlighter: HighlighterGeneric<BundledLanguage, BundledTheme> =
17
+ import.meta.hot?.data.shellHighlighter ?? (await createHighlighter(highlighterOptions));
18
+
19
+ if (import.meta.hot) {
20
+ import.meta.hot.data.shellHighlighter = shellHighlighter;
21
+ }
22
 
23
  interface ArtifactProps {
24
+ artifactId: string;
25
  messageId: string;
26
  }
27
 
28
+ export function Artifact({ artifactId, messageId }: ArtifactProps) {
29
+ const [showActions, setShowActions] = useState(false);
30
 
31
+ const artifacts = useStore(workbenchStore.artifacts);
32
+ const artifact = artifacts[getArtifactKey(artifactId, messageId)];
33
+
34
+ const actions = useStore(
35
+ computed(artifact.actions, (actions) => {
36
+ return Object.values(actions);
37
+ }),
38
+ );
39
 
40
  return (
41
+ <div className="flex flex-col overflow-hidden border rounded-lg w-full">
42
+ <div className="flex">
43
+ <button
44
+ className="flex items-stretch bg-gray-50/25 w-full overflow-hidden"
45
+ onClick={() => {
46
+ const showWorkbench = workbenchStore.showWorkbench.get();
47
+ workbenchStore.showWorkbench.set(!showWorkbench);
48
+ }}
49
+ >
50
+ <div className="flex items-center px-6 bg-gray-100/50">
51
+ {!artifact?.closed ? (
52
+ <div className="i-svg-spinners:90-ring-with-bg scale-130"></div>
53
+ ) : (
54
+ <div className="i-ph:code-bold scale-130 text-gray-600"></div>
55
+ )}
56
+ </div>
57
+ <div className="px-4 p-3 w-full text-left">
58
+ <div className="w-full">{artifact?.title}</div>
59
+ <small className="inline-block w-full w-full">Click to open Workbench</small>
60
+ </div>
61
+ </button>
62
+ <AnimatePresence>
63
+ {actions.length && (
64
+ <motion.button
65
+ initial={{ width: 0 }}
66
+ animate={{ width: 'auto' }}
67
+ exit={{ width: 0 }}
68
+ transition={{ duration: 0.15, ease: cubicEasingFn }}
69
+ className="hover:bg-gray-200"
70
+ onClick={() => setShowActions(!showActions)}
71
+ >
72
+ <div className="p-4">
73
+ <div className={showActions ? 'i-ph:caret-up-bold' : 'i-ph:caret-down-bold'}></div>
74
+ </div>
75
+ </motion.button>
76
+ )}
77
+ </AnimatePresence>
78
  </div>
79
+ <AnimatePresence>
80
+ {showActions && actions.length > 0 && (
81
+ <motion.div
82
+ className="actions"
83
+ initial={{ height: 0 }}
84
+ animate={{ height: 'auto' }}
85
+ exit={{ height: '0px' }}
86
+ transition={{ duration: 0.15 }}
87
+ >
88
+ <div className="p-4 text-left border-t">
89
+ <motion.div
90
+ initial={{ opacity: 0 }}
91
+ animate={{ opacity: 1 }}
92
+ exit={{ opacity: 0 }}
93
+ transition={{ duration: 0.15 }}
94
+ >
95
+ <h4 className="font-semibold mb-2">Actions</h4>
96
+ <ul className="list-none space-y-2.5">
97
+ {actions.map((action, index) => {
98
+ const { status, type, content, abort } = action;
99
+
100
+ return (
101
+ <li key={index} className={classNames(getTextColor(action.status))}>
102
+ <div className="flex items-center gap-1.5">
103
+ <div className="text-lg">
104
+ {status === 'running' ? (
105
+ <div className="i-svg-spinners:90-ring-with-bg"></div>
106
+ ) : status === 'pending' ? (
107
+ <div className="i-ph:circle-duotone"></div>
108
+ ) : status === 'complete' ? (
109
+ <div className="i-ph:check-circle-duotone"></div>
110
+ ) : status === 'failed' || status === 'aborted' ? (
111
+ <div className="i-ph:x-circle-duotone"></div>
112
+ ) : null}
113
+ </div>
114
+ {type === 'file' ? (
115
+ <div>
116
+ Create <code className="bg-gray-100 text-gray-700">{action.filePath}</code>
117
+ </div>
118
+ ) : type === 'shell' ? (
119
+ <div className="flex items-center w-full min-h-[28px]">
120
+ <span className="flex-1">Run command</span>
121
+ {abort !== undefined && status === 'running' && (
122
+ <IconButton icon="i-ph:x-circle" size="xl" onClick={() => abort()} />
123
+ )}
124
+ </div>
125
+ ) : null}
126
+ </div>
127
+ {type === 'shell' && <ShellCodeBlock classsName="mt-1" code={content} />}
128
+ </li>
129
+ );
130
+ })}
131
+ </ul>
132
+ </motion.div>
133
+ </div>
134
+ </motion.div>
135
+ )}
136
+ </AnimatePresence>
137
+ </div>
138
+ );
139
+ }
140
+
141
+ function getTextColor(status: ActionState['status']) {
142
+ switch (status) {
143
+ case 'pending': {
144
+ return 'text-gray-500';
145
+ }
146
+ case 'running': {
147
+ return 'text-gray-1000';
148
+ }
149
+ case 'complete': {
150
+ return 'text-positive-600';
151
+ }
152
+ case 'aborted': {
153
+ return 'text-gray-600';
154
+ }
155
+ case 'failed': {
156
+ return 'text-negative-600';
157
+ }
158
+ default: {
159
+ return undefined;
160
+ }
161
+ }
162
+ }
163
+
164
+ interface ShellCodeBlockProps {
165
+ classsName?: string;
166
+ code: string;
167
+ }
168
+
169
+ function ShellCodeBlock({ classsName, code }: ShellCodeBlockProps) {
170
+ return (
171
+ <div
172
+ className={classNames('text-xs', classsName)}
173
+ dangerouslySetInnerHTML={{ __html: shellHighlighter.codeToHtml(code, { lang: 'shell', theme: 'dark-plus' }) }}
174
+ ></div>
175
  );
176
  }
packages/bolt/app/components/chat/BaseChat.tsx CHANGED
@@ -2,16 +2,14 @@ import type { Message } from 'ai';
2
  import type { LegacyRef } from 'react';
3
  import React from 'react';
4
  import { ClientOnly } from 'remix-utils/client-only';
5
- import { IconButton } from '~/components/ui/IconButton';
6
- import { Workspace } from '~/components/workspace/Workspace.client';
7
- import { classNames } from '~/utils/classNames';
8
  import { Messages } from './Messages.client';
9
  import { SendButton } from './SendButton.client';
10
 
11
  interface BaseChatProps {
12
  textareaRef?: LegacyRef<HTMLTextAreaElement> | undefined;
13
- messagesSlot?: React.ReactNode;
14
- workspaceSlot?: React.ReactNode;
15
  chatStarted?: boolean;
16
  isStreaming?: boolean;
17
  messages?: Message[];
@@ -80,14 +78,17 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
80
  </ClientOnly>
81
  <div
82
  className={classNames('relative w-full max-w-3xl md:mx-auto z-2', {
83
- 'sticky bottom-0 bg-bolt-elements-app-backgroundColor': chatStarted,
84
  })}
85
  >
86
  <div
87
- className={classNames('shadow-sm mb-6 border border-gray-200 bg-white rounded-lg overflow-hidden')}
 
 
88
  >
89
  <textarea
90
  ref={textareaRef}
 
91
  onKeyDown={(event) => {
92
  if (event.key === 'Enter') {
93
  if (event.shiftKey) {
@@ -103,7 +104,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
103
  onChange={(event) => {
104
  handleInputChange?.(event);
105
  }}
106
- className={`w-full pl-4 pt-4 pr-16 focus:outline-none resize-none`}
107
  style={{
108
  minHeight: TEXTAREA_MIN_HEIGHT,
109
  maxHeight: TEXTAREA_MAX_HEIGHT,
@@ -146,10 +146,11 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
146
  ) : null}
147
  </div>
148
  </div>
 
149
  </div>
150
  </div>
151
  </div>
152
- <ClientOnly>{() => <Workspace chatStarted={chatStarted} />}</ClientOnly>
153
  </div>
154
  </div>
155
  );
 
2
  import type { LegacyRef } from 'react';
3
  import React from 'react';
4
  import { ClientOnly } from 'remix-utils/client-only';
5
+ import { classNames } from '../../utils/classNames';
6
+ import { IconButton } from '../ui/IconButton';
7
+ import { Workbench } from '../workbench/Workbench.client';
8
  import { Messages } from './Messages.client';
9
  import { SendButton } from './SendButton.client';
10
 
11
  interface BaseChatProps {
12
  textareaRef?: LegacyRef<HTMLTextAreaElement> | undefined;
 
 
13
  chatStarted?: boolean;
14
  isStreaming?: boolean;
15
  messages?: Message[];
 
78
  </ClientOnly>
79
  <div
80
  className={classNames('relative w-full max-w-3xl md:mx-auto z-2', {
81
+ 'sticky bottom-0': chatStarted,
82
  })}
83
  >
84
  <div
85
+ className={classNames(
86
+ 'shadow-sm border border-gray-200 bg-white/85 backdrop-filter backdrop-blur-[8px] rounded-lg overflow-hidden',
87
+ )}
88
  >
89
  <textarea
90
  ref={textareaRef}
91
+ className={`w-full pl-4 pt-4 pr-16 focus:outline-none resize-none bg-transparent`}
92
  onKeyDown={(event) => {
93
  if (event.key === 'Enter') {
94
  if (event.shiftKey) {
 
104
  onChange={(event) => {
105
  handleInputChange?.(event);
106
  }}
 
107
  style={{
108
  minHeight: TEXTAREA_MIN_HEIGHT,
109
  maxHeight: TEXTAREA_MAX_HEIGHT,
 
146
  ) : null}
147
  </div>
148
  </div>
149
+ <div className="bg-white pb-6">{/* Ghost Element */}</div>
150
  </div>
151
  </div>
152
  </div>
153
+ <ClientOnly>{() => <Workbench chatStarted={chatStarted} />}</ClientOnly>
154
  </div>
155
  </div>
156
  );
packages/bolt/app/components/chat/Chat.client.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import { useChat } from 'ai/react';
2
  import { useAnimate } from 'framer-motion';
3
  import { useEffect, useRef, useState } from 'react';
4
- import { useMessageParser, usePromptEnhancer } from '~/lib/hooks';
5
- import { cubicEasingFn } from '~/utils/easings';
6
- import { createScopedLogger } from '~/utils/logger';
7
  import { BaseChat } from './BaseChat';
8
 
9
  const logger = createScopedLogger('Chat');
 
1
  import { useChat } from 'ai/react';
2
  import { useAnimate } from 'framer-motion';
3
  import { useEffect, useRef, useState } from 'react';
4
+ import { useMessageParser, usePromptEnhancer } from '../../lib/hooks';
5
+ import { cubicEasingFn } from '../../utils/easings';
6
+ import { createScopedLogger } from '../../utils/logger';
7
  import { BaseChat } from './BaseChat';
8
 
9
  const logger = createScopedLogger('Chat');
packages/bolt/app/components/chat/CodeBlock.tsx CHANGED
@@ -1,82 +1,81 @@
1
  import { memo, useEffect, useState } from 'react';
2
- import {
3
- bundledLanguages,
4
- codeToHtml,
5
- isSpecialLang,
6
- type BundledLanguage,
7
- type BundledTheme,
8
- type SpecialLanguage,
9
- } from 'shiki';
10
- import { classNames } from '~/utils/classNames';
11
- import { createScopedLogger } from '~/utils/logger';
12
  import styles from './CodeBlock.module.scss';
13
 
14
  const logger = createScopedLogger('CodeBlock');
15
 
16
  interface CodeBlockProps {
 
17
  code: string;
18
- language?: BundledLanguage;
19
- theme?: BundledTheme | SpecialLanguage;
 
20
  }
21
 
22
- export const CodeBlock = memo(({ code, language, theme }: CodeBlockProps) => {
23
- const [html, setHTML] = useState<string | undefined>(undefined);
24
- const [copied, setCopied] = useState(false);
 
25
 
26
- const copyToClipboard = () => {
27
- if (copied) {
28
- return;
29
- }
30
 
31
- navigator.clipboard.writeText(code);
32
 
33
- setCopied(true);
34
 
35
- setTimeout(() => {
36
- setCopied(false);
37
- }, 2000);
38
- };
39
 
40
- useEffect(() => {
41
- if (language && !isSpecialLang(language) && !(language in bundledLanguages)) {
42
- logger.warn(`Unsupported language '${language}'`);
43
- }
44
 
45
- logger.trace(`Language = ${language}`);
46
 
47
- const processCode = async () => {
48
- setHTML(await codeToHtml(code, { lang: language ?? 'plaintext', theme: theme ?? 'dark-plus' }));
49
- };
50
 
51
- processCode();
52
- }, [code]);
53
 
54
- return (
55
- <div className="relative group">
56
- <div
57
- className={classNames(
58
- styles.CopyButtonContainer,
59
- 'bg-white absolute top-[10px] right-[10px] rounded-md z-10 text-lg flex items-center justify-center opacity-0 group-hover:opacity-100',
60
- {
61
- 'rounded-l-0 opacity-100': copied,
62
- },
63
- )}
64
- >
65
- <button
66
  className={classNames(
67
- 'flex items-center bg-transparent p-[6px] justify-center before:bg-white before:rounded-l-md before:text-gray-500 before:border-r before:border-gray-300',
 
68
  {
69
- 'before:opacity-0': !copied,
70
- 'before:opacity-100': copied,
71
  },
72
  )}
73
- title="Copy Code"
74
- onClick={() => copyToClipboard()}
75
  >
76
- <div className="i-ph:clipboard-text-duotone"></div>
77
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </div>
79
- <div dangerouslySetInnerHTML={{ __html: html ?? '' }}></div>
80
- </div>
81
- );
82
- });
 
1
  import { memo, useEffect, useState } from 'react';
2
+ import { bundledLanguages, codeToHtml, isSpecialLang, type BundledLanguage, type SpecialLanguage } from 'shiki';
3
+ import { classNames } from '../../utils/classNames';
4
+ import { createScopedLogger } from '../../utils/logger';
 
 
 
 
 
 
 
5
  import styles from './CodeBlock.module.scss';
6
 
7
  const logger = createScopedLogger('CodeBlock');
8
 
9
  interface CodeBlockProps {
10
+ className?: string;
11
  code: string;
12
+ language?: BundledLanguage | SpecialLanguage;
13
+ theme?: 'light-plus' | 'dark-plus';
14
+ disableCopy?: boolean;
15
  }
16
 
17
+ export const CodeBlock = memo(
18
+ ({ className, code, language = 'plaintext', theme = 'dark-plus', disableCopy = false }: CodeBlockProps) => {
19
+ const [html, setHTML] = useState<string | undefined>(undefined);
20
+ const [copied, setCopied] = useState(false);
21
 
22
+ const copyToClipboard = () => {
23
+ if (copied) {
24
+ return;
25
+ }
26
 
27
+ navigator.clipboard.writeText(code);
28
 
29
+ setCopied(true);
30
 
31
+ setTimeout(() => {
32
+ setCopied(false);
33
+ }, 2000);
34
+ };
35
 
36
+ useEffect(() => {
37
+ if (language && !isSpecialLang(language) && !(language in bundledLanguages)) {
38
+ logger.warn(`Unsupported language '${language}'`);
39
+ }
40
 
41
+ logger.trace(`Language = ${language}`);
42
 
43
+ const processCode = async () => {
44
+ setHTML(await codeToHtml(code, { lang: language, theme }));
45
+ };
46
 
47
+ processCode();
48
+ }, [code]);
49
 
50
+ return (
51
+ <div className={classNames('relative group text-left', className)}>
52
+ <div
 
 
 
 
 
 
 
 
 
53
  className={classNames(
54
+ styles.CopyButtonContainer,
55
+ 'bg-white absolute top-[10px] right-[10px] rounded-md z-10 text-lg flex items-center justify-center opacity-0 group-hover:opacity-100',
56
  {
57
+ 'rounded-l-0 opacity-100': copied,
 
58
  },
59
  )}
 
 
60
  >
61
+ {!disableCopy && (
62
+ <button
63
+ className={classNames(
64
+ 'flex items-center bg-transparent p-[6px] justify-center before:bg-white before:rounded-l-md before:text-gray-500 before:border-r before:border-gray-300',
65
+ {
66
+ 'before:opacity-0': !copied,
67
+ 'before:opacity-100': copied,
68
+ },
69
+ )}
70
+ title="Copy Code"
71
+ onClick={() => copyToClipboard()}
72
+ >
73
+ <div className="i-ph:clipboard-text-duotone"></div>
74
+ </button>
75
+ )}
76
+ </div>
77
+ <div dangerouslySetInnerHTML={{ __html: html ?? '' }}></div>
78
  </div>
79
+ );
80
+ },
81
+ );
 
packages/bolt/app/components/chat/Markdown.module.scss CHANGED
@@ -6,6 +6,12 @@ $color-link: #3498db;
6
  $color-code-bg: #f8f8f8;
7
  $color-blockquote-border: #dfe2e5;
8
 
 
 
 
 
 
 
9
  .MarkdownContent {
10
  line-height: 1.6;
11
  color: $color-text;
@@ -15,11 +21,13 @@ $color-blockquote-border: #dfe2e5;
15
  }
16
 
17
  :is(h1, h2, h3, h4, h5, h6) {
18
- margin-top: 24px;
19
- margin-bottom: 16px;
20
- font-weight: 600;
21
- line-height: 1.25;
22
- color: $color-heading;
 
 
23
  }
24
 
25
  h1 {
@@ -68,9 +76,12 @@ $color-blockquote-border: #dfe2e5;
68
  :not(pre) > code {
69
  font-family: $font-mono;
70
  font-size: 14px;
71
- background-color: $color-code-bg;
72
  border-radius: 6px;
73
  padding: 0.2em 0.4em;
 
 
 
 
74
  }
75
 
76
  pre {
@@ -83,6 +94,7 @@ $color-blockquote-border: #dfe2e5;
83
  font-size: 14px;
84
  background: transparent;
85
  overflow-x: auto;
 
86
  }
87
 
88
  blockquote {
@@ -93,25 +105,35 @@ $color-blockquote-border: #dfe2e5;
93
  }
94
 
95
  :is(ul, ol) {
96
- padding-left: 2em;
97
- margin-top: 0;
98
- margin-bottom: 24px;
 
 
99
  }
100
 
101
  ul {
102
- list-style-type: disc;
 
 
103
  }
104
 
105
  ol {
106
- list-style-type: decimal;
 
 
107
  }
108
 
109
- li + li {
110
- margin-top: 8px;
111
- }
 
 
112
 
113
- li > *:not(:last-child) {
114
- margin-bottom: 16px;
 
 
115
  }
116
 
117
  img {
 
6
  $color-code-bg: #f8f8f8;
7
  $color-blockquote-border: #dfe2e5;
8
 
9
+ @mixin not-inside-actions {
10
+ &:not(:has(:global(.actions)), :global(.actions *)) {
11
+ @content;
12
+ }
13
+ }
14
+
15
  .MarkdownContent {
16
  line-height: 1.6;
17
  color: $color-text;
 
21
  }
22
 
23
  :is(h1, h2, h3, h4, h5, h6) {
24
+ @include not-inside-actions {
25
+ margin-top: 24px;
26
+ margin-bottom: 16px;
27
+ font-weight: 600;
28
+ line-height: 1.25;
29
+ color: $color-heading;
30
+ }
31
  }
32
 
33
  h1 {
 
76
  :not(pre) > code {
77
  font-family: $font-mono;
78
  font-size: 14px;
 
79
  border-radius: 6px;
80
  padding: 0.2em 0.4em;
81
+
82
+ @include not-inside-actions {
83
+ background-color: $color-code-bg;
84
+ }
85
  }
86
 
87
  pre {
 
94
  font-size: 14px;
95
  background: transparent;
96
  overflow-x: auto;
97
+ min-width: 0;
98
  }
99
 
100
  blockquote {
 
105
  }
106
 
107
  :is(ul, ol) {
108
+ @include not-inside-actions {
109
+ padding-left: 2em;
110
+ margin-top: 0;
111
+ margin-bottom: 24px;
112
+ }
113
  }
114
 
115
  ul {
116
+ @include not-inside-actions {
117
+ list-style-type: disc;
118
+ }
119
  }
120
 
121
  ol {
122
+ @include not-inside-actions {
123
+ list-style-type: decimal;
124
+ }
125
  }
126
 
127
+ li {
128
+ @include not-inside-actions {
129
+ & + li {
130
+ margin-top: 8px;
131
+ }
132
 
133
+ > *:not(:last-child) {
134
+ margin-bottom: 16px;
135
+ }
136
+ }
137
  }
138
 
139
  img {
packages/bolt/app/components/chat/Markdown.tsx CHANGED
@@ -1,10 +1,11 @@
1
  import { memo, useMemo } from 'react';
2
  import ReactMarkdown, { type Components } from 'react-markdown';
3
  import type { BundledLanguage } from 'shiki';
4
- import { createScopedLogger } from '~/utils/logger';
5
- import { rehypePlugins, remarkPlugins } from '~/utils/markdown';
6
  import { Artifact } from './Artifact';
7
  import { CodeBlock } from './CodeBlock';
 
8
  import styles from './Markdown.module.scss';
9
 
10
  const logger = createScopedLogger('MarkdownComponent');
@@ -20,13 +21,18 @@ export const Markdown = memo(({ children }: MarkdownProps) => {
20
  return {
21
  div: ({ className, children, node, ...props }) => {
22
  if (className?.includes('__boltArtifact__')) {
 
23
  const messageId = node?.properties.dataMessageId as string;
24
 
 
 
 
 
25
  if (!messageId) {
26
- logger.warn(`Invalud message id ${messageId}`);
27
  }
28
 
29
- return <Artifact messageId={messageId} />;
30
  }
31
 
32
  return (
 
1
  import { memo, useMemo } from 'react';
2
  import ReactMarkdown, { type Components } from 'react-markdown';
3
  import type { BundledLanguage } from 'shiki';
4
+ import { createScopedLogger } from '../../utils/logger';
5
+ import { rehypePlugins, remarkPlugins } from '../../utils/markdown';
6
  import { Artifact } from './Artifact';
7
  import { CodeBlock } from './CodeBlock';
8
+
9
  import styles from './Markdown.module.scss';
10
 
11
  const logger = createScopedLogger('MarkdownComponent');
 
21
  return {
22
  div: ({ className, children, node, ...props }) => {
23
  if (className?.includes('__boltArtifact__')) {
24
+ const artifactId = node?.properties.dataArtifactId as string;
25
  const messageId = node?.properties.dataMessageId as string;
26
 
27
+ if (!artifactId) {
28
+ logger.debug(`Invalid artifact id ${messageId}`);
29
+ }
30
+
31
  if (!messageId) {
32
+ logger.debug(`Invalid message id ${messageId}`);
33
  }
34
 
35
+ return <Artifact artifactId={artifactId} messageId={messageId} />;
36
  }
37
 
38
  return (
packages/bolt/app/components/chat/Messages.client.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import type { Message } from 'ai';
2
- import { classNames } from '~/utils/classNames';
3
  import { AssistantMessage } from './AssistantMessage';
4
  import { UserMessage } from './UserMessage';
5
 
@@ -50,7 +50,9 @@ export function Messages(props: MessagesProps) {
50
  >
51
  <div className={isUserMessage ? 'i-ph:user-fill text-xl' : 'i-blitz:logo'}></div>
52
  </div>
53
- {isUser ? <UserMessage content={content} /> : <AssistantMessage content={content} />}
 
 
54
  </div>
55
  </div>
56
  );
 
1
  import type { Message } from 'ai';
2
+ import { classNames } from '../../utils/classNames';
3
  import { AssistantMessage } from './AssistantMessage';
4
  import { UserMessage } from './UserMessage';
5
 
 
50
  >
51
  <div className={isUserMessage ? 'i-ph:user-fill text-xl' : 'i-blitz:logo'}></div>
52
  </div>
53
+ <div className="grid grid-col-1 w-full">
54
+ {isUser ? <UserMessage content={content} /> : <AssistantMessage content={content} />}
55
+ </div>
56
  </div>
57
  </div>
58
  );
packages/bolt/app/components/editor/codemirror/BinaryContent.tsx ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ export function BinaryContent() {
2
+ return (
3
+ <div className="flex items-center justify-center absolute inset-0 z-10 text-sm bg-tk-elements-app-backgroundColor text-tk-elements-app-textColor">
4
+ File format cannot be displayed.
5
+ </div>
6
+ );
7
+ }
packages/bolt/app/components/editor/codemirror/CodeMirrorEditor.tsx ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { acceptCompletion, autocompletion, closeBrackets } from '@codemirror/autocomplete';
2
+ import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
3
+ import { bracketMatching, foldGutter, indentOnInput, indentUnit } from '@codemirror/language';
4
+ import { searchKeymap } from '@codemirror/search';
5
+ import { Compartment, EditorSelection, EditorState, type Extension } from '@codemirror/state';
6
+ import {
7
+ EditorView,
8
+ drawSelection,
9
+ dropCursor,
10
+ highlightActiveLine,
11
+ highlightActiveLineGutter,
12
+ keymap,
13
+ lineNumbers,
14
+ scrollPastEnd,
15
+ } from '@codemirror/view';
16
+ import { useEffect, useRef, useState, type MutableRefObject } from 'react';
17
+ import type { Theme } from '../../../types/theme';
18
+ import { classNames } from '../../../utils/classNames';
19
+ import { debounce } from '../../../utils/debounce';
20
+ import { createScopedLogger } from '../../../utils/logger';
21
+ import { BinaryContent } from './BinaryContent';
22
+ import { getTheme, reconfigureTheme } from './cm-theme';
23
+ import { indentKeyBinding } from './indent';
24
+ import { getLanguage } from './languages';
25
+
26
+ const logger = createScopedLogger('CodeMirrorEditor');
27
+
28
+ export interface EditorDocument {
29
+ value: string | Uint8Array;
30
+ loading: boolean;
31
+ filePath: string;
32
+ scroll?: ScrollPosition;
33
+ }
34
+
35
+ export interface EditorSettings {
36
+ fontSize?: string;
37
+ tabSize?: number;
38
+ }
39
+
40
+ type TextEditorDocument = EditorDocument & {
41
+ value: string;
42
+ };
43
+
44
+ export interface ScrollPosition {
45
+ top: number;
46
+ left: number;
47
+ }
48
+
49
+ export interface EditorUpdate {
50
+ selection: EditorSelection;
51
+ content: string;
52
+ }
53
+
54
+ export type OnChangeCallback = (update: EditorUpdate) => void;
55
+ export type OnScrollCallback = (position: ScrollPosition) => void;
56
+
57
+ interface Props {
58
+ theme: Theme;
59
+ id?: unknown;
60
+ doc?: EditorDocument;
61
+ debounceChange?: number;
62
+ debounceScroll?: number;
63
+ autoFocusOnDocumentChange?: boolean;
64
+ onChange?: OnChangeCallback;
65
+ onScroll?: OnScrollCallback;
66
+ className?: string;
67
+ settings?: EditorSettings;
68
+ }
69
+
70
+ type EditorStates = Map<string, EditorState>;
71
+
72
+ export function CodeMirrorEditor({
73
+ id,
74
+ doc,
75
+ debounceScroll = 100,
76
+ debounceChange = 150,
77
+ autoFocusOnDocumentChange = false,
78
+ onScroll,
79
+ onChange,
80
+ theme,
81
+ settings,
82
+ className = '',
83
+ }: Props) {
84
+ const [language] = useState(new Compartment());
85
+ const [readOnly] = useState(new Compartment());
86
+
87
+ const containerRef = useRef<HTMLDivElement | null>(null);
88
+ const viewRef = useRef<EditorView>();
89
+ const themeRef = useRef<Theme>();
90
+ const docRef = useRef<EditorDocument>();
91
+ const editorStatesRef = useRef<EditorStates>();
92
+ const onScrollRef = useRef(onScroll);
93
+ const onChangeRef = useRef(onChange);
94
+
95
+ const isBinaryFile = doc?.value instanceof Uint8Array;
96
+
97
+ onScrollRef.current = onScroll;
98
+ onChangeRef.current = onChange;
99
+
100
+ docRef.current = doc;
101
+ themeRef.current = theme;
102
+
103
+ useEffect(() => {
104
+ const onUpdate = debounce((update: EditorUpdate) => {
105
+ onChangeRef.current?.(update);
106
+ }, debounceChange);
107
+
108
+ const view = new EditorView({
109
+ parent: containerRef.current!,
110
+ dispatchTransactions(transactions) {
111
+ const previousSelection = view.state.selection;
112
+
113
+ view.update(transactions);
114
+
115
+ const newSelection = view.state.selection;
116
+
117
+ const selectionChanged =
118
+ newSelection !== previousSelection &&
119
+ (newSelection === undefined || previousSelection === undefined || !newSelection.eq(previousSelection));
120
+
121
+ if (
122
+ docRef.current &&
123
+ !docRef.current.loading &&
124
+ (transactions.some((transaction) => transaction.docChanged) || selectionChanged)
125
+ ) {
126
+ onUpdate({
127
+ selection: view.state.selection,
128
+ content: view.state.doc.toString(),
129
+ });
130
+
131
+ editorStatesRef.current!.set(docRef.current.filePath, view.state);
132
+ }
133
+ },
134
+ });
135
+
136
+ viewRef.current = view;
137
+
138
+ return () => {
139
+ viewRef.current?.destroy();
140
+ viewRef.current = undefined;
141
+ };
142
+ }, []);
143
+
144
+ useEffect(() => {
145
+ if (!viewRef.current) {
146
+ return;
147
+ }
148
+
149
+ viewRef.current.dispatch({
150
+ effects: [reconfigureTheme(theme)],
151
+ });
152
+ }, [theme]);
153
+
154
+ useEffect(() => {
155
+ editorStatesRef.current = new Map<string, EditorState>();
156
+ }, [id]);
157
+
158
+ useEffect(() => {
159
+ const editorStates = editorStatesRef.current!;
160
+ const view = viewRef.current!;
161
+ const theme = themeRef.current!;
162
+
163
+ if (!doc) {
164
+ const state = newEditorState('', theme, settings, onScrollRef, debounceScroll, [language.of([])]);
165
+
166
+ view.setState(state);
167
+
168
+ setNoDocument(view);
169
+
170
+ return;
171
+ }
172
+
173
+ if (doc.value instanceof Uint8Array) {
174
+ return;
175
+ }
176
+
177
+ if (doc.filePath === '') {
178
+ logger.warn('File path should not be empty');
179
+ }
180
+
181
+ let state = editorStates.get(doc.filePath);
182
+
183
+ if (!state) {
184
+ state = newEditorState(doc.value, theme, settings, onScrollRef, debounceScroll, [
185
+ language.of([]),
186
+ readOnly.of([EditorState.readOnly.of(doc.loading)]),
187
+ ]);
188
+
189
+ editorStates.set(doc.filePath, state);
190
+ }
191
+
192
+ view.setState(state);
193
+
194
+ setEditorDocument(view, theme, language, readOnly, autoFocusOnDocumentChange, doc as TextEditorDocument);
195
+ }, [doc?.value, doc?.filePath, doc?.loading, autoFocusOnDocumentChange]);
196
+
197
+ return (
198
+ <div className={classNames('relative h-full', className)}>
199
+ {isBinaryFile && <BinaryContent />}
200
+ <div className="h-full overflow-hidden" ref={containerRef} />
201
+ </div>
202
+ );
203
+ }
204
+
205
+ export default CodeMirrorEditor;
206
+
207
+ CodeMirrorEditor.displayName = 'CodeMirrorEditor';
208
+
209
+ function newEditorState(
210
+ content: string,
211
+ theme: Theme,
212
+ settings: EditorSettings | undefined,
213
+ onScrollRef: MutableRefObject<OnScrollCallback | undefined>,
214
+ debounceScroll: number,
215
+ extensions: Extension[],
216
+ ) {
217
+ return EditorState.create({
218
+ doc: content,
219
+ extensions: [
220
+ EditorView.domEventHandlers({
221
+ scroll: debounce((_event, view) => {
222
+ onScrollRef.current?.({ left: view.scrollDOM.scrollLeft, top: view.scrollDOM.scrollTop });
223
+ }, debounceScroll),
224
+ keydown: (event) => {
225
+ if (event.code === 'KeyS' && (event.ctrlKey || event.metaKey)) {
226
+ event.preventDefault();
227
+ }
228
+ },
229
+ }),
230
+ getTheme(theme, settings),
231
+ history(),
232
+ keymap.of([
233
+ ...defaultKeymap,
234
+ ...historyKeymap,
235
+ ...searchKeymap,
236
+ { key: 'Tab', run: acceptCompletion },
237
+ indentKeyBinding,
238
+ ]),
239
+ indentUnit.of('\t'),
240
+ autocompletion({
241
+ closeOnBlur: false,
242
+ }),
243
+ closeBrackets(),
244
+ lineNumbers(),
245
+ scrollPastEnd(),
246
+ dropCursor(),
247
+ drawSelection(),
248
+ bracketMatching(),
249
+ EditorState.tabSize.of(settings?.tabSize ?? 2),
250
+ indentOnInput(),
251
+ highlightActiveLineGutter(),
252
+ highlightActiveLine(),
253
+ foldGutter({
254
+ markerDOM: (open) => {
255
+ const icon = document.createElement('div');
256
+
257
+ icon.className = `fold-icon ${open ? 'i-ph-caret-down-bold' : 'i-ph-caret-right-bold'}`;
258
+
259
+ return icon;
260
+ },
261
+ }),
262
+ ...extensions,
263
+ ],
264
+ });
265
+ }
266
+
267
+ function setNoDocument(view: EditorView) {
268
+ view.dispatch({
269
+ selection: { anchor: 0 },
270
+ changes: {
271
+ from: 0,
272
+ to: view.state.doc.length,
273
+ insert: '',
274
+ },
275
+ });
276
+
277
+ view.scrollDOM.scrollTo(0, 0);
278
+ }
279
+
280
+ function setEditorDocument(
281
+ view: EditorView,
282
+ theme: Theme,
283
+ language: Compartment,
284
+ readOnly: Compartment,
285
+ autoFocus: boolean,
286
+ doc: TextEditorDocument,
287
+ ) {
288
+ if (doc.value !== view.state.doc.toString()) {
289
+ view.dispatch({
290
+ selection: { anchor: 0 },
291
+ changes: {
292
+ from: 0,
293
+ to: view.state.doc.length,
294
+ insert: doc.value,
295
+ },
296
+ });
297
+ }
298
+
299
+ view.dispatch({
300
+ effects: [readOnly.reconfigure([EditorState.readOnly.of(doc.loading)])],
301
+ });
302
+
303
+ getLanguage(doc.filePath).then((languageSupport) => {
304
+ if (!languageSupport) {
305
+ return;
306
+ }
307
+
308
+ view.dispatch({
309
+ effects: [language.reconfigure([languageSupport]), reconfigureTheme(theme)],
310
+ });
311
+
312
+ requestAnimationFrame(() => {
313
+ const currentLeft = view.scrollDOM.scrollLeft;
314
+ const currentTop = view.scrollDOM.scrollTop;
315
+ const newLeft = doc.scroll?.left ?? 0;
316
+ const newTop = doc.scroll?.top ?? 0;
317
+
318
+ const needsScrolling = currentLeft !== newLeft || currentTop !== newTop;
319
+
320
+ if (autoFocus) {
321
+ if (needsScrolling) {
322
+ // we have to wait until the scroll position was changed before we can set the focus
323
+ view.scrollDOM.addEventListener(
324
+ 'scroll',
325
+ () => {
326
+ view.focus();
327
+ },
328
+ { once: true },
329
+ );
330
+ } else {
331
+ // if the scroll position is still the same we can focus immediately
332
+ view.focus();
333
+ }
334
+ }
335
+
336
+ view.scrollDOM.scrollTo(newLeft, newTop);
337
+ });
338
+ });
339
+ }
packages/bolt/app/components/editor/codemirror/cm-theme.ts ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
2
+ import { Compartment, type Extension } from '@codemirror/state';
3
+ import { EditorView } from '@codemirror/view';
4
+ import type { Theme } from '../../../types/theme.js';
5
+ import type { EditorSettings } from './CodeMirrorEditor.js';
6
+ import { vscodeDarkTheme } from './themes/vscode-dark.js';
7
+
8
+ import './styles.css';
9
+
10
+ export const darkTheme = EditorView.theme({}, { dark: true });
11
+ export const themeSelection = new Compartment();
12
+
13
+ export function getTheme(theme: Theme, settings: EditorSettings = {}): Extension {
14
+ return [
15
+ getEditorTheme(settings),
16
+ theme === 'dark' ? themeSelection.of([getDarkTheme()]) : themeSelection.of([getLightTheme()]),
17
+ ];
18
+ }
19
+
20
+ export function reconfigureTheme(theme: Theme) {
21
+ return themeSelection.reconfigure(theme === 'dark' ? getDarkTheme() : getLightTheme());
22
+ }
23
+
24
+ function getEditorTheme(settings: EditorSettings) {
25
+ return EditorView.theme({
26
+ ...(settings.fontSize && {
27
+ '&': {
28
+ fontSize: settings.fontSize,
29
+ },
30
+ }),
31
+ '&.cm-editor': {
32
+ height: '100%',
33
+ background: 'var(--cm-backgroundColor)',
34
+ color: 'var(--cm-textColor)',
35
+ },
36
+ '.cm-cursor': {
37
+ borderLeft: 'var(--cm-cursor-width) solid var(--cm-cursor-backgroundColor)',
38
+ },
39
+ '.cm-scroller': {
40
+ lineHeight: '1.5',
41
+ },
42
+ '.cm-line': {
43
+ padding: '0 0 0 4px',
44
+ },
45
+ '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
46
+ backgroundColor: 'var(--cm-selection-backgroundColorFocused)',
47
+ opacity: 'var(--cm-selection-backgroundOpacityFocused, 0.3)',
48
+ },
49
+ '&:not(.cm-focused) > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
50
+ backgroundColor: 'var(--cm-selection-backgroundColorBlured)',
51
+ opacity: 'var(--cm-selection-backgroundOpacityBlured, 0.3)',
52
+ },
53
+ '&.cm-focused > .cm-scroller .cm-matchingBracket': {
54
+ backgroundColor: 'var(--cm-matching-bracket)',
55
+ },
56
+ '.cm-activeLine': {
57
+ background: 'var(--cm-activeLineBackgroundColor)',
58
+ },
59
+ '.cm-gutters': {
60
+ background: 'var(--cm-gutter-backgroundColor)',
61
+ borderRight: 0,
62
+ color: 'var(--cm-gutter-textColor)',
63
+ },
64
+ '.cm-gutter': {
65
+ '&.cm-lineNumbers': {
66
+ fontFamily: 'Roboto Mono, monospace',
67
+ fontSize: '13px',
68
+ minWidth: '28px',
69
+ },
70
+ '& .cm-activeLineGutter': {
71
+ background: 'transparent',
72
+ color: 'var(--cm-gutter-activeLineTextColor)',
73
+ },
74
+ '&.cm-foldGutter .cm-gutterElement > .fold-icon': {
75
+ cursor: 'pointer',
76
+ color: 'var(--cm-foldGutter-textColor)',
77
+ transform: 'translateY(2px)',
78
+ '&:hover': {
79
+ color: 'var(--cm-foldGutter-textColorHover)',
80
+ },
81
+ },
82
+ },
83
+ '.cm-foldGutter .cm-gutterElement': {
84
+ padding: '0 4px',
85
+ },
86
+ '.cm-tooltip-autocomplete > ul > li': {
87
+ minHeight: '18px',
88
+ },
89
+ '.cm-panel.cm-search label': {
90
+ marginLeft: '2px',
91
+ },
92
+ '.cm-panel.cm-search input[type=checkbox]': {
93
+ position: 'relative',
94
+ transform: 'translateY(2px)',
95
+ marginRight: '4px',
96
+ },
97
+ '.cm-panels': {
98
+ borderColor: 'var(--cm-panels-borderColor)',
99
+ },
100
+ '.cm-panel.cm-search': {
101
+ background: 'var(--cm-search-backgroundColor)',
102
+ color: 'var(--cm-search-textColor)',
103
+ padding: '6px 8px',
104
+ },
105
+ '.cm-search .cm-button': {
106
+ background: 'var(--cm-search-button-backgroundColor)',
107
+ borderColor: 'var(--cm-search-button-borderColor)',
108
+ color: 'var(--cm-search-button-textColor)',
109
+ borderRadius: '4px',
110
+ '&:hover': {
111
+ color: 'var(--cm-search-button-textColorHover)',
112
+ },
113
+ '&:focus-visible': {
114
+ outline: 'none',
115
+ borderColor: 'var(--cm-search-button-borderColorFocused)',
116
+ },
117
+ '&:hover:not(:focus-visible)': {
118
+ background: 'var(--cm-search-button-backgroundColorHover)',
119
+ borderColor: 'var(--cm-search-button-borderColorHover)',
120
+ },
121
+ '&:hover:focus-visible': {
122
+ background: 'var(--cm-search-button-backgroundColorHover)',
123
+ borderColor: 'var(--cm-search-button-borderColorFocused)',
124
+ },
125
+ },
126
+ '.cm-panel.cm-search [name=close]': {
127
+ top: '6px',
128
+ right: '6px',
129
+ padding: '0 6px',
130
+ backgroundColor: 'var(--cm-search-closeButton-backgroundColor)',
131
+ color: 'var(--cm-search-closeButton-textColor)',
132
+ '&:hover': {
133
+ 'border-radius': '6px',
134
+ color: 'var(--cm-search-closeButton-textColorHover)',
135
+ backgroundColor: 'var(--cm-search-closeButton-backgroundColorHover)',
136
+ },
137
+ },
138
+ '.cm-search input': {
139
+ background: 'var(--cm-search-input-backgroundColor)',
140
+ borderColor: 'var(--cm-search-input-borderColor)',
141
+ outline: 'none',
142
+ borderRadius: '4px',
143
+ '&:focus-visible': {
144
+ borderColor: 'var(--cm-search-input-borderColorFocused)',
145
+ },
146
+ },
147
+ '.cm-tooltip': {
148
+ background: 'var(--cm-tooltip-backgroundColor)',
149
+ borderColor: 'var(--cm-tooltip-borderColor)',
150
+ color: 'var(--cm-tooltip-textColor)',
151
+ },
152
+ '.cm-tooltip.cm-tooltip-autocomplete ul li[aria-selected]': {
153
+ background: 'var(--cm-tooltip-backgroundColorSelected)',
154
+ color: 'var(--cm-tooltip-textColorSelected)',
155
+ },
156
+ });
157
+ }
158
+
159
+ function getLightTheme() {
160
+ return syntaxHighlighting(defaultHighlightStyle);
161
+ }
162
+
163
+ function getDarkTheme() {
164
+ return syntaxHighlighting(vscodeDarkTheme);
165
+ }
packages/bolt/app/components/editor/codemirror/indent.ts ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { indentLess } from '@codemirror/commands';
2
+ import { indentUnit } from '@codemirror/language';
3
+ import { EditorSelection, EditorState, Line, type ChangeSpec } from '@codemirror/state';
4
+ import { EditorView, type KeyBinding } from '@codemirror/view';
5
+
6
+ export const indentKeyBinding: KeyBinding = {
7
+ key: 'Tab',
8
+ run: indentMore,
9
+ shift: indentLess,
10
+ };
11
+
12
+ function indentMore({ state, dispatch }: EditorView) {
13
+ if (state.readOnly) {
14
+ return false;
15
+ }
16
+
17
+ dispatch(
18
+ state.update(
19
+ changeBySelectedLine(state, (from, to, changes) => {
20
+ changes.push({ from, to, insert: state.facet(indentUnit) });
21
+ }),
22
+ { userEvent: 'input.indent' },
23
+ ),
24
+ );
25
+
26
+ return true;
27
+ }
28
+
29
+ function changeBySelectedLine(
30
+ state: EditorState,
31
+ cb: (from: number, to: number | undefined, changes: ChangeSpec[], line: Line) => void,
32
+ ) {
33
+ return state.changeByRange((range) => {
34
+ const changes: ChangeSpec[] = [];
35
+
36
+ const line = state.doc.lineAt(range.from);
37
+
38
+ // just insert single indent unit at the current cursor position
39
+ if (range.from === range.to) {
40
+ cb(range.from, undefined, changes, line);
41
+ }
42
+ // handle the case when multiple characters are selected in a single line
43
+ else if (range.from < range.to && range.to <= line.to) {
44
+ cb(range.from, range.to, changes, line);
45
+ } else {
46
+ let atLine = -1;
47
+
48
+ // handle the case when selection spans multiple lines
49
+ for (let pos = range.from; pos <= range.to; ) {
50
+ const line = state.doc.lineAt(pos);
51
+
52
+ if (line.number > atLine && (range.empty || range.to > line.from)) {
53
+ cb(line.from, undefined, changes, line);
54
+ atLine = line.number;
55
+ }
56
+
57
+ pos = line.to + 1;
58
+ }
59
+ }
60
+
61
+ const changeSet = state.changes(changes);
62
+
63
+ return {
64
+ changes,
65
+ range: EditorSelection.range(changeSet.mapPos(range.anchor, 1), changeSet.mapPos(range.head, 1)),
66
+ };
67
+ });
68
+ }
packages/bolt/app/components/editor/codemirror/languages.ts ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { LanguageDescription } from '@codemirror/language';
2
+
3
+ export const supportedLanguages = [
4
+ LanguageDescription.of({
5
+ name: 'TS',
6
+ extensions: ['ts'],
7
+ async load() {
8
+ return import('@codemirror/lang-javascript').then((module) => module.javascript({ typescript: true }));
9
+ },
10
+ }),
11
+ LanguageDescription.of({
12
+ name: 'JS',
13
+ extensions: ['js', 'mjs', 'cjs'],
14
+ async load() {
15
+ return import('@codemirror/lang-javascript').then((module) => module.javascript());
16
+ },
17
+ }),
18
+ LanguageDescription.of({
19
+ name: 'TSX',
20
+ extensions: ['tsx'],
21
+ async load() {
22
+ return import('@codemirror/lang-javascript').then((module) => module.javascript({ jsx: true, typescript: true }));
23
+ },
24
+ }),
25
+ LanguageDescription.of({
26
+ name: 'JSX',
27
+ extensions: ['jsx'],
28
+ async load() {
29
+ return import('@codemirror/lang-javascript').then((module) => module.javascript({ jsx: true }));
30
+ },
31
+ }),
32
+ LanguageDescription.of({
33
+ name: 'HTML',
34
+ extensions: ['html'],
35
+ async load() {
36
+ return import('@codemirror/lang-html').then((module) => module.html());
37
+ },
38
+ }),
39
+ LanguageDescription.of({
40
+ name: 'CSS',
41
+ extensions: ['css'],
42
+ async load() {
43
+ return import('@codemirror/lang-css').then((module) => module.css());
44
+ },
45
+ }),
46
+ LanguageDescription.of({
47
+ name: 'SASS',
48
+ extensions: ['sass'],
49
+ async load() {
50
+ return import('@codemirror/lang-sass').then((module) => module.sass({ indented: true }));
51
+ },
52
+ }),
53
+ LanguageDescription.of({
54
+ name: 'SCSS',
55
+ extensions: ['scss'],
56
+ async load() {
57
+ return import('@codemirror/lang-sass').then((module) => module.sass({ indented: false }));
58
+ },
59
+ }),
60
+ LanguageDescription.of({
61
+ name: 'JSON',
62
+ extensions: ['json'],
63
+ async load() {
64
+ return import('@codemirror/lang-json').then((module) => module.json());
65
+ },
66
+ }),
67
+ LanguageDescription.of({
68
+ name: 'Markdown',
69
+ extensions: ['md'],
70
+ async load() {
71
+ return import('@codemirror/lang-markdown').then((module) => module.markdown());
72
+ },
73
+ }),
74
+ LanguageDescription.of({
75
+ name: 'Wasm',
76
+ extensions: ['wat'],
77
+ async load() {
78
+ return import('@codemirror/lang-wast').then((module) => module.wast());
79
+ },
80
+ }),
81
+ ];
82
+
83
+ export async function getLanguage(fileName: string) {
84
+ const languageDescription = LanguageDescription.matchFilename(supportedLanguages, fileName);
85
+
86
+ if (languageDescription) {
87
+ return await languageDescription.load();
88
+ }
89
+
90
+ return undefined;
91
+ }
packages/bolt/app/components/editor/codemirror/styles.css ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --cm-backgroundColor: var(--bolt-elements-editor-backgroundColor, var(--bolt-elements-app-backgroundColor));
3
+ --cm-textColor: var(--bolt-elements-editor-textColor, var(--bolt-text-primary));
4
+
5
+ /* Gutter */
6
+
7
+ --cm-gutter-backgroundColor: var(--bolt-elements-editor-gutter-backgroundColor, var(--cm-backgroundColor));
8
+ --cm-gutter-textColor: var(--bolt-elements-editor-gutter-textColor, var(--bolt-text-secondary));
9
+ --cm-gutter-activeLineTextColor: var(--bolt-elements-editor-gutter-activeLineTextColor, var(--cm-gutter-textColor));
10
+
11
+ /* Fold Gutter */
12
+
13
+ --cm-foldGutter-textColor: var(--bolt-elements-editor-foldGutter-textColor, var(--cm-gutter-textColor));
14
+ --cm-foldGutter-textColorHover: var(--bolt-elements-editor-foldGutter-textColorHover, var(--cm-gutter-textColor));
15
+
16
+ /* Active Line */
17
+
18
+ --cm-activeLineBackgroundColor: var(--bolt-elements-editor-activeLineBackgroundColor, rgb(224 231 235 / 30%));
19
+
20
+ /* Cursor */
21
+
22
+ --cm-cursor-width: 2px;
23
+ --cm-cursor-backgroundColor: var(--bolt-elements-editor-cursorColor, var(--bolt-text-primary));
24
+
25
+ /* Matching Brackets */
26
+
27
+ --cm-matching-bracket: var(--bolt-elements-editor-matchingBracketBackgroundColor, rgb(50 140 130 / 0.3));
28
+
29
+ /* Selection */
30
+
31
+ --cm-selection-backgroundColorFocused: var(--bolt-elements-editor-selection-backgroundColor, #42b4ff);
32
+ --cm-selection-backgroundOpacityFocused: var(--bolt-elements-editor-selection-backgroundOpacity, 0.3);
33
+ --cm-selection-backgroundColorBlured: var(--bolt-elements-editor-selection-inactiveBackgroundColor, #c9e9ff);
34
+ --cm-selection-backgroundOpacityBlured: var(--bolt-elements-editor-selection-inactiveBackgroundOpacity, 0.3);
35
+
36
+ /* Panels */
37
+
38
+ --cm-panels-borderColor: var(--bolt-elements-editor-panels-borderColor, var(--bolt-elements-app-borderColor));
39
+
40
+ /* Search */
41
+
42
+ --cm-search-backgroundColor: var(--bolt-elements-editor-search-backgroundColor, var(--cm-backgroundColor));
43
+ --cm-search-textColor: var(--bolt-elements-editor-search-textColor, var(--bolt-elements-app-textColor));
44
+ --cm-search-closeButton-backgroundColor: var(--bolt-elements-editor-search-closeButton-backgroundColor, transparent);
45
+
46
+ --cm-search-closeButton-backgroundColorHover: var(
47
+ --bolt-elements-editor-search-closeButton-backgroundColorHover,
48
+ var(--bolt-background-secondary)
49
+ );
50
+
51
+ --cm-search-closeButton-textColor: var(
52
+ --bolt-elements-editor-search-closeButton-textColor,
53
+ var(--bolt-text-secondary)
54
+ );
55
+
56
+ --cm-search-closeButton-textColorHover: var(
57
+ --bolt-elements-editor-search-closeButton-textColorHover,
58
+ var(--bolt-text-primary)
59
+ );
60
+
61
+ --cm-search-button-backgroundColor: var(
62
+ --bolt-elements-editor-search-button-backgroundColor,
63
+ var(--bolt-background-secondary)
64
+ );
65
+
66
+ --cm-search-button-backgroundColorHover: var(
67
+ --bolt-elements-editor-search-button-backgroundColorHover,
68
+ var(--bolt-background-active)
69
+ );
70
+
71
+ --cm-search-button-textColor: var(--bolt-elements-editor-search-button-textColor, var(--bolt-text-secondary));
72
+ --cm-search-button-textColorHover: var(--bolt-elements-editor-search-button-textColorHover, var(--bolt-text-primary));
73
+ --cm-search-button-borderColor: var(--bolt-elements-editor-search-button-borderColor, transparent);
74
+
75
+ --cm-search-button-borderColorHover: var(
76
+ --bolt-elements-editor-search-button-borderColorHover,
77
+ var(--cm-search-button-borderColor)
78
+ );
79
+
80
+ --cm-search-button-borderColorFocused: var(
81
+ --bolt-elements-editor-search-button-borderColorFocused,
82
+ var(--bolt-border-accent)
83
+ );
84
+
85
+ --cm-search-input-backgroundColor: var(
86
+ --bolt-elements-editor-search-input-backgroundColor,
87
+ var(--bolt-background-primary)
88
+ );
89
+
90
+ --cm-search-input-borderColor: var(
91
+ --bolt-elements-editor-search-input-borderColor,
92
+ var(--bolt-elements-app-borderColor)
93
+ );
94
+
95
+ --cm-search-input-borderColorFocused: var(
96
+ --bolt-elements-editor-search-input-borderColorFocused,
97
+ var(--bolt-border-accent)
98
+ );
99
+
100
+ /* Tooltip */
101
+
102
+ --cm-tooltip-backgroundColor: var(
103
+ --bolt-elements-editor-tooltip-backgroundColor,
104
+ var(--bolt-elements-app-backgroundColor)
105
+ );
106
+
107
+ --cm-tooltip-textColor: var(--bolt-elements-editor-tooltip-textColor, var(--bolt-text-primary));
108
+
109
+ --cm-tooltip-backgroundColorSelected: var(
110
+ --bolt-elements-editor-tooltip-backgroundColorSelected,
111
+ var(--bolt-background-accent)
112
+ );
113
+
114
+ --cm-tooltip-textColorSelected: var(
115
+ --bolt-elements-editor-tooltip-textColorSelected,
116
+ var(--bolt-text-primary-inverted)
117
+ );
118
+
119
+ --cm-tooltip-borderColor: var(--bolt-elements-editor-tooltip-borderColor, var(--bolt-elements-app-borderColor));
120
+ }
121
+
122
+ html[data-theme='light'] {
123
+ --bolt-elements-editor-gutter-textColor: #237893;
124
+ --bolt-elements-editor-gutter-activeLineTextColor: var(--bolt-text-primary);
125
+ --bolt-elements-editor-foldGutter-textColorHover: var(--bolt-text-primary);
126
+ }
127
+
128
+ html[data-theme='dark'] {
129
+ --bolt-elements-editor-gutter-activeLineTextColor: var(--bolt-text-primary);
130
+ --bolt-elements-editor-selection-backgroundOpacityBlured: 0.1;
131
+ --bolt-elements-editor-activeLineBackgroundColor: rgb(50 53 63 / 50%);
132
+ --bolt-elements-editor-foldGutter-textColorHover: var(--bolt-text-primary);
133
+ }
packages/bolt/app/components/editor/codemirror/themes/vscode-dark.ts ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { HighlightStyle } from '@codemirror/language';
2
+ import { tags } from '@lezer/highlight';
3
+
4
+ export const vscodeDarkTheme = HighlightStyle.define([
5
+ {
6
+ tag: [
7
+ tags.keyword,
8
+ tags.operatorKeyword,
9
+ tags.modifier,
10
+ tags.color,
11
+ tags.constant(tags.name),
12
+ tags.standard(tags.name),
13
+ tags.standard(tags.tagName),
14
+ tags.special(tags.brace),
15
+ tags.atom,
16
+ tags.bool,
17
+ tags.special(tags.variableName),
18
+ ],
19
+ color: '#569cd6',
20
+ },
21
+ {
22
+ tag: [tags.controlKeyword, tags.moduleKeyword],
23
+ color: '#c586c0',
24
+ },
25
+ {
26
+ tag: [
27
+ tags.name,
28
+ tags.deleted,
29
+ tags.character,
30
+ tags.macroName,
31
+ tags.propertyName,
32
+ tags.variableName,
33
+ tags.labelName,
34
+ tags.definition(tags.name),
35
+ ],
36
+ color: '#9cdcfe',
37
+ },
38
+ { tag: tags.heading, fontWeight: 'bold', color: '#9cdcfe' },
39
+ {
40
+ tag: [
41
+ tags.typeName,
42
+ tags.className,
43
+ tags.tagName,
44
+ tags.number,
45
+ tags.changed,
46
+ tags.annotation,
47
+ tags.self,
48
+ tags.namespace,
49
+ ],
50
+ color: '#4ec9b0',
51
+ },
52
+ {
53
+ tag: [tags.function(tags.variableName), tags.function(tags.propertyName)],
54
+ color: '#dcdcaa',
55
+ },
56
+ { tag: [tags.number], color: '#b5cea8' },
57
+ {
58
+ tag: [tags.operator, tags.punctuation, tags.separator, tags.url, tags.escape, tags.regexp],
59
+ color: '#d4d4d4',
60
+ },
61
+ {
62
+ tag: [tags.regexp],
63
+ color: '#d16969',
64
+ },
65
+ {
66
+ tag: [tags.special(tags.string), tags.processingInstruction, tags.string, tags.inserted],
67
+ color: '#ce9178',
68
+ },
69
+ { tag: [tags.angleBracket], color: '#808080' },
70
+ { tag: tags.strong, fontWeight: 'bold' },
71
+ { tag: tags.emphasis, fontStyle: 'italic' },
72
+ { tag: tags.strikethrough, textDecoration: 'line-through' },
73
+ { tag: [tags.meta, tags.comment], color: '#6a9955' },
74
+ { tag: tags.link, color: '#6a9955', textDecoration: 'underline' },
75
+ { tag: tags.invalid, color: '#ff0000' },
76
+ ]);
packages/bolt/app/components/ui/IconButton.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import { memo } from 'react';
2
- import { classNames } from '~/utils/classNames';
3
 
4
  type IconSize = 'sm' | 'md' | 'xl' | 'xxl';
5
 
 
1
  import { memo } from 'react';
2
+ import { classNames } from '../../utils/classNames';
3
 
4
  type IconSize = 'sm' | 'md' | 'xl' | 'xxl';
5
 
packages/bolt/app/components/workbench/EditorPanel.tsx ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useStore } from '@nanostores/react';
2
+ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
3
+ import { themeStore } from '../../lib/stores/theme';
4
+ import CodeMirrorEditor from '../editor/codemirror/CodeMirrorEditor';
5
+ import { FileTreePanel } from './FileTreePanel';
6
+
7
+ export function EditorPanel() {
8
+ const theme = useStore(themeStore);
9
+
10
+ return (
11
+ <PanelGroup direction="horizontal">
12
+ <Panel defaultSize={30} minSize={20} collapsible={false}>
13
+ <FileTreePanel />
14
+ </Panel>
15
+ <PanelResizeHandle />
16
+ <Panel defaultSize={70} minSize={20}>
17
+ <CodeMirrorEditor theme={theme} settings={{ tabSize: 2 }} />
18
+ </Panel>
19
+ </PanelGroup>
20
+ );
21
+ }
packages/bolt/app/components/workbench/FileTree.tsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ export function FileTree() {
2
+ return <div>File Tree</div>;
3
+ }
packages/bolt/app/components/workbench/FileTreePanel.tsx ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import { FileTree } from './FileTree';
2
+
3
+ export function FileTreePanel() {
4
+ return (
5
+ <div className="border-r h-full p-4">
6
+ <FileTree />
7
+ </div>
8
+ );
9
+ }
packages/bolt/app/components/workbench/Preview.tsx ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useStore } from '@nanostores/react';
2
+ import { memo, useEffect, useRef, useState } from 'react';
3
+ import { workbenchStore } from '../../lib/stores/workbench';
4
+ import { IconButton } from '../ui/IconButton';
5
+
6
+ export const Preview = memo(() => {
7
+ const iframeRef = useRef<HTMLIFrameElement>(null);
8
+ const [activePreviewIndex] = useState(0);
9
+ const previews = useStore(workbenchStore.previews);
10
+ const activePreview = previews[activePreviewIndex];
11
+
12
+ const [url, setUrl] = useState('');
13
+ const [iframeUrl, setIframeUrl] = useState<string | undefined>();
14
+
15
+ useEffect(() => {
16
+ if (activePreview && !iframeUrl) {
17
+ const { baseUrl } = activePreview;
18
+
19
+ setUrl(baseUrl);
20
+ setIframeUrl(baseUrl);
21
+ }
22
+ }, [activePreview, iframeUrl]);
23
+
24
+ const reloadPreview = () => {
25
+ if (iframeRef.current) {
26
+ iframeRef.current.src = iframeRef.current.src;
27
+ }
28
+ };
29
+
30
+ return (
31
+ <div className="w-full h-full flex flex-col">
32
+ <div className="bg-gray-100 rounded-t-lg p-2 flex items-center space-x-1.5">
33
+ <div className="i-ph:circle-fill text-[#FF5F57]"></div>
34
+ <div className="i-ph:circle-fill text-[#FEBC2E]"></div>
35
+ <div className="i-ph:circle-fill text-[#29CC41]"></div>
36
+ <div className="flex-grow"></div>
37
+ </div>
38
+ <div className="bg-white p-2 flex items-center gap-1">
39
+ <IconButton icon="i-ph:arrow-clockwise" onClick={reloadPreview} />
40
+ <div className="flex items-center gap-1 flex-grow bg-gray-100 rounded-full px-3 py-1 text-sm text-gray-600 hover:bg-gray-200 hover:focus-within:bg-white focus-within:bg-white focus-within:ring-2 focus-within:ring-accent">
41
+ <div className="bg-white rounded-full p-[2px] -ml-1">
42
+ <div className="i-ph:info-bold text-lg"></div>
43
+ </div>
44
+ <input
45
+ className="w-full bg-transparent outline-none"
46
+ type="text"
47
+ value={url}
48
+ onChange={(event) => {
49
+ setUrl(event.target.value);
50
+ }}
51
+ />
52
+ </div>
53
+ </div>
54
+ <div className="flex-1 bg-white border-t">
55
+ {activePreview ? (
56
+ <iframe ref={iframeRef} className="border-none w-full h-full" src={iframeUrl}></iframe>
57
+ ) : (
58
+ <div className="flex w-full h-full justify-center items-center">No preview available</div>
59
+ )}
60
+ </div>
61
+ </div>
62
+ );
63
+ });
packages/bolt/app/components/{workspace/Workspace.client.tsx → workbench/Workbench.client.tsx} RENAMED
@@ -1,14 +1,17 @@
1
  import { useStore } from '@nanostores/react';
2
  import { AnimatePresence, motion, type Variants } from 'framer-motion';
3
- import { IconButton } from '~/components/ui/IconButton';
4
- import { cubicEasingFn } from '~/utils/easings';
5
- import { workspaceStore } from '../../lib/stores/workspace';
 
 
 
6
 
7
  interface WorkspaceProps {
8
  chatStarted?: boolean;
9
  }
10
 
11
- const workspaceVariants = {
12
  closed: {
13
  width: 0,
14
  transition: {
@@ -19,32 +22,43 @@ const workspaceVariants = {
19
  open: {
20
  width: '100%',
21
  transition: {
22
- duration: 0.5,
23
- type: 'spring',
24
  },
25
  },
26
  } satisfies Variants;
27
 
28
- export function Workspace({ chatStarted }: WorkspaceProps) {
29
- const showWorkspace = useStore(workspaceStore.showWorkspace);
30
 
31
  return (
32
  chatStarted && (
33
  <AnimatePresence>
34
- {showWorkspace && (
35
- <motion.div initial="closed" animate="open" exit="closed" variants={workspaceVariants}>
36
- <div className="fixed top-[calc(var(--header-height)+1.5rem)] bottom-6 w-[50vw] mr-4 z-0">
37
- <div className="bg-white border border-gray-200 shadow-sm rounded-lg overflow-hidden absolute inset-0 right-8">
38
- <header className="px-3 py-2 border-b border-gray-200">
39
  <IconButton
40
  icon="i-ph:x-circle"
41
  className="ml-auto"
42
  size="xxl"
43
  onClick={() => {
44
- workspaceStore.showWorkspace.set(false);
45
  }}
46
  />
47
- </header>
 
 
 
 
 
 
 
 
 
 
 
48
  </div>
49
  </div>
50
  </motion.div>
 
1
  import { useStore } from '@nanostores/react';
2
  import { AnimatePresence, motion, type Variants } from 'framer-motion';
3
+ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
4
+ import { workbenchStore } from '../../lib/stores/workbench';
5
+ import { cubicEasingFn } from '../../utils/easings';
6
+ import { IconButton } from '../ui/IconButton';
7
+ import { EditorPanel } from './EditorPanel';
8
+ import { Preview } from './Preview';
9
 
10
  interface WorkspaceProps {
11
  chatStarted?: boolean;
12
  }
13
 
14
+ const workbenchVariants = {
15
  closed: {
16
  width: 0,
17
  transition: {
 
22
  open: {
23
  width: '100%',
24
  transition: {
25
+ duration: 0.2,
26
+ ease: cubicEasingFn,
27
  },
28
  },
29
  } satisfies Variants;
30
 
31
+ export function Workbench({ chatStarted }: WorkspaceProps) {
32
+ const showWorkbench = useStore(workbenchStore.showWorkbench);
33
 
34
  return (
35
  chatStarted && (
36
  <AnimatePresence>
37
+ {showWorkbench && (
38
+ <motion.div initial="closed" animate="open" exit="closed" variants={workbenchVariants}>
39
+ <div className="fixed top-[calc(var(--header-height)+1.5rem)] bottom-[calc(1.5rem-1px)] w-[50vw] mr-4 z-0">
40
+ <div className="flex flex-col bg-white border border-gray-200 shadow-sm rounded-lg overflow-hidden absolute inset-0 right-8">
41
+ <div className="px-3 py-2 border-b border-gray-200">
42
  <IconButton
43
  icon="i-ph:x-circle"
44
  className="ml-auto"
45
  size="xxl"
46
  onClick={() => {
47
+ workbenchStore.showWorkbench.set(false);
48
  }}
49
  />
50
+ </div>
51
+ <div className="flex-1 overflow-hidden">
52
+ <PanelGroup direction="vertical">
53
+ <Panel defaultSize={50} minSize={20}>
54
+ <EditorPanel />
55
+ </Panel>
56
+ <PanelResizeHandle />
57
+ <Panel defaultSize={50} minSize={20}>
58
+ <Preview />
59
+ </Panel>
60
+ </PanelGroup>
61
+ </div>
62
  </div>
63
  </div>
64
  </motion.div>
packages/bolt/app/lib/.server/llm/constants.ts ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ // see https://docs.anthropic.com/en/docs/about-claude/models
2
+ export const MAX_TOKENS = 8192;
packages/bolt/app/lib/.server/llm/prompts.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const systemPrompt = `
2
  You are Bolt, an expert AI assistant and exceptional senior software developer with vast knowledge across multiple programming languages, frameworks, and best practices.
3
 
4
  <system_constraints>
@@ -22,34 +22,45 @@ You are Bolt, an expert AI assistant and exceptional senior software developer w
22
 
23
  - Shell commands to run including dependencies to install using a package manager (NPM)
24
  - Files to create and their contents
 
25
 
26
  <artifact_instructions>
27
- 1. Think BEFORE creating an artifact.
28
 
29
- 2. Wrap the content in opening and closing \`<boltArtifact>\` tags. These tags contain more specific \`<boltAction>\` elements.
30
 
31
- 3. Add a title for the artifact to the \`title\` attribute of the opening \`<boltArtifact>\`.
32
 
33
- 3. Use \`<boltAction>\` tags to define specific actions to perform.
34
 
35
- 4. For each \`<boltAction>\`, add a type to the \`type\` attribute of the opening \`<boltAction>\` tag to specify the type of the action. Assign one of the following values to the \`type\` attribute:
36
 
37
- - shell: For running shell commands. When Using \`npx\`, ALWAYS provide the \`--yes\` flag!
38
 
39
- - file: For writing new files or updating existing files. For each file add a \`path\` attribute to the opening \`<boltArtifact>\` tag to specify the file path. The content of the the file artifact is the file contents.
40
 
41
- 4. The order of the actions is VERY IMPORTANT. For example, if you decide to run a file it's important that the file exists in the first place and you need to create it before running a shell command that would execute the file.
42
 
43
- 5. ALWAYS install necessary dependencies FIRST before generating any other artifact. If that requires a \`package.json\` then you should create that first!
 
 
 
 
 
 
 
 
44
 
45
  IMPORTANT: Add all required dependencies to the \`package.json\` already and try to avoid \`npm i <pkg>\` if possible!
46
 
47
- 5. Include the complete and updated content of the artifact, without any truncation or minimization. Don't use "// rest of the code remains the same...".
48
 
49
- 6. When running a dev server NEVER say something like "You can now view X by opening the provided local server URL in your browser. The preview will be opened automatically or by the user manually!
50
  </artifact_instructions>
51
  </artifact_info>
52
 
 
 
53
  NEVER use the word "artifact". For example:
54
  - DO NOT SAY: "This artifact sets up a simple Snake game using HTML, CSS, and JavaScript."
55
  - INSTEAD SAY: "We set up a simple Snake game using HTML, CSS, and JavaScript."
@@ -69,16 +80,10 @@ Here are some examples of correct usage of artifacts:
69
  <assistant_response>
70
  Certainly, I can help you create a JavaScript function to calculate the factorial of a number.
71
 
72
- <boltArtifact title="JavaScript Factorial Function">
73
- <boltAction type="file" path="index.js">
74
  function factorial(n) {
75
- if (n === 0 || n === 1) {
76
- return 1;
77
- } else if (n < 0) {
78
- return "Factorial is not defined for negative numbers";
79
- } else {
80
- return n * factorial(n - 1);
81
- }
82
  }
83
 
84
  ...
@@ -97,8 +102,8 @@ Here are some examples of correct usage of artifacts:
97
  <assistant_response>
98
  Certainly! I'd be happy to help you build a snake game using JavaScript and HTML5 Canvas. This will be a basic implementation that you can later expand upon. Let's create the game step by step.
99
 
100
- <boltArtifact title="Snake Game in HTML and JavaScript">
101
- <boltAction type="file" path="package.json">
102
  {
103
  "name": "snake",
104
  "scripts": {
@@ -112,7 +117,7 @@ Here are some examples of correct usage of artifacts:
112
  npm install --save-dev vite
113
  </boltAction>
114
 
115
- <boltAction type="file" path="index.html">
116
  ...
117
  </boltAction>
118
 
@@ -131,8 +136,8 @@ Here are some examples of correct usage of artifacts:
131
  <assistant_response>
132
  Certainly! I'll create a bouncing ball with real gravity using React. We'll use the react-spring library for physics-based animations.
133
 
134
- <boltArtifact title="Bouncing Ball with Gravity in React">
135
- <boltAction type="file" path="package.json">
136
  {
137
  "name": "bouncing-ball",
138
  "private": true,
@@ -157,19 +162,19 @@ Here are some examples of correct usage of artifacts:
157
  }
158
  </boltAction>
159
 
160
- <boltAction type="file" path="index.html">
161
  ...
162
  </boltAction>
163
 
164
- <boltAction type="file" path="src/main.jsx">
165
  ...
166
  </boltAction>
167
 
168
- <boltAction type="file" path="src/index.css">
169
  ...
170
  </boltAction>
171
 
172
- <boltAction type="file" path="src/App.jsx">
173
  ...
174
  </boltAction>
175
 
 
1
+ export const getSystemPrompt = (cwd: string = '/home/project') => `
2
  You are Bolt, an expert AI assistant and exceptional senior software developer with vast knowledge across multiple programming languages, frameworks, and best practices.
3
 
4
  <system_constraints>
 
22
 
23
  - Shell commands to run including dependencies to install using a package manager (NPM)
24
  - Files to create and their contents
25
+ - Folders to create if necessary
26
 
27
  <artifact_instructions>
28
+ 1. Think BEFORE creating an artifact
29
 
30
+ 2. The current working directory is \`${cwd}\`.
31
 
32
+ 3. Wrap the content in opening and closing \`<boltArtifact>\` tags. These tags contain more specific \`<boltAction>\` elements.
33
 
34
+ 4. Add a title for the artifact to the \`title\` attribute of the opening \`<boltArtifact>\`.
35
 
36
+ 5. Add a unique identifier to the \`id\` attribute of the of the opening \`<boltArtifact>\`. For updates, reuse the prior identifier. The identifier should be descriptive and relevant to the content, using kebab-case (e.g., "example-code-snippet"). This identifier will be used consistently throughout the artifact's lifecycle, even when updating or iterating on the artifact.
37
 
38
+ 6. Use \`<boltAction>\` tags to define specific actions to perform.
39
 
40
+ 7. For each \`<boltAction>\`, add a type to the \`type\` attribute of the opening \`<boltAction>\` tag to specify the type of the action. Assign one of the following values to the \`type\` attribute:
41
 
42
+ - shell: For running shell commands.
43
 
44
+ - When Using \`npx\`, ALWAYS provide the \`--yes\` flag.
45
+ - When running multiple shell commands, use \`&&\` to run them sequentially.
46
+ - Do NOT re-run a dev command if there is one that starts a dev server and new dependencies were installed. If a dev server has started already, assume that installing dependencies will be executed in a different process and will be picked up by the dev server.
47
+
48
+ - file: For writing new files or updating existing files. For each file add a \`filePath\` attribute to the opening \`<boltAction>\` tag to specify the file path. The content of the file artifact is the file contents. All file paths MUST BE relative to the current working directory.
49
+
50
+ 8. The order of the actions is VERY IMPORTANT. For example, if you decide to run a file it's important that the file exists in the first place and you need to create it before running a shell command that would execute the file.
51
+
52
+ 9. ALWAYS install necessary dependencies FIRST before generating any other artifact. If that requires a \`package.json\` then you should create that first!
53
 
54
  IMPORTANT: Add all required dependencies to the \`package.json\` already and try to avoid \`npm i <pkg>\` if possible!
55
 
56
+ 10. Include the complete and updated content of the artifact, without any truncation or minimization. Don't use "// rest of the code remains the same...".
57
 
58
+ 11. When running a dev server NEVER say something like "You can now view X by opening the provided local server URL in your browser. The preview will be opened automatically or by the user manually!
59
  </artifact_instructions>
60
  </artifact_info>
61
 
62
+ BEST PRACTICES: Follow coding best practices. Whenever creating files, split functionality into smaller modules instead of placing everything in a single large file. If possible, files should be as small as possible, with functionality extracted into separate modules. This is VERY IMPORTANT so that updates to the project can be done to smaller modules without re-generating large files!
63
+
64
  NEVER use the word "artifact". For example:
65
  - DO NOT SAY: "This artifact sets up a simple Snake game using HTML, CSS, and JavaScript."
66
  - INSTEAD SAY: "We set up a simple Snake game using HTML, CSS, and JavaScript."
 
80
  <assistant_response>
81
  Certainly, I can help you create a JavaScript function to calculate the factorial of a number.
82
 
83
+ <boltArtifact id="factorial-function" title="JavaScript Factorial Function">
84
+ <boltAction type="file" filePath="index.js">
85
  function factorial(n) {
86
+ ...
 
 
 
 
 
 
87
  }
88
 
89
  ...
 
102
  <assistant_response>
103
  Certainly! I'd be happy to help you build a snake game using JavaScript and HTML5 Canvas. This will be a basic implementation that you can later expand upon. Let's create the game step by step.
104
 
105
+ <boltArtifact id="snake-game" title="Snake Game in HTML and JavaScript">
106
+ <boltAction type="file" filePath="package.json">
107
  {
108
  "name": "snake",
109
  "scripts": {
 
117
  npm install --save-dev vite
118
  </boltAction>
119
 
120
+ <boltAction type="file" filePath="index.html">
121
  ...
122
  </boltAction>
123
 
 
136
  <assistant_response>
137
  Certainly! I'll create a bouncing ball with real gravity using React. We'll use the react-spring library for physics-based animations.
138
 
139
+ <boltArtifact id="bouncing-ball-react" title="Bouncing Ball with Gravity in React">
140
+ <boltAction type="file" filePath="package.json">
141
  {
142
  "name": "bouncing-ball",
143
  "private": true,
 
162
  }
163
  </boltAction>
164
 
165
+ <boltAction type="file" filePath="index.html">
166
  ...
167
  </boltAction>
168
 
169
+ <boltAction type="file" filePath="src/main.jsx">
170
  ...
171
  </boltAction>
172
 
173
+ <boltAction type="file" filePath="src/index.css">
174
  ...
175
  </boltAction>
176
 
177
+ <boltAction type="file" filePath="src/App.jsx">
178
  ...
179
  </boltAction>
180
 
packages/bolt/app/lib/.server/llm/stream-text.ts ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { streamText as _streamText, convertToCoreMessages } from 'ai';
2
+ import { getAPIKey } from '../llm/api-key';
3
+ import { getAnthropicModel } from '../llm/model';
4
+ import { MAX_TOKENS } from './constants';
5
+ import { getSystemPrompt } from './prompts';
6
+
7
+ interface ToolResult<Name extends string, Args, Result> {
8
+ toolCallId: string;
9
+ toolName: Name;
10
+ args: Args;
11
+ result: Result;
12
+ }
13
+
14
+ interface Message {
15
+ role: 'user' | 'assistant';
16
+ content: string;
17
+ toolInvocations?: ToolResult<string, unknown, unknown>[];
18
+ }
19
+
20
+ export type Messages = Message[];
21
+
22
+ export type StreamingOptions = Omit<Parameters<typeof _streamText>[0], 'model'>;
23
+
24
+ export function streamText(messages: Messages, env: Env, options?: StreamingOptions) {
25
+ return _streamText({
26
+ model: getAnthropicModel(getAPIKey(env)),
27
+ system: getSystemPrompt(),
28
+ maxTokens: MAX_TOKENS,
29
+ headers: {
30
+ 'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15',
31
+ },
32
+ messages: convertToCoreMessages(messages),
33
+ onFinish: ({ finishReason, usage, warnings }) => {
34
+ console.log({ finishReason, usage, warnings });
35
+ },
36
+ ...options,
37
+ });
38
+ }
packages/bolt/app/lib/hooks/useMessageParser.ts CHANGED
@@ -1,23 +1,28 @@
1
  import type { Message } from 'ai';
2
  import { useCallback, useState } from 'react';
3
- import { StreamingMessageParser } from '~/lib/runtime/message-parser';
4
- import { workspaceStore } from '~/lib/stores/workspace';
5
- import { createScopedLogger } from '~/utils/logger';
6
 
7
  const logger = createScopedLogger('useMessageParser');
8
 
9
  const messageParser = new StreamingMessageParser({
10
  callbacks: {
11
- onArtifactOpen: (messageId, { title }) => {
12
- logger.debug('onArtifactOpen', title);
13
- workspaceStore.updateArtifact(messageId, { title, closed: false });
 
 
14
  },
15
- onArtifactClose: (messageId) => {
16
- logger.debug('onArtifactClose');
17
- workspaceStore.updateArtifact(messageId, { closed: true });
 
18
  },
19
- onAction: (messageId, { type, path, content }) => {
20
- console.log('ACTION', messageId, { type, path, content });
 
 
21
  },
22
  },
23
  });
 
1
  import type { Message } from 'ai';
2
  import { useCallback, useState } from 'react';
3
+ import { createScopedLogger } from '../../utils/logger';
4
+ import { StreamingMessageParser } from '../runtime/message-parser';
5
+ import { workbenchStore } from '../stores/workbench';
6
 
7
  const logger = createScopedLogger('useMessageParser');
8
 
9
  const messageParser = new StreamingMessageParser({
10
  callbacks: {
11
+ onArtifactOpen: (data) => {
12
+ logger.trace('onArtifactOpen', data);
13
+
14
+ workbenchStore.showWorkbench.set(true);
15
+ workbenchStore.addArtifact(data);
16
  },
17
+ onArtifactClose: (data) => {
18
+ logger.trace('onArtifactClose');
19
+
20
+ workbenchStore.updateArtifact(data, { closed: true });
21
  },
22
+ onAction: (data) => {
23
+ logger.trace('onAction', data);
24
+
25
+ workbenchStore.runAction(data);
26
  },
27
  },
28
  });
packages/bolt/app/lib/hooks/usePromptEnhancer.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { useState } from 'react';
2
- import { createScopedLogger } from '~/utils/logger';
3
 
4
  const logger = createScopedLogger('usePromptEnhancement');
5
 
 
1
  import { useState } from 'react';
2
+ import { createScopedLogger } from '../../utils/logger';
3
 
4
  const logger = createScopedLogger('usePromptEnhancement');
5
 
packages/bolt/app/lib/runtime/action-runner.ts ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { WebContainer } from '@webcontainer/api';
2
+ import * as nodePath from 'node:path';
3
+ import { createScopedLogger } from '../../utils/logger';
4
+ import type { ActionCallbackData } from './message-parser';
5
+
6
+ const logger = createScopedLogger('ActionRunner');
7
+
8
+ export class ActionRunner {
9
+ #webcontainer: Promise<WebContainer>;
10
+
11
+ constructor(webcontainerPromise: Promise<WebContainer>) {
12
+ this.#webcontainer = webcontainerPromise;
13
+ }
14
+
15
+ async runAction({ action }: ActionCallbackData, abortSignal?: AbortSignal) {
16
+ logger.trace('Running action', action);
17
+
18
+ const { content } = action;
19
+
20
+ const webcontainer = await this.#webcontainer;
21
+
22
+ switch (action.type) {
23
+ case 'file': {
24
+ let folder = nodePath.dirname(action.filePath);
25
+
26
+ // remove trailing slashes
27
+ folder = folder.replace(/\/$/g, '');
28
+
29
+ if (folder !== '.') {
30
+ try {
31
+ await webcontainer.fs.mkdir(folder, { recursive: true });
32
+ logger.debug('Created folder', folder);
33
+ } catch (error) {
34
+ logger.error('Failed to create folder\n', error);
35
+ }
36
+ }
37
+
38
+ try {
39
+ await webcontainer.fs.writeFile(action.filePath, content);
40
+ logger.debug(`File written ${action.filePath}`);
41
+ } catch (error) {
42
+ logger.error('Failed to write file\n', error);
43
+ }
44
+
45
+ break;
46
+ }
47
+ case 'shell': {
48
+ const process = await webcontainer.spawn('jsh', ['-c', content]);
49
+
50
+ abortSignal?.addEventListener('abort', () => {
51
+ process.kill();
52
+ });
53
+
54
+ process.output.pipeTo(
55
+ new WritableStream({
56
+ write(data) {
57
+ console.log(data);
58
+ },
59
+ }),
60
+ );
61
+
62
+ const exitCode = await process.exit;
63
+
64
+ logger.debug(`Process terminated with code ${exitCode}`);
65
+ }
66
+ }
67
+ }
68
+ }
packages/bolt/app/lib/runtime/message-parser.spec.ts CHANGED
@@ -38,28 +38,30 @@ describe('StreamingMessageParser', () => {
38
  ['Before <boltArtifactt>foo</boltArtifact> After', 'Before <boltArtifactt>foo</boltArtifact> After'],
39
  ['Before <boltArtifact title="Some title">foo</boltArtifact> After', 'Before After'],
40
  [
41
- 'Before <boltArtifact title="Some title"><boltAction type="shell">npm install</boltAction></boltArtifact> After',
42
  'Before After',
43
  [{ type: 'shell', content: 'npm install' }],
44
  ],
45
  [
46
- 'Before <boltArtifact title="Some title"><boltAction type="shell">npm install</boltAction><boltAction type="file" path="index.js">some content</boltAction></boltArtifact> After',
47
  'Before After',
48
  [
49
  { type: 'shell', content: 'npm install' },
50
- { type: 'file', path: 'index.js', content: 'some content\n' },
51
  ],
52
  ],
53
  ])('should correctly parse chunks and strip out bolt artifacts', (input, expected, expectedActions = []) => {
54
  let actionCounter = 0;
55
 
56
- const testId = 'test_id';
 
57
 
58
  const parser = new StreamingMessageParser({
59
  artifactElement: '',
60
  callbacks: {
61
- onAction: (id, action) => {
62
- expect(testId).toBe(id);
 
63
  expect(action).toEqual(expectedActions[actionCounter]);
64
  actionCounter++;
65
  },
@@ -75,7 +77,7 @@ describe('StreamingMessageParser', () => {
75
  for (const chunk of chunks) {
76
  message += chunk;
77
 
78
- result += parser.parse(testId, message);
79
  }
80
 
81
  expect(actionCounter).toBe(expectedActions.length);
 
38
  ['Before <boltArtifactt>foo</boltArtifact> After', 'Before <boltArtifactt>foo</boltArtifact> After'],
39
  ['Before <boltArtifact title="Some title">foo</boltArtifact> After', 'Before After'],
40
  [
41
+ 'Before <boltArtifact title="Some title" id="artifact_1"><boltAction type="shell">npm install</boltAction></boltArtifact> After',
42
  'Before After',
43
  [{ type: 'shell', content: 'npm install' }],
44
  ],
45
  [
46
+ 'Before <boltArtifact title="Some title" id="artifact_1"><boltAction type="shell">npm install</boltAction><boltAction type="file" filePath="index.js">some content</boltAction></boltArtifact> After',
47
  'Before After',
48
  [
49
  { type: 'shell', content: 'npm install' },
50
+ { type: 'file', filePath: 'index.js', content: 'some content\n' },
51
  ],
52
  ],
53
  ])('should correctly parse chunks and strip out bolt artifacts', (input, expected, expectedActions = []) => {
54
  let actionCounter = 0;
55
 
56
+ const expectedArtifactId = 'artifact_1';
57
+ const expectedMessageId = 'message_1';
58
 
59
  const parser = new StreamingMessageParser({
60
  artifactElement: '',
61
  callbacks: {
62
+ onAction: ({ artifactId, messageId, action }) => {
63
+ expect(artifactId).toBe(expectedArtifactId);
64
+ expect(messageId).toBe(expectedMessageId);
65
  expect(action).toEqual(expectedActions[actionCounter]);
66
  actionCounter++;
67
  },
 
77
  for (const chunk of chunks) {
78
  message += chunk;
79
 
80
+ result += parser.parse(expectedMessageId, message);
81
  }
82
 
83
  expect(actionCounter).toBe(expectedActions.length);
packages/bolt/app/lib/runtime/message-parser.ts CHANGED
@@ -1,24 +1,30 @@
 
 
 
 
 
1
  const ARTIFACT_TAG_OPEN = '<boltArtifact';
2
  const ARTIFACT_TAG_CLOSE = '</boltArtifact>';
3
  const ARTIFACT_ACTION_TAG_OPEN = '<boltAction';
4
  const ARTIFACT_ACTION_TAG_CLOSE = '</boltAction>';
5
 
6
- interface BoltArtifact {
7
- title: string;
8
- }
9
-
10
- type ArtifactOpenCallback = (messageId: string, artifact: BoltArtifact) => void;
11
- type ArtifactCloseCallback = (messageId: string) => void;
12
- type ActionCallback = (messageId: string, action: BoltActionData) => void;
13
 
14
- type ActionType = 'file' | 'shell';
 
 
15
 
16
- export interface BoltActionData {
17
- type?: ActionType;
18
- path?: string;
19
- content: string;
 
20
  }
21
 
 
 
 
 
22
  interface Callbacks {
23
  onArtifactOpen?: ArtifactOpenCallback;
24
  onArtifactClose?: ArtifactCloseCallback;
@@ -32,39 +38,72 @@ interface StreamingMessageParserOptions {
32
  artifactElement?: string | ElementFactory;
33
  }
34
 
 
 
 
 
 
 
 
 
 
35
  export class StreamingMessageParser {
36
- #lastPositions = new Map<string, number>();
37
- #insideArtifact = false;
38
- #insideAction = false;
39
- #currentAction: BoltActionData = { content: '' };
40
 
41
  constructor(private _options: StreamingMessageParserOptions = {}) {}
42
 
43
- parse(id: string, input: string) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  let output = '';
45
- let i = this.#lastPositions.get(id) ?? 0;
46
  let earlyBreak = false;
47
 
48
  while (i < input.length) {
49
- if (this.#insideArtifact) {
50
- if (this.#insideAction) {
 
 
 
 
 
 
51
  const closeIndex = input.indexOf(ARTIFACT_ACTION_TAG_CLOSE, i);
52
 
 
 
53
  if (closeIndex !== -1) {
54
- this.#currentAction.content += input.slice(i, closeIndex);
55
 
56
- let content = this.#currentAction.content.trim();
57
 
58
- if (this.#currentAction.type === 'file') {
59
  content += '\n';
60
  }
61
 
62
- this.#currentAction.content = content;
63
 
64
- this._options.callbacks?.onAction?.(id, this.#currentAction);
 
 
 
 
 
65
 
66
- this.#insideAction = false;
67
- this.#currentAction = { content: '' };
68
 
69
  i = closeIndex + ARTIFACT_ACTION_TAG_CLOSE.length;
70
  } else {
@@ -79,17 +118,39 @@ export class StreamingMessageParser {
79
 
80
  if (actionEndIndex !== -1) {
81
  const actionTag = input.slice(actionOpenIndex, actionEndIndex + 1);
82
- this.#currentAction.type = this.#extractAttribute(actionTag, 'type') as ActionType;
83
- this.#currentAction.path = this.#extractAttribute(actionTag, 'path');
84
- this.#insideAction = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  i = actionEndIndex + 1;
86
  } else {
87
  break;
88
  }
89
  } else if (artifactCloseIndex !== -1) {
90
- this.#insideArtifact = false;
91
 
92
- this._options.callbacks?.onArtifactClose?.(id);
 
93
 
94
  i = artifactCloseIndex + ARTIFACT_TAG_CLOSE.length;
95
  } else {
@@ -118,12 +179,30 @@ export class StreamingMessageParser {
118
  const artifactTag = input.slice(i, openTagEnd + 1);
119
 
120
  const artifactTitle = this.#extractAttribute(artifactTag, 'title') as string;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
- this.#insideArtifact = true;
123
 
124
- this._options.callbacks?.onArtifactOpen?.(id, { title: artifactTitle });
125
 
126
- output += this._options.artifactElement ?? `<div class="__boltArtifact__" data-message-id="${id}"></div>`;
 
 
127
 
128
  i = openTagEnd + 1;
129
  } else {
@@ -153,16 +232,13 @@ export class StreamingMessageParser {
153
  }
154
  }
155
 
156
- this.#lastPositions.set(id, i);
157
 
158
  return output;
159
  }
160
 
161
  reset() {
162
- this.#lastPositions.clear();
163
- this.#insideArtifact = false;
164
- this.#insideAction = false;
165
- this.#currentAction = { content: '' };
166
  }
167
 
168
  #extractAttribute(tag: string, attributeName: string): string | undefined {
 
1
+ import type { ActionType, BoltAction, BoltActionData, FileAction, ShellAction } from '../../types/actions';
2
+ import type { BoltArtifactData } from '../../types/artifact';
3
+ import { createScopedLogger } from '../../utils/logger';
4
+ import { unreachable } from '../../utils/unreachable';
5
+
6
  const ARTIFACT_TAG_OPEN = '<boltArtifact';
7
  const ARTIFACT_TAG_CLOSE = '</boltArtifact>';
8
  const ARTIFACT_ACTION_TAG_OPEN = '<boltAction';
9
  const ARTIFACT_ACTION_TAG_CLOSE = '</boltAction>';
10
 
11
+ const logger = createScopedLogger('MessageParser');
 
 
 
 
 
 
12
 
13
+ export interface ArtifactCallbackData extends BoltArtifactData {
14
+ messageId: string;
15
+ }
16
 
17
+ export interface ActionCallbackData {
18
+ artifactId: string;
19
+ messageId: string;
20
+ actionId: string;
21
+ action: BoltAction;
22
  }
23
 
24
+ type ArtifactOpenCallback = (data: ArtifactCallbackData) => void;
25
+ type ArtifactCloseCallback = (data: ArtifactCallbackData) => void;
26
+ type ActionCallback = (data: ActionCallbackData) => void;
27
+
28
  interface Callbacks {
29
  onArtifactOpen?: ArtifactOpenCallback;
30
  onArtifactClose?: ArtifactCloseCallback;
 
38
  artifactElement?: string | ElementFactory;
39
  }
40
 
41
+ interface MessageState {
42
+ position: number;
43
+ insideArtifact: boolean;
44
+ insideAction: boolean;
45
+ currentArtifact?: BoltArtifactData;
46
+ currentAction: BoltActionData;
47
+ actionId: number;
48
+ }
49
+
50
  export class StreamingMessageParser {
51
+ #messages = new Map<string, MessageState>();
 
 
 
52
 
53
  constructor(private _options: StreamingMessageParserOptions = {}) {}
54
 
55
+ parse(messageId: string, input: string) {
56
+ let state = this.#messages.get(messageId);
57
+
58
+ if (!state) {
59
+ state = {
60
+ position: 0,
61
+ insideAction: false,
62
+ insideArtifact: false,
63
+ currentAction: { content: '' },
64
+ actionId: 0,
65
+ };
66
+
67
+ this.#messages.set(messageId, state);
68
+ }
69
+
70
  let output = '';
71
+ let i = state.position;
72
  let earlyBreak = false;
73
 
74
  while (i < input.length) {
75
+ if (state.insideArtifact) {
76
+ const currentArtifact = state.currentArtifact;
77
+
78
+ if (currentArtifact === undefined) {
79
+ unreachable('Artifact not initialized');
80
+ }
81
+
82
+ if (state.insideAction) {
83
  const closeIndex = input.indexOf(ARTIFACT_ACTION_TAG_CLOSE, i);
84
 
85
+ const currentAction = state.currentAction;
86
+
87
  if (closeIndex !== -1) {
88
+ currentAction.content += input.slice(i, closeIndex);
89
 
90
+ let content = currentAction.content.trim();
91
 
92
+ if ('type' in currentAction && currentAction.type === 'file') {
93
  content += '\n';
94
  }
95
 
96
+ currentAction.content = content;
97
 
98
+ this._options.callbacks?.onAction?.({
99
+ artifactId: currentArtifact.id,
100
+ messageId,
101
+ actionId: String(state.actionId++),
102
+ action: currentAction as BoltAction,
103
+ });
104
 
105
+ state.insideAction = false;
106
+ state.currentAction = { content: '' };
107
 
108
  i = closeIndex + ARTIFACT_ACTION_TAG_CLOSE.length;
109
  } else {
 
118
 
119
  if (actionEndIndex !== -1) {
120
  const actionTag = input.slice(actionOpenIndex, actionEndIndex + 1);
121
+
122
+ const actionType = this.#extractAttribute(actionTag, 'type') as ActionType;
123
+
124
+ const actionAttributes = {
125
+ type: actionType,
126
+ content: '',
127
+ };
128
+
129
+ if (actionType === 'file') {
130
+ const filePath = this.#extractAttribute(actionTag, 'filePath') as string;
131
+
132
+ if (!filePath) {
133
+ logger.debug('File path not specified');
134
+ }
135
+
136
+ (actionAttributes as FileAction).filePath = filePath;
137
+ } else if (actionType !== 'shell') {
138
+ logger.warn(`Unknown action type '${actionType}'`);
139
+ }
140
+
141
+ state.currentAction = actionAttributes as FileAction | ShellAction;
142
+
143
+ state.insideAction = true;
144
+
145
  i = actionEndIndex + 1;
146
  } else {
147
  break;
148
  }
149
  } else if (artifactCloseIndex !== -1) {
150
+ this._options.callbacks?.onArtifactClose?.({ messageId, ...currentArtifact });
151
 
152
+ state.insideArtifact = false;
153
+ state.currentArtifact = undefined;
154
 
155
  i = artifactCloseIndex + ARTIFACT_TAG_CLOSE.length;
156
  } else {
 
179
  const artifactTag = input.slice(i, openTagEnd + 1);
180
 
181
  const artifactTitle = this.#extractAttribute(artifactTag, 'title') as string;
182
+ const artifactId = this.#extractAttribute(artifactTag, 'id') as string;
183
+
184
+ if (!artifactTitle) {
185
+ logger.warn('Artifact title missing');
186
+ }
187
+
188
+ if (!artifactId) {
189
+ logger.warn('Artifact id missing');
190
+ }
191
+
192
+ state.insideArtifact = true;
193
+
194
+ const currentArtifact = {
195
+ id: artifactId,
196
+ title: artifactTitle,
197
+ } satisfies BoltArtifactData;
198
 
199
+ state.currentArtifact = currentArtifact;
200
 
201
+ this._options.callbacks?.onArtifactOpen?.({ messageId, ...currentArtifact });
202
 
203
+ output +=
204
+ this._options.artifactElement ??
205
+ `<div class="__boltArtifact__" data-artifact-id="${artifactId}" data-message-id="${messageId}"></div>`;
206
 
207
  i = openTagEnd + 1;
208
  } else {
 
232
  }
233
  }
234
 
235
+ state.position = i;
236
 
237
  return output;
238
  }
239
 
240
  reset() {
241
+ this.#messages.clear();
 
 
 
242
  }
243
 
244
  #extractAttribute(tag: string, attributeName: string): string | undefined {
packages/bolt/app/lib/stores/previews.ts ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { WebContainer } from '@webcontainer/api';
2
+ import { atom } from 'nanostores';
3
+
4
+ export interface PreviewInfo {
5
+ port: number;
6
+ ready: boolean;
7
+ baseUrl: string;
8
+ }
9
+
10
+ export class PreviewsStore {
11
+ #availablePreviews = new Map<number, PreviewInfo>();
12
+ #webcontainer: Promise<WebContainer>;
13
+
14
+ previews = atom<PreviewInfo[]>([]);
15
+
16
+ constructor(webcontainerPromise: Promise<WebContainer>) {
17
+ this.#webcontainer = webcontainerPromise;
18
+
19
+ this.#init();
20
+ }
21
+
22
+ async #init() {
23
+ const webcontainer = await this.#webcontainer;
24
+
25
+ webcontainer.on('port', (port, type, url) => {
26
+ let previewInfo = this.#availablePreviews.get(port);
27
+
28
+ const previews = this.previews.get();
29
+
30
+ if (!previewInfo) {
31
+ previewInfo = { port, ready: type === 'open', baseUrl: url };
32
+ this.#availablePreviews.set(port, previewInfo);
33
+ previews.push(previewInfo);
34
+ }
35
+
36
+ previewInfo.ready = type === 'open';
37
+ previewInfo.baseUrl = url;
38
+
39
+ this.previews.set([...previews]);
40
+ });
41
+ }
42
+ }
packages/bolt/app/lib/stores/theme.ts ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { atom } from 'nanostores';
2
+
3
+ export type Theme = 'dark' | 'light';
4
+
5
+ export const kTheme = 'bolt_theme';
6
+
7
+ export function themeIsDark() {
8
+ return themeStore.get() === 'dark';
9
+ }
10
+
11
+ export const themeStore = atom<Theme>(initStore());
12
+
13
+ function initStore() {
14
+ if (!import.meta.env.SSR) {
15
+ const persistedTheme = localStorage.getItem(kTheme) as Theme | undefined;
16
+ const themeAttribute = document.querySelector('html')?.getAttribute('data-theme');
17
+
18
+ return persistedTheme ?? (themeAttribute as Theme) ?? 'light';
19
+ }
20
+
21
+ return 'light';
22
+ }
23
+
24
+ export function toggleTheme() {
25
+ const currentTheme = themeStore.get();
26
+ const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
27
+
28
+ themeStore.set(newTheme);
29
+
30
+ localStorage.setItem(kTheme, newTheme);
31
+
32
+ document.querySelector('html')?.setAttribute('data-theme', newTheme);
33
+ }
packages/bolt/app/lib/stores/workbench.ts ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { atom, map, type MapStore, type WritableAtom } from 'nanostores';
2
+ import type { BoltAction } from '../../types/actions';
3
+ import { unreachable } from '../../utils/unreachable';
4
+ import { ActionRunner } from '../runtime/action-runner';
5
+ import type { ActionCallbackData, ArtifactCallbackData } from '../runtime/message-parser';
6
+ import { webcontainer } from '../webcontainer';
7
+ import { PreviewsStore } from './previews';
8
+
9
+ export type RunningState = BoltAction & {
10
+ status: 'running' | 'complete' | 'pending' | 'aborted';
11
+ abort?: () => void;
12
+ };
13
+
14
+ export type FailedState = BoltAction & {
15
+ status: 'failed';
16
+ error: string;
17
+ abort?: () => void;
18
+ };
19
+
20
+ export type ActionState = RunningState | FailedState;
21
+
22
+ export type ActionStateUpdate =
23
+ | { status: 'running' | 'complete' | 'pending' | 'aborted'; abort?: () => void }
24
+ | { status: 'failed'; error: string; abort?: () => void }
25
+ | { abort?: () => void };
26
+
27
+ export interface ArtifactState {
28
+ title: string;
29
+ closed: boolean;
30
+ currentActionPromise: Promise<void>;
31
+ actions: MapStore<Record<string, ActionState>>;
32
+ }
33
+
34
+ type Artifacts = MapStore<Record<string, ArtifactState>>;
35
+
36
+ export class WorkbenchStore {
37
+ #actionRunner = new ActionRunner(webcontainer);
38
+ #previewsStore = new PreviewsStore(webcontainer);
39
+
40
+ artifacts: Artifacts = import.meta.hot?.data.artifacts ?? map({});
41
+
42
+ showWorkbench: WritableAtom<boolean> = import.meta.hot?.data.showWorkbench ?? atom(false);
43
+
44
+ get previews() {
45
+ return this.#previewsStore.previews;
46
+ }
47
+
48
+ setShowWorkbench(show: boolean) {
49
+ this.showWorkbench.set(show);
50
+ }
51
+
52
+ addArtifact({ id, messageId, title }: ArtifactCallbackData) {
53
+ const artifacts = this.artifacts.get();
54
+ const artifactKey = getArtifactKey(id, messageId);
55
+ const artifact = artifacts[artifactKey];
56
+
57
+ if (artifact) {
58
+ return;
59
+ }
60
+
61
+ this.artifacts.setKey(artifactKey, {
62
+ title,
63
+ closed: false,
64
+ actions: map({}),
65
+ currentActionPromise: Promise.resolve(),
66
+ });
67
+ }
68
+
69
+ updateArtifact({ id, messageId }: ArtifactCallbackData, state: Partial<ArtifactState>) {
70
+ const artifacts = this.artifacts.get();
71
+ const key = getArtifactKey(id, messageId);
72
+ const artifact = artifacts[key];
73
+
74
+ if (!artifact) {
75
+ return;
76
+ }
77
+
78
+ this.artifacts.setKey(key, { ...artifact, ...state });
79
+ }
80
+
81
+ async runAction(data: ActionCallbackData) {
82
+ const { artifactId, messageId, actionId } = data;
83
+
84
+ const artifacts = this.artifacts.get();
85
+ const key = getArtifactKey(artifactId, messageId);
86
+ const artifact = artifacts[key];
87
+
88
+ if (!artifact) {
89
+ unreachable('Artifact not found');
90
+ }
91
+
92
+ const actions = artifact.actions.get();
93
+ const action = actions[actionId];
94
+
95
+ if (action) {
96
+ return;
97
+ }
98
+
99
+ artifact.actions.setKey(actionId, { ...data.action, status: 'pending' });
100
+
101
+ artifact.currentActionPromise = artifact.currentActionPromise.then(async () => {
102
+ try {
103
+ let abortController: AbortController | undefined;
104
+
105
+ if (data.action.type === 'shell') {
106
+ abortController = new AbortController();
107
+ }
108
+
109
+ let aborted = false;
110
+
111
+ this.#updateAction(key, actionId, {
112
+ status: 'running',
113
+ abort: () => {
114
+ aborted = true;
115
+ abortController?.abort();
116
+ },
117
+ });
118
+
119
+ await this.#actionRunner.runAction(data, abortController?.signal);
120
+
121
+ this.#updateAction(key, actionId, { status: aborted ? 'aborted' : 'complete' });
122
+ } catch (error) {
123
+ this.#updateAction(key, actionId, { status: 'failed', error: 'Action failed' });
124
+
125
+ throw error;
126
+ }
127
+ });
128
+ }
129
+
130
+ #updateAction(artifactId: string, actionId: string, newState: ActionStateUpdate) {
131
+ const artifacts = this.artifacts.get();
132
+ const artifact = artifacts[artifactId];
133
+
134
+ if (!artifact) {
135
+ return;
136
+ }
137
+
138
+ const actions = artifact.actions.get();
139
+
140
+ artifact.actions.setKey(actionId, { ...actions[actionId], ...newState });
141
+ }
142
+ }
143
+
144
+ export function getArtifactKey(artifactId: string, messageId: string) {
145
+ return `${artifactId}_${messageId}`;
146
+ }
147
+
148
+ export const workbenchStore = new WorkbenchStore();
149
+
150
+ if (import.meta.hot) {
151
+ import.meta.hot.data.artifacts = workbenchStore.artifacts;
152
+ import.meta.hot.data.showWorkbench = workbenchStore.showWorkbench;
153
+ }
packages/bolt/app/lib/stores/workspace.ts DELETED
@@ -1,42 +0,0 @@
1
- import type { WebContainer } from '@webcontainer/api';
2
- import { atom, map, type MapStore, type WritableAtom } from 'nanostores';
3
- import { webcontainer } from '~/lib/webcontainer';
4
-
5
- interface WorkspaceStoreOptions {
6
- webcontainer: Promise<WebContainer>;
7
- }
8
-
9
- interface ArtifactState {
10
- title: string;
11
- closed: boolean;
12
- actions: any /* TODO */;
13
- }
14
-
15
- export class WorkspaceStore {
16
- #webcontainer: Promise<WebContainer>;
17
-
18
- artifacts: MapStore<Record<string, ArtifactState>> = import.meta.hot?.data.artifacts ?? map({});
19
- showWorkspace: WritableAtom<boolean> = import.meta.hot?.data.showWorkspace ?? atom(false);
20
-
21
- constructor({ webcontainer }: WorkspaceStoreOptions) {
22
- this.#webcontainer = webcontainer;
23
- }
24
-
25
- updateArtifact(id: string, state: Partial<ArtifactState>) {
26
- const artifacts = this.artifacts.get();
27
- const artifact = artifacts[id];
28
-
29
- this.artifacts.setKey(id, { ...artifact, ...state });
30
- }
31
-
32
- runAction() {
33
- // TODO
34
- }
35
- }
36
-
37
- export const workspaceStore = new WorkspaceStore({ webcontainer });
38
-
39
- if (import.meta.hot) {
40
- import.meta.hot.data.artifacts = workspaceStore.artifacts;
41
- import.meta.hot.data.showWorkspace = workspaceStore.showWorkspace;
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
packages/bolt/app/lib/webcontainer/index.ts CHANGED
@@ -21,8 +21,9 @@ if (!import.meta.env.SSR) {
21
  import.meta.hot?.data.webcontainer ??
22
  Promise.resolve()
23
  .then(() => WebContainer.boot({ workdirName: 'project' }))
24
- .then(() => {
25
  webcontainerContext.loaded = true;
 
26
  });
27
 
28
  if (import.meta.hot) {
 
21
  import.meta.hot?.data.webcontainer ??
22
  Promise.resolve()
23
  .then(() => WebContainer.boot({ workdirName: 'project' }))
24
+ .then((webcontainer) => {
25
  webcontainerContext.loaded = true;
26
+ return webcontainer;
27
  });
28
 
29
  if (import.meta.hot) {
packages/bolt/app/root.tsx CHANGED
@@ -1,7 +1,11 @@
 
1
  import type { LinksFunction } from '@remix-run/cloudflare';
2
  import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
3
  import tailwindReset from '@unocss/reset/tailwind-compat.css?url';
4
- import globalStyles from '~/styles/index.scss?url';
 
 
 
5
 
6
  import 'virtual:uno.css';
7
 
@@ -28,14 +32,31 @@ export const links: LinksFunction = () => [
28
  },
29
  ];
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  export function Layout({ children }: { children: React.ReactNode }) {
 
 
32
  return (
33
- <html lang="en">
34
  <head>
35
  <meta charSet="utf-8" />
36
  <meta name="viewport" content="width=device-width, initial-scale=1" />
37
  <Meta />
38
  <Links />
 
39
  </head>
40
  <body>
41
  {children}
 
1
+ import { useStore } from '@nanostores/react';
2
  import type { LinksFunction } from '@remix-run/cloudflare';
3
  import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
4
  import tailwindReset from '@unocss/reset/tailwind-compat.css?url';
5
+ import { themeStore } from './lib/stores/theme';
6
+ import { stripIndents } from './utils/stripIndent';
7
+
8
+ import globalStyles from './styles/index.scss?url';
9
 
10
  import 'virtual:uno.css';
11
 
 
32
  },
33
  ];
34
 
35
+ const inlineThemeCode = stripIndents`
36
+ setTutorialKitTheme();
37
+
38
+ function setTutorialKitTheme() {
39
+ let theme = localStorage.getItem('bolt_theme');
40
+
41
+ if (!theme) {
42
+ theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
43
+ }
44
+
45
+ document.querySelector('html')?.setAttribute('data-theme', theme);
46
+ }
47
+ `;
48
+
49
  export function Layout({ children }: { children: React.ReactNode }) {
50
+ const theme = useStore(themeStore);
51
+
52
  return (
53
+ <html lang="en" data-theme={theme}>
54
  <head>
55
  <meta charSet="utf-8" />
56
  <meta name="viewport" content="width=device-width, initial-scale=1" />
57
  <Meta />
58
  <Links />
59
+ <script dangerouslySetInnerHTML={{ __html: inlineThemeCode }} />
60
  </head>
61
  <body>
62
  {children}
packages/bolt/app/routes/_index.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import { json, redirect, type LoaderFunctionArgs, type MetaFunction } from '@remix-run/cloudflare';
2
  import { ClientOnly } from 'remix-utils/client-only';
3
- import { BaseChat } from '~/components/chat/BaseChat';
4
- import { Chat } from '~/components/chat/Chat.client';
5
- import { Header } from '~/components/Header';
6
- import { isAuthenticated } from '~/lib/.server/sessions';
7
 
8
  export const meta: MetaFunction = () => {
9
  return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];
 
1
  import { json, redirect, type LoaderFunctionArgs, type MetaFunction } from '@remix-run/cloudflare';
2
  import { ClientOnly } from 'remix-utils/client-only';
3
+ import { BaseChat } from '../components/chat/BaseChat';
4
+ import { Chat } from '../components/chat/Chat.client';
5
+ import { Header } from '../components/Header';
6
+ import { isAuthenticated } from '../lib/.server/sessions';
7
 
8
  export const meta: MetaFunction = () => {
9
  return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];
packages/bolt/app/routes/api.chat.ts CHANGED
@@ -1,36 +1,11 @@
1
  import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
- import { convertToCoreMessages, streamText } from 'ai';
3
- import { getAPIKey } from '~/lib/.server/llm/api-key';
4
- import { getAnthropicModel } from '~/lib/.server/llm/model';
5
- import { systemPrompt } from '~/lib/.server/llm/prompts';
6
-
7
- interface ToolResult<Name extends string, Args, Result> {
8
- toolCallId: string;
9
- toolName: Name;
10
- args: Args;
11
- result: Result;
12
- }
13
-
14
- interface Message {
15
- role: 'user' | 'assistant';
16
- content: string;
17
- toolInvocations?: ToolResult<string, unknown, unknown>[];
18
- }
19
 
20
  export async function action({ context, request }: ActionFunctionArgs) {
21
- const { messages } = await request.json<{ messages: Message[] }>();
22
 
23
  try {
24
- const result = await streamText({
25
- model: getAnthropicModel(getAPIKey(context.cloudflare.env)),
26
- messages: convertToCoreMessages(messages),
27
- toolChoice: 'none',
28
- onFinish: ({ finishReason, usage, warnings }) => {
29
- console.log({ finishReason, usage, warnings });
30
- },
31
- system: systemPrompt,
32
- });
33
-
34
  return result.toAIStreamResponse();
35
  } catch (error) {
36
  console.log(error);
 
1
  import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
+ import { streamText, type Messages } from '../lib/.server/llm/stream-text';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  export async function action({ context, request }: ActionFunctionArgs) {
5
+ const { messages } = await request.json<{ messages: Messages }>();
6
 
7
  try {
8
+ const result = await streamText(messages, context.cloudflare.env, { toolChoice: 'none' });
 
 
 
 
 
 
 
 
 
9
  return result.toAIStreamResponse();
10
  } catch (error) {
11
  console.log(error);
packages/bolt/app/routes/api.enhancer.ts CHANGED
@@ -1,9 +1,7 @@
1
  import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
- import { StreamingTextResponse, convertToCoreMessages, parseStreamPart, streamText } from 'ai';
3
- import { getAPIKey } from '~/lib/.server/llm/api-key';
4
- import { getAnthropicModel } from '~/lib/.server/llm/model';
5
- import { systemPrompt } from '~/lib/.server/llm/prompts';
6
- import { stripIndents } from '~/utils/stripIndent';
7
 
8
  const encoder = new TextEncoder();
9
  const decoder = new TextDecoder();
@@ -12,30 +10,23 @@ export async function action({ context, request }: ActionFunctionArgs) {
12
  const { message } = await request.json<{ message: string }>();
13
 
14
  try {
15
- const result = await streamText({
16
- model: getAnthropicModel(getAPIKey(context.cloudflare.env)),
17
- system: systemPrompt,
18
- messages: convertToCoreMessages([
19
  {
20
  role: 'user',
21
  content: stripIndents`
22
- I want you to improve the user prompt that is wrapped in \`<original_prompt>\` tags.
23
 
24
- IMPORTANT: Only respond with the improved prompt and nothing else!
25
 
26
- <original_prompt>
27
- ${message}
28
- </original_prompt>
29
- `,
30
  },
31
- ]),
32
- });
33
-
34
- if (import.meta.env.DEV) {
35
- result.usage.then((usage) => {
36
- console.log('Usage', usage);
37
- });
38
- }
39
 
40
  const transformStream = new TransformStream({
41
  transform(chunk, controller) {
 
1
  import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
+ import { StreamingTextResponse, parseStreamPart } from 'ai';
3
+ import { streamText } from '../lib/.server/llm/stream-text';
4
+ import { stripIndents } from '../utils/stripIndent';
 
 
5
 
6
  const encoder = new TextEncoder();
7
  const decoder = new TextDecoder();
 
10
  const { message } = await request.json<{ message: string }>();
11
 
12
  try {
13
+ const result = await streamText(
14
+ [
 
 
15
  {
16
  role: 'user',
17
  content: stripIndents`
18
+ I want you to improve the user prompt that is wrapped in \`<original_prompt>\` tags.
19
 
20
+ IMPORTANT: Only respond with the improved prompt and nothing else!
21
 
22
+ <original_prompt>
23
+ ${message}
24
+ </original_prompt>
25
+ `,
26
  },
27
+ ],
28
+ context.cloudflare.env,
29
+ );
 
 
 
 
 
30
 
31
  const transformStream = new TransformStream({
32
  transform(chunk, controller) {
packages/bolt/app/routes/login.tsx CHANGED
@@ -6,8 +6,8 @@ import {
6
  type TypedResponse,
7
  } from '@remix-run/cloudflare';
8
  import { Form, useActionData } from '@remix-run/react';
9
- import { verifyPassword } from '~/lib/.server/login';
10
- import { createUserSession, isAuthenticated } from '~/lib/.server/sessions';
11
 
12
  interface Errors {
13
  password?: string;
 
6
  type TypedResponse,
7
  } from '@remix-run/cloudflare';
8
  import { Form, useActionData } from '@remix-run/react';
9
+ import { verifyPassword } from '../lib/.server/login';
10
+ import { createUserSession, isAuthenticated } from '../lib/.server/sessions';
11
 
12
  interface Errors {
13
  password?: string;
packages/bolt/app/styles/variables.scss CHANGED
@@ -1,12 +1,30 @@
 
1
  :root,
2
  :root[data-theme='light'] {
3
- /* Color Tokens */
4
- --bolt-background-primary: theme('colors.gray.50');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  }
6
 
 
7
  :root,
8
  :root[data-theme='dark'] {
9
- /* Color Tokens */
10
  --bolt-background-primary: theme('colors.gray.50');
11
  }
12
 
@@ -20,4 +38,7 @@
20
 
21
  /* App */
22
  --bolt-elements-app-backgroundColor: var(--bolt-background-primary);
 
 
 
23
  }
 
1
+ /* Color Tokens Light Theme */
2
  :root,
3
  :root[data-theme='light'] {
4
+ --bolt-background-primary: theme('colors.gray.0');
5
+ --bolt-background-secondary: theme('colors.gray.50');
6
+ --bolt-background-active: theme('colors.gray.200');
7
+ --bolt-background-accent: theme('colors.accent.600');
8
+ --bolt-background-accent-secondary: theme('colors.accent.600');
9
+ --bolt-background-accent-active: theme('colors.accent.500');
10
+
11
+ --bolt-text-primary: theme('colors.gray.800');
12
+ --bolt-text-primary-inverted: theme('colors.gray.0');
13
+ --bolt-text-secondary: theme('colors.gray.600');
14
+ --bolt-text-secondary-inverted: theme('colors.gray.200');
15
+ --bolt-text-disabled: theme('colors.gray.400');
16
+ --bolt-text-accent: theme('colors.accent.600');
17
+ --bolt-text-positive: theme('colors.positive.700');
18
+ --bolt-text-warning: theme('colors.warning.600');
19
+ --bolt-text-negative: theme('colors.negative.600');
20
+
21
+ --bolt-border-primary: theme('colors.gray.200');
22
+ --bolt-border-accent: theme('colors.accent.600');
23
  }
24
 
25
+ /* Color Tokens Dark Theme */
26
  :root,
27
  :root[data-theme='dark'] {
 
28
  --bolt-background-primary: theme('colors.gray.50');
29
  }
30
 
 
38
 
39
  /* App */
40
  --bolt-elements-app-backgroundColor: var(--bolt-background-primary);
41
+ --bolt-elements-app-borderColor: var(--bolt-border-primary);
42
+ --bolt-elements-app-textColor: var(--bolt-text-primary);
43
+ --bolt-elements-app-linkColor: var(--bolt-text-accent);
44
  }
packages/bolt/app/types/actions.ts ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export type ActionType = 'file' | 'shell';
2
+
3
+ export interface BaseAction {
4
+ content: string;
5
+ }
6
+
7
+ export interface FileAction extends BaseAction {
8
+ type: 'file';
9
+ filePath: string;
10
+ }
11
+
12
+ export interface ShellAction extends BaseAction {
13
+ type: 'shell';
14
+ }
15
+
16
+ export type BoltAction = FileAction | ShellAction;
17
+
18
+ export type BoltActionData = BoltAction | BaseAction;
packages/bolt/app/types/artifact.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ export interface BoltArtifactData {
2
+ id: string;
3
+ title: string;
4
+ }
packages/bolt/app/types/theme.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ export type Theme = 'dark' | 'light';
packages/bolt/app/utils/debounce.ts ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export function debounce<Args extends any[]>(fn: (...args: Args) => void, delay = 100) {
2
+ if (delay === 0) {
3
+ return fn;
4
+ }
5
+
6
+ let timer: number | undefined;
7
+
8
+ return function <U>(this: U, ...args: Args) {
9
+ const context = this;
10
+
11
+ clearTimeout(timer);
12
+
13
+ timer = window.setTimeout(() => {
14
+ fn.apply(context, args);
15
+ }, delay);
16
+ };
17
+ }
packages/bolt/app/utils/unreachable.ts ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ export function unreachable(message: string): never {
2
+ throw new Error(`Unreachable: ${message}`);
3
+ }
packages/bolt/package.json CHANGED
@@ -9,31 +9,47 @@
9
  "build": "remix vite:build",
10
  "dev": "remix vite:dev",
11
  "test": "vitest --run",
 
12
  "start": "bindings=$(./bindings.sh) && wrangler pages dev ./build/client $bindings",
13
  "typecheck": "tsc",
14
  "typegen": "wrangler types",
15
  "preview": "pnpm run build && pnpm run start"
16
  },
17
  "dependencies": {
18
- "@ai-sdk/anthropic": "^0.0.27",
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  "@iconify-json/ph": "^1.1.13",
20
  "@iconify-json/svg-spinners": "^1.1.2",
 
21
  "@nanostores/react": "^0.7.2",
22
  "@remix-run/cloudflare": "^2.10.2",
23
  "@remix-run/cloudflare-pages": "^2.10.2",
24
  "@remix-run/react": "^2.10.2",
25
  "@unocss/reset": "^0.61.0",
26
- "@webcontainer/api": "^1.2.0",
27
  "@xterm/addon-fit": "^0.10.0",
28
  "@xterm/addon-web-links": "^0.11.0",
29
  "@xterm/xterm": "^5.5.0",
30
- "ai": "^3.2.16",
31
  "framer-motion": "^11.2.12",
32
  "isbot": "^4.1.0",
33
  "nanostores": "^0.10.3",
34
  "react": "^18.2.0",
35
  "react-dom": "^18.2.0",
36
  "react-markdown": "^9.0.1",
 
37
  "rehype-raw": "^7.0.0",
38
  "remark-gfm": "^4.0.0",
39
  "remix-utils": "^7.6.0",
@@ -49,6 +65,8 @@
49
  "unified": "^11.0.5",
50
  "unocss": "^0.61.3",
51
  "vite": "^5.3.1",
 
 
52
  "vite-tsconfig-paths": "^4.3.2",
53
  "wrangler": "^3.63.2",
54
  "zod": "^3.23.8"
 
9
  "build": "remix vite:build",
10
  "dev": "remix vite:dev",
11
  "test": "vitest --run",
12
+ "test:watch": "vitest",
13
  "start": "bindings=$(./bindings.sh) && wrangler pages dev ./build/client $bindings",
14
  "typecheck": "tsc",
15
  "typegen": "wrangler types",
16
  "preview": "pnpm run build && pnpm run start"
17
  },
18
  "dependencies": {
19
+ "@ai-sdk/anthropic": "^0.0.30",
20
+ "@codemirror/autocomplete": "^6.17.0",
21
+ "@codemirror/commands": "^6.6.0",
22
+ "@codemirror/lang-css": "^6.2.1",
23
+ "@codemirror/lang-html": "^6.4.9",
24
+ "@codemirror/lang-javascript": "^6.2.2",
25
+ "@codemirror/lang-json": "^6.0.1",
26
+ "@codemirror/lang-markdown": "^6.2.5",
27
+ "@codemirror/lang-sass": "^6.0.2",
28
+ "@codemirror/lang-wast": "^6.0.2",
29
+ "@codemirror/language": "^6.10.2",
30
+ "@codemirror/search": "^6.5.6",
31
+ "@codemirror/state": "^6.4.1",
32
+ "@codemirror/view": "^6.28.4",
33
  "@iconify-json/ph": "^1.1.13",
34
  "@iconify-json/svg-spinners": "^1.1.2",
35
+ "@lezer/highlight": "^1.2.0",
36
  "@nanostores/react": "^0.7.2",
37
  "@remix-run/cloudflare": "^2.10.2",
38
  "@remix-run/cloudflare-pages": "^2.10.2",
39
  "@remix-run/react": "^2.10.2",
40
  "@unocss/reset": "^0.61.0",
41
+ "@webcontainer/api": "^1.3.0-internal.1",
42
  "@xterm/addon-fit": "^0.10.0",
43
  "@xterm/addon-web-links": "^0.11.0",
44
  "@xterm/xterm": "^5.5.0",
45
+ "ai": "^3.2.27",
46
  "framer-motion": "^11.2.12",
47
  "isbot": "^4.1.0",
48
  "nanostores": "^0.10.3",
49
  "react": "^18.2.0",
50
  "react-dom": "^18.2.0",
51
  "react-markdown": "^9.0.1",
52
+ "react-resizable-panels": "^2.0.20",
53
  "rehype-raw": "^7.0.0",
54
  "remark-gfm": "^4.0.0",
55
  "remix-utils": "^7.6.0",
 
65
  "unified": "^11.0.5",
66
  "unocss": "^0.61.3",
67
  "vite": "^5.3.1",
68
+ "vite-plugin-node-polyfills": "^0.22.0",
69
+ "vite-plugin-optimize-css-modules": "^1.1.0",
70
  "vite-tsconfig-paths": "^4.3.2",
71
  "wrangler": "^3.63.2",
72
  "zod": "^3.23.8"
packages/bolt/uno.config.ts CHANGED
@@ -111,6 +111,9 @@ export default defineConfig({
111
  elements: {
112
  app: {
113
  backgroundColor: 'var(--bolt-elements-app-backgroundColor)',
 
 
 
114
  },
115
  },
116
  },
 
111
  elements: {
112
  app: {
113
  backgroundColor: 'var(--bolt-elements-app-backgroundColor)',
114
+ borderColor: 'var(--bolt-elements-app-borderColor)',
115
+ textColor: 'var(--bolt-elements-app-textColor)',
116
+ linkColor: 'var(--bolt-elements-app-linkColor)',
117
  },
118
  },
119
  },
packages/bolt/vite.config.ts CHANGED
@@ -1,11 +1,16 @@
1
  import { cloudflareDevProxyVitePlugin as remixCloudflareDevProxy, vitePlugin as remixVitePlugin } from '@remix-run/dev';
2
  import UnoCSS from 'unocss/vite';
3
  import { defineConfig } from 'vite';
 
 
4
  import tsconfigPaths from 'vite-tsconfig-paths';
5
 
6
  export default defineConfig((config) => {
7
  return {
8
  plugins: [
 
 
 
9
  config.mode !== 'test' && remixCloudflareDevProxy(),
10
  remixVitePlugin({
11
  future: {
@@ -16,6 +21,7 @@ export default defineConfig((config) => {
16
  }),
17
  UnoCSS(),
18
  tsconfigPaths(),
 
19
  ],
20
  };
21
  });
 
1
  import { cloudflareDevProxyVitePlugin as remixCloudflareDevProxy, vitePlugin as remixVitePlugin } from '@remix-run/dev';
2
  import UnoCSS from 'unocss/vite';
3
  import { defineConfig } from 'vite';
4
+ import { nodePolyfills } from 'vite-plugin-node-polyfills';
5
+ import { optimizeCssModules } from 'vite-plugin-optimize-css-modules';
6
  import tsconfigPaths from 'vite-tsconfig-paths';
7
 
8
  export default defineConfig((config) => {
9
  return {
10
  plugins: [
11
+ nodePolyfills({
12
+ include: ['path'],
13
+ }),
14
  config.mode !== 'test' && remixCloudflareDevProxy(),
15
  remixVitePlugin({
16
  future: {
 
21
  }),
22
  UnoCSS(),
23
  tsconfigPaths(),
24
+ config.mode === 'production' && optimizeCssModules({ apply: 'build' }),
25
  ],
26
  };
27
  });
pnpm-lock.yaml CHANGED
@@ -36,14 +36,56 @@ importers:
36
  packages/bolt:
37
  dependencies:
38
  '@ai-sdk/anthropic':
39
- specifier: ^0.0.27
40
- version: 0.0.27([email protected])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  '@iconify-json/ph':
42
  specifier: ^1.1.13
43
  version: 1.1.13
44
  '@iconify-json/svg-spinners':
45
  specifier: ^1.1.2
46
  version: 1.1.2
 
 
 
47
  '@nanostores/react':
48
  specifier: ^0.7.2
49
@@ -60,8 +102,8 @@ importers:
60
  specifier: ^0.61.0
61
  version: 0.61.0
62
  '@webcontainer/api':
63
- specifier: ^1.2.0
64
- version: 1.2.0
65
  '@xterm/addon-fit':
66
  specifier: ^0.10.0
67
  version: 0.10.0(@xterm/[email protected])
@@ -72,8 +114,8 @@ importers:
72
  specifier: ^5.5.0
73
  version: 5.5.0
74
  ai:
75
- specifier: ^3.2.16
76
77
  framer-motion:
78
  specifier: ^11.2.12
79
@@ -92,6 +134,9 @@ importers:
92
  react-markdown:
93
  specifier: ^9.0.1
94
  version: 9.0.1(@types/[email protected])([email protected])
 
 
 
95
  rehype-raw:
96
  specifier: ^7.0.0
97
  version: 7.0.0
@@ -132,6 +177,12 @@ importers:
132
  vite:
133
  specifier: ^5.3.1
134
  version: 5.3.1(@types/[email protected])([email protected])
 
 
 
 
 
 
135
  vite-tsconfig-paths:
136
  specifier: ^4.3.2
137
@@ -144,14 +195,23 @@ importers:
144
 
145
  packages:
146
 
147
- '@ai-sdk/[email protected].27':
148
- resolution: {integrity: sha512-SmWf4YnyAmPag6XMXK8rhvmwvzuD6+KW9jeyvvIHAQDDu3HqOKTuAEQ19UOSLkThyEqV6PyO4GAwbrTeOKpecA==}
 
 
 
 
 
 
149
  engines: {node: '>=18'}
150
  peerDependencies:
151
  zod: ^3.0.0
 
 
 
152
 
153
- '@ai-sdk/[email protected].0':
154
- resolution: {integrity: sha512-Akq7MmGQII8xAuoVjJns/n/2BTUrF6qaXIj/3nEuXk/hPSdETlLWRSrjrTmLpte1VIPE5ecNzTALST+6nz47UQ==}
155
  engines: {node: '>=18'}
156
  peerDependencies:
157
  zod: ^3.0.0
@@ -159,12 +219,16 @@ packages:
159
  zod:
160
  optional: true
161
 
162
- '@ai-sdk/[email protected].11':
163
- resolution: {integrity: sha512-VTipPQ92Moa5Ovg/nZIc8yNoIFfukZjUHZcQMduJbiUh3CLQyrBAKTEV9AwjPy8wgVxj3+GZjon0yyOJKhfp5g==}
164
  engines: {node: '>=18'}
165
 
166
- '@ai-sdk/react@0.0.16':
167
- resolution: {integrity: sha512-PUPjI4XB8or2m2NvRU8SBzGfSwjlJ19Mdde8LkeppFoNj++53kgM4BiniAsVRl8v8WNGZ55rrsLyY5g8h+gfeA==}
 
 
 
 
168
  engines: {node: '>=18'}
169
  peerDependencies:
170
  react: ^18 || ^19
@@ -175,8 +239,8 @@ packages:
175
  zod:
176
  optional: true
177
 
178
- '@ai-sdk/[email protected].11':
179
- resolution: {integrity: sha512-8L4YoNNmDWmdnqtKnFdmaDZ+bIf1m160NXSPMEDhhWvp+t1SGMS/eLemuYEkDnlO18hhM/0IKX8lbQEyz7QYPQ==}
180
  engines: {node: '>=18'}
181
  peerDependencies:
182
  solid-js: ^1.7.7
@@ -184,8 +248,8 @@ packages:
184
  solid-js:
185
  optional: true
186
 
187
- '@ai-sdk/[email protected].12':
188
- resolution: {integrity: sha512-pSgIQhu0H2MRuoi/oj/5sq7UIK7Nm1oLRmZQ0tz2iQeqO2uo3Pe0si4n7lo8gb8gOMCyqJtqteb13A7rAlusfQ==}
189
  engines: {node: '>=18'}
190
  peerDependencies:
191
  svelte: ^3.0.0 || ^4.0.0
@@ -193,8 +257,8 @@ packages:
193
  svelte:
194
  optional: true
195
 
196
- '@ai-sdk/[email protected].9':
197
- resolution: {integrity: sha512-RdC68yG1abpFQgpm3Tcn4hMbRzpRj0BXbphhwSpMwHqPQu4c/n82tYYJvhGB+rRXs/qLftLBS1NtrhqEYSVZTg==}
198
  engines: {node: '>=18'}
199
  peerDependencies:
200
  zod: ^3.0.0
@@ -202,8 +266,8 @@ packages:
202
  zod:
203
  optional: true
204
 
205
- '@ai-sdk/[email protected].11':
206
- resolution: {integrity: sha512-YXqrFCIo8iOCsTBagEAAH6YIgveZCvS66Lm+WcyYVC5ehwx4Hn2vSayaRUiqQiHxDkF/IdETURRKki/cGbp/eg==}
207
  engines: {node: '>=18'}
208
  peerDependencies:
209
  vue: ^3.3.4
@@ -424,6 +488,53 @@ packages:
424
  '@cloudflare/[email protected]':
425
  resolution: {integrity: sha512-CQD8YS6evRob7LChvIX3gE3zYo0KVgaLDOu1SwNP1BVIS2Sa0b+FC8S1e1hhrNN8/E4chYlVN+FDAgA4KRDUEQ==}
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  '@commitlint/[email protected]':
428
  resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==}
429
  engines: {node: '>=v18'}
@@ -994,6 +1105,33 @@ packages:
994
  '@jspm/[email protected]':
995
  resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==}
996
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
997
  '@mdx-js/[email protected]':
998
  resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==}
999
 
@@ -1032,6 +1170,10 @@ packages:
1032
  resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
1033
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
1034
 
 
 
 
 
1035
  '@pkgjs/[email protected]':
1036
  resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
1037
  engines: {node: '>=14'}
@@ -1169,6 +1311,15 @@ packages:
1169
  '@remix-run/[email protected]':
1170
  resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==}
1171
 
 
 
 
 
 
 
 
 
 
1172
  '@rollup/[email protected]':
1173
  resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
1174
  engines: {node: '>=14.0.0'}
@@ -1550,8 +1701,8 @@ packages:
1550
  '@web3-storage/[email protected]':
1551
  resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==}
1552
 
1553
- '@webcontainer/api@1.2.0':
1554
- resolution: {integrity: sha512-tzoKBd4lLdhHy5GHFpUkl+ndoSba8JqmB7x0ZQFnWfjbcbQOvKQfxA8MEMUYhgqjWHnbrWdAfnBEHz5f5lYG5A==}
1555
 
1556
  '@xterm/[email protected]':
1557
  resolution: {integrity: sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==}
@@ -1599,8 +1750,8 @@ packages:
1599
  resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
1600
  engines: {node: '>=8'}
1601
 
1602
1603
- resolution: {integrity: sha512-kNqnmSQxUm3dcxLv/NoOusoMAq7EK/zahB/N//wkGoawgYqfOUpvz3+uS/FG52tZwMyy4YblVoeuBHpfPWzNDw==}
1604
  engines: {node: '>=18'}
1605
  peerDependencies:
1606
  openai: ^4.42.0
@@ -1673,6 +1824,12 @@ packages:
1673
1674
  resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
1675
 
 
 
 
 
 
 
1676
1677
  resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
1678
  engines: {node: '>=12'}
@@ -1711,6 +1868,12 @@ packages:
1711
1712
  resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
1713
 
 
 
 
 
 
 
1714
1715
  resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
1716
  engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -1725,9 +1888,34 @@ packages:
1725
  resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
1726
  engines: {node: '>=8'}
1727
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1728
1729
  resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==}
1730
 
 
 
 
1731
1732
  resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
1733
  engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@@ -1736,9 +1924,15 @@ packages:
1736
1737
  resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
1738
 
 
 
 
1739
1740
  resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
1741
 
 
 
 
1742
1743
  resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
1744
  engines: {node: '>= 0.8'}
@@ -1819,6 +2013,9 @@ packages:
1819
  resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
1820
  engines: {node: '>=8'}
1821
 
 
 
 
1822
1823
  resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
1824
  engines: {node: '>=6'}
@@ -1891,6 +2088,12 @@ packages:
1891
  resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
1892
  engines: {node: ^14.18.0 || >=16.10.0}
1893
 
 
 
 
 
 
 
1894
1895
  resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
1896
  engines: {node: '>= 0.6'}
@@ -1950,10 +2153,28 @@ packages:
1950
  typescript:
1951
  optional: true
1952
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1953
1954
  resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
1955
  engines: {node: '>= 8'}
1956
 
 
 
 
1957
1958
  resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
1959
  engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
@@ -2033,6 +2254,10 @@ packages:
2033
  resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
2034
  engines: {node: '>= 0.4'}
2035
 
 
 
 
 
2036
2037
  resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
2038
 
@@ -2044,6 +2269,9 @@ packages:
2044
  resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
2045
  engines: {node: '>=6'}
2046
 
 
 
 
2047
2048
  resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
2049
 
@@ -2065,10 +2293,17 @@ packages:
2065
  resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
2066
  engines: {node: '>=0.3.1'}
2067
 
 
 
 
2068
2069
  resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
2070
  engines: {node: '>=8'}
2071
 
 
 
 
 
2072
2073
  resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
2074
  engines: {node: '>=8'}
@@ -2092,6 +2327,9 @@ packages:
2092
2093
  resolution: {integrity: sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==}
2094
 
 
 
 
2095
2096
  resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
2097
 
@@ -2289,10 +2527,17 @@ packages:
2289
  resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
2290
  engines: {node: '>=6'}
2291
 
 
 
 
 
2292
2293
  resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==}
2294
  engines: {node: '>=14.18'}
2295
 
 
 
 
2296
2297
  resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
2298
  engines: {node: '>=10'}
@@ -2534,6 +2779,17 @@ packages:
2534
  resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
2535
  engines: {node: '>= 0.4'}
2536
 
 
 
 
 
 
 
 
 
 
 
 
2537
2538
  resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
2539
  engines: {node: '>= 0.4'}
@@ -2565,6 +2821,9 @@ packages:
2565
2566
  resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
2567
 
 
 
 
2568
2569
  resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==}
2570
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -2579,6 +2838,9 @@ packages:
2579
  resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
2580
  engines: {node: '>= 0.8'}
2581
 
 
 
 
2582
2583
  resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
2584
  engines: {node: '>=10.17.0'}
@@ -2710,6 +2972,10 @@ packages:
2710
  resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
2711
  engines: {node: '>=8'}
2712
 
 
 
 
 
2713
2714
  resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
2715
  engines: {node: '>=0.12.0'}
@@ -2763,6 +3029,10 @@ packages:
2763
2764
  resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
2765
 
 
 
 
 
2766
2767
  resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
2768
  engines: {node: '>=14'}
@@ -2945,6 +3215,9 @@ packages:
2945
2946
  resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
2947
 
 
 
 
2948
2949
  resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
2950
 
@@ -3226,6 +3499,10 @@ packages:
3226
  resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
3227
  engines: {node: '>=8.6'}
3228
 
 
 
 
 
3229
3230
  resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
3231
  engines: {node: '>= 0.6'}
@@ -3262,6 +3539,12 @@ packages:
3262
  engines: {node: '>=16.13'}
3263
  hasBin: true
3264
 
 
 
 
 
 
 
3265
3266
  resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
3267
 
@@ -3374,6 +3657,10 @@ packages:
3374
3375
  resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
3376
 
 
 
 
 
3377
3378
  resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==}
3379
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -3410,6 +3697,18 @@ packages:
3410
  resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
3411
  engines: {node: '>= 0.4'}
3412
 
 
 
 
 
 
 
 
 
 
 
 
 
3413
3414
  resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==}
3415
 
@@ -3444,6 +3743,9 @@ packages:
3444
  resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
3445
  engines: {node: '>=10'}
3446
 
 
 
 
3447
3448
  resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==}
3449
 
@@ -3473,10 +3775,17 @@ packages:
3473
3474
  resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
3475
 
 
 
 
3476
3477
  resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
3478
  engines: {node: '>=6'}
3479
 
 
 
 
 
3480
3481
  resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
3482
 
@@ -3495,6 +3804,9 @@ packages:
3495
  resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
3496
  engines: {node: '>= 0.8'}
3497
 
 
 
 
3498
3499
  resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
3500
  engines: {node: '>=8'}
@@ -3535,6 +3847,10 @@ packages:
3535
  resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
3536
  engines: {node: '>= 14.16'}
3537
 
 
 
 
 
3538
3539
  resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==}
3540
 
@@ -3556,6 +3872,10 @@ packages:
3556
  engines: {node: '>=0.10'}
3557
  hasBin: true
3558
 
 
 
 
 
3559
3560
  resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
3561
 
@@ -3657,6 +3977,10 @@ packages:
3657
3658
  resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
3659
 
 
 
 
 
3660
3661
  resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
3662
  peerDependencies:
@@ -3676,6 +4000,9 @@ packages:
3676
  resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
3677
  engines: {node: '>= 0.10'}
3678
 
 
 
 
3679
3680
  resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==}
3681
 
@@ -3685,6 +4012,9 @@ packages:
3685
3686
  resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==}
3687
 
 
 
 
3688
3689
  resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
3690
  engines: {node: '>=6'}
@@ -3693,9 +4023,23 @@ packages:
3693
  resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
3694
  engines: {node: '>=0.6'}
3695
 
 
 
 
 
 
 
 
 
3696
3697
  resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
3698
 
 
 
 
 
 
 
3699
3700
  resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
3701
  engines: {node: '>= 0.6'}
@@ -3722,6 +4066,12 @@ packages:
3722
  resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
3723
  engines: {node: '>=0.10.0'}
3724
 
 
 
 
 
 
 
3725
3726
  resolution: {integrity: sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==}
3727
  engines: {node: '>=14.0.0'}
@@ -3859,6 +4209,9 @@ packages:
3859
  resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
3860
  engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
3861
 
 
 
 
3862
3863
  resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==}
3864
  deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
@@ -3929,9 +4282,16 @@ packages:
3929
  resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
3930
  engines: {node: '>= 0.4'}
3931
 
 
 
 
3932
3933
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
3934
 
 
 
 
 
3935
3936
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
3937
  engines: {node: '>=8'}
@@ -4029,6 +4389,12 @@ packages:
4029
  resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
4030
  engines: {node: '>=4', npm: '>=6'}
4031
 
 
 
 
 
 
 
4032
4033
  resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
4034
 
@@ -4079,6 +4445,9 @@ packages:
4079
  resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
4080
  engines: {node: '>=8'}
4081
 
 
 
 
4082
4083
  resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==}
4084
 
@@ -4146,6 +4515,10 @@ packages:
4146
4147
  resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
4148
 
 
 
 
 
4149
4150
  resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==}
4151
 
@@ -4205,6 +4578,9 @@ packages:
4205
4206
  resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
4207
 
 
 
 
4208
4209
  resolution: {integrity: sha512-FKFg7A0To1VU4CH9YmSMON5QphK0BXjSoiC7D9yMh+mEEbXLUP9qJ4hEt1qcjKtzncs1OpcnjZO8NgrlVbZH+g==}
4210
 
@@ -4343,6 +4719,9 @@ packages:
4343
4344
  resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
4345
 
 
 
 
4346
4347
  resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==}
4348
  peerDependencies:
@@ -4399,6 +4778,16 @@ packages:
4399
  engines: {node: ^18.0.0 || >=20.0.0}
4400
  hasBin: true
4401
 
 
 
 
 
 
 
 
 
 
 
4402
4403
  resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==}
4404
  peerDependencies:
@@ -4460,6 +4849,9 @@ packages:
4460
  jsdom:
4461
  optional: true
4462
 
 
 
 
4463
4464
  resolution: {integrity: sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==}
4465
  peerDependencies:
@@ -4468,6 +4860,9 @@ packages:
4468
  typescript:
4469
  optional: true
4470
 
 
 
 
4471
4472
  resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
4473
 
@@ -4608,60 +5003,74 @@ packages:
4608
 
4609
  snapshots:
4610
 
4611
 
 
 
 
 
 
4612
  dependencies:
4613
- '@ai-sdk/provider': 0.0.11
4614
- '@ai-sdk/provider-utils': 1.0.0([email protected])
 
 
 
4615
  zod: 3.23.8
4616
 
4617
4618
  dependencies:
4619
- '@ai-sdk/provider': 0.0.11
4620
  eventsource-parser: 1.1.2
4621
  nanoid: 3.3.6
4622
  secure-json-parse: 2.7.0
4623
  optionalDependencies:
4624
  zod: 3.23.8
4625
 
4626
- '@ai-sdk/[email protected].11':
4627
  dependencies:
4628
  json-schema: 0.4.0
4629
 
4630
- '@ai-sdk/react@0.0.16([email protected])([email protected])':
4631
  dependencies:
4632
- '@ai-sdk/provider-utils': 1.0.0([email protected])
4633
- '@ai-sdk/ui-utils': 0.0.9([email protected])
 
 
 
 
4634
  swr: 2.2.0([email protected])
4635
  optionalDependencies:
4636
  react: 18.3.1
4637
  zod: 3.23.8
4638
 
4639
4640
  dependencies:
4641
- '@ai-sdk/ui-utils': 0.0.9([email protected])
4642
  transitivePeerDependencies:
4643
  - zod
4644
 
4645
4646
  dependencies:
4647
- '@ai-sdk/provider-utils': 1.0.0([email protected])
4648
- '@ai-sdk/ui-utils': 0.0.9([email protected])
4649
  sswr: 2.1.0([email protected])
4650
  optionalDependencies:
4651
  svelte: 4.2.18
4652
  transitivePeerDependencies:
4653
  - zod
4654
 
4655
4656
  dependencies:
4657
- '@ai-sdk/provider-utils': 1.0.0([email protected])
4658
  secure-json-parse: 2.7.0
4659
  optionalDependencies:
4660
  zod: 3.23.8
4661
 
4662
4663
  dependencies:
4664
- '@ai-sdk/ui-utils': 0.0.9([email protected])
 
4665
4666
  optionalDependencies:
4667
  vue: 3.4.30([email protected])
@@ -4954,6 +5363,113 @@ snapshots:
4954
 
4955
  '@cloudflare/[email protected]': {}
4956
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4957
4958
  dependencies:
4959
  '@commitlint/format': 19.3.0
@@ -5380,6 +5896,51 @@ snapshots:
5380
 
5381
  '@jspm/[email protected]': {}
5382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5383
  '@mdx-js/[email protected]':
5384
  dependencies:
5385
  '@types/estree-jsx': 1.0.5
@@ -5452,6 +6013,8 @@ snapshots:
5452
  dependencies:
5453
  which: 3.0.1
5454
 
 
 
5455
  '@pkgjs/[email protected]':
5456
  optional: true
5457
 
@@ -5666,6 +6229,14 @@ snapshots:
5666
  dependencies:
5667
  web-streams-polyfill: 3.3.3
5668
 
 
 
 
 
 
 
 
 
5669
5670
  dependencies:
5671
  '@types/estree': 1.0.5
@@ -6188,7 +6759,7 @@ snapshots:
6188
 
6189
  '@web3-storage/[email protected]': {}
6190
 
6191
- '@webcontainer/api@1.2.0': {}
6192
 
6193
  '@xterm/[email protected](@xterm/[email protected])':
6194
  dependencies:
@@ -6232,15 +6803,16 @@ snapshots:
6232
  clean-stack: 2.2.0
6233
  indent-string: 4.0.0
6234
 
6235
6236
  dependencies:
6237
- '@ai-sdk/provider': 0.0.11
6238
- '@ai-sdk/provider-utils': 1.0.0([email protected])
6239
- '@ai-sdk/react': 0.0.16([email protected])([email protected])
6240
- '@ai-sdk/solid': 0.0.11([email protected])
6241
- '@ai-sdk/svelte': 0.0.12([email protected])([email protected])
6242
- '@ai-sdk/ui-utils': 0.0.9([email protected])
6243
 
6244
  eventsource-parser: 1.1.2
6245
  json-schema: 0.4.0
6246
  jsondiffpatch: 0.6.0
@@ -6309,6 +6881,20 @@ snapshots:
6309
  dependencies:
6310
  printable-characters: 1.0.42
6311
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6312
6313
 
6314
@@ -6342,6 +6928,10 @@ snapshots:
6342
 
6343
6344
 
 
 
 
 
6345
6346
  dependencies:
6347
  bytes: 3.1.2
@@ -6372,10 +6962,60 @@ snapshots:
6372
  dependencies:
6373
  fill-range: 7.1.1
6374
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6375
6376
  dependencies:
6377
  pako: 0.2.9
6378
 
 
 
 
 
6379
6380
  dependencies:
6381
  caniuse-lite: 1.0.30001637
@@ -6385,11 +7025,15 @@ snapshots:
6385
 
6386
6387
 
 
 
6388
6389
  dependencies:
6390
  base64-js: 1.5.1
6391
  ieee754: 1.2.1
6392
 
 
 
6393
6394
  optional: true
6395
 
@@ -6482,6 +7126,11 @@ snapshots:
6482
 
6483
6484
 
 
 
 
 
 
6485
6486
 
6487
@@ -6561,6 +7210,10 @@ snapshots:
6561
 
6562
6563
 
 
 
 
 
6564
6565
  dependencies:
6566
  safe-buffer: 5.2.1
@@ -6610,12 +7263,52 @@ snapshots:
6610
  optionalDependencies:
6611
  typescript: 5.5.2
6612
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6613
6614
  dependencies:
6615
  path-key: 3.1.1
6616
  shebang-command: 2.0.0
6617
  which: 2.0.2
6618
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6619
6620
  dependencies:
6621
  mdn-data: 2.0.30
@@ -6667,12 +7360,23 @@ snapshots:
6667
  es-errors: 1.3.0
6668
  gopd: 1.0.1
6669
 
 
 
 
 
 
 
6670
6671
 
6672
6673
 
6674
6675
 
 
 
 
 
 
6676
6677
 
6678
@@ -6687,10 +7391,18 @@ snapshots:
6687
 
6688
6689
 
 
 
 
 
 
 
6690
6691
  dependencies:
6692
  path-type: 4.0.0
6693
 
 
 
6694
6695
  dependencies:
6696
  is-obj: 2.0.0
@@ -6712,6 +7424,16 @@ snapshots:
6712
 
6713
6714
 
 
 
 
 
 
 
 
 
 
 
6715
6716
 
6717
@@ -6983,8 +7705,15 @@ snapshots:
6983
 
6984
6985
 
 
 
6986
6987
 
 
 
 
 
 
6988
6989
  dependencies:
6990
  cross-spawn: 7.0.3
@@ -7266,6 +7995,22 @@ snapshots:
7266
  dependencies:
7267
  has-symbols: 1.0.3
7268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7269
7270
  dependencies:
7271
  function-bind: 1.1.2
@@ -7365,6 +8110,12 @@ snapshots:
7365
  property-information: 6.5.0
7366
  space-separated-tokens: 2.0.2
7367
 
 
 
 
 
 
 
7368
7369
  dependencies:
7370
  lru-cache: 7.18.3
@@ -7381,6 +8132,8 @@ snapshots:
7381
  statuses: 2.0.1
7382
  toidentifier: 1.0.1
7383
 
 
 
7384
7385
 
7386
@@ -7475,6 +8228,11 @@ snapshots:
7475
 
7476
7477
 
 
 
 
 
 
7478
7479
 
7480
@@ -7509,6 +8267,8 @@ snapshots:
7509
 
7510
7511
 
 
 
7512
7513
  dependencies:
7514
  '@isaacs/cliui': 8.0.2
@@ -7657,6 +8417,12 @@ snapshots:
7657
 
7658
7659
 
 
 
 
 
 
 
7660
7661
  dependencies:
7662
  '@types/mdast': 3.0.15
@@ -8344,6 +9110,11 @@ snapshots:
8344
  braces: 3.0.3
8345
  picomatch: 2.3.1
8346
 
 
 
 
 
 
8347
8348
 
8349
@@ -8379,6 +9150,10 @@ snapshots:
8379
  - supports-color
8380
  - utf-8-validate
8381
 
 
 
 
 
8382
8383
  dependencies:
8384
  brace-expansion: 1.1.11
@@ -8468,6 +9243,36 @@ snapshots:
8468
 
8469
8470
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8471
8472
  dependencies:
8473
  hosted-git-info: 6.1.1
@@ -8507,6 +9312,20 @@ snapshots:
8507
 
8508
8509
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8510
8511
  dependencies:
8512
  destr: 2.0.3
@@ -8558,6 +9377,8 @@ snapshots:
8558
  strip-ansi: 6.0.1
8559
  wcwidth: 1.0.1
8560
 
 
 
8561
8562
 
8563
@@ -8584,10 +9405,21 @@ snapshots:
8584
 
8585
8586
 
 
 
8587
8588
  dependencies:
8589
  callsites: 3.1.0
8590
 
 
 
 
 
 
 
 
 
 
8591
8592
  dependencies:
8593
  '@types/unist': 2.0.10
@@ -8614,6 +9446,8 @@ snapshots:
8614
 
8615
8616
 
 
 
8617
8618
 
8619
@@ -8639,6 +9473,14 @@ snapshots:
8639
 
8640
8641
 
 
 
 
 
 
 
 
 
8642
8643
  dependencies:
8644
  buffer-from: 1.1.2
@@ -8659,6 +9501,10 @@ snapshots:
8659
 
8660
8661
 
 
 
 
 
8662
8663
  dependencies:
8664
  confbox: 0.1.7
@@ -8750,6 +9596,8 @@ snapshots:
8750
 
8751
8752
 
 
 
8753
8754
 
8755
@@ -8764,6 +9612,15 @@ snapshots:
8764
  forwarded: 0.2.0
8765
  ipaddr.js: 1.9.1
8766
 
 
 
 
 
 
 
 
 
 
8767
8768
  dependencies:
8769
  end-of-stream: 1.4.4
@@ -8780,14 +9637,31 @@ snapshots:
8780
  inherits: 2.0.4
8781
  pump: 2.0.1
8782
 
 
 
8783
8784
 
8785
8786
  dependencies:
8787
  side-channel: 1.0.6
8788
 
 
 
 
 
 
 
8789
8790
 
 
 
 
 
 
 
 
 
 
8791
8792
 
8793
@@ -8824,6 +9698,11 @@ snapshots:
8824
 
8825
8826
 
 
 
 
 
 
8827
8828
  dependencies:
8829
  '@remix-run/router': 1.17.1
@@ -8976,6 +9855,11 @@ snapshots:
8976
 
8977
8978
 
 
 
 
 
 
8979
8980
  dependencies:
8981
  estree-walker: 0.6.1
@@ -9086,8 +9970,15 @@ snapshots:
9086
  gopd: 1.0.1
9087
  has-property-descriptors: 1.0.2
9088
 
 
 
9089
9090
 
 
 
 
 
 
9091
9092
  dependencies:
9093
  shebang-regex: 3.0.0
@@ -9172,6 +10063,18 @@ snapshots:
9172
 
9173
9174
 
 
 
 
 
 
 
 
 
 
 
 
 
9175
9176
 
9177
@@ -9219,6 +10122,8 @@ snapshots:
9219
 
9220
9221
 
 
 
9222
9223
  dependencies:
9224
  inline-style-parser: 0.1.1
@@ -9309,6 +10214,10 @@ snapshots:
9309
 
9310
9311
 
 
 
 
 
9312
9313
 
9314
@@ -9347,6 +10256,8 @@ snapshots:
9347
 
9348
9349
 
 
 
9350
9351
 
9352
@@ -9533,6 +10444,11 @@ snapshots:
9533
  dependencies:
9534
  punycode: 2.3.1
9535
 
 
 
 
 
 
9536
9537
  dependencies:
9538
  react: 18.3.1
@@ -9627,6 +10543,18 @@ snapshots:
9627
  - supports-color
9628
  - terser
9629
 
 
 
 
 
 
 
 
 
 
 
 
 
9630
9631
  dependencies:
9632
  debug: 4.3.5
@@ -9679,6 +10607,8 @@ snapshots:
9679
  - supports-color
9680
  - terser
9681
 
 
 
9682
9683
  dependencies:
9684
  '@vue/compiler-dom': 3.4.30
@@ -9689,6 +10619,8 @@ snapshots:
9689
  optionalDependencies:
9690
  typescript: 5.5.2
9691
 
 
 
9692
9693
  dependencies:
9694
  defaults: 1.0.4
 
36
  packages/bolt:
37
  dependencies:
38
  '@ai-sdk/anthropic':
39
+ specifier: ^0.0.30
40
+ version: 0.0.30([email protected])
41
+ '@codemirror/autocomplete':
42
+ specifier: ^6.17.0
43
+ version: 6.17.0(@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])
44
+ '@codemirror/commands':
45
+ specifier: ^6.6.0
46
+ version: 6.6.0
47
+ '@codemirror/lang-css':
48
+ specifier: ^6.2.1
49
+ version: 6.2.1(@codemirror/[email protected])
50
+ '@codemirror/lang-html':
51
+ specifier: ^6.4.9
52
+ version: 6.4.9
53
+ '@codemirror/lang-javascript':
54
+ specifier: ^6.2.2
55
+ version: 6.2.2
56
+ '@codemirror/lang-json':
57
+ specifier: ^6.0.1
58
+ version: 6.0.1
59
+ '@codemirror/lang-markdown':
60
+ specifier: ^6.2.5
61
+ version: 6.2.5
62
+ '@codemirror/lang-sass':
63
+ specifier: ^6.0.2
64
+ version: 6.0.2(@codemirror/[email protected])
65
+ '@codemirror/lang-wast':
66
+ specifier: ^6.0.2
67
+ version: 6.0.2
68
+ '@codemirror/language':
69
+ specifier: ^6.10.2
70
+ version: 6.10.2
71
+ '@codemirror/search':
72
+ specifier: ^6.5.6
73
+ version: 6.5.6
74
+ '@codemirror/state':
75
+ specifier: ^6.4.1
76
+ version: 6.4.1
77
+ '@codemirror/view':
78
+ specifier: ^6.28.4
79
+ version: 6.28.4
80
  '@iconify-json/ph':
81
  specifier: ^1.1.13
82
  version: 1.1.13
83
  '@iconify-json/svg-spinners':
84
  specifier: ^1.1.2
85
  version: 1.1.2
86
+ '@lezer/highlight':
87
+ specifier: ^1.2.0
88
+ version: 1.2.0
89
  '@nanostores/react':
90
  specifier: ^0.7.2
91
 
102
  specifier: ^0.61.0
103
  version: 0.61.0
104
  '@webcontainer/api':
105
+ specifier: ^1.3.0-internal.1
106
+ version: 1.3.0-internal.1
107
  '@xterm/addon-fit':
108
  specifier: ^0.10.0
109
  version: 0.10.0(@xterm/[email protected])
 
114
  specifier: ^5.5.0
115
  version: 5.5.0
116
  ai:
117
+ specifier: ^3.2.27
118
119
  framer-motion:
120
  specifier: ^11.2.12
121
 
134
  react-markdown:
135
  specifier: ^9.0.1
136
  version: 9.0.1(@types/[email protected])([email protected])
137
+ react-resizable-panels:
138
+ specifier: ^2.0.20
139
140
  rehype-raw:
141
  specifier: ^7.0.0
142
  version: 7.0.0
 
177
  vite:
178
  specifier: ^5.3.1
179
  version: 5.3.1(@types/[email protected])([email protected])
180
+ vite-plugin-node-polyfills:
181
+ specifier: ^0.22.0
182
183
+ vite-plugin-optimize-css-modules:
184
+ specifier: ^1.1.0
185
186
  vite-tsconfig-paths:
187
  specifier: ^4.3.2
188
 
195
 
196
  packages:
197
 
198
+ '@ai-sdk/[email protected].30':
199
+ resolution: {integrity: sha512-iPJjKtIH8yk2cf5BNXLN6sn6TTghOh8puWothX4pPVBM/OKC4RWVjYTEELwUv2VDPIw918KBg2j/T0RfTgu+bw==}
200
+ engines: {node: '>=18'}
201
+ peerDependencies:
202
+ zod: ^3.0.0
203
+
204
+ '@ai-sdk/[email protected]':
205
+ resolution: {integrity: sha512-PCQFN3MlC6DShS/81IFU9NVvt9OekQGiZTEowRc2AwAwWrDsv7er3UkcMswFAL/Z7xZKjgu0dZTNH1z9oUlo7A==}
206
  engines: {node: '>=18'}
207
  peerDependencies:
208
  zod: ^3.0.0
209
+ peerDependenciesMeta:
210
+ zod:
211
+ optional: true
212
 
213
+ '@ai-sdk/[email protected].2':
214
+ resolution: {integrity: sha512-57f6O4OFVNEpI8Z8o+K40tIB3YQiTw+VCql/qrAO9Utq7Ti1o6+X9tvm177DlZJL7ft0Rwzvgy48S9YhrEKgmA==}
215
  engines: {node: '>=18'}
216
  peerDependencies:
217
  zod: ^3.0.0
 
219
  zod:
220
  optional: true
221
 
222
+ '@ai-sdk/[email protected].10':
223
+ resolution: {integrity: sha512-NzkrtREQpHID1cTqY/C4CI30PVOaXWKYytDR2EcytmFgnP7Z6+CrGIA/YCnNhYAuUm6Nx+nGpRL/Hmyrv7NYzg==}
224
  engines: {node: '>=18'}
225
 
226
+ '@ai-sdk/provider@0.0.12':
227
+ resolution: {integrity: sha512-oOwPQD8i2Ynpn22cur4sk26FW3mSy6t6/X/K1Ay2yGBKYiSpRyLfObhOrZEGsXDx+3euKy4nEZ193R36NM+tpQ==}
228
+ engines: {node: '>=18'}
229
+
230
+ '@ai-sdk/[email protected]':
231
+ resolution: {integrity: sha512-r84qhn08GHtVGjvbveMekP1CeXDs5sIrdDvMaoxhCL8o90HjYTWBSDywuRJU1Jk1uPE/BwZWQu9f5bqaIx6AgA==}
232
  engines: {node: '>=18'}
233
  peerDependencies:
234
  react: ^18 || ^19
 
239
  zod:
240
  optional: true
241
 
242
+ '@ai-sdk/[email protected].16':
243
+ resolution: {integrity: sha512-rhBTHLY2fx+weF/vrNmYY8S+D6Gcni77YlDDq9kANpNycL99WQo1hRy9fVJ44ICMJCpVrY/kHIl3Jlumdy3oPw==}
244
  engines: {node: '>=18'}
245
  peerDependencies:
246
  solid-js: ^1.7.7
 
248
  solid-js:
249
  optional: true
250
 
251
+ '@ai-sdk/[email protected].17':
252
+ resolution: {integrity: sha512-dkN8tTMNq7U4Ya02aKd1nH2gZLj0BdleuSY6PAeIQ3huo2Z8Ixgf90ZdnWEf1BSUtdIuXwkkVz6gn+jbh3IbQQ==}
253
  engines: {node: '>=18'}
254
  peerDependencies:
255
  svelte: ^3.0.0 || ^4.0.0
 
257
  svelte:
258
  optional: true
259
 
260
+ '@ai-sdk/[email protected].14':
261
+ resolution: {integrity: sha512-mm9jAkdZW+UTrSLMGwRcT7o8pHGO7Z5FmmLC0B1NH7BRzLfh1/t0ZuF1U6T7GQbmRQXwQUWjdjnlpY83kc62zw==}
262
  engines: {node: '>=18'}
263
  peerDependencies:
264
  zod: ^3.0.0
 
266
  zod:
267
  optional: true
268
 
269
+ '@ai-sdk/[email protected].17':
270
+ resolution: {integrity: sha512-DoWimMtYNQbqaZZZT00NlfR/G/hEMZLwOZLC58Jp0iIxagJnAcamMJlS1rSR4+vd2UWNk4iPdgsMFdkpDvD9aA==}
271
  engines: {node: '>=18'}
272
  peerDependencies:
273
  vue: ^3.3.4
 
488
  '@cloudflare/[email protected]':
489
  resolution: {integrity: sha512-CQD8YS6evRob7LChvIX3gE3zYo0KVgaLDOu1SwNP1BVIS2Sa0b+FC8S1e1hhrNN8/E4chYlVN+FDAgA4KRDUEQ==}
490
 
491
+ '@codemirror/[email protected]':
492
+ resolution: {integrity: sha512-fdfj6e6ZxZf8yrkMHUSJJir7OJkHkZKaOZGzLWIYp2PZ3jd+d+UjG8zVPqJF6d3bKxkhvXTPan/UZ1t7Bqm0gA==}
493
+ peerDependencies:
494
+ '@codemirror/language': ^6.0.0
495
+ '@codemirror/state': ^6.0.0
496
+ '@codemirror/view': ^6.0.0
497
+ '@lezer/common': ^1.0.0
498
+
499
+ '@codemirror/[email protected]':
500
+ resolution: {integrity: sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==}
501
+
502
+ '@codemirror/[email protected]':
503
+ resolution: {integrity: sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==}
504
+
505
+ '@codemirror/[email protected]':
506
+ resolution: {integrity: sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==}
507
+
508
+ '@codemirror/[email protected]':
509
+ resolution: {integrity: sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==}
510
+
511
+ '@codemirror/[email protected]':
512
+ resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==}
513
+
514
+ '@codemirror/[email protected]':
515
+ resolution: {integrity: sha512-Hgke565YcO4fd9pe2uLYxnMufHO5rQwRr+AAhFq8ABuhkrjyX8R5p5s+hZUTdV60O0dMRjxKhBLxz8pu/MkUVA==}
516
+
517
+ '@codemirror/[email protected]':
518
+ resolution: {integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==}
519
+
520
+ '@codemirror/[email protected]':
521
+ resolution: {integrity: sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==}
522
+
523
+ '@codemirror/[email protected]':
524
+ resolution: {integrity: sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==}
525
+
526
+ '@codemirror/[email protected]':
527
+ resolution: {integrity: sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==}
528
+
529
+ '@codemirror/[email protected]':
530
+ resolution: {integrity: sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==}
531
+
532
+ '@codemirror/[email protected]':
533
+ resolution: {integrity: sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==}
534
+
535
+ '@codemirror/[email protected]':
536
+ resolution: {integrity: sha512-QScv95fiviSQ/CaVGflxAvvvDy/9wi0RFyDl4LkHHWiMr/UPebyuTspmYSeN5Nx6eujcPYwsQzA6ZIZucKZVHQ==}
537
+
538
  '@commitlint/[email protected]':
539
  resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==}
540
  engines: {node: '>=v18'}
 
1105
  '@jspm/[email protected]':
1106
  resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==}
1107
 
1108
+ '@lezer/[email protected]':
1109
+ resolution: {integrity: sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==}
1110
+
1111
+ '@lezer/[email protected]':
1112
+ resolution: {integrity: sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==}
1113
+
1114
+ '@lezer/[email protected]':
1115
+ resolution: {integrity: sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==}
1116
+
1117
+ '@lezer/[email protected]':
1118
+ resolution: {integrity: sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==}
1119
+
1120
+ '@lezer/[email protected]':
1121
+ resolution: {integrity: sha512-bYW4ctpyGK+JMumDApeUzuIezX01H76R1foD6LcRX224FWfyYit/HYxiPGDjXXe/wQWASjCvVGoukTH68+0HIA==}
1122
+
1123
+ '@lezer/[email protected]':
1124
+ resolution: {integrity: sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==}
1125
+
1126
+ '@lezer/[email protected]':
1127
+ resolution: {integrity: sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==}
1128
+
1129
+ '@lezer/[email protected]':
1130
+ resolution: {integrity: sha512-ErbEQ15eowmJUyT095e9NJc3BI9yZ894fjSDtHftD0InkfUBGgnKSU6dvan9jqsZuNHg2+ag/1oyDRxNsENupQ==}
1131
+
1132
+ '@lezer/[email protected]':
1133
+ resolution: {integrity: sha512-w/RCO2dIzZH1To8p+xjs8cE+yfgGus8NZ/dXeWl/QzHyr+TeBs71qiE70KPImEwvTsmEjoWh0A5SxMzKd5BWBQ==}
1134
+
1135
  '@mdx-js/[email protected]':
1136
  resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==}
1137
 
 
1170
  resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
1171
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
1172
 
1173
+ '@opentelemetry/[email protected]':
1174
+ resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
1175
+ engines: {node: '>=8.0.0'}
1176
+
1177
  '@pkgjs/[email protected]':
1178
  resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
1179
  engines: {node: '>=14'}
 
1311
  '@remix-run/[email protected]':
1312
  resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==}
1313
 
1314
+ '@rollup/[email protected]':
1315
+ resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==}
1316
+ engines: {node: '>=14.0.0'}
1317
+ peerDependencies:
1318
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
1319
+ peerDependenciesMeta:
1320
+ rollup:
1321
+ optional: true
1322
+
1323
  '@rollup/[email protected]':
1324
  resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
1325
  engines: {node: '>=14.0.0'}
 
1701
  '@web3-storage/[email protected]':
1702
  resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==}
1703
 
1704
+ '@webcontainer/api@1.3.0-internal.1':
1705
+ resolution: {integrity: sha512-XHveAaZgZItLWieict8xTteBbPLeAwCJLuc80Zq6Mmk0LEWTw8yYZep0dTKbet6bd9MPTQ1+vjPAsEtD0H1fOA==}
1706
 
1707
  '@xterm/[email protected]':
1708
  resolution: {integrity: sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==}
 
1750
  resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
1751
  engines: {node: '>=8'}
1752
 
1753
1754
+ resolution: {integrity: sha512-J0SCozj1c8ZTprYVAH3LL1XYR5TRT6oGsXZ5leSqXeEo1SWBx6rFEqDKZLFskLvOf3Ta/AG6EDDrP1EErwapMQ==}
1755
  engines: {node: '>=18'}
1756
  peerDependencies:
1757
  openai: ^4.42.0
 
1824
1825
  resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
1826
 
1827
1828
+ resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==}
1829
+
1830
1831
+ resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==}
1832
+
1833
1834
  resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
1835
  engines: {node: '>=12'}
 
1868
1869
  resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
1870
 
1871
1872
+ resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
1873
+
1874
1875
+ resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==}
1876
+
1877
1878
  resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
1879
  engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
 
1888
  resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
1889
  engines: {node: '>=8'}
1890
 
1891
1892
+ resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
1893
+
1894
1895
+ resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==}
1896
+
1897
1898
+ resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
1899
+
1900
1901
+ resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==}
1902
+
1903
1904
+ resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
1905
+
1906
1907
+ resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==}
1908
+
1909
1910
+ resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==}
1911
+ engines: {node: '>= 0.12'}
1912
+
1913
1914
  resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==}
1915
 
1916
1917
+ resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==}
1918
+
1919
1920
  resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
1921
  engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
 
1924
1925
  resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
1926
 
1927
1928
+ resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==}
1929
+
1930
1931
  resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
1932
 
1933
1934
+ resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==}
1935
+
1936
1937
  resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
1938
  engines: {node: '>= 0.8'}
 
2013
  resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
2014
  engines: {node: '>=8'}
2015
 
2016
2017
+ resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
2018
+
2019
2020
  resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
2021
  engines: {node: '>=6'}
 
2088
  resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
2089
  engines: {node: ^14.18.0 || >=16.10.0}
2090
 
2091
2092
+ resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
2093
+
2094
2095
+ resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==}
2096
+
2097
2098
  resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
2099
  engines: {node: '>= 0.6'}
 
2153
  typescript:
2154
  optional: true
2155
 
2156
2157
+ resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
2158
+
2159
2160
+ resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
2161
+
2162
2163
+ resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
2164
+
2165
2166
+ resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
2167
+
2168
2169
+ resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
2170
+
2171
2172
  resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
2173
  engines: {node: '>= 8'}
2174
 
2175
2176
+ resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
2177
+
2178
2179
  resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
2180
  engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
 
2254
  resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
2255
  engines: {node: '>= 0.4'}
2256
 
2257
2258
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
2259
+ engines: {node: '>= 0.4'}
2260
+
2261
2262
  resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
2263
 
 
2269
  resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
2270
  engines: {node: '>=6'}
2271
 
2272
2273
+ resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==}
2274
+
2275
2276
  resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
2277
 
 
2293
  resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
2294
  engines: {node: '>=0.3.1'}
2295
 
2296
2297
+ resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
2298
+
2299
2300
  resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
2301
  engines: {node: '>=8'}
2302
 
2303
2304
+ resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==}
2305
+ engines: {node: '>=10'}
2306
+
2307
2308
  resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
2309
  engines: {node: '>=8'}
 
2327
2328
  resolution: {integrity: sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==}
2329
 
2330
2331
+ resolution: {integrity: sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==}
2332
+
2333
2334
  resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
2335
 
 
2527
  resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
2528
  engines: {node: '>=6'}
2529
 
2530
2531
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
2532
+ engines: {node: '>=0.8.x'}
2533
+
2534
2535
  resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==}
2536
  engines: {node: '>=14.18'}
2537
 
2538
2539
+ resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
2540
+
2541
2542
  resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
2543
  engines: {node: '>=10'}
 
2779
  resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
2780
  engines: {node: '>= 0.4'}
2781
 
2782
2783
+ resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==}
2784
+ engines: {node: '>=4'}
2785
+
2786
2787
+ resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
2788
+ engines: {node: '>=4'}
2789
+
2790
2791
+ resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
2792
+
2793
2794
  resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
2795
  engines: {node: '>= 0.4'}
 
2821
2822
  resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
2823
 
2824
2825
+ resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
2826
+
2827
2828
  resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==}
2829
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
2838
  resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
2839
  engines: {node: '>= 0.8'}
2840
 
2841
2842
+ resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==}
2843
+
2844
2845
  resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
2846
  engines: {node: '>=10.17.0'}
 
2972
  resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
2973
  engines: {node: '>=8'}
2974
 
2975
2976
+ resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==}
2977
+ engines: {node: '>= 0.4'}
2978
+
2979
2980
  resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
2981
  engines: {node: '>=0.12.0'}
 
3029
3030
  resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
3031
 
3032
3033
+ resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==}
3034
+ engines: {node: '>=10'}
3035
+
3036
3037
  resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
3038
  engines: {node: '>=14'}
 
3215
3216
  resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
3217
 
3218
3219
+ resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
3220
+
3221
3222
  resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
3223
 
 
3499
  resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
3500
  engines: {node: '>=8.6'}
3501
 
3502
3503
+ resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==}
3504
+ hasBin: true
3505
+
3506
3507
  resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
3508
  engines: {node: '>= 0.6'}
 
3539
  engines: {node: '>=16.13'}
3540
  hasBin: true
3541
 
3542
3543
+ resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
3544
+
3545
3546
+ resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==}
3547
+
3548
3549
  resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
3550
 
 
3657
3658
  resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
3659
 
3660
3661
+ resolution: {integrity: sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==}
3662
+ engines: {node: '>=10'}
3663
+
3664
3665
  resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==}
3666
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
3697
  resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
3698
  engines: {node: '>= 0.4'}
3699
 
3700
3701
+ resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==}
3702
+ engines: {node: '>= 0.4'}
3703
+
3704
3705
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
3706
+ engines: {node: '>= 0.4'}
3707
+
3708
3709
+ resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
3710
+ engines: {node: '>= 0.4'}
3711
+
3712
3713
  resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==}
3714
 
 
3743
  resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
3744
  engines: {node: '>=10'}
3745
 
3746
3747
+ resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==}
3748
+
3749
3750
  resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==}
3751
 
 
3775
3776
  resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
3777
 
3778
3779
+ resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
3780
+
3781
3782
  resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
3783
  engines: {node: '>=6'}
3784
 
3785
3786
+ resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==}
3787
+ engines: {node: '>= 0.10'}
3788
+
3789
3790
  resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
3791
 
 
3804
  resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
3805
  engines: {node: '>= 0.8'}
3806
 
3807
3808
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
3809
+
3810
3811
  resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
3812
  engines: {node: '>=8'}
 
3847
  resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
3848
  engines: {node: '>= 14.16'}
3849
 
3850
3851
+ resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
3852
+ engines: {node: '>=0.12'}
3853
+
3854
3855
  resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==}
3856
 
 
3872
  engines: {node: '>=0.10'}
3873
  hasBin: true
3874
 
3875
3876
+ resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
3877
+ engines: {node: '>=10'}
3878
+
3879
3880
  resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
3881
 
 
3977
3978
  resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
3979
 
3980
3981
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
3982
+ engines: {node: '>= 0.6.0'}
3983
+
3984
3985
  resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
3986
  peerDependencies:
 
4000
  resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
4001
  engines: {node: '>= 0.10'}
4002
 
4003
4004
+ resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==}
4005
+
4006
4007
  resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==}
4008
 
 
4012
4013
  resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==}
4014
 
4015
4016
+ resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==}
4017
+
4018
4019
  resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
4020
  engines: {node: '>=6'}
 
4023
  resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
4024
  engines: {node: '>=0.6'}
4025
 
4026
4027
+ resolution: {integrity: sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==}
4028
+ engines: {node: '>=0.6'}
4029
+
4030
4031
+ resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==}
4032
+ engines: {node: '>=0.4.x'}
4033
+
4034
4035
  resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
4036
 
4037
4038
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
4039
+
4040
4041
+ resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==}
4042
+
4043
4044
  resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
4045
  engines: {node: '>= 0.6'}
 
4066
  resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
4067
  engines: {node: '>=0.10.0'}
4068
 
4069
4070
+ resolution: {integrity: sha512-aMbK3VF8U+VBICG+rwhE0Rr/eFZaRzmNq3akBRL1TrayIpLXz7Rbok0//kYeWj6SQRsjcQ3f4eRplJicM+oL6w==}
4071
+ peerDependencies:
4072
+ react: ^16.14.0 || ^17.0.0 || ^18.0.0
4073
+ react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0
4074
+
4075
4076
  resolution: {integrity: sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==}
4077
  engines: {node: '>=14.0.0'}
 
4209
  resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
4210
  engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
4211
 
4212
4213
+ resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
4214
+
4215
4216
  resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==}
4217
  deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
 
4282
  resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
4283
  engines: {node: '>= 0.4'}
4284
 
4285
4286
+ resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
4287
+
4288
4289
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
4290
 
4291
4292
+ resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==}
4293
+ hasBin: true
4294
+
4295
4296
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
4297
  engines: {node: '>=8'}
 
4389
  resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
4390
  engines: {node: '>=4', npm: '>=6'}
4391
 
4392
4393
+ resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==}
4394
+
4395
4396
+ resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==}
4397
+
4398
4399
  resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
4400
 
 
4445
  resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
4446
  engines: {node: '>=8'}
4447
 
4448
4449
+ resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
4450
+
4451
4452
  resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==}
4453
 
 
4515
4516
  resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
4517
 
4518
4519
+ resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==}
4520
+ engines: {node: '>=0.6.0'}
4521
+
4522
4523
  resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==}
4524
 
 
4578
4579
  resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
4580
 
4581
4582
+ resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==}
4583
+
4584
4585
  resolution: {integrity: sha512-FKFg7A0To1VU4CH9YmSMON5QphK0BXjSoiC7D9yMh+mEEbXLUP9qJ4hEt1qcjKtzncs1OpcnjZO8NgrlVbZH+g==}
4586
 
 
4719
4720
  resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
4721
 
4722
4723
+ resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==}
4724
+
4725
4726
  resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==}
4727
  peerDependencies:
 
4778
  engines: {node: ^18.0.0 || >=20.0.0}
4779
  hasBin: true
4780
 
4781
4782
+ resolution: {integrity: sha512-F+G3LjiGbG8QpbH9bZ//GSBr9i1InSTkaulfUHFa9jkLqVGORFBoqc2A/Yu5Mmh1kNAbiAeKeK+6aaQUf3x0JA==}
4783
+ peerDependencies:
4784
+ vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
4785
+
4786
4787
+ resolution: {integrity: sha512-6vtG+GwqBoT0yz90LAKKPf0HkiKkX7oCUzdw0Y0Jjv2S4pKyifq2IKTgCEJu5cLYhPku1mrPIjNVvQRmP0RgLQ==}
4788
+ peerDependencies:
4789
+ vite: ^5.0.0 || ^4.0.0 || ^3.0.0 || ^2.0.0
4790
+
4791
4792
  resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==}
4793
  peerDependencies:
 
4849
  jsdom:
4850
  optional: true
4851
 
4852
4853
+ resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
4854
+
4855
4856
  resolution: {integrity: sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==}
4857
  peerDependencies:
 
4860
  typescript:
4861
  optional: true
4862
 
4863
4864
+ resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
4865
+
4866
4867
  resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
4868
 
 
5003
 
5004
  snapshots:
5005
 
5006
5007
+ dependencies:
5008
+ '@ai-sdk/provider': 0.0.12
5009
+ '@ai-sdk/provider-utils': 1.0.2([email protected])
5010
+ zod: 3.23.8
5011
+
5012
5013
  dependencies:
5014
+ '@ai-sdk/provider': 0.0.10
5015
+ eventsource-parser: 1.1.2
5016
+ nanoid: 3.3.6
5017
+ secure-json-parse: 2.7.0
5018
+ optionalDependencies:
5019
  zod: 3.23.8
5020
 
5021
5022
  dependencies:
5023
+ '@ai-sdk/provider': 0.0.12
5024
  eventsource-parser: 1.1.2
5025
  nanoid: 3.3.6
5026
  secure-json-parse: 2.7.0
5027
  optionalDependencies:
5028
  zod: 3.23.8
5029
 
5030
+ '@ai-sdk/[email protected].10':
5031
  dependencies:
5032
  json-schema: 0.4.0
5033
 
5034
+ '@ai-sdk/provider@0.0.12':
5035
  dependencies:
5036
+ json-schema: 0.4.0
5037
+
5038
5039
+ dependencies:
5040
+ '@ai-sdk/provider-utils': 1.0.2([email protected])
5041
+ '@ai-sdk/ui-utils': 0.0.14([email protected])
5042
  swr: 2.2.0([email protected])
5043
  optionalDependencies:
5044
  react: 18.3.1
5045
  zod: 3.23.8
5046
 
5047
5048
  dependencies:
5049
+ '@ai-sdk/ui-utils': 0.0.14([email protected])
5050
  transitivePeerDependencies:
5051
  - zod
5052
 
5053
5054
  dependencies:
5055
+ '@ai-sdk/provider-utils': 1.0.2([email protected])
5056
+ '@ai-sdk/ui-utils': 0.0.14([email protected])
5057
  sswr: 2.1.0([email protected])
5058
  optionalDependencies:
5059
  svelte: 4.2.18
5060
  transitivePeerDependencies:
5061
  - zod
5062
 
5063
5064
  dependencies:
5065
+ '@ai-sdk/provider-utils': 1.0.2([email protected])
5066
  secure-json-parse: 2.7.0
5067
  optionalDependencies:
5068
  zod: 3.23.8
5069
 
5070
5071
  dependencies:
5072
+ '@ai-sdk/provider-utils': 0.0.14([email protected])
5073
+ '@ai-sdk/ui-utils': 0.0.14([email protected])
5074
5075
  optionalDependencies:
5076
  vue: 3.4.30([email protected])
 
5363
 
5364
  '@cloudflare/[email protected]': {}
5365
 
5366
+ '@codemirror/[email protected](@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])':
5367
+ dependencies:
5368
+ '@codemirror/language': 6.10.2
5369
+ '@codemirror/state': 6.4.1
5370
+ '@codemirror/view': 6.28.4
5371
+ '@lezer/common': 1.2.1
5372
+
5373
+ '@codemirror/[email protected]':
5374
+ dependencies:
5375
+ '@codemirror/language': 6.10.2
5376
+ '@codemirror/state': 6.4.1
5377
+ '@codemirror/view': 6.28.4
5378
+ '@lezer/common': 1.2.1
5379
+
5380
+ '@codemirror/[email protected](@codemirror/[email protected])':
5381
+ dependencies:
5382
+ '@codemirror/autocomplete': 6.17.0(@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])
5383
+ '@codemirror/language': 6.10.2
5384
+ '@codemirror/state': 6.4.1
5385
+ '@lezer/common': 1.2.1
5386
+ '@lezer/css': 1.1.8
5387
+ transitivePeerDependencies:
5388
+ - '@codemirror/view'
5389
+
5390
+ '@codemirror/[email protected]':
5391
+ dependencies:
5392
+ '@codemirror/autocomplete': 6.17.0(@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])
5393
+ '@codemirror/lang-css': 6.2.1(@codemirror/[email protected])
5394
+ '@codemirror/lang-javascript': 6.2.2
5395
+ '@codemirror/language': 6.10.2
5396
+ '@codemirror/state': 6.4.1
5397
+ '@codemirror/view': 6.28.4
5398
+ '@lezer/common': 1.2.1
5399
+ '@lezer/css': 1.1.8
5400
+ '@lezer/html': 1.3.10
5401
+
5402
+ '@codemirror/[email protected]':
5403
+ dependencies:
5404
+ '@codemirror/autocomplete': 6.17.0(@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])
5405
+ '@codemirror/language': 6.10.2
5406
+ '@codemirror/lint': 6.8.1
5407
+ '@codemirror/state': 6.4.1
5408
+ '@codemirror/view': 6.28.4
5409
+ '@lezer/common': 1.2.1
5410
+ '@lezer/javascript': 1.4.17
5411
+
5412
+ '@codemirror/[email protected]':
5413
+ dependencies:
5414
+ '@codemirror/language': 6.10.2
5415
+ '@lezer/json': 1.0.2
5416
+
5417
+ '@codemirror/[email protected]':
5418
+ dependencies:
5419
+ '@codemirror/autocomplete': 6.17.0(@codemirror/[email protected])(@codemirror/[email protected])(@codemirror/[email protected])(@lezer/[email protected])
5420
+ '@codemirror/lang-html': 6.4.9
5421
+ '@codemirror/language': 6.10.2
5422
+ '@codemirror/state': 6.4.1
5423
+ '@codemirror/view': 6.28.4
5424
+ '@lezer/common': 1.2.1
5425
+ '@lezer/markdown': 1.3.0
5426
+
5427
+ '@codemirror/[email protected](@codemirror/[email protected])':
5428
+ dependencies:
5429
+ '@codemirror/lang-css': 6.2.1(@codemirror/[email protected])
5430
+ '@codemirror/language': 6.10.2
5431
+ '@codemirror/state': 6.4.1
5432
+ '@lezer/common': 1.2.1
5433
+ '@lezer/sass': 1.0.6
5434
+ transitivePeerDependencies:
5435
+ - '@codemirror/view'
5436
+
5437
+ '@codemirror/[email protected]':
5438
+ dependencies:
5439
+ '@codemirror/language': 6.10.2
5440
+ '@lezer/common': 1.2.1
5441
+ '@lezer/highlight': 1.2.0
5442
+ '@lezer/lr': 1.4.1
5443
+
5444
+ '@codemirror/[email protected]':
5445
+ dependencies:
5446
+ '@codemirror/state': 6.4.1
5447
+ '@codemirror/view': 6.28.4
5448
+ '@lezer/common': 1.2.1
5449
+ '@lezer/highlight': 1.2.0
5450
+ '@lezer/lr': 1.4.1
5451
+ style-mod: 4.1.2
5452
+
5453
+ '@codemirror/[email protected]':
5454
+ dependencies:
5455
+ '@codemirror/state': 6.4.1
5456
+ '@codemirror/view': 6.28.4
5457
+ crelt: 1.0.6
5458
+
5459
+ '@codemirror/[email protected]':
5460
+ dependencies:
5461
+ '@codemirror/state': 6.4.1
5462
+ '@codemirror/view': 6.28.4
5463
+ crelt: 1.0.6
5464
+
5465
+ '@codemirror/[email protected]': {}
5466
+
5467
+ '@codemirror/[email protected]':
5468
+ dependencies:
5469
+ '@codemirror/state': 6.4.1
5470
+ style-mod: 4.1.2
5471
+ w3c-keyname: 2.2.8
5472
+
5473
5474
  dependencies:
5475
  '@commitlint/format': 19.3.0
 
5896
 
5897
  '@jspm/[email protected]': {}
5898
 
5899
+ '@lezer/[email protected]': {}
5900
+
5901
+ '@lezer/[email protected]':
5902
+ dependencies:
5903
+ '@lezer/common': 1.2.1
5904
+ '@lezer/highlight': 1.2.0
5905
+ '@lezer/lr': 1.4.1
5906
+
5907
+ '@lezer/[email protected]':
5908
+ dependencies:
5909
+ '@lezer/common': 1.2.1
5910
+
5911
+ '@lezer/[email protected]':
5912
+ dependencies:
5913
+ '@lezer/common': 1.2.1
5914
+ '@lezer/highlight': 1.2.0
5915
+ '@lezer/lr': 1.4.1
5916
+
5917
+ '@lezer/[email protected]':
5918
+ dependencies:
5919
+ '@lezer/common': 1.2.1
5920
+ '@lezer/highlight': 1.2.0
5921
+ '@lezer/lr': 1.4.1
5922
+
5923
+ '@lezer/[email protected]':
5924
+ dependencies:
5925
+ '@lezer/common': 1.2.1
5926
+ '@lezer/highlight': 1.2.0
5927
+ '@lezer/lr': 1.4.1
5928
+
5929
+ '@lezer/[email protected]':
5930
+ dependencies:
5931
+ '@lezer/common': 1.2.1
5932
+
5933
+ '@lezer/[email protected]':
5934
+ dependencies:
5935
+ '@lezer/common': 1.2.1
5936
+ '@lezer/highlight': 1.2.0
5937
+
5938
+ '@lezer/[email protected]':
5939
+ dependencies:
5940
+ '@lezer/common': 1.2.1
5941
+ '@lezer/highlight': 1.2.0
5942
+ '@lezer/lr': 1.4.1
5943
+
5944
  '@mdx-js/[email protected]':
5945
  dependencies:
5946
  '@types/estree-jsx': 1.0.5
 
6013
  dependencies:
6014
  which: 3.0.1
6015
 
6016
+ '@opentelemetry/[email protected]': {}
6017
+
6018
  '@pkgjs/[email protected]':
6019
  optional: true
6020
 
 
6229
  dependencies:
6230
  web-streams-polyfill: 3.3.3
6231
 
6232
6233
+ dependencies:
6234
+ '@rollup/pluginutils': 5.1.0([email protected])
6235
+ estree-walker: 2.0.2
6236
+ magic-string: 0.30.10
6237
+ optionalDependencies:
6238
+ rollup: 4.18.0
6239
+
6240
6241
  dependencies:
6242
  '@types/estree': 1.0.5
 
6759
 
6760
  '@web3-storage/[email protected]': {}
6761
 
6762
+ '@webcontainer/api@1.3.0-internal.1': {}
6763
 
6764
  '@xterm/[email protected](@xterm/[email protected])':
6765
  dependencies:
 
6803
  clean-stack: 2.2.0
6804
  indent-string: 4.0.0
6805
 
6806
6807
  dependencies:
6808
+ '@ai-sdk/provider': 0.0.12
6809
+ '@ai-sdk/provider-utils': 1.0.2([email protected])
6810
+ '@ai-sdk/react': 0.0.22([email protected])([email protected])
6811
+ '@ai-sdk/solid': 0.0.16([email protected])
6812
+ '@ai-sdk/svelte': 0.0.17([email protected])([email protected])
6813
+ '@ai-sdk/ui-utils': 0.0.14([email protected])
6814
6815
+ '@opentelemetry/api': 1.9.0
6816
  eventsource-parser: 1.1.2
6817
  json-schema: 0.4.0
6818
  jsondiffpatch: 0.6.0
 
6881
  dependencies:
6882
  printable-characters: 1.0.42
6883
 
6884
6885
+ dependencies:
6886
+ bn.js: 4.12.0
6887
+ inherits: 2.0.4
6888
+ minimalistic-assert: 1.0.1
6889
+
6890
6891
+ dependencies:
6892
+ call-bind: 1.0.7
6893
+ is-nan: 1.3.2
6894
+ object-is: 1.1.6
6895
+ object.assign: 4.1.5
6896
+ util: 0.12.5
6897
+
6898
6899
 
6900
 
6928
 
6929
6930
 
6931
6932
+
6933
6934
+
6935
6936
  dependencies:
6937
  bytes: 3.1.2
 
6962
  dependencies:
6963
  fill-range: 7.1.1
6964
 
6965
6966
+
6967
6968
+ dependencies:
6969
+ resolve: 1.22.8
6970
+
6971
6972
+ dependencies:
6973
+ buffer-xor: 1.0.3
6974
+ cipher-base: 1.0.4
6975
+ create-hash: 1.2.0
6976
+ evp_bytestokey: 1.0.3
6977
+ inherits: 2.0.4
6978
+ safe-buffer: 5.2.1
6979
+
6980
6981
+ dependencies:
6982
+ browserify-aes: 1.2.0
6983
+ browserify-des: 1.0.2
6984
+ evp_bytestokey: 1.0.3
6985
+
6986
6987
+ dependencies:
6988
+ cipher-base: 1.0.4
6989
+ des.js: 1.1.0
6990
+ inherits: 2.0.4
6991
+ safe-buffer: 5.2.1
6992
+
6993
6994
+ dependencies:
6995
+ bn.js: 5.2.1
6996
+ randombytes: 2.1.0
6997
+
6998
6999
+ dependencies:
7000
+ bn.js: 5.2.1
7001
+ browserify-rsa: 4.1.0
7002
+ create-hash: 1.2.0
7003
+ create-hmac: 1.1.7
7004
+ elliptic: 6.5.6
7005
+ hash-base: 3.0.4
7006
+ inherits: 2.0.4
7007
+ parse-asn1: 5.1.7
7008
+ readable-stream: 2.3.8
7009
+ safe-buffer: 5.2.1
7010
+
7011
7012
  dependencies:
7013
  pako: 0.2.9
7014
 
7015
7016
+ dependencies:
7017
+ pako: 1.0.11
7018
+
7019
7020
  dependencies:
7021
  caniuse-lite: 1.0.30001637
 
7025
 
7026
7027
 
7028
7029
+
7030
7031
  dependencies:
7032
  base64-js: 1.5.1
7033
  ieee754: 1.2.1
7034
 
7035
7036
+
7037
7038
  optional: true
7039
 
 
7126
 
7127
7128
 
7129
7130
+ dependencies:
7131
+ inherits: 2.0.4
7132
+ safe-buffer: 5.2.1
7133
+
7134
7135
 
7136
 
7210
 
7211
7212
 
7213
7214
+
7215
7216
+
7217
7218
  dependencies:
7219
  safe-buffer: 5.2.1
 
7263
  optionalDependencies:
7264
  typescript: 5.5.2
7265
 
7266
7267
+ dependencies:
7268
+ bn.js: 4.12.0
7269
+ elliptic: 6.5.6
7270
+
7271
7272
+ dependencies:
7273
+ cipher-base: 1.0.4
7274
+ inherits: 2.0.4
7275
+ md5.js: 1.3.5
7276
+ ripemd160: 2.0.2
7277
+ sha.js: 2.4.11
7278
+
7279
7280
+ dependencies:
7281
+ cipher-base: 1.0.4
7282
+ create-hash: 1.2.0
7283
+ inherits: 2.0.4
7284
+ ripemd160: 2.0.2
7285
+ safe-buffer: 5.2.1
7286
+ sha.js: 2.4.11
7287
+
7288
7289
+
7290
7291
+
7292
7293
  dependencies:
7294
  path-key: 3.1.1
7295
  shebang-command: 2.0.0
7296
  which: 2.0.2
7297
 
7298
7299
+ dependencies:
7300
+ browserify-cipher: 1.0.1
7301
+ browserify-sign: 4.2.3
7302
+ create-ecdh: 4.0.4
7303
+ create-hash: 1.2.0
7304
+ create-hmac: 1.1.7
7305
+ diffie-hellman: 5.0.3
7306
+ inherits: 2.0.4
7307
+ pbkdf2: 3.1.2
7308
+ public-encrypt: 4.0.3
7309
+ randombytes: 2.1.0
7310
+ randomfill: 1.0.4
7311
+
7312
7313
  dependencies:
7314
  mdn-data: 2.0.30
 
7360
  es-errors: 1.3.0
7361
  gopd: 1.0.1
7362
 
7363
7364
+ dependencies:
7365
+ define-data-property: 1.1.4
7366
+ has-property-descriptors: 1.0.2
7367
+ object-keys: 1.1.1
7368
+
7369
7370
 
7371
7372
 
7373
7374
 
7375
7376
+ dependencies:
7377
+ inherits: 2.0.4
7378
+ minimalistic-assert: 1.0.1
7379
+
7380
7381
 
7382
 
7391
 
7392
7393
 
7394
7395
+ dependencies:
7396
+ bn.js: 4.12.0
7397
+ miller-rabin: 4.0.1
7398
+ randombytes: 2.1.0
7399
+
7400
7401
  dependencies:
7402
  path-type: 4.0.0
7403
 
7404
7405
+
7406
7407
  dependencies:
7408
  is-obj: 2.0.0
 
7424
 
7425
7426
 
7427
7428
+ dependencies:
7429
+ bn.js: 4.12.0
7430
+ brorand: 1.1.0
7431
+ hash.js: 1.1.7
7432
+ hmac-drbg: 1.0.1
7433
+ inherits: 2.0.4
7434
+ minimalistic-assert: 1.0.1
7435
+ minimalistic-crypto-utils: 1.0.1
7436
+
7437
7438
 
7439
 
7705
 
7706
7707
 
7708
7709
+
7710
7711
 
7712
7713
+ dependencies:
7714
+ md5.js: 1.3.5
7715
+ safe-buffer: 5.2.1
7716
+
7717
7718
  dependencies:
7719
  cross-spawn: 7.0.3
 
7995
  dependencies:
7996
  has-symbols: 1.0.3
7997
 
7998
7999
+ dependencies:
8000
+ inherits: 2.0.4
8001
+ safe-buffer: 5.2.1
8002
+
8003
8004
+ dependencies:
8005
+ inherits: 2.0.4
8006
+ readable-stream: 3.6.2
8007
+ safe-buffer: 5.2.1
8008
+
8009
8010
+ dependencies:
8011
+ inherits: 2.0.4
8012
+ minimalistic-assert: 1.0.1
8013
+
8014
8015
  dependencies:
8016
  function-bind: 1.1.2
 
8110
  property-information: 6.5.0
8111
  space-separated-tokens: 2.0.2
8112
 
8113
8114
+ dependencies:
8115
+ hash.js: 1.1.7
8116
+ minimalistic-assert: 1.0.1
8117
+ minimalistic-crypto-utils: 1.0.1
8118
+
8119
8120
  dependencies:
8121
  lru-cache: 7.18.3
 
8132
  statuses: 2.0.1
8133
  toidentifier: 1.0.1
8134
 
8135
8136
+
8137
8138
 
8139
 
8228
 
8229
8230
 
8231
8232
+ dependencies:
8233
+ call-bind: 1.0.7
8234
+ define-properties: 1.2.1
8235
+
8236
8237
 
8238
 
8267
 
8268
8269
 
8270
8271
+
8272
8273
  dependencies:
8274
  '@isaacs/cliui': 8.0.2
 
8417
 
8418
8419
 
8420
8421
+ dependencies:
8422
+ hash-base: 3.1.0
8423
+ inherits: 2.0.4
8424
+ safe-buffer: 5.2.1
8425
+
8426
8427
  dependencies:
8428
  '@types/mdast': 3.0.15
 
9110
  braces: 3.0.3
9111
  picomatch: 2.3.1
9112
 
9113
9114
+ dependencies:
9115
+ bn.js: 4.12.0
9116
+ brorand: 1.1.0
9117
+
9118
9119
 
9120
 
9150
  - supports-color
9151
  - utf-8-validate
9152
 
9153
9154
+
9155
9156
+
9157
9158
  dependencies:
9159
  brace-expansion: 1.1.11
 
9243
 
9244
9245
 
9246
9247
+ dependencies:
9248
+ assert: 2.1.0
9249
+ browser-resolve: 2.0.0
9250
+ browserify-zlib: 0.2.0
9251
+ buffer: 5.7.1
9252
+ console-browserify: 1.2.0
9253
+ constants-browserify: 1.0.0
9254
+ create-require: 1.1.1
9255
+ crypto-browserify: 3.12.0
9256
+ domain-browser: 4.23.0
9257
+ events: 3.3.0
9258
+ https-browserify: 1.0.0
9259
+ isomorphic-timers-promises: 1.0.1
9260
+ os-browserify: 0.3.0
9261
+ path-browserify: 1.0.1
9262
+ pkg-dir: 5.0.0
9263
+ process: 0.11.10
9264
+ punycode: 1.4.1
9265
+ querystring-es3: 0.2.1
9266
+ readable-stream: 3.6.2
9267
+ stream-browserify: 3.0.0
9268
+ stream-http: 3.2.0
9269
+ string_decoder: 1.3.0
9270
+ timers-browserify: 2.0.12
9271
+ tty-browserify: 0.0.1
9272
+ url: 0.11.3
9273
+ util: 0.12.5
9274
+ vm-browserify: 1.1.2
9275
+
9276
9277
  dependencies:
9278
  hosted-git-info: 6.1.1
 
9312
 
9313
9314
 
9315
9316
+ dependencies:
9317
+ call-bind: 1.0.7
9318
+ define-properties: 1.2.1
9319
+
9320
9321
+
9322
9323
+ dependencies:
9324
+ call-bind: 1.0.7
9325
+ define-properties: 1.2.1
9326
+ has-symbols: 1.0.3
9327
+ object-keys: 1.1.1
9328
+
9329
9330
  dependencies:
9331
  destr: 2.0.3
 
9377
  strip-ansi: 6.0.1
9378
  wcwidth: 1.0.1
9379
 
9380
9381
+
9382
9383
 
9384
 
9405
 
9406
9407
 
9408
9409
+
9410
9411
  dependencies:
9412
  callsites: 3.1.0
9413
 
9414
9415
+ dependencies:
9416
+ asn1.js: 4.10.1
9417
+ browserify-aes: 1.2.0
9418
+ evp_bytestokey: 1.0.3
9419
+ hash-base: 3.0.4
9420
+ pbkdf2: 3.1.2
9421
+ safe-buffer: 5.2.1
9422
+
9423
9424
  dependencies:
9425
  '@types/unist': 2.0.10
 
9446
 
9447
9448
 
9449
9450
+
9451
9452
 
9453
 
9473
 
9474
9475
 
9476
9477
+ dependencies:
9478
+ create-hash: 1.2.0
9479
+ create-hmac: 1.1.7
9480
+ ripemd160: 2.0.2
9481
+ safe-buffer: 5.2.1
9482
+ sha.js: 2.4.11
9483
+
9484
9485
  dependencies:
9486
  buffer-from: 1.1.2
 
9501
 
9502
9503
 
9504
9505
+ dependencies:
9506
+ find-up: 5.0.0
9507
+
9508
9509
  dependencies:
9510
  confbox: 0.1.7
 
9596
 
9597
9598
 
9599
9600
+
9601
9602
 
9603
 
9612
  forwarded: 0.2.0
9613
  ipaddr.js: 1.9.1
9614
 
9615
9616
+ dependencies:
9617
+ bn.js: 4.12.0
9618
+ browserify-rsa: 4.1.0
9619
+ create-hash: 1.2.0
9620
+ parse-asn1: 5.1.7
9621
+ randombytes: 2.1.0
9622
+ safe-buffer: 5.2.1
9623
+
9624
9625
  dependencies:
9626
  end-of-stream: 1.4.4
 
9637
  inherits: 2.0.4
9638
  pump: 2.0.1
9639
 
9640
9641
+
9642
9643
 
9644
9645
  dependencies:
9646
  side-channel: 1.0.6
9647
 
9648
9649
+ dependencies:
9650
+ side-channel: 1.0.6
9651
+
9652
9653
+
9654
9655
 
9656
9657
+ dependencies:
9658
+ safe-buffer: 5.2.1
9659
+
9660
9661
+ dependencies:
9662
+ randombytes: 2.1.0
9663
+ safe-buffer: 5.2.1
9664
+
9665
9666
 
9667
 
9698
 
9699
9700
 
9701
9702
+ dependencies:
9703
+ react: 18.3.1
9704
+ react-dom: 18.3.1([email protected])
9705
+
9706
9707
  dependencies:
9708
  '@remix-run/router': 1.17.1
 
9855
 
9856
9857
 
9858
9859
+ dependencies:
9860
+ hash-base: 3.1.0
9861
+ inherits: 2.0.4
9862
+
9863
9864
  dependencies:
9865
  estree-walker: 0.6.1
 
9970
  gopd: 1.0.1
9971
  has-property-descriptors: 1.0.2
9972
 
9973
9974
+
9975
9976
 
9977
9978
+ dependencies:
9979
+ inherits: 2.0.4
9980
+ safe-buffer: 5.2.1
9981
+
9982
9983
  dependencies:
9984
  shebang-regex: 3.0.0
 
10063
 
10064
10065
 
10066
10067
+ dependencies:
10068
+ inherits: 2.0.4
10069
+ readable-stream: 3.6.2
10070
+
10071
10072
+ dependencies:
10073
+ builtin-status-codes: 3.0.0
10074
+ inherits: 2.0.4
10075
+ readable-stream: 3.6.2
10076
+ xtend: 4.0.2
10077
+
10078
10079
 
10080
 
10122
 
10123
10124
 
10125
10126
+
10127
10128
  dependencies:
10129
  inline-style-parser: 0.1.1
 
10214
 
10215
10216
 
10217
10218
+ dependencies:
10219
+ setimmediate: 1.0.5
10220
+
10221
10222
 
10223
 
10256
 
10257
10258
 
10259
10260
+
10261
10262
 
10263
 
10444
  dependencies:
10445
  punycode: 2.3.1
10446
 
10447
10448
+ dependencies:
10449
+ punycode: 1.4.1
10450
+ qs: 6.12.3
10451
+
10452
10453
  dependencies:
10454
  react: 18.3.1
 
10543
  - supports-color
10544
  - terser
10545
 
10546
10547
+ dependencies:
10548
+ '@rollup/plugin-inject': 5.0.5([email protected])
10549
+ node-stdlib-browser: 1.2.0
10550
+ vite: 5.3.1(@types/[email protected])([email protected])
10551
+ transitivePeerDependencies:
10552
+ - rollup
10553
+
10554
10555
+ dependencies:
10556
+ vite: 5.3.1(@types/[email protected])([email protected])
10557
+
10558
10559
  dependencies:
10560
  debug: 4.3.5
 
10607
  - supports-color
10608
  - terser
10609
 
10610
10611
+
10612
10613
  dependencies:
10614
  '@vue/compiler-dom': 3.4.30
 
10619
  optionalDependencies:
10620
  typescript: 5.5.2
10621
 
10622
10623
+
10624
10625
  dependencies:
10626
  defaults: 1.0.4