Sam Denty commited on
Commit
6fb59d2
Β·
unverified Β·
1 Parent(s): d364a6f

fix: remove monorepo

Browse files
This view is limited to 50 files because it contains too many changes. Β  See raw diff
Files changed (50) hide show
  1. .github/workflows/ci.yaml +0 -1
  2. README.md +53 -24
  3. {packages/bolt/app β†’ app}/components/chat/Artifact.tsx +0 -0
  4. {packages/bolt/app β†’ app}/components/chat/AssistantMessage.tsx +0 -0
  5. {packages/bolt/app β†’ app}/components/chat/BaseChat.module.scss +0 -0
  6. {packages/bolt/app β†’ app}/components/chat/BaseChat.tsx +0 -0
  7. {packages/bolt/app β†’ app}/components/chat/Chat.client.tsx +0 -13
  8. {packages/bolt/app β†’ app}/components/chat/CodeBlock.module.scss +0 -0
  9. {packages/bolt/app β†’ app}/components/chat/CodeBlock.tsx +0 -0
  10. {packages/bolt/app β†’ app}/components/chat/Markdown.module.scss +0 -0
  11. {packages/bolt/app β†’ app}/components/chat/Markdown.tsx +0 -0
  12. {packages/bolt/app β†’ app}/components/chat/Messages.client.tsx +0 -0
  13. {packages/bolt/app β†’ app}/components/chat/SendButton.client.tsx +0 -0
  14. {packages/bolt/app β†’ app}/components/chat/UserMessage.tsx +0 -0
  15. {packages/bolt/app β†’ app}/components/editor/codemirror/BinaryContent.tsx +0 -0
  16. {packages/bolt/app β†’ app}/components/editor/codemirror/CodeMirrorEditor.tsx +0 -0
  17. {packages/bolt/app β†’ app}/components/editor/codemirror/cm-theme.ts +0 -0
  18. {packages/bolt/app β†’ app}/components/editor/codemirror/indent.ts +0 -0
  19. {packages/bolt/app β†’ app}/components/editor/codemirror/languages.ts +0 -0
  20. {packages/bolt/app β†’ app}/components/header/Header.tsx +0 -0
  21. {packages/bolt/app β†’ app}/components/header/HeaderActionButtons.client.tsx +0 -4
  22. {packages/bolt/app β†’ app}/components/sidebar/HistoryItem.tsx +0 -0
  23. {packages/bolt/app β†’ app}/components/sidebar/Menu.client.tsx +0 -0
  24. {packages/bolt/app β†’ app}/components/sidebar/date-binning.ts +0 -0
  25. {packages/bolt/app β†’ app}/components/ui/Dialog.tsx +0 -0
  26. {packages/bolt/app β†’ app}/components/ui/IconButton.tsx +0 -0
  27. {packages/bolt/app β†’ app}/components/ui/LoadingDots.tsx +0 -0
  28. {packages/bolt/app β†’ app}/components/ui/PanelHeader.tsx +0 -0
  29. {packages/bolt/app β†’ app}/components/ui/PanelHeaderButton.tsx +0 -0
  30. {packages/bolt/app β†’ app}/components/ui/Slider.tsx +0 -0
  31. {packages/bolt/app β†’ app}/components/ui/ThemeSwitch.tsx +0 -0
  32. {packages/bolt/app β†’ app}/components/workbench/EditorPanel.tsx +0 -0
  33. {packages/bolt/app β†’ app}/components/workbench/FileBreadcrumb.tsx +0 -0
  34. {packages/bolt/app β†’ app}/components/workbench/FileTree.tsx +0 -0
  35. {packages/bolt/app β†’ app}/components/workbench/PortDropdown.tsx +0 -0
  36. {packages/bolt/app β†’ app}/components/workbench/Preview.tsx +0 -0
  37. {packages/bolt/app β†’ app}/components/workbench/Workbench.client.tsx +0 -0
  38. {packages/bolt/app β†’ app}/components/workbench/terminal/Terminal.tsx +0 -0
  39. {packages/bolt/app β†’ app}/components/workbench/terminal/theme.ts +0 -0
  40. {packages/bolt/app β†’ app}/entry.client.tsx +0 -0
  41. {packages/bolt/app β†’ app}/entry.server.tsx +0 -0
  42. {packages/bolt/app β†’ app}/lib/.server/auth.ts +0 -0
  43. {packages/bolt/app β†’ app}/lib/.server/llm/api-key.ts +0 -0
  44. {packages/bolt/app β†’ app}/lib/.server/llm/constants.ts +0 -0
  45. {packages/bolt/app β†’ app}/lib/.server/llm/model.ts +0 -0
  46. {packages/bolt/app β†’ app}/lib/.server/llm/prompts.ts +0 -0
  47. {packages/bolt/app β†’ app}/lib/.server/llm/stream-text.ts +0 -0
  48. {packages/bolt/app β†’ app}/lib/.server/llm/switchable-stream.ts +0 -0
  49. {packages/bolt/app β†’ app}/lib/.server/sessions.ts +0 -0
  50. {packages/bolt/app β†’ app}/lib/analytics.ts +0 -67
