diff --git a/apps/code/package.json b/apps/code/package.json
index 188469e3e..de26dbe59 100644
--- a/apps/code/package.json
+++ b/apps/code/package.json
@@ -133,7 +133,7 @@
"@posthog/git": "workspace:*",
"@posthog/hedgehog-mode": "^0.0.48",
"@posthog/platform": "workspace:*",
- "@posthog/quill": "0.1.0-alpha.7",
+ "@posthog/quill": "0.3.0-beta.1",
"@posthog/shared": "workspace:*",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-icons": "^1.3.2",
@@ -186,16 +186,17 @@
"react-markdown": "^10.1.0",
"react-resizable-panels": "^3.0.6",
"reflect-metadata": "^0.2.2",
- "semver": "^7.6.0",
"rehype-raw": "^7.0.0",
"rehype-sanitize": "^6.0.0",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1",
+ "semver": "^7.6.0",
"shadcn": "^4.1.2",
"smol-toml": "^1.6.0",
"sonner": "^2.0.7",
"striptags": "^3.2.0",
"tailwind-merge": "^3.5.0",
+ "tailwindcss-scroll-mask": "^0.0.3",
"tippy.js": "^6.3.7",
"tw-animate-css": "^1.4.0",
"vaul": "^1.1.2",
diff --git a/apps/code/src/renderer/features/command/components/CommandKeyHints.tsx b/apps/code/src/renderer/features/command/components/CommandKeyHints.tsx
index 865cac623..c06f67b35 100644
--- a/apps/code/src/renderer/features/command/components/CommandKeyHints.tsx
+++ b/apps/code/src/renderer/features/command/components/CommandKeyHints.tsx
@@ -1,34 +1,27 @@
-import { KeyHint } from "@features/command/components/KeyHint";
-import { Code, Flex } from "@radix-ui/themes";
+import { Kbd, KbdGroup } from "@posthog/quill";
export function CommandKeyHints() {
return (
-
-
-
-
- Navigate
-
-
-
-
-
- Select
-
-
-
-
-
- Close
-
-
-
+
+
+
+ ↑
+ ↓
+
+ navigate
+
+
+
+ ↵
+
+ select
+
+
+
+ Esc
+
+ close
+
+
);
}
diff --git a/apps/code/src/renderer/features/command/components/CommandMenu.tsx b/apps/code/src/renderer/features/command/components/CommandMenu.tsx
index 48cbcde36..3fafe99f4 100644
--- a/apps/code/src/renderer/features/command/components/CommandMenu.tsx
+++ b/apps/code/src/renderer/features/command/components/CommandMenu.tsx
@@ -1,9 +1,20 @@
import { useReviewNavigationStore } from "@features/code-review/stores/reviewNavigationStore";
-import { Command } from "@features/command/components/Command";
import { CommandKeyHints } from "@features/command/components/CommandKeyHints";
import { useFolders } from "@features/folders/hooks/useFolders";
import { useSettingsDialogStore } from "@features/settings/stores/settingsDialogStore";
import { useSidebarStore } from "@features/sidebar/stores/sidebarStore";
+import {
+ Autocomplete,
+ AutocompleteCollection,
+ AutocompleteGroup,
+ AutocompleteInput,
+ AutocompleteItem,
+ AutocompleteLabel,
+ AutocompleteList,
+ AutocompleteStatus,
+ Dialog,
+ DialogContent,
+} from "@posthog/quill";
import {
DesktopIcon,
FileTextIcon,
@@ -13,27 +24,37 @@ import {
SunIcon,
ViewVerticalIcon,
} from "@radix-ui/react-icons";
-import { Flex, Text } from "@radix-ui/themes";
import {
ANALYTICS_EVENTS,
type CommandMenuAction,
} from "@shared/types/analytics";
import { useNavigationStore } from "@stores/navigationStore";
-import { THEME_CYCLE_LABELS, useThemeStore } from "@stores/themeStore";
+import { useThemeStore } from "@stores/themeStore";
import { track } from "@utils/analytics";
-import { useCallback, useEffect, useRef } from "react";
-import { useHotkeys } from "react-hotkeys-hook";
+import { useCallback, useEffect, useMemo, useState } from "react";
interface CommandMenuProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
+type Command = {
+ id: string;
+ label: string;
+ keywords?: string;
+ icon: React.ReactNode;
+ action: CommandMenuAction;
+ onRun: () => void;
+};
+
+type CommandSection = { label: string; items: Command[] };
+
export function CommandMenu({ open, onOpenChange }: CommandMenuProps) {
const { navigateToTaskInput } = useNavigationStore();
const openSettingsDialog = useSettingsDialogStore((state) => state.open);
+ const closeSettingsDialog = useSettingsDialogStore((state) => state.close);
const { folders } = useFolders();
- const { theme, cycleTheme } = useThemeStore();
+ const { theme, setTheme } = useThemeStore();
const toggleLeftSidebar = useSidebarStore((state) => state.toggle);
const view = useNavigationStore((state) => state.view);
const setReviewMode = useReviewNavigationStore(
@@ -42,6 +63,19 @@ export function CommandMenu({ open, onOpenChange }: CommandMenuProps) {
const getReviewMode = useReviewNavigationStore(
(state) => state.getReviewMode,
);
+ const [query, setQuery] = useState("");
+ const [systemPrefersDark, setSystemPrefersDark] = useState(
+ () => window.matchMedia("(prefers-color-scheme: dark)").matches,
+ );
+
+ useEffect(() => {
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
+ const onChange = (e: MediaQueryListEvent) =>
+ setSystemPrefersDark(e.matches);
+ mq.addEventListener("change", onChange);
+ return () => mq.removeEventListener("change", onChange);
+ }, []);
+
const openReviewPanel = useCallback(() => {
const taskId = view.type === "task-detail" ? view.data?.id : undefined;
if (!taskId) return;
@@ -50,179 +84,209 @@ export function CommandMenu({ open, onOpenChange }: CommandMenuProps) {
setReviewMode(taskId, "split");
}
}, [view, getReviewMode, setReviewMode]);
- const commandRef = useRef(null);
-
- const close = useCallback(() => onOpenChange(false), [onOpenChange]);
-
- const trackAction = useCallback((action: CommandMenuAction) => {
- track(ANALYTICS_EVENTS.COMMAND_MENU_ACTION, { action_type: action });
- }, []);
-
- const runAndClose = useCallback(
- (
- fn: (...args: T) => void,
- action?: CommandMenuAction,
- ) =>
- (...args: T) => {
- if (action) {
- trackAction(action);
- }
- fn(...args);
- close();
- },
- [close, trackAction],
- );
useEffect(() => {
if (open) {
track(ANALYTICS_EVENTS.COMMAND_MENU_OPENED);
+ } else {
+ setQuery("");
}
}, [open]);
- useHotkeys("escape", close, {
- enabled: open,
- enableOnContentEditable: true,
- enableOnFormTags: true,
- preventDefault: true,
- });
-
- useHotkeys("mod+k", close, {
- enabled: open,
- enableOnContentEditable: true,
- enableOnFormTags: true,
- preventDefault: true,
- });
-
- useHotkeys("mod+p", close, {
- enabled: open,
- enableOnContentEditable: true,
- enableOnFormTags: true,
- preventDefault: true,
- });
+ const themeOptions = useMemo(() => {
+ const options: Command[] = [];
+ if (theme !== "light") {
+ options.push({
+ id: "switch-theme-light",
+ label: "Switch to light mode",
+ keywords: "theme appearance",
+ icon: ,
+ action: "toggle-theme",
+ onRun: () => setTheme("light"),
+ });
+ }
+ if (theme !== "dark") {
+ options.push({
+ id: "switch-theme-dark",
+ label: "Switch to dark mode",
+ keywords: "theme appearance",
+ icon: ,
+ action: "toggle-theme",
+ onRun: () => setTheme("dark"),
+ });
+ }
+ const systemMatchesCurrent =
+ (theme === "dark" && systemPrefersDark) ||
+ (theme === "light" && !systemPrefersDark);
+ if (theme !== "system" && !systemMatchesCurrent) {
+ options.push({
+ id: "switch-theme-system",
+ label: "Switch to system theme",
+ keywords: "theme appearance auto",
+ icon: ,
+ action: "toggle-theme",
+ onRun: () => setTheme("system"),
+ });
+ }
+ return options;
+ }, [theme, setTheme, systemPrefersDark]);
- useEffect(() => {
- if (!open) return;
+ const sections = useMemo(() => {
+ const navigation: Command[] = [
+ {
+ id: "home",
+ label: "Home",
+ icon: ,
+ action: "home",
+ onRun: () => {
+ closeSettingsDialog();
+ navigateToTaskInput();
+ },
+ },
+ {
+ id: "settings",
+ label: "Settings",
+ icon: ,
+ action: "settings",
+ onRun: () => openSettingsDialog(),
+ },
+ ];
+
+ const actions: Command[] = [
+ ...themeOptions,
+ {
+ id: "toggle-left-sidebar",
+ label: "Toggle left sidebar",
+ icon: ,
+ action: "toggle-left-sidebar",
+ onRun: toggleLeftSidebar,
+ },
+ {
+ id: "open-review-panel",
+ label: "Open review panel",
+ icon: ,
+ action: "open-review-panel",
+ onRun: openReviewPanel,
+ },
+ {
+ id: "new-task",
+ label: "New task",
+ keywords: "create",
+ icon: ,
+ action: "new-task",
+ onRun: () => {
+ closeSettingsDialog();
+ navigateToTaskInput();
+ },
+ },
+ ];
- const handleClickOutside = (event: MouseEvent) => {
- if (
- commandRef.current &&
- !commandRef.current.contains(event.target as Node)
- ) {
- close();
- }
- };
+ const out: CommandSection[] = [
+ { label: "Navigation", items: navigation },
+ { label: "Actions", items: actions },
+ ];
- document.addEventListener("mousedown", handleClickOutside);
- return () => document.removeEventListener("mousedown", handleClickOutside);
- }, [open, close]);
+ if (folders.length > 0) {
+ out.push({
+ label: "New task in folder",
+ items: folders.map((folder) => ({
+ id: `new-task-folder-${folder.id}`,
+ label: `New task in ${folder.name}`,
+ keywords: folder.path,
+ icon: ,
+ action: "new-task",
+ onRun: () => {
+ closeSettingsDialog();
+ navigateToTaskInput(folder.id);
+ },
+ })),
+ });
+ }
- if (!open) return null;
+ return out;
+ }, [
+ folders,
+ themeOptions,
+ navigateToTaskInput,
+ openSettingsDialog,
+ closeSettingsDialog,
+ toggleLeftSidebar,
+ openReviewPanel,
+ ]);
+
+ const allCommands = useMemo(
+ () => sections.flatMap((s) => s.items),
+ [sections],
+ );
+
+ const handleSelect = (id: string | null): void => {
+ if (id === null) return;
+ const cmd = allCommands.find((c) => c.id === id);
+ if (!cmd) return;
+ track(ANALYTICS_EVENTS.COMMAND_MENU_ACTION, { action_type: cmd.action });
+ cmd.onRun();
+ onOpenChange(false);
+ setQuery("");
+ };
return (
-
-
+
-
-
-
-
-
-
- No results found.
-
-
-
-
- Home
-
- openSettingsDialog(), "settings")}
- >
-
- Settings
-
-
-
-
-
- {theme === "dark" && (
-
- )}
- {theme === "light" && (
-
- )}
- {theme === "system" && (
-
- )}
- {THEME_CYCLE_LABELS[theme]}
-
-
-
- Toggle left sidebar
-
-
-
- Open review panel
-
-
-
- New task
-
-
-
- {folders.length > 0 && (
-
- {folders.map((folder) => (
- navigateToTaskInput(folder.id),
- "new-task",
- )}
- >
-
-
- New task in{" "}
- {folder.name}
-
-
- ))}
-
+
+ inline
+ defaultOpen
+ items={sections}
+ value={query}
+ autoHighlight="always"
+ onValueChange={(val, eventDetails) => {
+ if (eventDetails.reason !== "input-change") return;
+ if (typeof val === "string") {
+ setQuery(val);
+ }
+ }}
+ filter={(cmd, q) => {
+ if (!q) return true;
+ const haystack = `${cmd.label} ${cmd.keywords ?? ""}`.toLowerCase();
+ return haystack.includes(q.toLowerCase());
+ }}
+ >
+
+
+ No commands match "{query}"
+
+ }
+ />
+
+ {(section: CommandSection) => (
+
+ {section.label}
+
+ {(cmd: Command) => (
+ handleSelect(cmd.id)}
+ >
+ {cmd.icon}
+ {cmd.label}
+
+ )}
+
+
)}
-
-
-
+
+
-
-
+
+
);
}
diff --git a/apps/code/src/renderer/features/command/components/FilePicker.css b/apps/code/src/renderer/features/command/components/FilePicker.css
deleted file mode 100644
index 648605def..000000000
--- a/apps/code/src/renderer/features/command/components/FilePicker.css
+++ /dev/null
@@ -1,112 +0,0 @@
-.file-picker-popover [cmdk-root] {
- width: 640px;
- min-width: 640px;
- background: var(--color-panel-solid);
- border-radius: var(--radius-3);
- border: 1px solid var(--gray-6);
- box-shadow: var(--shadow-6);
- overflow: hidden;
-}
-
-.file-picker-popover [cmdk-input] {
- font-family: var(--default-font-family);
- font-size: 13px;
- padding: 12px 16px;
- width: 100%;
- background: transparent;
- border: none;
- outline: none;
- color: var(--gray-12);
- caret-color: var(--accent-9);
-}
-
-.file-picker-popover [cmdk-input]::placeholder {
- color: var(--gray-9);
-}
-
-.file-picker-popover [cmdk-list] {
- max-height: 400px;
- overflow-y: auto;
- overflow-x: hidden;
- overscroll-behavior: contain;
- transition: height 150ms ease;
-}
-
-.file-picker-popover [cmdk-list]::-webkit-scrollbar {
- width: 8px;
-}
-
-.file-picker-popover [cmdk-list]::-webkit-scrollbar-track {
- background: transparent;
-}
-
-.file-picker-popover [cmdk-list]::-webkit-scrollbar-thumb {
- background: var(--gray-6);
- border-radius: 4px;
-}
-
-.file-picker-popover [cmdk-list]::-webkit-scrollbar-thumb:hover {
- background: var(--gray-7);
-}
-
-.file-picker-popover [cmdk-group] {
- padding: 4px 8px;
-}
-
-.file-picker-popover [cmdk-group-heading] {
- font-size: 12px;
- font-weight: 500;
- color: var(--gray-11);
- padding: 8px 12px 4px;
- text-transform: uppercase;
- letter-spacing: 0.05em;
-}
-
-.file-picker-popover [cmdk-item] {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 8px 12px;
- border-radius: var(--radius-2);
- cursor: pointer;
- user-select: none;
- transition: background-color 150ms ease;
- color: var(--gray-12);
-}
-
-.file-picker-popover [cmdk-item][data-selected="true"] {
- background: var(--accent-3);
- color: var(--accent-11);
-}
-
-.file-picker-popover [cmdk-item][data-disabled="true"] {
- opacity: 0.5;
- cursor: not-allowed;
- pointer-events: none;
-}
-
-.file-picker-popover [cmdk-item]:active {
- background: var(--accent-4);
-}
-
-.file-picker-popover [cmdk-empty] {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 64px;
- font-size: 13px;
- color: var(--gray-9);
-}
-
-.file-picker-popover [cmdk-separator] {
- height: 1px;
- background: var(--gray-6);
- margin: 4px 0;
-}
-
-.rt-PopoverContent:has(.file-picker-popover) {
- padding: 0;
- background: transparent;
- border: none;
- box-shadow: none;
-}
diff --git a/apps/code/src/renderer/features/command/components/FilePicker.tsx b/apps/code/src/renderer/features/command/components/FilePicker.tsx
index 25f755f35..c9da87672 100644
--- a/apps/code/src/renderer/features/command/components/FilePicker.tsx
+++ b/apps/code/src/renderer/features/command/components/FilePicker.tsx
@@ -1,10 +1,25 @@
import { FileIcon } from "@components/ui/FileIcon";
+import { CommandKeyHints } from "@features/command/components/CommandKeyHints";
import { usePanelLayoutStore } from "@features/panels/store/panelLayoutStore";
-import { pathToFileItem, searchFiles, useRepoFiles } from "@hooks/useRepoFiles";
-import { Popover, Text } from "@radix-ui/themes";
+import {
+ type FileItem,
+ pathToFileItem,
+ searchFiles,
+ useRepoFiles,
+} from "@hooks/useRepoFiles";
+import {
+ Autocomplete,
+ AutocompleteCollection,
+ AutocompleteGroup,
+ AutocompleteInput,
+ AutocompleteItem,
+ AutocompleteLabel,
+ AutocompleteList,
+ AutocompleteStatus,
+ Dialog,
+ DialogContent,
+} from "@posthog/quill";
import { useCallback, useMemo, useState } from "react";
-import { Command } from "./Command";
-import "./FilePicker.css";
interface FilePickerProps {
open: boolean;
@@ -13,6 +28,12 @@ interface FilePickerProps {
repoPath: string | undefined;
}
+type FileSection = { label?: string; items: FileItem[] };
+
+// Cap the empty-query list to keep render cost bounded without virtualization.
+// Typed queries are already capped upstream by fzf (MENTION_DISPLAY_LIMIT = 20).
+const EMPTY_QUERY_LIMIT = 200;
+
export function FilePicker({
open,
onOpenChange,
@@ -28,84 +49,106 @@ export function FilePicker({
const handleOpenChange = useCallback(
(isOpen: boolean) => {
onOpenChange(isOpen);
- if (!isOpen) {
- setSearchQuery("");
- }
+ if (!isOpen) setSearchQuery("");
},
[onOpenChange],
);
const { files: fileItems, fzf } = useRepoFiles(repoPath, open);
- const displayedFiles = useMemo(() => {
- if (!searchQuery.trim() && recentFiles.length > 0) {
- return recentFiles.map(pathToFileItem);
+ const sections = useMemo(() => {
+ if (searchQuery.trim()) {
+ return [{ items: searchFiles(fzf, fileItems, searchQuery) }];
+ }
+ if (recentFiles.length === 0) {
+ return [{ items: fileItems.slice(0, EMPTY_QUERY_LIMIT) }];
}
- return searchFiles(fzf, fileItems, searchQuery);
+ // recentFiles is string[] of paths from panelLayoutStore, ordered most-recent-first.
+ const recentPathSet = new Set(recentFiles);
+ const recentItems = recentFiles.map(pathToFileItem);
+ const rest = fileItems
+ .filter((f) => !recentPathSet.has(f.path))
+ .slice(0, Math.max(0, EMPTY_QUERY_LIMIT - recentItems.length));
+ return [
+ { label: "Recent", items: recentItems },
+ { label: "Other files", items: rest },
+ ];
}, [fzf, fileItems, searchQuery, recentFiles]);
- const resultsKey = useMemo(
- () => displayedFiles.map((f) => f.path).join(","),
- [displayedFiles],
- );
-
const handleSelect = useCallback(
- (filePath: string) => {
- openFileInSplit(taskId, filePath, false);
+ (path: string) => {
+ openFileInSplit(taskId, path, false);
handleOpenChange(false);
},
[openFileInSplit, taskId, handleOpenChange],
);
return (
-
-
-
-
- handleOpenChange(false)}
+
-
+
+ {(file: FileItem) => (
+ handleSelect(file.path)}
+ className="block"
+ >
+
+ {file.name}
+ {file.dir && (
+
+ {file.dir}
+
+ )}
+
+ )}
+
+
+ )}
+
+
+
+
+
);
}
diff --git a/apps/code/src/renderer/features/command/components/KeyHint.tsx b/apps/code/src/renderer/features/command/components/KeyHint.tsx
deleted file mode 100644
index d456e195c..000000000
--- a/apps/code/src/renderer/features/command/components/KeyHint.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Kbd } from "@radix-ui/themes";
-
-interface KeyHintProps {
- keys: string[];
- className?: string;
-}
-
-export function KeyHint({ keys, className }: KeyHintProps) {
- return (
-
- {keys.map((key) => (
-
- {key}
-
- ))}
-
- );
-}
diff --git a/apps/code/src/renderer/features/editor/components/GithubRefChip.tsx b/apps/code/src/renderer/features/editor/components/GithubRefChip.tsx
index cd2d96475..ccd97bb67 100644
--- a/apps/code/src/renderer/features/editor/components/GithubRefChip.tsx
+++ b/apps/code/src/renderer/features/editor/components/GithubRefChip.tsx
@@ -15,7 +15,6 @@ export function GithubRefChip({
return (
window.open(href, "_blank")}
className="cli-file-mention mx-0.5 max-w-full cursor-pointer! whitespace-nowrap pl-1 align-middle active:translate-y-0"
>
diff --git a/apps/code/src/renderer/features/message-editor/tiptap/MentionChipView.tsx b/apps/code/src/renderer/features/message-editor/tiptap/MentionChipView.tsx
index a1673d0d5..3d87a65da 100644
--- a/apps/code/src/renderer/features/message-editor/tiptap/MentionChipView.tsx
+++ b/apps/code/src/renderer/features/message-editor/tiptap/MentionChipView.tsx
@@ -87,7 +87,6 @@ function DefaultChip({
const chipContent = (
window.open(id, "_blank") : undefined}
className={`${chipBase} max-w-full whitespace-nowrap ${isGithubRef ? "cursor-pointer!" : "cursor-default! active:translate-y-0!"} ${isCommand ? "cli-slash-command" : "cli-file-mention"} ${selected ? selectedRing : ""}`}
@@ -148,7 +147,6 @@ function PastedTextChip({
=20'}
peerDependencies:
- react: ^19.0.0
- react-dom: ^19.0.0
+ react: ^18.3.1 || ^19.0.0
+ react-dom: ^18.3.1 || ^19.0.0
tailwindcss: ^4.0.0
'@posthog/rollup-plugin@1.4.0':
@@ -10824,6 +10827,11 @@ packages:
tailwind-merge@3.5.0:
resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==}
+ tailwindcss-scroll-mask@0.0.3:
+ resolution: {integrity: sha512-vPuacFs5yHJRZ8MFP/qqKKRbnWlVDPAJ5VfRzOwrmtEJQ4pHm5K1xw/dXdF4v6Sx1QdbtCWJuGs9ucSTc+YanQ==}
+ peerDependencies:
+ tailwindcss: ^4
+
tailwindcss@3.4.19:
resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
engines: {node: '>=14.0.0'}
@@ -15286,22 +15294,19 @@ snapshots:
dependencies:
cross-spawn: 7.0.6
- '@posthog/quill@0.1.0-alpha.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.2.2)':
+ '@posthog/quill@0.3.0-beta.1(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.2.2)':
dependencies:
'@base-ui/react': 1.3.0(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
class-variance-authority: 0.7.1
clsx: 2.1.1
- cmdk: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
lucide-react: 0.577.0(react@19.1.0)
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
react-resizable-panels: 4.10.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
tailwind-merge: 2.6.1
tailwindcss: 4.2.2
- vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- '@types/react'
- - '@types/react-dom'
'@posthog/rollup-plugin@1.4.0(rollup@4.57.1)':
dependencies:
@@ -23493,6 +23498,10 @@ snapshots:
tailwind-merge@3.5.0: {}
+ tailwindcss-scroll-mask@0.0.3(tailwindcss@4.2.2):
+ dependencies:
+ tailwindcss: 4.2.2
+
tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2):
dependencies:
'@alloc/quick-lru': 5.2.0