├── public ├── favicon.ico ├── repomind.png ├── 1080x1080.png ├── user-avatar.png ├── assets │ └── demo.webp ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── icon-maskable-512x512.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── manifest.json └── _offline.html ├── src ├── app │ ├── favicon.ico │ ├── robots.ts │ ├── sitemap.ts │ ├── components │ │ └── json-ld.tsx │ ├── api │ │ ├── stats │ │ │ ├── badge │ │ │ │ └── route.ts │ │ │ └── card │ │ │ │ └── route.tsx │ │ └── fix-mermaid │ │ │ └── route.ts │ ├── chat │ │ └── page.tsx │ ├── globals.css │ ├── layout.tsx │ ├── page.tsx │ └── admin │ │ └── stats │ │ └── page.tsx ├── lib │ ├── types.ts │ ├── utils.ts │ ├── streaming-types.ts │ ├── tokens.ts │ ├── generator.ts │ ├── repro_issue.ts │ ├── file-filters.ts │ ├── cache.ts │ ├── quality-analyzer.ts │ ├── analytics.ts │ ├── search-engine.ts │ ├── storage.ts │ ├── markdown-utils.ts │ └── gemini-security.ts ├── components │ ├── icons │ │ ├── UserIcon.tsx │ │ └── BotIcon.tsx │ ├── StreamingProgress.tsx │ ├── CAGBadge.tsx │ ├── WhatsNewBadge.tsx │ ├── GitHubBadge.tsx │ ├── RepoLayout.tsx │ ├── ChatInput.tsx │ ├── InstallPWA.tsx │ ├── RepoCard.tsx │ ├── CodeBlock.tsx │ ├── EnhancedMarkdown.tsx │ ├── ConfirmDialog.tsx │ ├── SmartLink.tsx │ ├── DeveloperCard.tsx │ ├── Footer.tsx │ ├── FeatureTiles.tsx │ ├── ProfileLoader.tsx │ ├── RepoLoader.tsx │ ├── CAGComparison.tsx │ ├── WhatsNewModal.tsx │ └── FilePreview.tsx └── proxy.ts ├── postcss.config.mjs ├── .env.example ├── eslint.config.mjs ├── clear-cache.mjs ├── .gitignore ├── .github └── FUNDING.yml ├── tsconfig.json ├── next-pwa.d.ts ├── LICENSE ├── package.json ├── next.config.ts └── CHANGELOG.md /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/repomind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/repomind.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /public/1080x1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/1080x1080.png -------------------------------------------------------------------------------- /public/user-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/user-avatar.png -------------------------------------------------------------------------------- /public/assets/demo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/assets/demo.webp -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/icon-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/icon-maskable-512x512.png -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/403errors/repomind/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: { 3 | "@tailwindcss/postcss": {}, 4 | }, 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /src/lib/types.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | id: string; 3 | role: "user" | "model"; 4 | content: string; 5 | relevantFiles?: string[]; 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /src/app/robots.ts: -------------------------------------------------------------------------------- 1 | import { MetadataRoute } from "next"; 2 | 3 | export default function robots(): MetadataRoute.Robots { 4 | return { 5 | rules: { 6 | userAgent: "*", 7 | allow: "/", 8 | }, 9 | sitemap: "https://repomind-ai.vercel.app/sitemap.xml", 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # GitHub Token 2 | GITHUB_TOKEN="your_github_token" 3 | 4 | # Gemini API Key 5 | GEMINI_API_KEY="your_gemini_api_key" 6 | 7 | # Caching Vercel KV 8 | KV_REST_API_READ_ONLY_TOKEN="your_kv_rest_api_read_only_token" 9 | KV_REST_API_TOKEN="your_kv_rest_api_token" 10 | KV_REST_API_URL="your_kv_rest_api_url" 11 | KV_URL="your_kv_url" 12 | REDIS_URL="your_redis_url" -------------------------------------------------------------------------------- /src/app/sitemap.ts: -------------------------------------------------------------------------------- 1 | import { MetadataRoute } from "next"; 2 | 3 | export default function sitemap(): MetadataRoute.Sitemap { 4 | const baseUrl = "https://repomind-ai.vercel.app"; 5 | 6 | return [ 7 | { 8 | url: baseUrl, 9 | lastModified: new Date(), 10 | changeFrequency: "daily", 11 | priority: 1, 12 | }, 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/icons/UserIcon.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import Image from "next/image"; 3 | 4 | export function UserIcon({ className }: { className?: string }) { 5 | return ( 6 | User 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/components/icons/BotIcon.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import Image from "next/image"; 3 | 4 | export function BotIcon({ className }: { className?: string }) { 5 | return ( 6 | RepoMind Bot 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/app/components/json-ld.tsx: -------------------------------------------------------------------------------- 1 | export default function JsonLd() { 2 | return ( 3 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/components/ChatInput.tsx: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect, useState } from "react"; 2 | import { Send } from "lucide-react"; 3 | import { cn } from "@/lib/utils"; 4 | 5 | interface ChatInputProps { 6 | value: string; 7 | onChange: (value: string) => void; 8 | onSubmit: (e: React.FormEvent) => void; 9 | placeholder?: string; 10 | disabled?: boolean; 11 | loading?: boolean; 12 | } 13 | 14 | export function ChatInput({ value, onChange, onSubmit, placeholder, disabled, loading }: ChatInputProps) { 15 | const textareaRef = useRef(null); 16 | const [isMobile, setIsMobile] = useState(false); 17 | 18 | useEffect(() => { 19 | const checkMobile = () => { 20 | setIsMobile(window.matchMedia('(pointer: coarse)').matches); 21 | }; 22 | checkMobile(); 23 | window.addEventListener('resize', checkMobile); 24 | return () => window.removeEventListener('resize', checkMobile); 25 | }, []); 26 | 27 | const adjustHeight = () => { 28 | const textarea = textareaRef.current; 29 | if (textarea) { 30 | textarea.style.height = 'auto'; 31 | const newHeight = Math.min(textarea.scrollHeight, 200); 32 | textarea.style.height = `${newHeight}px`; 33 | 34 | // Only show scrollbar if content exceeds max height 35 | if (textarea.scrollHeight > 200) { 36 | textarea.style.overflowY = 'auto'; 37 | } else { 38 | textarea.style.overflowY = 'hidden'; 39 | } 40 | } 41 | }; 42 | 43 | useEffect(() => { 44 | adjustHeight(); 45 | }, [value]); 46 | 47 | const handleKeyDown = (e: React.KeyboardEvent) => { 48 | if (e.key === 'Enter' && !e.shiftKey && !isMobile) { 49 | e.preventDefault(); 50 | onSubmit(e); 51 | } 52 | }; 53 | 54 | return ( 55 |
56 |