.github/workflows/ci.yaml CHANGED
@@ -45,7 +45,6 @@ jobs:
45
  with:
46
  wranglerVersion: '* -w'
47
  packageManager: pnpm
48
- workingDirectory: 'packages/bolt'
49
  apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
50
  accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
51
  command: pages deploy
 
45
  with:
46
  wranglerVersion: '* -w'
47
  packageManager: pnpm
 
48
  apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
49
  accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
50
  command: pages deploy
README.md CHANGED
@@ -1,55 +1,84 @@
1
- # Bolt Monorepo
2
 
3
- Welcome to the Bolt monorepo! This repository contains the codebase for Bolt, an AI assistant developed by StackBlitz.
4
 
5
- ## Repository Structure
6
 
7
- Currently, this monorepo contains a single package:
8
-
9
- - [`bolt`](packages/bolt): The main package containing the UI interface for Bolt as well as the server components.
10
-
11
- As the project grows, additional packages may be added to this workspace.
12
-
13
- ## Getting Started
14
-
15
- ### Prerequisites
16
 
17
  - Node.js (v20.15.1)
18
  - pnpm (v9.4.0)
19
 
20
- ### Installation
21
 
22
- 1. Clone the repository:
23
 
24
  ```bash
25
  git clone https://github.com/stackblitz/bolt.git
26
- cd bolt
27
  ```
28
 
29
  2. Install dependencies:
30
 
31
  ```bash
32
- pnpm i
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  ```
34
 
35
- 3. Optionally, init git hooks:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  ```bash
38
- pnpmx husky
39
  ```
40
 
41
- ### Development
42
 
43
- To start developing the Bolt UI:
44
 
45
- 1. Navigate to the bolt package:
46
 
47
  ```bash
48
- cd packages/bolt
49
  ```
50
 
51
- 2. Start the development server:
 
 
52
 
53
  ```bash
54
- pnpm run dev
55
  ```
 
 
 
1
+ # Bolt
2
 
