mirror of https://github.com/buster-so/buster.git
Merge pull request #867 from buster-so/big-nate-bus-1710-make-suggested-questions-dropdown
Big nate bus 1710 make suggested questions dropdown
This commit is contained in:
commit
a19da883ab
|
@ -18,3 +18,4 @@ storybook-static
|
|||
.env.staging
|
||||
.env.dev
|
||||
.env.local
|
||||
.vercel
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"build:production": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode production -- --typecheck",
|
||||
"build:local": "pnpm prebuild && cross-env NODE_OPTIONS=--max-old-space-size=12288 vite build -- --typecheck --local",
|
||||
"build-storybook": "storybook build",
|
||||
"log:staging": "WRANGLER_LOG=debug npx wrangler tail --format=pretty --env=staging",
|
||||
"build:visualize": "npx vite-bundle-visualizer",
|
||||
"deploy:dev": "pnpm run build && npx wrangler deploy .output/server/index.mjs --env dev --assets .output/public",
|
||||
"deploy:production": "pnpm run build:production && npx wrangler deploy .output/server/index.mjs --env production --assets .output/public",
|
||||
|
@ -42,7 +43,6 @@
|
|||
"@electric-sql/react": "^1.0.10",
|
||||
"@emoji-mart/data": "^1.2.1",
|
||||
"@faker-js/faker": "^10.0.0",
|
||||
"@modelcontextprotocol/sdk": "^1.17.5",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@platejs/ai": "^50.1.2",
|
||||
"@platejs/autoformat": "^49.0.0",
|
||||
|
@ -161,6 +161,7 @@
|
|||
"react-hotkeys-hook": "^5.1.0",
|
||||
"react-lite-youtube-embed": "^2.5.6",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-mentions": "^4.4.10",
|
||||
"react-player": "^3.3.2",
|
||||
"react-textarea-autosize": "^8.5.9",
|
||||
"remark-gfm": "^4.0.1",
|
||||
|
@ -199,6 +200,7 @@
|
|||
"@types/pluralize": "^0.0.33",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"@types/react-mentions": "^4.4.1",
|
||||
"@vitejs/plugin-react": "^5.0.2",
|
||||
"@vitest/browser": "3.2.4",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { BusterInput } from './BusterInput';
|
||||
|
||||
const meta: Meta<typeof BusterInput> = {
|
||||
title: 'UI/Inputs/BusterInput',
|
||||
component: BusterInput,
|
||||
tags: ['autodocs'],
|
||||
args: {},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="p-4">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof BusterInput>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
value: 'Sample text value',
|
||||
},
|
||||
};
|
|
@ -0,0 +1,127 @@
|
|||
import { Command } from 'cmdk';
|
||||
import type React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Mention, MentionsInput } from 'react-mentions';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { BusterInputProps } from './BusterInput.types';
|
||||
import { BusterInputEmpty } from './BusterInputEmpty';
|
||||
import { BusterInputSeparator } from './BusterInputSeparator';
|
||||
import { DEFAULT_MENTION_MARKUP } from './parse-input';
|
||||
|
||||
const users = [
|
||||
{ id: '1', display: 'BigNate' },
|
||||
{ id: '2', display: 'ReactFan42' },
|
||||
{ id: '3', display: 'NextJSDev' },
|
||||
];
|
||||
|
||||
export const BusterInput = ({ defaultValue, value: valueProp, onChange }: BusterInputProps) => {
|
||||
const [value, setValue] = useState(valueProp ?? defaultValue);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<MentionsInput
|
||||
value={value}
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
console.log(e.target.value);
|
||||
}}
|
||||
placeholder="Type @ to mention…"
|
||||
style={{
|
||||
control: { fontSize: 16, minHeight: 46 },
|
||||
highlighter: { padding: 8 },
|
||||
input: { padding: 8 },
|
||||
}}
|
||||
classNames={{
|
||||
highlighter: 'bg-red-500/10',
|
||||
suggestions: 'bg-blue-500/20 border',
|
||||
item: 'text-red-500',
|
||||
}}
|
||||
>
|
||||
{/* Always render a valid Mention node */}
|
||||
<Mention
|
||||
trigger="@"
|
||||
markup={DEFAULT_MENTION_MARKUP}
|
||||
data={users}
|
||||
displayTransform={(_, display) => `@${display}`}
|
||||
appendSpaceOnAdd
|
||||
renderSuggestion={(d) => {
|
||||
return d.display;
|
||||
}}
|
||||
/>
|
||||
</MentionsInput>
|
||||
|
||||
<div className="w-full h-px bg-border" />
|
||||
|
||||
<Command
|
||||
label="Command Menu"
|
||||
onValueChange={(e) => {
|
||||
console.log(e);
|
||||
}}
|
||||
>
|
||||
<Command.Input
|
||||
className="w-full outline-1 outline-amber-600"
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
asChild
|
||||
autoFocus
|
||||
readOnly
|
||||
placeholder="Type @ to mention…"
|
||||
>
|
||||
<textarea />
|
||||
</Command.Input>
|
||||
<Command.List>
|
||||
<BusterInputEmpty>No results found.</BusterInputEmpty>
|
||||
|
||||
<CommandGroup heading="Letters">
|
||||
<CommandItem
|
||||
onSelect={() => {
|
||||
setValue('a');
|
||||
}}
|
||||
>
|
||||
a
|
||||
</CommandItem>
|
||||
<CommandItem>b</CommandItem>
|
||||
<BusterInputSeparator />
|
||||
<CommandItem>c</CommandItem>
|
||||
</CommandGroup>
|
||||
|
||||
<CommandItem>Apple</CommandItem>
|
||||
</Command.List>
|
||||
</Command>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CommandGroup = ({
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentPropsWithoutRef<typeof Command.Group>) => {
|
||||
return (
|
||||
<Command.Group
|
||||
className={cn(
|
||||
'text-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',
|
||||
props.className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Command.Group>
|
||||
);
|
||||
};
|
||||
|
||||
const CommandItem = ({
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentPropsWithoutRef<typeof Command.Item>) => {
|
||||
return (
|
||||
<Command.Item
|
||||
className={cn(
|
||||
'data-[selected=true]:bg-item-hover data-[selected=true]:text-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
props.className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Command.Item>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
import type React from 'react';
|
||||
import type { DisplayTransformFunc } from 'react-mentions';
|
||||
|
||||
export type BusterInputDropdownItem<T = string> = {
|
||||
value: T;
|
||||
label: string | React.ReactNode;
|
||||
shortcut?: string;
|
||||
icon?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
loading?: boolean;
|
||||
closeOnSelect?: boolean; //defaults to parent
|
||||
};
|
||||
|
||||
export type BusterInputDropdownGroup<T = string> = {
|
||||
label: string | React.ReactNode;
|
||||
items: BusterInputDropdownItem<T>[];
|
||||
};
|
||||
|
||||
export type BusterMentionItem<V = string> = {
|
||||
value: V;
|
||||
parsedValue?: string; //if this is undefined, the value will be used
|
||||
label: string | React.ReactNode;
|
||||
selected?: boolean;
|
||||
};
|
||||
|
||||
export type BusterMentionItems<V = string, T = string> = {
|
||||
items: BusterMentionItem<V>[];
|
||||
displayTransform?: DisplayTransformFunc;
|
||||
style?: React.CSSProperties;
|
||||
appendSpaceOnAdd?: boolean; //defaults to true
|
||||
trigger: T;
|
||||
popoverContent?: (v: BusterMentionItem<V>) => React.ReactNode;
|
||||
};
|
||||
|
||||
export type BusterMentionRecords<V = string, T extends string = string> = {
|
||||
[K in T]: BusterMentionItems<V, T>;
|
||||
};
|
||||
|
||||
export type BusterInputProps<T = string> = {
|
||||
defaultValue: string;
|
||||
value?: string;
|
||||
onChange?: (value: string) => void;
|
||||
submitting?: boolean;
|
||||
onSubmit: (value: string) => void;
|
||||
onStop: () => void;
|
||||
onItemClick?: (value: string) => void;
|
||||
items: (BusterInputDropdownItem<T> | BusterInputDropdownGroup<T>)[];
|
||||
mentions?: BusterMentionRecords<T>;
|
||||
variant?: 'default';
|
||||
sendIcon?: React.ReactNode;
|
||||
secondaryActions?: React.ReactNode;
|
||||
closeOnSelect?: boolean; //defaults to true
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
import { Command } from 'cmdk';
|
||||
import type React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export const BusterInputEmpty = ({
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentPropsWithoutRef<typeof Command.Empty>) => {
|
||||
return (
|
||||
<Command.Empty
|
||||
className={cn('text-gray-light py-6 text-center text-base', props.className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Command.Empty>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
import { Command } from 'cmdk';
|
||||
import type React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export const BusterInputSeparator = ({
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentPropsWithoutRef<typeof Command.Separator>) => {
|
||||
return (
|
||||
<Command.Separator className={cn('bg-border -mx-1 h-px', props.className)} {...props}>
|
||||
{children}
|
||||
</Command.Separator>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import type { BusterMentionItem } from './BusterInput.types';
|
||||
import { parseMarkupInput } from './parse-input';
|
||||
|
||||
describe('parseMarkupInput', () => {
|
||||
const mockItems: BusterMentionItem<string>[] = [
|
||||
{
|
||||
value: '1',
|
||||
parsedValue: 'BigNate User',
|
||||
label: 'BigNate',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'ReactFan42',
|
||||
// No parsedValue - should use value instead
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
parsedValue: 'Next.js Developer',
|
||||
label: 'NextJSDev',
|
||||
},
|
||||
];
|
||||
|
||||
const mockItemsRecord = {
|
||||
'@': {
|
||||
items: mockItems,
|
||||
trigger: '@' as const,
|
||||
},
|
||||
};
|
||||
|
||||
it('should replace mention markup with parsedValue when available', () => {
|
||||
const input = 'Hello @[BigNate](1) how are you?';
|
||||
const result = parseMarkupInput({
|
||||
input,
|
||||
items: mockItemsRecord,
|
||||
});
|
||||
|
||||
expect(result).toBe('Hello BigNate User how are you?');
|
||||
});
|
||||
|
||||
it('should replace mention markup with value when parsedValue is undefined', () => {
|
||||
const input = 'Hey @[ReactFan42](2) welcome!';
|
||||
const result = parseMarkupInput({
|
||||
input,
|
||||
items: mockItemsRecord,
|
||||
});
|
||||
|
||||
expect(result).toBe('Hey 2 welcome!');
|
||||
});
|
||||
|
||||
it('should handle multiple mentions in the same string', () => {
|
||||
const input = 'Meeting with @[BigNate](1) and @[NextJSDev](3) at 3pm';
|
||||
const result = parseMarkupInput({
|
||||
input,
|
||||
items: mockItemsRecord,
|
||||
});
|
||||
|
||||
expect(result).toBe('Meeting with BigNate User and Next.js Developer at 3pm');
|
||||
});
|
||||
|
||||
it('should return original text when no mentions are found', () => {
|
||||
const input = 'This is just regular text without any mentions';
|
||||
const result = parseMarkupInput({
|
||||
input,
|
||||
items: mockItemsRecord,
|
||||
});
|
||||
|
||||
expect(result).toBe('This is just regular text without any mentions');
|
||||
});
|
||||
|
||||
it('should handle mentions with unknown IDs by leaving them unchanged', () => {
|
||||
const input = 'Hello @[UnknownUser](999) how are you?';
|
||||
const result = parseMarkupInput({
|
||||
input,
|
||||
items: mockItemsRecord,
|
||||
});
|
||||
|
||||
expect(result).toBe('Hello @[UnknownUser](999) how are you?');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
import type { BusterMentionItems } from './BusterInput.types';
|
||||
|
||||
export const DEFAULT_MENTION_MARKUP = '@[__display__](__id__)';
|
||||
const DEFAULT_MENTION_REGEX = /@\[([^\]]+)\]\(([^)]+)\)/g;
|
||||
|
||||
type BusterMentionItemsRecord<V = string, T extends string = string> = Record<
|
||||
T,
|
||||
Pick<BusterMentionItems<V, T>, 'items' | 'trigger'>
|
||||
>;
|
||||
|
||||
export const parseMarkupInput = <V = string, T extends string = string>({
|
||||
input,
|
||||
items,
|
||||
}: {
|
||||
input: string;
|
||||
items: BusterMentionItemsRecord<V, T>;
|
||||
}): string => {
|
||||
return input.replace(DEFAULT_MENTION_REGEX, (match, _display, id) => {
|
||||
for (const mentionType of Object.values(items) as Pick<
|
||||
BusterMentionItems<V, T>,
|
||||
'items' | 'trigger'
|
||||
>[]) {
|
||||
const item = mentionType.items.find((item) => String(item.value) === String(id));
|
||||
if (item) {
|
||||
// Use parsedValue if available, otherwise use value
|
||||
return item.parsedValue ?? String(item.value);
|
||||
}
|
||||
}
|
||||
|
||||
// If no matching item found in any mention type, return the original mention
|
||||
return match;
|
||||
});
|
||||
};
|
|
@ -28,8 +28,8 @@ export const createCspHeader = (isEmbed = false): string => {
|
|||
return [
|
||||
// Default directives
|
||||
"default-src 'self'",
|
||||
// Scripts
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://*.cloudflareinsights.com https://*.posthog.com https://us-assets.i.posthog.com https://eu-assets.i.posthog.com",
|
||||
// Scripts - removed 'unsafe-eval' which can cause hydration issues in Cloudflare
|
||||
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://*.cloudflareinsights.com https://*.posthog.com https://us-assets.i.posthog.com https://eu-assets.i.posthog.com",
|
||||
// Styles
|
||||
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net",
|
||||
// Images
|
||||
|
|
|
@ -4,9 +4,8 @@ export const htmlCacheHeaders = [
|
|||
{ httpEquiv: 'Pragma', content: 'cache' },
|
||||
];
|
||||
|
||||
// Only use aggressive no-cache for specific routes that need it
|
||||
// Use less aggressive caching to work better with Cloudflare
|
||||
export const preventBrowserCacheHeaders = [
|
||||
{ httpEquiv: 'Cache-Control', content: 'no-cache, no-store, must-revalidate' },
|
||||
{ httpEquiv: 'Cache-Control', content: 'public, max-age=0, must-revalidate' },
|
||||
{ httpEquiv: 'Pragma', content: 'no-cache' },
|
||||
{ httpEquiv: 'Expires', content: '0' },
|
||||
];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { createRootRouteWithContext, HeadContent, Scripts } from '@tanstack/react-router';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { RootProviders } from '@/context/Providers';
|
||||
import { htmlCacheHeaders } from '@/middleware/shared-headers';
|
||||
import { preventBrowserCacheHeaders } from '@/middleware/shared-headers';
|
||||
import shareImage from '../assets/png/default_preview.png';
|
||||
import favicon from '../assets/png/favicon.ico';
|
||||
import { TanstackDevtools } from '../integrations/tanstack-dev-tools/tanstack-devtools';
|
||||
|
@ -31,7 +32,7 @@ export const Route = createRootRouteWithContext<AppRouterContext>()({
|
|||
{ name: 'og:type', content: 'website' },
|
||||
{ name: 'og:locale', content: 'en_US' },
|
||||
{ name: 'og:site_name', content: 'Buster' },
|
||||
...htmlCacheHeaders,
|
||||
...preventBrowserCacheHeaders,
|
||||
],
|
||||
links: [
|
||||
{ rel: 'stylesheet', href: appCss },
|
||||
|
@ -55,6 +56,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
|
|||
</head>
|
||||
<body>
|
||||
<RootProviders>{children}</RootProviders>
|
||||
|
||||
<TanstackDevtools />
|
||||
<Scripts />
|
||||
</body>
|
||||
|
|
|
@ -14,6 +14,7 @@ const DEFAULT_LAYOUT: LayoutSize = ['230px', 'auto'];
|
|||
|
||||
export const Route = createFileRoute('/app')({
|
||||
head: () => {
|
||||
console.log('app head');
|
||||
return {
|
||||
meta: [...preventBrowserCacheHeaders],
|
||||
};
|
||||
|
@ -21,7 +22,10 @@ export const Route = createFileRoute('/app')({
|
|||
context: ({ context }) => ({ ...context, getAppLayout }),
|
||||
beforeLoad: async () => {
|
||||
try {
|
||||
console.log('app beforeLoad - getSupabaseSession');
|
||||
const { isExpired, accessToken = '' } = await getSupabaseSession();
|
||||
console.log('app beforeLoad - getSupabaseSession - isExpired', isExpired);
|
||||
console.log('app beforeLoad - getSupabaseSession - accessToken', accessToken);
|
||||
|
||||
if (isExpired || !accessToken) {
|
||||
console.error('Access token is expired or not found');
|
||||
|
@ -39,6 +43,7 @@ export const Route = createFileRoute('/app')({
|
|||
loader: async ({ context }) => {
|
||||
const { queryClient, accessToken } = context;
|
||||
try {
|
||||
console.log('app loader - getAppLayout');
|
||||
const [initialLayout, user] = await Promise.all([
|
||||
getAppLayout({ id: PRIMARY_APP_LAYOUT_ID }),
|
||||
getSupabaseUser(),
|
||||
|
@ -47,6 +52,8 @@ export const Route = createFileRoute('/app')({
|
|||
prefetchListDatasources(queryClient),
|
||||
prefetchGetDatasets(queryClient),
|
||||
]);
|
||||
console.log('app loader - getAppLayout - initialLayout', initialLayout);
|
||||
console.log('app loader - getAppLayout - user', user);
|
||||
|
||||
if (!user) {
|
||||
console.error('User not found - redirecting to login');
|
||||
|
@ -66,7 +73,10 @@ export const Route = createFileRoute('/app')({
|
|||
}
|
||||
},
|
||||
component: () => {
|
||||
console.log('app component');
|
||||
const { user, accessToken } = Route.useLoaderData();
|
||||
console.log('app component - user', user);
|
||||
console.log('app component - accessToken', accessToken);
|
||||
|
||||
return (
|
||||
<AppProviders user={user} accessToken={accessToken}>
|
||||
|
|
|
@ -11,7 +11,7 @@ const config = defineConfig(({ command, mode }) => {
|
|||
const isTypecheck = process.argv.includes('--typecheck') || process.env.TYPECHECK === 'true';
|
||||
const useChecker = !process.env.VITEST && isBuild;
|
||||
const isLocalBuild = process.argv.includes('--local') || mode === 'development';
|
||||
const target = isLocalBuild ? ('bun' as const) : ('cloudflare-module' as const);
|
||||
const target = isLocalBuild ? ('bun' as const) : ('vercel' as const);
|
||||
|
||||
return {
|
||||
server: { port: 3000 },
|
||||
|
|
136
pnpm-lock.yaml
136
pnpm-lock.yaml
|
@ -406,9 +406,6 @@ importers:
|
|||
'@faker-js/faker':
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
'@modelcontextprotocol/sdk':
|
||||
specifier: ^1.17.5
|
||||
version: 1.17.5
|
||||
'@monaco-editor/react':
|
||||
specifier: ^4.7.0
|
||||
version: 4.7.0(monaco-editor@0.53.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
|
@ -763,6 +760,9 @@ importers:
|
|||
react-markdown:
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0(@types/react@19.1.12)(react@19.1.1)
|
||||
react-mentions:
|
||||
specifier: ^4.4.10
|
||||
version: 4.4.10(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
react-player:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
|
@ -872,6 +872,9 @@ importers:
|
|||
'@types/react-dom':
|
||||
specifier: 'catalog:'
|
||||
version: 19.1.9(@types/react@19.1.12)
|
||||
'@types/react-mentions':
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2(vite@7.1.4(@types/node@24.0.10)(jiti@2.5.1)(lightningcss@1.30.1)(sass@1.92.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))
|
||||
|
@ -1918,6 +1921,9 @@ packages:
|
|||
resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.4.5':
|
||||
resolution: {integrity: sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
@ -3402,10 +3408,6 @@ packages:
|
|||
'@microsoft/fetch-event-source@2.0.1':
|
||||
resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==}
|
||||
|
||||
'@modelcontextprotocol/sdk@1.17.5':
|
||||
resolution: {integrity: sha512-QakrKIGniGuRVfWBdMsDea/dx1PNE739QJ7gCM41s9q+qaCYTHCdsIBXQVVXry3mfWAiaM9kT22Hyz53Uw8mfg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==}
|
||||
|
||||
|
@ -5952,6 +5954,9 @@ packages:
|
|||
peerDependencies:
|
||||
'@types/react': ^19.0.0
|
||||
|
||||
'@types/react-mentions@4.4.1':
|
||||
resolution: {integrity: sha512-65QdcZYkGe2I4GnOLY2OhlXCGz/Csd8NhytwE5r59CoFeYafMltAE/WqFB/Y6SoPU8LvF7EyUrq6Rxrf0Kzxkg==}
|
||||
|
||||
'@types/react@19.1.12':
|
||||
resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==}
|
||||
|
||||
|
@ -7667,12 +7672,6 @@ packages:
|
|||
resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
express-rate-limit@7.5.1:
|
||||
resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==}
|
||||
engines: {node: '>= 16'}
|
||||
peerDependencies:
|
||||
express: '>= 4.11'
|
||||
|
||||
express@4.21.2:
|
||||
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
|
@ -8333,6 +8332,9 @@ packages:
|
|||
resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
invariant@2.2.4:
|
||||
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
||||
|
||||
ioredis@5.7.0:
|
||||
resolution: {integrity: sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
|
@ -9878,10 +9880,6 @@ packages:
|
|||
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
pkce-challenge@5.0.0:
|
||||
resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
|
||||
pkg-dir@4.2.0:
|
||||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -10179,6 +10177,12 @@ packages:
|
|||
'@types/react': '>=18'
|
||||
react: '>=18'
|
||||
|
||||
react-mentions@4.4.10:
|
||||
resolution: {integrity: sha512-JHiQlgF1oSZR7VYPjq32wy97z1w1oE4x10EuhKjPr4WUKhVzG1uFQhQjKqjQkbVqJrmahf+ldgBTv36NrkpKpA==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.3'
|
||||
react-dom: '>=16.8.3'
|
||||
|
||||
react-player@3.3.2:
|
||||
resolution: {integrity: sha512-MBSCxTA1FPyMR19Wy+2LtVjguhrLl9p2l5nODY4fbumgsoaCEuhMLpZvxh8RWjzzvqL8V3jYcPfw/XhqrbTzFw==}
|
||||
peerDependencies:
|
||||
|
@ -10294,6 +10298,9 @@ packages:
|
|||
redux@4.2.1:
|
||||
resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
|
||||
|
||||
regenerator-runtime@0.13.11:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
|
||||
regex-recursion@6.0.2:
|
||||
resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
|
||||
|
||||
|
@ -10849,6 +10856,11 @@ packages:
|
|||
babel-plugin-macros:
|
||||
optional: true
|
||||
|
||||
substyle@9.4.1:
|
||||
resolution: {integrity: sha512-VOngeq/W1/UkxiGzeqVvDbGDPM8XgUyJVWjrqeh+GgKqspEPiLYndK+XRcsKUHM5Muz/++1ctJ1QCF/OqRiKWA==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.3'
|
||||
|
||||
sucrase@3.35.0:
|
||||
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
@ -13461,6 +13473,10 @@ snapshots:
|
|||
|
||||
'@babel/runtime@7.27.6': {}
|
||||
|
||||
'@babel/runtime@7.4.5':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.11
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
|
@ -14600,23 +14616,6 @@ snapshots:
|
|||
|
||||
'@microsoft/fetch-event-source@2.0.1': {}
|
||||
|
||||
'@modelcontextprotocol/sdk@1.17.5':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
content-type: 1.0.5
|
||||
cors: 2.8.5
|
||||
cross-spawn: 7.0.6
|
||||
eventsource: 3.0.7
|
||||
eventsource-parser: 3.0.6
|
||||
express: 5.1.0
|
||||
express-rate-limit: 7.5.1(express@5.1.0)
|
||||
pkce-challenge: 5.0.0
|
||||
raw-body: 3.0.1
|
||||
zod: 3.25.76
|
||||
zod-to-json-schema: 3.24.6(zod@3.25.76)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
dependencies:
|
||||
state-local: 1.0.7
|
||||
|
@ -17665,6 +17664,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/react': 19.1.12
|
||||
|
||||
'@types/react-mentions@4.4.1':
|
||||
dependencies:
|
||||
'@types/react': 19.1.12
|
||||
|
||||
'@types/react@19.1.12':
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
|
@ -17917,7 +17920,7 @@ snapshots:
|
|||
sirv: 3.0.1
|
||||
tinyglobby: 0.2.14
|
||||
tinyrainbow: 2.0.0
|
||||
vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@22.18.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.11.2(@types/node@22.18.0)(typescript@5.9.2))(sass@1.92.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)
|
||||
vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.10)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.5.1)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.11.2(@types/node@24.0.10)(typescript@5.9.2))(sass@1.92.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)
|
||||
|
||||
'@vitest/utils@3.2.4':
|
||||
dependencies:
|
||||
|
@ -18100,6 +18103,7 @@ snapshots:
|
|||
dependencies:
|
||||
mime-types: 3.0.1
|
||||
negotiator: 1.0.0
|
||||
optional: true
|
||||
|
||||
acorn-import-attributes@1.9.5(acorn@8.15.0):
|
||||
dependencies:
|
||||
|
@ -18157,6 +18161,7 @@ snapshots:
|
|||
fast-json-stable-stringify: 2.1.0
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
optional: true
|
||||
|
||||
ajv@8.17.1:
|
||||
dependencies:
|
||||
|
@ -18432,6 +18437,7 @@ snapshots:
|
|||
type-is: 2.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
boolbase@1.0.0: {}
|
||||
|
||||
|
@ -18857,6 +18863,7 @@ snapshots:
|
|||
content-disposition@1.0.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
optional: true
|
||||
|
||||
content-type@1.0.5: {}
|
||||
|
||||
|
@ -18872,7 +18879,8 @@ snapshots:
|
|||
|
||||
cookie-signature@1.0.6: {}
|
||||
|
||||
cookie-signature@1.2.2: {}
|
||||
cookie-signature@1.2.2:
|
||||
optional: true
|
||||
|
||||
cookie@0.4.2: {}
|
||||
|
||||
|
@ -19607,10 +19615,6 @@ snapshots:
|
|||
|
||||
expect-type@1.2.2: {}
|
||||
|
||||
express-rate-limit@7.5.1(express@5.1.0):
|
||||
dependencies:
|
||||
express: 5.1.0
|
||||
|
||||
express@4.21.2:
|
||||
dependencies:
|
||||
accepts: 1.3.8
|
||||
|
@ -19678,6 +19682,7 @@ snapshots:
|
|||
vary: 1.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
exsolve@1.0.7: {}
|
||||
|
||||
|
@ -19703,7 +19708,8 @@ snapshots:
|
|||
merge2: 1.4.1
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-json-stable-stringify@2.1.0: {}
|
||||
fast-json-stable-stringify@2.1.0:
|
||||
optional: true
|
||||
|
||||
fast-levenshtein@2.0.6:
|
||||
optional: true
|
||||
|
@ -19796,6 +19802,7 @@ snapshots:
|
|||
statuses: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
find-cache-dir@3.3.2:
|
||||
dependencies:
|
||||
|
@ -20322,6 +20329,7 @@ snapshots:
|
|||
iconv-lite@0.7.0:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
optional: true
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
|
@ -20435,6 +20443,10 @@ snapshots:
|
|||
|
||||
install@0.13.0: {}
|
||||
|
||||
invariant@2.2.4:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
|
||||
ioredis@5.7.0:
|
||||
dependencies:
|
||||
'@ioredis/commands': 1.3.1
|
||||
|
@ -20538,7 +20550,8 @@ snapshots:
|
|||
|
||||
is-potential-custom-element-name@1.0.1: {}
|
||||
|
||||
is-promise@4.0.0: {}
|
||||
is-promise@4.0.0:
|
||||
optional: true
|
||||
|
||||
is-property@1.0.2: {}
|
||||
|
||||
|
@ -20735,7 +20748,8 @@ snapshots:
|
|||
json-parse-even-better-errors@2.3.1:
|
||||
optional: true
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
json-schema-traverse@0.4.1:
|
||||
optional: true
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
|
||||
|
@ -21235,13 +21249,15 @@ snapshots:
|
|||
|
||||
media-typer@0.3.0: {}
|
||||
|
||||
media-typer@1.1.0: {}
|
||||
media-typer@1.1.0:
|
||||
optional: true
|
||||
|
||||
mensch@0.3.4: {}
|
||||
|
||||
merge-descriptors@1.0.3: {}
|
||||
|
||||
merge-descriptors@2.0.0: {}
|
||||
merge-descriptors@2.0.0:
|
||||
optional: true
|
||||
|
||||
merge-stream@2.0.0: {}
|
||||
|
||||
|
@ -21837,7 +21853,8 @@ snapshots:
|
|||
|
||||
negotiator@0.6.3: {}
|
||||
|
||||
negotiator@1.0.0: {}
|
||||
negotiator@1.0.0:
|
||||
optional: true
|
||||
|
||||
neo-async@2.6.2:
|
||||
optional: true
|
||||
|
@ -22308,7 +22325,8 @@ snapshots:
|
|||
|
||||
path-to-regexp@6.3.0: {}
|
||||
|
||||
path-to-regexp@8.3.0: {}
|
||||
path-to-regexp@8.3.0:
|
||||
optional: true
|
||||
|
||||
path-type@6.0.0: {}
|
||||
|
||||
|
@ -22409,8 +22427,6 @@ snapshots:
|
|||
|
||||
pirates@4.0.7: {}
|
||||
|
||||
pkce-challenge@5.0.0: {}
|
||||
|
||||
pkg-dir@4.2.0:
|
||||
dependencies:
|
||||
find-up: 4.1.0
|
||||
|
@ -22605,6 +22621,7 @@ snapshots:
|
|||
qs@6.14.0:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
optional: true
|
||||
|
||||
quansync@0.2.11: {}
|
||||
|
||||
|
@ -22637,6 +22654,7 @@ snapshots:
|
|||
http-errors: 2.0.0
|
||||
iconv-lite: 0.7.0
|
||||
unpipe: 1.0.0
|
||||
optional: true
|
||||
|
||||
rc9@2.1.2:
|
||||
dependencies:
|
||||
|
@ -22738,6 +22756,15 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
react-mentions@4.4.10(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.4.5
|
||||
invariant: 2.2.4
|
||||
prop-types: 15.8.1
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
substyle: 9.4.1(react@19.1.1)
|
||||
|
||||
react-player@3.3.2(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
|
||||
dependencies:
|
||||
'@mux/mux-player-react': 3.5.1(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
|
@ -22869,6 +22896,8 @@ snapshots:
|
|||
dependencies:
|
||||
'@babel/runtime': 7.27.6
|
||||
|
||||
regenerator-runtime@0.13.11: {}
|
||||
|
||||
regex-recursion@6.0.2:
|
||||
dependencies:
|
||||
regex-utilities: 2.3.0
|
||||
|
@ -23032,6 +23061,7 @@ snapshots:
|
|||
path-to-regexp: 8.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
rrweb-cssom@0.8.0: {}
|
||||
|
||||
|
@ -23609,6 +23639,12 @@ snapshots:
|
|||
'@babel/core': 7.28.4
|
||||
optional: true
|
||||
|
||||
substyle@9.4.1(react@19.1.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.6
|
||||
invariant: 2.2.4
|
||||
react: 19.1.1
|
||||
|
||||
sucrase@3.35.0:
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.12
|
||||
|
@ -23997,6 +24033,7 @@ snapshots:
|
|||
content-type: 1.0.5
|
||||
media-typer: 1.1.0
|
||||
mime-types: 3.0.1
|
||||
optional: true
|
||||
|
||||
typedarray-to-buffer@3.1.5:
|
||||
dependencies:
|
||||
|
@ -24213,6 +24250,7 @@ snapshots:
|
|||
uri-js@4.4.1:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
optional: true
|
||||
|
||||
use-callback-ref@1.3.3(@types/react@19.1.12)(react@19.1.1):
|
||||
dependencies:
|
||||
|
|
Loading…
Reference in New Issue