diff --git a/package-lock.json b/package-lock.json index 9ad63776..c1d3a806 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1038,6 +1038,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -3175,6 +3176,7 @@ "integrity": "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18" }, @@ -5846,6 +5848,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -5856,6 +5859,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -5865,8 +5869,7 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@types/unist": { "version": "3.0.3", @@ -5919,6 +5922,7 @@ "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", @@ -6437,6 +6441,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6760,6 +6765,7 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -6873,6 +6879,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -7532,7 +7539,6 @@ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -7879,6 +7885,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -8064,6 +8071,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -8366,6 +8374,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -10192,7 +10201,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -10968,6 +10976,7 @@ "resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz", "integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==", "license": "MIT", + "peer": true, "dependencies": { "@next/env": "16.0.10", "@swc/helpers": "0.5.15", @@ -11146,17 +11155,6 @@ } } }, - "node_modules/next-intl/node_modules/@swc/helpers": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", - "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/next-themes": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", @@ -12133,6 +12131,7 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -12164,6 +12163,7 @@ "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@prisma/config": "6.19.1", "@prisma/engines": "6.19.1" @@ -12343,6 +12343,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -12352,6 +12353,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -12364,6 +12366,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.68.0.tgz", "integrity": "sha512-oNN3fjrZ/Xo40SWlHf1yCjlMK417JxoSJVUXQjGdvdRCU07NTFei1i1f8ApUAts+IVh14e4EdakeLEA+BEAs/Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -13421,6 +13424,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13655,6 +13659,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14148,6 +14153,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 38a5a44b..cfbdfbb4 100644 --- a/package.json +++ b/package.json @@ -78,5 +78,8 @@ "tsx": "^4.21.0", "tw-animate-css": "^1.4.0", "typescript": "^5" + }, + "engines": { + "node": "24.x" } } diff --git a/scripts/check-translations.js b/scripts/check-translations.js index e30b7588..77aed969 100755 --- a/scripts/check-translations.js +++ b/scripts/check-translations.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +/* eslint-disable @typescript-eslint/no-require-imports */ const fs = require('fs'); const path = require('path'); diff --git a/scripts/setup.js b/scripts/setup.js index de1a274d..22988e94 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +/* eslint-disable @typescript-eslint/no-require-imports */ /** * Interactive setup script for private prompts.chat clones. diff --git a/src/app/[username]/page.tsx b/src/app/[username]/page.tsx index a9204a99..405cb5f7 100644 --- a/src/app/[username]/page.tsx +++ b/src/app/[username]/page.tsx @@ -12,7 +12,6 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { Card, CardContent } from "@/components/ui/card"; import { PromptList } from "@/components/prompts/prompt-list"; import { PromptCard, type PromptCardProps } from "@/components/prompts/prompt-card"; import { McpServerPopup } from "@/components/mcp/mcp-server-popup"; diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index b8f3138b..adabb740 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -5,7 +5,7 @@ import { auth } from "@/lib/auth"; import { db } from "@/lib/db"; import { Prisma } from "@prisma/client"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Users, FolderTree, Tags, FileText, Webhook, Flag } from "lucide-react"; import { UsersTable } from "@/components/admin/users-table"; import { CategoriesTable } from "@/components/admin/categories-table"; diff --git a/src/app/api/prompts/route.ts b/src/app/api/prompts/route.ts index a64ce284..98da879c 100644 --- a/src/app/api/prompts/route.ts +++ b/src/app/api/prompts/route.ts @@ -295,6 +295,7 @@ export async function GET(request: Request) { } // Build order by clause + // eslint-disable-next-line @typescript-eslint/no-explicit-any let orderBy: any = { createdAt: "desc" }; if (sort === "oldest") { orderBy = { createdAt: "asc" }; diff --git a/src/app/docs/self-hosting/page.tsx b/src/app/docs/self-hosting/page.tsx index 45582018..eaa4ce6b 100644 --- a/src/app/docs/self-hosting/page.tsx +++ b/src/app/docs/self-hosting/page.tsx @@ -564,7 +564,7 @@ export default function SelfHostingPage() {
  • Hide "Clone on GitHub" button
  • -

    // prompts.config.ts

    +

    {"// prompts.config.ts"}

    const useCloneBranding = true;

    diff --git a/src/app/prompts/[id]/page.tsx b/src/app/prompts/[id]/page.tsx index 3e06118e..b5bf67bf 100644 --- a/src/app/prompts/[id]/page.tsx +++ b/src/app/prompts/[id]/page.tsx @@ -3,7 +3,7 @@ import { notFound } from "next/navigation"; import Link from "next/link"; import { getTranslations, getLocale } from "next-intl/server"; import { formatDistanceToNow } from "@/lib/date"; -import { Calendar, Clock, Copy, Share2, Edit, History, GitPullRequest, Check, X, Users, ImageIcon, Video, FileText, Shield } from "lucide-react"; +import { Calendar, Clock, Edit, History, GitPullRequest, Check, X, Users, ImageIcon, Video, FileText, Shield } from "lucide-react"; import { ShareDropdown } from "@/components/prompts/share-dropdown"; import { auth } from "@/lib/auth"; import { db } from "@/lib/db"; diff --git a/src/app/prompts/page.tsx b/src/app/prompts/page.tsx index 0f5cfd2f..46fa185f 100644 --- a/src/app/prompts/page.tsx +++ b/src/app/prompts/page.tsx @@ -7,7 +7,7 @@ import { InfinitePromptList } from "@/components/prompts/infinite-prompt-list"; import { PromptFilters } from "@/components/prompts/prompt-filters"; import { FilterProvider } from "@/components/prompts/filter-context"; import { HFDataStudioDropdown } from "@/components/prompts/hf-data-studio-dropdown"; -import { McpServerPopup, McpIcon } from "@/components/mcp/mcp-server-popup"; +import { McpServerPopup } from "@/components/mcp/mcp-server-popup"; import { db } from "@/lib/db"; import { isAISearchEnabled, semanticSearch } from "@/lib/ai/embeddings"; import { isAIGenerationEnabled } from "@/lib/ai/generation"; @@ -122,6 +122,7 @@ export default async function PromptsPage({ searchParams }: PromptsPageProps) { const aiGenerationAvailable = await isAIGenerationEnabled(); const useAISearch = aiSearchAvailable && params.ai === "1" && params.q; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let prompts: any[] = []; let total = 0; @@ -176,6 +177,7 @@ export default async function PromptsPage({ searchParams }: PromptsPageProps) { // Build order by clause const isUpvoteSort = params.sort === "upvotes"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let orderBy: any = { createdAt: "desc" }; if (params.sort === "oldest") { orderBy = { createdAt: "asc" }; diff --git a/src/components/admin/prompts-management.tsx b/src/components/admin/prompts-management.tsx index b5d9ff42..584a9f52 100644 --- a/src/components/admin/prompts-management.tsx +++ b/src/components/admin/prompts-management.tsx @@ -6,7 +6,6 @@ import { useTranslations } from "next-intl"; import Link from "next/link"; import { Upload, Trash2, Loader2, CheckCircle, AlertCircle, Sparkles, Download, RefreshCw, Link2, Search, ExternalLink, Eye, EyeOff, Star, Flag, ChevronLeft, ChevronRight, Filter } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; diff --git a/src/components/admin/webhooks-table.tsx b/src/components/admin/webhooks-table.tsx index 2066933e..b26a7821 100644 --- a/src/components/admin/webhooks-table.tsx +++ b/src/components/admin/webhooks-table.tsx @@ -3,7 +3,6 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -13,7 +12,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; -import { Plus, MoreHorizontal, Pencil, Trash2, Webhook, Slack, X, Play } from "lucide-react"; +import { Plus, MoreHorizontal, Pencil, Trash2, Slack, X, Play } from "lucide-react"; import { SLACK_PRESET_PAYLOAD, WEBHOOK_PLACEHOLDERS } from "@/lib/webhook"; import { CodeEditor } from "@/components/ui/code-editor"; diff --git a/src/components/comments/comment-item.tsx b/src/components/comments/comment-item.tsx index ea67389a..a2542094 100644 --- a/src/components/comments/comment-item.tsx +++ b/src/components/comments/comment-item.tsx @@ -103,7 +103,7 @@ export function CommentItem({ isAdmin, isLoggedIn, locale, - replies, + replies: _replies, allComments, onCommentAdded, onCommentDeleted, diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx index ce08c556..bd4f33d1 100644 --- a/src/components/layout/header.tsx +++ b/src/components/layout/header.tsx @@ -43,7 +43,7 @@ import { import { NotificationBell } from "@/components/layout/notification-bell"; import { setLocale } from "@/lib/i18n/client"; import { useBranding } from "@/components/providers/branding-provider"; -import { analyticsAuth, analyticsNav, analyticsSettings } from "@/lib/analytics"; +import { analyticsAuth, analyticsSettings } from "@/lib/analytics"; const languages = [ { code: "en", name: "English" }, @@ -69,8 +69,6 @@ interface HeaderProps { export function Header({ authProvider = "credentials", allowRegistration = true }: HeaderProps) { const isOAuth = authProvider !== "credentials"; - // Show register button for OAuth (with login text) or credentials with registration enabled - const showRegisterButton = isOAuth || (authProvider === "credentials" && allowRegistration); const { data: session } = useSession(); const t = useTranslations(); const { theme, setTheme } = useTheme(); diff --git a/src/components/prompts/change-request-form.tsx b/src/components/prompts/change-request-form.tsx index 88d895f2..510c7e5d 100644 --- a/src/components/prompts/change-request-form.tsx +++ b/src/components/prompts/change-request-form.tsx @@ -3,7 +3,7 @@ import { useState, useRef } from "react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; -import { Loader2, Eye, Edit3, GitCompare } from "lucide-react"; +import { Loader2, Edit3, GitCompare } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Input } from "@/components/ui/input"; diff --git a/src/components/prompts/download-prompt-dropdown.tsx b/src/components/prompts/download-prompt-dropdown.tsx index 6e12e580..34135fee 100644 --- a/src/components/prompts/download-prompt-dropdown.tsx +++ b/src/components/prompts/download-prompt-dropdown.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { useTranslations } from "next-intl"; -import { Download, FileText, FileCode, Copy, Check, Link } from "lucide-react"; +import { Download, FileText, FileCode, Check, Link } from "lucide-react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, diff --git a/src/components/prompts/hero-prompt-input.tsx b/src/components/prompts/hero-prompt-input.tsx index 03f4df11..994b465f 100644 --- a/src/components/prompts/hero-prompt-input.tsx +++ b/src/components/prompts/hero-prompt-input.tsx @@ -56,8 +56,11 @@ export function HeroPromptInput() { setDisplayText((prev) => prev.slice(0, -1)); }, DELETE_SPEED); } else { - setIsDeleting(false); - setCurrentPromptIndex((prev) => (prev + 1) % examplePrompts.length); + // Schedule state updates to avoid synchronous setState in effect + animationRef.current = setTimeout(() => { + setIsDeleting(false); + setCurrentPromptIndex((prev) => (prev + 1) % examplePrompts.length); + }, 0); } } else { if (displayText.length < currentPrompt.length) { diff --git a/src/components/prompts/hf-data-studio-dropdown.tsx b/src/components/prompts/hf-data-studio-dropdown.tsx index d6bddf34..0130e600 100644 --- a/src/components/prompts/hf-data-studio-dropdown.tsx +++ b/src/components/prompts/hf-data-studio-dropdown.tsx @@ -6,7 +6,6 @@ import { useTheme } from "next-themes"; import { ChevronDown, Play, ExternalLink, Sparkles, Loader2 } from "lucide-react"; import Editor from "@monaco-editor/react"; import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; import { Popover, PopoverContent, diff --git a/src/components/prompts/infinite-prompt-list.tsx b/src/components/prompts/infinite-prompt-list.tsx index 5df12bf3..ee5cfcc2 100644 --- a/src/components/prompts/infinite-prompt-list.tsx +++ b/src/components/prompts/infinite-prompt-list.tsx @@ -49,7 +49,7 @@ export function InfinitePromptList({ filters }: InfinitePromptListProps) { const t = useTranslations("prompts"); - const searchParams = useSearchParams(); + const _searchParams = useSearchParams(); const { isFilterPending, setFilterPending } = useFilterContext(); const [prompts, setPrompts] = useState(initialPrompts); const [page, setPage] = useState(1); diff --git a/src/components/prompts/interactive-prompt-content.tsx b/src/components/prompts/interactive-prompt-content.tsx index b87b6917..a91c5eae 100644 --- a/src/components/prompts/interactive-prompt-content.tsx +++ b/src/components/prompts/interactive-prompt-content.tsx @@ -78,10 +78,11 @@ function EditableSpan({ if (!value && !document.activeElement?.isSameNode(spanRef.current)) { // Show placeholder when empty and not focused spanRef.current.textContent = placeholder; - setIsShowingPlaceholder(true); + // Sync state with DOM - intentional pattern + queueMicrotask(() => setIsShowingPlaceholder(true)); } else if (value && spanRef.current.textContent !== value) { spanRef.current.textContent = value; - setIsShowingPlaceholder(false); + queueMicrotask(() => setIsShowingPlaceholder(false)); } } }, [value, placeholder]); diff --git a/src/components/prompts/private-prompts-note.tsx b/src/components/prompts/private-prompts-note.tsx index bbd09693..c99d24d3 100644 --- a/src/components/prompts/private-prompts-note.tsx +++ b/src/components/prompts/private-prompts-note.tsx @@ -17,7 +17,8 @@ export function PrivatePromptsNote({ count }: PrivatePromptsNoteProps) { useEffect(() => { const dismissed = localStorage.getItem(STORAGE_KEY) === "true"; - setIsDismissed(dismissed); + // Read from localStorage on mount - use queueMicrotask to avoid sync setState + queueMicrotask(() => setIsDismissed(dismissed)); }, []); const handleDismiss = () => { diff --git a/src/components/prompts/prompt-builder.tsx b/src/components/prompts/prompt-builder.tsx index bad01c77..ecb863ca 100644 --- a/src/components/prompts/prompt-builder.tsx +++ b/src/components/prompts/prompt-builder.tsx @@ -166,8 +166,8 @@ export const PromptBuilder = forwardRef } let fullContent = ""; - let toolCalls: ToolCall[] = []; - let searchResults: Message["searchResults"] = []; + const toolCalls: ToolCall[] = []; + const searchResults: Message["searchResults"] = []; let newState: PromptBuilderState | null = null; while (true) { diff --git a/src/components/prompts/prompt-form.tsx b/src/components/prompts/prompt-form.tsx index de2dd9f5..1f6a6618 100644 --- a/src/components/prompts/prompt-form.tsx +++ b/src/components/prompts/prompt-form.tsx @@ -739,6 +739,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors {isStructuredInput && ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any