3
+ Bolt is an AI assistant developed by StackBlitz. This package contains the UI interface for Bolt as well as the server components, built using [Remix Run](https://remix.run/).
4
 
5
+ ## Prerequisites
6
 
7
+ Before you begin, ensure you have the following installed:
 
 
 
 
 
 
 
 
8
 
9
  - Node.js (v20.15.1)
10
  - pnpm (v9.4.0)
11
 
12
+ ## Setup
13
 
14
+ 1. Clone the repository (if you haven't already):
15
 
16
  ```bash
17
  git clone https://github.com/stackblitz/bolt.git
 
18
  ```
19
 
20
  2. Install dependencies:
21
 
22
  ```bash
23
+ pnpm install
24
+ ```
25
+
26
+ 3. Create a `.env.local` file in the root directory and add your Anthropic API key:
27
+
28
+ ```
29
+ ANTHROPIC_API_KEY=XXX
30
+ ```
31
+
32
+ Optionally, you an set the debug level or disable authentication:
33
+
34
+ ```
35
+ VITE_LOG_LEVEL=debug
36
+ VITE_DISABLE_AUTH=1
37
  ```
38
 
39
+ If you want to run authentication against a local StackBlitz instance, add:
40
+
41
+ ```
42
+ VITE_CLIENT_ORIGIN=https://local.stackblitz.com:3000
43
+ ```
44
+
45
+ **Important**: Never commit your `.env.local` file to version control. It's already included in .gitignore.
46
+
47
+ ## Available Scripts
48
+
49
+ - `pnpm run dev`: Starts the development server.
50
+ - `pnpm run build`: Builds the project.
51
+ - `pnpm run start`: Runs the built application locally using Wrangler Pages. This script uses `bindings.sh` to set up necessary bindings so you don't have to duplicate environment variables.
52
+ - `pnpm run preview`: Builds the project and then starts it locally, useful for testing the production build. Note, HTTP streaming currently doesn't work as expected with `wrangler pages dev`.
53
+ - `pnpm test:` Runs the test suite using Vitest.
54
+ - `pnpm run typecheck`: Runs TypeScript type checking.
55
+ - `pnpm run typegen`: Generates TypeScript types using Wrangler.
56
+ - `pnpm run deploy`: Builds the project and deploys it to Cloudflare Pages.
57
+
58
+ ## Development
59
+
60
+ To start the development server:
61
 
62
  ```bash
63
+ pnpm run dev
64
  ```
65
 
66
+ This will start the Remix Vite development server.
67
 
68
+ ## Testing
69
 
70
+ Run the test suite with:
71
 
72
  ```bash
73
+ pnpm test
74
  ```
75
 
76
+ ## Deployment
77
+
78
+ To deploy the application to Cloudflare Pages:
79
 
80
  ```bash
81
+ pnpm run deploy
82
  ```
83
+
84
+ Make sure you have the necessary permissions and Wrangler is correctly configured for your Cloudflare account.
{packages/bolt/app β†’ app}/components/chat/Artifact.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/AssistantMessage.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/BaseChat.module.scss RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/BaseChat.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/Chat.client.tsx RENAMED
@@ -4,7 +4,6 @@ import { useChat } from 'ai/react';
4
  import { useAnimate } from 'framer-motion';
5
  import { memo, useEffect, useRef, useState } from 'react';
6
  import { cssTransition, toast, ToastContainer } from 'react-toastify';
7
- import { AnalyticsAction, AnalyticsTrackEvent, sendAnalyticsEvent } from '~/lib/analytics';
8
  import { useMessageParser, usePromptEnhancer, useShortcuts, useSnapScroll } from '~/lib/hooks';
9
  import { useChatHistory } from '~/lib/persistence';
10
  import { chatStore } from '~/lib/stores/chat';
@@ -195,18 +194,6 @@ export const ChatImpl = memo(({ initialMessages, storeMessageHistory }: ChatProp
195
  resetEnhancer();
196
 
197
  textareaRef.current?.blur();
198
-
199
- const event = messages.length === 0 ? AnalyticsTrackEvent.ChatCreated : AnalyticsTrackEvent.MessageSent;
200
-
201
- sendAnalyticsEvent({
202
- action: AnalyticsAction.Track,
203
- payload: {
204
- event,
205
- properties: {
206
- message: _input,
207
- },
208
- },
209
- });
210
  };
211
 
212
  const [messageRef, scrollRef] = useSnapScroll();
 
4
  import { useAnimate } from 'framer-motion';
5
  import { memo, useEffect, useRef, useState } from 'react';
6
  import { cssTransition, toast, ToastContainer } from 'react-toastify';
 
7
  import { useMessageParser, usePromptEnhancer, useShortcuts, useSnapScroll } from '~/lib/hooks';
8
  import { useChatHistory } from '~/lib/persistence';
9
  import { chatStore } from '~/lib/stores/chat';
 
194
  resetEnhancer();
195
 
196
  textareaRef.current?.blur();
 
 
 
 
 
 
 
 
 
 
 
 
197
  };
198
 
199
  const [messageRef, scrollRef] = useSnapScroll();
{packages/bolt/app β†’ app}/components/chat/CodeBlock.module.scss RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/CodeBlock.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/Markdown.module.scss RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/Markdown.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/Messages.client.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/SendButton.client.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/chat/UserMessage.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/editor/codemirror/BinaryContent.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/editor/codemirror/CodeMirrorEditor.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/editor/codemirror/cm-theme.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/components/editor/codemirror/indent.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/components/editor/codemirror/languages.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/components/header/Header.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/header/HeaderActionButtons.client.tsx RENAMED
@@ -2,7 +2,6 @@ import { useStore } from '@nanostores/react';
2
  import { chatStore } from '~/lib/stores/chat';
3
  import { workbenchStore } from '~/lib/stores/workbench';
4
  import { classNames } from '~/utils/classNames';
5
- import { OpenStackBlitz } from './OpenStackBlitz.client';
6
 
7
  interface HeaderActionButtonsProps {}
8
 
@@ -40,9 +39,6 @@ export function HeaderActionButtons({}: HeaderActionButtonsProps) {
40
  <div className="i-ph:code-bold" />
41
  </Button>
42
  </div>
43
- <div className="flex ml-2">
44
- <OpenStackBlitz />
45
- </div>
46
  </div>
47
  );
48
  }
 
2
  import { chatStore } from '~/lib/stores/chat';
3
  import { workbenchStore } from '~/lib/stores/workbench';
4
  import { classNames } from '~/utils/classNames';
 
5
 
6
  interface HeaderActionButtonsProps {}
7
 
 
39
  <div className="i-ph:code-bold" />
40
  </Button>
41
  </div>
 
 
 
42
  </div>
43
  );
