@@ -9,13 +9,14 @@ import TableOfContents from '@/components/TableOfContents';
99import RepoMetadata from '@/components/RepoMetadata' ;
1010import WikiTreeView from '@/components/WikiTreeView' ;
1111import ExportMenu from '@/components/ExportMenu' ;
12+ import WaitlistModal from '@/components/WaitlistModal' ;
1213import { useLanguage } from '@/contexts/LanguageContext' ;
1314import { RepoInfo } from '@/types/repoinfo' ;
1415import Link from 'next/link' ;
1516import { useParams , useSearchParams } from 'next/navigation' ;
1617import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
1718import { motion } from 'framer-motion' ;
18- import { ArrowLeft , Book , BookOpen , List , MessageSquare , AlertTriangle , Home , Network , Search , RefreshCw , X } from 'lucide-react' ;
19+ import { ArrowLeft , Book , BookOpen , List , Lock , MessageSquare , AlertTriangle , Home , Network , Search , RefreshCw , X } from 'lucide-react' ;
1920import DependencyGraph from '@/components/DependencyGraph' ;
2021import WikiSidebarSkeleton from '@/components/skeletons/WikiSidebarSkeleton' ;
2122import WikiContentSkeleton from '@/components/skeletons/WikiContentSkeleton' ;
@@ -28,6 +29,7 @@ import { useWikiCache } from '@/hooks/useWikiCache';
2829import { useRepoStructure } from '@/hooks/useRepoStructure' ;
2930import { useWikiExport } from '@/hooks/useWikiExport' ;
3031import { wikiStyles } from '@/styles/wikiStyles' ;
32+ import { SignInButton } from '@clerk/nextjs' ;
3133
3234export default function RepoWikiPage ( ) {
3335 // Get route parameters and search params
@@ -153,7 +155,20 @@ export default function RepoWikiPage() {
153155 } | null > ( null ) ;
154156
155157 // Authentication (extracted hook)
156- const { authRequired, authCode, setAuthCode, isAuthLoading } = useAuthentication ( ) ;
158+ const { authRequired, authCode, setAuthCode, isAuthLoading, isAuthenticated, getToken } = useAuthentication ( ) ;
159+
160+ // Clerk JWT token for WebSocket auth
161+ const [ clerkToken , setClerkToken ] = useState < string | null > ( null ) ;
162+
163+ // Waitlist modal state
164+ const [ isWaitlistModalOpen , setIsWaitlistModalOpen ] = useState ( false ) ;
165+
166+ // Fetch Clerk token when authenticated
167+ useEffect ( ( ) => {
168+ if ( isAuthenticated ) {
169+ getToken ( ) . then ( setClerkToken ) ;
170+ }
171+ } , [ isAuthenticated , getToken ] ) ;
157172
158173 // Default branch state
159174 const [ defaultBranch , setDefaultBranch ] = useState < string > ( 'main' ) ;
@@ -235,6 +250,7 @@ export default function RepoWikiPage() {
235250 modelIncludedFiles,
236251 isComprehensiveView,
237252 selectedTemplate,
253+ clerkToken,
238254 setIsLoading,
239255 setLoadingMessage,
240256 setError,
@@ -259,6 +275,7 @@ export default function RepoWikiPage() {
259275 modelExcludedFiles,
260276 authRequired,
261277 authCode,
278+ isClerkAuthenticated : isAuthenticated ,
262279 setIsLoading,
263280 setLoadingMessage,
264281 setError,
@@ -532,6 +549,37 @@ export default function RepoWikiPage() {
532549 </ div >
533550 </ >
534551
552+ ) : error === '__AUTH_REQUIRED__' ? (
553+ /* Auth gate: user needs to sign in to generate new wikis */
554+ < div className = "max-w-md mx-auto mt-16 p-8 border border-border bg-card rounded-xl text-center" >
555+ < div className = "inline-flex items-center justify-center p-3 bg-primary/10 rounded-full mb-4" >
556+ < Lock size = { 24 } className = "text-primary" />
557+ </ div >
558+ < h3 className = "text-xl font-semibold text-foreground mb-2" > Sign in to Generate Wikis</ h3 >
559+ < p className = "text-muted-foreground mb-6 text-sm" >
560+ This repository doesn't have a cached wiki yet. Sign in to generate an AI-powered wiki for < strong > { owner } /{ repo } </ strong > .
561+ </ p >
562+ < div className = "flex flex-col gap-3 items-center" >
563+ < SignInButton mode = "modal" >
564+ < button className = "inline-flex items-center justify-center rounded-md text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-6 py-2 transition-colors" >
565+ Sign In to Generate
566+ </ button >
567+ </ SignInButton >
568+ < button
569+ onClick = { ( ) => setIsWaitlistModalOpen ( true ) }
570+ className = "text-sm text-muted-foreground hover:text-foreground transition-colors underline underline-offset-4"
571+ >
572+ Or join the waitlist
573+ </ button >
574+ < Link
575+ href = "/"
576+ className = "mt-2 inline-flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
577+ >
578+ < Home size = { 14 } className = "mr-1.5" />
579+ Back to Home
580+ </ Link >
581+ </ div >
582+ </ div >
535583 ) : error ? (
536584 < div className = "max-w-2xl mx-auto mt-12 p-6 border border-destructive/20 bg-destructive/5 rounded-xl text-center" >
537585 < div className = "inline-flex items-center justify-center p-3 bg-destructive/10 rounded-full mb-4" >
@@ -902,16 +950,33 @@ export default function RepoWikiPage() {
902950 </ div >
903951 { /* Drawer body */ }
904952 < div className = "flex-1 overflow-y-auto" >
905- { effectiveRepoInfo && (
906- < Ask
907- repoInfo = { effectiveRepoInfo }
908- provider = { selectedProviderState }
909- model = { selectedModelState }
910- isCustomModel = { isCustomSelectedModelState }
911- customModel = { customSelectedModelState }
912- language = { language }
913- onRef = { ( ref ) => ( askComponentRef . current = ref ) }
914- />
953+ { isAuthenticated ? (
954+ effectiveRepoInfo && (
955+ < Ask
956+ repoInfo = { effectiveRepoInfo }
957+ provider = { selectedProviderState }
958+ model = { selectedModelState }
959+ isCustomModel = { isCustomSelectedModelState }
960+ customModel = { customSelectedModelState }
961+ language = { language }
962+ onRef = { ( ref ) => ( askComponentRef . current = ref ) }
963+ />
964+ )
965+ ) : (
966+ < div className = "flex flex-col items-center justify-center h-full px-8 text-center" >
967+ < div className = "inline-flex items-center justify-center p-3 bg-primary/10 rounded-full mb-4" >
968+ < Lock size = { 24 } className = "text-primary" />
969+ </ div >
970+ < h3 className = "text-lg font-semibold text-foreground mb-2" > Sign in to Chat</ h3 >
971+ < p className = "text-sm text-muted-foreground mb-6" >
972+ Sign in to ask questions and chat with this codebase using AI.
973+ </ p >
974+ < SignInButton mode = "modal" >
975+ < button className = "inline-flex items-center justify-center rounded-md text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-6 py-2 transition-colors" >
976+ Sign In
977+ </ button >
978+ </ SignInButton >
979+ </ div >
915980 ) }
916981 </ div >
917982 </ motion . div >
@@ -983,6 +1048,12 @@ export default function RepoWikiPage() {
9831048 onClose = { ( ) => setShowGraph ( false ) }
9841049 />
9851050
1051+ { /* Waitlist Modal */ }
1052+ < WaitlistModal
1053+ isOpen = { isWaitlistModalOpen }
1054+ onClose = { ( ) => setIsWaitlistModalOpen ( false ) }
1055+ />
1056+
9861057 { /* Onboarding tooltips */ }
9871058 { onboardingStep !== null && (
9881059 < div className = "fixed inset-0 z-[60] pointer-events-none" >
0 commit comments