44
  }
{packages/bolt/app β†’ app}/components/sidebar/HistoryItem.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/sidebar/Menu.client.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/sidebar/date-binning.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/Dialog.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/IconButton.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/LoadingDots.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/PanelHeader.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/PanelHeaderButton.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/Slider.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/ui/ThemeSwitch.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/EditorPanel.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/FileBreadcrumb.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/FileTree.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/PortDropdown.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/Preview.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/Workbench.client.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/terminal/Terminal.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/components/workbench/terminal/theme.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/entry.client.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/entry.server.tsx RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/auth.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/api-key.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/constants.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/model.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/prompts.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/stream-text.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/llm/switchable-stream.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/.server/sessions.ts RENAMED
File without changes
{packages/bolt/app β†’ app}/lib/analytics.ts RENAMED
@@ -1,7 +1,5 @@
1
- import { Analytics, type IdentifyParams, type PageParams, type TrackParams } from '@segment/analytics-node';
2
  import { CLIENT_ORIGIN } from '~/lib/constants';
3
  import { request as doRequest } from '~/lib/fetch';
4
- import { logger } from '~/utils/logger';
5
 
6
  export interface Identity {
7
  userId?: string | null;
@@ -18,20 +16,6 @@ export enum AnalyticsTrackEvent {
18
  ChatCreated = `${MESSAGE_PREFIX} Chat Created`,
19
  }
20
 
21
- export enum AnalyticsAction {
22
- Identify = 'identify',
23
- Page = 'page',
24
- Track = 'track',
25
- }
26
-
27
- // we can omit the user ID since it's retrieved from the user's session
28
- type OmitUserId<T> = Omit<T, 'userId'>;
29
-
30
- export type AnalyticsEvent =
31
- | { action: AnalyticsAction.Identify; payload: OmitUserId<IdentifyParams> }
32
- | { action: AnalyticsAction.Page; payload: OmitUserId<PageParams> }
33
- | { action: AnalyticsAction.Track; payload: OmitUserId<TrackParams> };
34
-
35
  export async function identifyUser(access: string): Promise<Identity | undefined> {
36
  const response = await doRequest(`${CLIENT_ORIGIN}/api/identify`, {
37
  method: 'GET',
@@ -52,54 +36,3 @@ export async function identifyUser(access: string): Promise<Identity | undefined
52
 
53
  return Object.fromEntries(stringified) as Identity;
54
  }
55
-
56
- // send an analytics event from the client
57
- export async function sendAnalyticsEvent(event: AnalyticsEvent) {
58
- // don't send analytics events when in dev mode
59
- if (import.meta.env.DEV) {
60
- return;
61
- }
62
-
63
- const request = await fetch('/api/analytics', {
64
- method: 'POST',
65
- headers: {
66
- 'Content-Type': 'application/json',
67
- },
68
- body: JSON.stringify(event),
69
- });
70
-
71
- if (!request.ok) {
72
- logger.error(`Error handling Segment Analytics action: ${event.action}`);
73
- }
74
- }
75
-
76
- // send an analytics event from the server
77
- export async function sendEventInternal(identity: Identity, { action, payload }: AnalyticsEvent) {
78
- const { userId, segmentWriteKey: writeKey } = identity;
79
-
80
- if (!userId || !writeKey) {
81
- logger.warn('Missing user ID or write key when logging analytics');
82
- return { success: false as const, error: 'missing-data' };
83
- }
84
-
85
- const analytics = new Analytics({ flushAt: 1, writeKey }).on('error', logger.error);
86
-
87
- try {
88
- await new Promise((resolve, reject) => {
89
- if (action === AnalyticsAction.Identify) {
90
- analytics.identify({ ...payload, userId }, resolve);
91
- } else if (action === AnalyticsAction.Page) {
92
- analytics.page({ ...payload, userId }, resolve);
93
- } else if (action === AnalyticsAction.Track) {
94
- analytics.track({ ...payload, userId }, resolve);
95
- } else {
96
- reject();
97
- }
98
- });
99
- } catch {
100
- logger.error(`Error handling Segment Analytics action: ${action}`);
101
- return { success: false as const, error: 'invalid-action' };
102
- }
103
-
104
- return { success: true as const };
105
- }
 
 
1
  import { CLIENT_ORIGIN } from '~/lib/constants';
2
  import { request as doRequest } from '~/lib/fetch';
 
3
 
4
  export interface Identity {
5
  userId?: string | null;
 
16
  ChatCreated = `${MESSAGE_PREFIX} Chat Created`,
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  export async function identifyUser(access: string): Promise<Identity | undefined> {
20
  const response = await doRequest(`${CLIENT_ORIGIN}/api/identify`, {
21
  method: 'GET',
 
36
 
37
  return Object.fromEntries(stringified) as Identity;
38
  }