From f0eec34116bc65f5fb67588f57c0cbf75c086bce Mon Sep 17 00:00:00 2001 From: D-K-P <8297864+D-K-P@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:04:08 +0000 Subject: [PATCH 01/21] initial commit --- claude-agent-github-wiki/.bolt/config.json | 3 + claude-agent-github-wiki/.bolt/ignore | 2 + claude-agent-github-wiki/.bolt/prompt | 9 + claude-agent-github-wiki/.eslintrc.json | 3 + claude-agent-github-wiki/.gitignore | 62 + claude-agent-github-wiki/README.md | 62 + .../app/chat/[runId]/page.tsx | 239 + claude-agent-github-wiki/app/globals.css | 102 + claude-agent-github-wiki/app/layout.tsx | 22 + claude-agent-github-wiki/app/page.tsx | 121 + claude-agent-github-wiki/components.json | 20 + .../components/chat/ai-message.tsx | 39 + .../components/chat/tool-card.tsx | 103 + .../components/chat/user-message.tsx | 16 + .../components/ui/accordion.tsx | 58 + .../components/ui/alert-dialog.tsx | 141 + .../components/ui/alert.tsx | 59 + .../components/ui/aspect-ratio.tsx | 7 + .../components/ui/avatar.tsx | 50 + .../components/ui/badge.tsx | 36 + .../components/ui/breadcrumb.tsx | 115 + .../components/ui/button.tsx | 56 + .../components/ui/calendar.tsx | 66 + .../components/ui/card.tsx | 86 + .../components/ui/carousel.tsx | 262 + .../components/ui/chart.tsx | 365 + .../components/ui/checkbox.tsx | 30 + .../components/ui/collapsible.tsx | 11 + .../components/ui/command.tsx | 155 + .../components/ui/context-menu.tsx | 200 + .../components/ui/dialog.tsx | 122 + .../components/ui/drawer.tsx | 118 + .../components/ui/dropdown-menu.tsx | 200 + .../components/ui/form.tsx | 179 + .../components/ui/hover-card.tsx | 29 + .../components/ui/input-otp.tsx | 71 + .../components/ui/input.tsx | 25 + .../components/ui/label.tsx | 26 + .../components/ui/menubar.tsx | 236 + .../components/ui/navigation-menu.tsx | 128 + .../components/ui/pagination.tsx | 117 + .../components/ui/popover.tsx | 31 + .../components/ui/progress.tsx | 28 + .../components/ui/radio-group.tsx | 44 + .../components/ui/resizable.tsx | 45 + .../components/ui/scroll-area.tsx | 48 + .../components/ui/select.tsx | 160 + .../components/ui/separator.tsx | 31 + .../components/ui/sheet.tsx | 140 + .../components/ui/skeleton.tsx | 15 + .../components/ui/slider.tsx | 28 + .../components/ui/sonner.tsx | 31 + .../components/ui/switch.tsx | 29 + .../components/ui/table.tsx | 117 + .../components/ui/tabs.tsx | 55 + .../components/ui/textarea.tsx | 24 + .../components/ui/toast.tsx | 129 + .../components/ui/toaster.tsx | 35 + .../components/ui/toggle-group.tsx | 61 + .../components/ui/toggle.tsx | 45 + .../components/ui/tooltip.tsx | 30 + claude-agent-github-wiki/hooks/use-toast.ts | 191 + claude-agent-github-wiki/lib/utils.ts | 6 + claude-agent-github-wiki/next-env.d.ts | 5 + claude-agent-github-wiki/next.config.js | 8 + claude-agent-github-wiki/package-lock.json | 8420 +++++++++++++++++ claude-agent-github-wiki/package.json | 74 + claude-agent-github-wiki/postcss.config.js | 6 + claude-agent-github-wiki/tailwind.config.ts | 90 + claude-agent-github-wiki/tsconfig.json | 27 + 70 files changed, 13704 insertions(+) create mode 100644 claude-agent-github-wiki/.bolt/config.json create mode 100644 claude-agent-github-wiki/.bolt/ignore create mode 100644 claude-agent-github-wiki/.bolt/prompt create mode 100644 claude-agent-github-wiki/.eslintrc.json create mode 100644 claude-agent-github-wiki/.gitignore create mode 100644 claude-agent-github-wiki/README.md create mode 100644 claude-agent-github-wiki/app/chat/[runId]/page.tsx create mode 100644 claude-agent-github-wiki/app/globals.css create mode 100644 claude-agent-github-wiki/app/layout.tsx create mode 100644 claude-agent-github-wiki/app/page.tsx create mode 100644 claude-agent-github-wiki/components.json create mode 100644 claude-agent-github-wiki/components/chat/ai-message.tsx create mode 100644 claude-agent-github-wiki/components/chat/tool-card.tsx create mode 100644 claude-agent-github-wiki/components/chat/user-message.tsx create mode 100644 claude-agent-github-wiki/components/ui/accordion.tsx create mode 100644 claude-agent-github-wiki/components/ui/alert-dialog.tsx create mode 100644 claude-agent-github-wiki/components/ui/alert.tsx create mode 100644 claude-agent-github-wiki/components/ui/aspect-ratio.tsx create mode 100644 claude-agent-github-wiki/components/ui/avatar.tsx create mode 100644 claude-agent-github-wiki/components/ui/badge.tsx create mode 100644 claude-agent-github-wiki/components/ui/breadcrumb.tsx create mode 100644 claude-agent-github-wiki/components/ui/button.tsx create mode 100644 claude-agent-github-wiki/components/ui/calendar.tsx create mode 100644 claude-agent-github-wiki/components/ui/card.tsx create mode 100644 claude-agent-github-wiki/components/ui/carousel.tsx create mode 100644 claude-agent-github-wiki/components/ui/chart.tsx create mode 100644 claude-agent-github-wiki/components/ui/checkbox.tsx create mode 100644 claude-agent-github-wiki/components/ui/collapsible.tsx create mode 100644 claude-agent-github-wiki/components/ui/command.tsx create mode 100644 claude-agent-github-wiki/components/ui/context-menu.tsx create mode 100644 claude-agent-github-wiki/components/ui/dialog.tsx create mode 100644 claude-agent-github-wiki/components/ui/drawer.tsx create mode 100644 claude-agent-github-wiki/components/ui/dropdown-menu.tsx create mode 100644 claude-agent-github-wiki/components/ui/form.tsx create mode 100644 claude-agent-github-wiki/components/ui/hover-card.tsx create mode 100644 claude-agent-github-wiki/components/ui/input-otp.tsx create mode 100644 claude-agent-github-wiki/components/ui/input.tsx create mode 100644 claude-agent-github-wiki/components/ui/label.tsx create mode 100644 claude-agent-github-wiki/components/ui/menubar.tsx create mode 100644 claude-agent-github-wiki/components/ui/navigation-menu.tsx create mode 100644 claude-agent-github-wiki/components/ui/pagination.tsx create mode 100644 claude-agent-github-wiki/components/ui/popover.tsx create mode 100644 claude-agent-github-wiki/components/ui/progress.tsx create mode 100644 claude-agent-github-wiki/components/ui/radio-group.tsx create mode 100644 claude-agent-github-wiki/components/ui/resizable.tsx create mode 100644 claude-agent-github-wiki/components/ui/scroll-area.tsx create mode 100644 claude-agent-github-wiki/components/ui/select.tsx create mode 100644 claude-agent-github-wiki/components/ui/separator.tsx create mode 100644 claude-agent-github-wiki/components/ui/sheet.tsx create mode 100644 claude-agent-github-wiki/components/ui/skeleton.tsx create mode 100644 claude-agent-github-wiki/components/ui/slider.tsx create mode 100644 claude-agent-github-wiki/components/ui/sonner.tsx create mode 100644 claude-agent-github-wiki/components/ui/switch.tsx create mode 100644 claude-agent-github-wiki/components/ui/table.tsx create mode 100644 claude-agent-github-wiki/components/ui/tabs.tsx create mode 100644 claude-agent-github-wiki/components/ui/textarea.tsx create mode 100644 claude-agent-github-wiki/components/ui/toast.tsx create mode 100644 claude-agent-github-wiki/components/ui/toaster.tsx create mode 100644 claude-agent-github-wiki/components/ui/toggle-group.tsx create mode 100644 claude-agent-github-wiki/components/ui/toggle.tsx create mode 100644 claude-agent-github-wiki/components/ui/tooltip.tsx create mode 100644 claude-agent-github-wiki/hooks/use-toast.ts create mode 100644 claude-agent-github-wiki/lib/utils.ts create mode 100644 claude-agent-github-wiki/next-env.d.ts create mode 100644 claude-agent-github-wiki/next.config.js create mode 100644 claude-agent-github-wiki/package-lock.json create mode 100644 claude-agent-github-wiki/package.json create mode 100644 claude-agent-github-wiki/postcss.config.js create mode 100644 claude-agent-github-wiki/tailwind.config.ts create mode 100644 claude-agent-github-wiki/tsconfig.json diff --git a/claude-agent-github-wiki/.bolt/config.json b/claude-agent-github-wiki/.bolt/config.json new file mode 100644 index 0000000..f236591 --- /dev/null +++ b/claude-agent-github-wiki/.bolt/config.json @@ -0,0 +1,3 @@ +{ + "template": "nextjs-shadcn" +} diff --git a/claude-agent-github-wiki/.bolt/ignore b/claude-agent-github-wiki/.bolt/ignore new file mode 100644 index 0000000..bbe3a15 --- /dev/null +++ b/claude-agent-github-wiki/.bolt/ignore @@ -0,0 +1,2 @@ +components/ui/* +hooks/use-toast.ts diff --git a/claude-agent-github-wiki/.bolt/prompt b/claude-agent-github-wiki/.bolt/prompt new file mode 100644 index 0000000..88d020b --- /dev/null +++ b/claude-agent-github-wiki/.bolt/prompt @@ -0,0 +1,9 @@ +For all designs I ask you to make, have them be beautiful, not cookie cutter. Make webpages that are fully featured and worthy for production. + +When using client-side hooks (useState and useEffect) in a component that's being treated as a Server Component by Next.js, always add the "use client" directive at the top of the file. + +Do not write code that will trigger this error: "Warning: Extra attributes from the server: %s%s""class,style" + +By default, this template supports JSX syntax with Tailwind CSS classes, the shadcn/ui library, React hooks, and Lucide React for icons. Do not install other packages for UI themes, icons, etc unless absolutely necessary or I request them. + +Use icons from lucide-react for logos. diff --git a/claude-agent-github-wiki/.eslintrc.json b/claude-agent-github-wiki/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/claude-agent-github-wiki/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/claude-agent-github-wiki/.gitignore b/claude-agent-github-wiki/.gitignore new file mode 100644 index 0000000..c3f40f4 --- /dev/null +++ b/claude-agent-github-wiki/.gitignore @@ -0,0 +1,62 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +CLAUDE.md + +postgres-data +# dependencies +node_modules +.pnp +.pnp.js + +# testing +coverage + +# next.js +.next/ +out/ +dist +packages/**/dist + +# Tailwind +apps/**/styles/tailwind.css +packages/**/styles/tailwind.css + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.docker +.docker/*.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# turbo +.turbo +.vercel +.cache +.env +.output +apps/**/public/build +.tests-container-id.txt +.sentryclirc +.buildt + +**/tmp/ +/test-results/ +/playwright-report/ +/playwright/.cache/ + +.cosine +.trigger +.tshy* +.yarn +*.tsbuildinfo +.claude \ No newline at end of file diff --git a/claude-agent-github-wiki/README.md b/claude-agent-github-wiki/README.md new file mode 100644 index 0000000..88e3408 --- /dev/null +++ b/claude-agent-github-wiki/README.md @@ -0,0 +1,62 @@ +# Repo Wiki Chat + +A Next.js 14 demo application that showcases how to chat with GitHub repositories using AI. Users can paste a GitHub URL, ask questions about the codebase, and see AI's reasoning and tool usage stream live. + +## Features + +- **Landing Page**: Clean, modern interface with GitHub URL input and example repositories +- **Chat Interface**: Real-time conversation with AI about repository code +- **Tool Usage Visualization**: View AI's tool calls (Read, Grep, Bash) with expandable results +- **Responsive Design**: Works seamlessly across desktop and mobile devices +- **Mock Data**: Demo includes sample conversations showing typical AI analysis + +## Tech Stack + +- Next.js 14 (App Router) +- TypeScript +- Tailwind CSS +- shadcn/ui components +- React Markdown for message formatting + +## Getting Started + +Install dependencies: + +```bash +npm install +``` + +Run the development server: + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) in your browser. + +## Project Structure + +``` +app/ + ├── page.tsx # Landing page with repo input + ├── chat/[runId]/ # Chat interface + └── globals.css # Global styles + +components/ + ├── chat/ + │ ├── user-message.tsx # User message bubble + │ ├── ai-message.tsx # AI response bubble with markdown + │ └── tool-card.tsx # Tool call visualization + └── ui/ # shadcn/ui components +``` + +## Usage + +1. Visit the landing page +2. Enter a GitHub repository URL or click one of the example repos +3. Ask questions about the repository's code, features, or architecture +4. Watch as the AI analyzes the codebase and provides insights + +## Note + +This is a demo application with mock data. In a production implementation, it would integrate with an actual AI service and GitHub API to provide real repository analysis. diff --git a/claude-agent-github-wiki/app/chat/[runId]/page.tsx b/claude-agent-github-wiki/app/chat/[runId]/page.tsx new file mode 100644 index 0000000..c409265 --- /dev/null +++ b/claude-agent-github-wiki/app/chat/[runId]/page.tsx @@ -0,0 +1,239 @@ +"use client"; + +import { useState, useRef, useEffect } from "react"; +import { useSearchParams } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Badge } from "@/components/ui/badge"; +import { Send, StopCircle, Github, MessageSquare } from "lucide-react"; +import { UserMessage } from "@/components/chat/user-message"; +import { AiMessage } from "@/components/chat/ai-message"; +import { ToolCard } from "@/components/chat/tool-card"; + +type Message = { + id: string; + type: "user" | "ai" | "tool"; + content: string; + toolName?: string; + toolInput?: any; + toolResult?: string; + timestamp: Date; +}; + +const mockMessages: Message[] = [ + { + id: "1", + type: "user", + content: "What are the main features of this repository?", + timestamp: new Date(Date.now() - 120000), + }, + { + id: "2", + type: "tool", + content: "", + toolName: "Read", + toolInput: { file_path: "/README.md" }, + toolResult: `# Next.js + +Next.js is a React framework for building full-stack web applications. + +## Main Features + +- **App Router**: A new router with support for layouts, nested routing, and more. +- **Server Components**: React Server Components for improved performance. +- **Data Fetching**: Simplified data fetching with async/await in Server Components. +- **Styling**: Support for CSS Modules, Tailwind CSS, and CSS-in-JS. +- **Optimizations**: Automatic image, font, and script optimizations. +- **TypeScript**: Built-in TypeScript support. + +## Getting Started + +\`\`\`bash +npx create-next-app@latest +\`\`\` + +## Learn More + +Visit [nextjs.org](https://nextjs.org) to learn more.`, + timestamp: new Date(Date.now() - 115000), + }, + { + id: "3", + type: "tool", + content: "", + toolName: "Grep", + toolInput: { pattern: "export.*function", glob: "**/*.ts", output_mode: "files_with_matches" }, + toolResult: `packages/next/src/server/app-render.tsx +packages/next/src/server/base-server.ts +packages/next/src/client/components/app-router.tsx +packages/next/src/build/webpack/loaders/next-app-loader.ts +packages/next/src/server/lib/render-server.ts +[...25 more files]`, + timestamp: new Date(Date.now() - 110000), + }, + { + id: "4", + type: "ai", + content: `Based on the README and codebase structure, here are the main features of this repository: + +**Core Features:** + +1. **App Router** - A new routing system with support for layouts, nested routes, and loading UI +2. **React Server Components** - Enables server-side rendering with reduced client-side JavaScript +3. **Simplified Data Fetching** - Uses async/await directly in components +4. **Built-in Optimizations** - Automatic image, font, and script optimizations for better performance +5. **Styling Flexibility** - Support for CSS Modules, Tailwind CSS, Sass, and CSS-in-JS solutions +6. **TypeScript Support** - First-class TypeScript integration out of the box + +The codebase shows extensive server-side rendering capabilities and a robust build system. The App Router implementation spans across multiple modules handling routing, rendering, and webpack integration.`, + timestamp: new Date(Date.now() - 105000), + }, +]; + +export default function ChatPage() { + const searchParams = useSearchParams(); + const repo = searchParams.get("repo") || ""; + const [messages, setMessages] = useState(mockMessages); + const [input, setInput] = useState(""); + const [isRunning, setIsRunning] = useState(false); + const scrollRef = useRef(null); + + const repoName = repo.split("/").slice(-2).join("/").replace(".git", ""); + + useEffect(() => { + if (scrollRef.current) { + scrollRef.current.scrollTop = scrollRef.current.scrollHeight; + } + }, [messages]); + + const handleSend = () => { + if (!input.trim() || isRunning) return; + + const newMessage: Message = { + id: Date.now().toString(), + type: "user", + content: input, + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, newMessage]); + setInput(""); + setIsRunning(true); + + setTimeout(() => { + const aiResponse: Message = { + id: (Date.now() + 1).toString(), + type: "ai", + content: "This is a demo. In a real implementation, the AI would analyze the repository and provide insights based on the codebase.", + timestamp: new Date(), + }; + setMessages((prev) => [...prev, aiResponse]); + setIsRunning(false); + }, 2000); + }; + + const handleAbort = () => { + setIsRunning(false); + }; + + return ( +
+
+ +
+ {repoName || "Repository"} + {repo && ( + + + {repo} + + + )} +
+
+ + +
+ {messages.length === 0 ? ( +
+ +

Ask a question about this repository

+
+ ) : ( + messages.map((message) => { + if (message.type === "user") { + return ; + } else if (message.type === "ai") { + return ; + } else if (message.type === "tool") { + return ( + + ); + } + return null; + }) + )} + + {isRunning && ( +
+
+
+
+
+
+ AI is thinking... +
+ )} +
+ + +
+
+
{ + e.preventDefault(); + handleSend(); + }} + className="flex gap-2" + > + setInput(e.target.value)} + placeholder="Ask a question about this repository..." + className="flex-1" + disabled={isRunning} + /> + {isRunning ? ( + + ) : ( + + )} +
+
+
+
+ ); +} diff --git a/claude-agent-github-wiki/app/globals.css b/claude-agent-github-wiki/app/globals.css new file mode 100644 index 0000000..6cffd7c --- /dev/null +++ b/claude-agent-github-wiki/app/globals.css @@ -0,0 +1,102 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-start-rgb: 0, 0, 0; + --background-end-rgb: 0, 0, 0; + } +} + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 0 0% 3.9%; + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + --secondary: 0 0% 96.1%; + --secondary-foreground: 0 0% 9%; + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.5rem; + } + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +@keyframes bounce { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-0.5rem); + } +} + +.animate-bounce { + animation: bounce 0.6s ease-in-out infinite; +} + +.line-clamp-3 { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} diff --git a/claude-agent-github-wiki/app/layout.tsx b/claude-agent-github-wiki/app/layout.tsx new file mode 100644 index 0000000..6c8d304 --- /dev/null +++ b/claude-agent-github-wiki/app/layout.tsx @@ -0,0 +1,22 @@ +import './globals.css'; +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; + +const inter = Inter({ subsets: ['latin'] }); + +export const metadata: Metadata = { + title: 'Repo Wiki Chat - Chat with any GitHub repository', + description: 'Ask questions about any GitHub repository and watch AI analyze the code in real-time with live reasoning and tool usage.', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/claude-agent-github-wiki/app/page.tsx b/claude-agent-github-wiki/app/page.tsx new file mode 100644 index 0000000..1eaf74b --- /dev/null +++ b/claude-agent-github-wiki/app/page.tsx @@ -0,0 +1,121 @@ +"use client"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Github, MessageSquare, Sparkles } from "lucide-react"; + +const exampleRepos = [ + { + name: "Next.js", + url: "https://github.com/vercel/next.js", + description: "The React Framework for Production", + stars: "120k", + }, + { + name: "React", + url: "https://github.com/facebook/react", + description: "A JavaScript library for building UIs", + stars: "220k", + }, + { + name: "VS Code", + url: "https://github.com/microsoft/vscode", + description: "Visual Studio Code", + stars: "158k", + }, +]; + +export default function Home() { + const [url, setUrl] = useState(""); + const router = useRouter(); + + const handleSubmit = (repoUrl: string) => { + const runId = Math.random().toString(36).substring(7); + router.push(`/chat/${runId}?repo=${encodeURIComponent(repoUrl)}`); + }; + + return ( +
+
+
+
+ + +
+ +

+ Chat with any GitHub repo +

+ +

+ Paste a GitHub repository URL and ask questions about the codebase. + Watch AI analyze the code in real-time with live reasoning and tool usage. +

+ +
+
{ + e.preventDefault(); + if (url) handleSubmit(url); + }} + className="flex gap-2" + > + setUrl(e.target.value)} + className="flex-1 h-12 text-base" + /> + +
+
+
+ +
+

+ Try these popular repositories +

+ +
+ {exampleRepos.map((repo) => ( + handleSubmit(repo.url)} + > + + + + {repo.name} + + {repo.description} + + +
+ + + + {repo.stars} stars +
+
+
+ ))} +
+
+ +
+

+ This demo showcases AI-powered repository analysis with real-time tool usage streaming +

+
+
+
+ ); +} diff --git a/claude-agent-github-wiki/components.json b/claude-agent-github-wiki/components.json new file mode 100644 index 0000000..c597462 --- /dev/null +++ b/claude-agent-github-wiki/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} diff --git a/claude-agent-github-wiki/components/chat/ai-message.tsx b/claude-agent-github-wiki/components/chat/ai-message.tsx new file mode 100644 index 0000000..5cc5661 --- /dev/null +++ b/claude-agent-github-wiki/components/chat/ai-message.tsx @@ -0,0 +1,39 @@ +import { cn } from "@/lib/utils"; +import ReactMarkdown from "react-markdown"; + +interface AiMessageProps { + content: string; + className?: string; +} + +export function AiMessage({ content, className }: AiMessageProps) { + return ( +
+
+
+

{children}

, + ul: ({ children }) =>
    {children}
, + ol: ({ children }) =>
    {children}
, + li: ({ children }) =>
  • {children}
  • , + strong: ({ children }) => {children}, + code: ({ children, ...props }) => { + const isInline = !props.className; + return isInline ? ( + {children} + ) : ( + + {children} + + ); + }, + }} + > + {content} +
    +
    +
    +
    + ); +} diff --git a/claude-agent-github-wiki/components/chat/tool-card.tsx b/claude-agent-github-wiki/components/chat/tool-card.tsx new file mode 100644 index 0000000..628fc66 --- /dev/null +++ b/claude-agent-github-wiki/components/chat/tool-card.tsx @@ -0,0 +1,103 @@ +"use client"; + +import { useState } from "react"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; +import { FileText, Search, Terminal, ChevronDown, ChevronRight } from "lucide-react"; +import { cn } from "@/lib/utils"; + +interface ToolCardProps { + toolName: string; + toolInput: any; + toolResult?: string; + timestamp: Date; +} + +const toolIcons = { + Read: FileText, + Grep: Search, + Bash: Terminal, + default: Terminal, +}; + +export function ToolCard({ toolName, toolInput, toolResult, timestamp }: ToolCardProps) { + const [isOpen, setIsOpen] = useState(false); + const Icon = toolIcons[toolName as keyof typeof toolIcons] || toolIcons.default; + + const resultLines = toolResult?.split("\n").length || 0; + const shouldCollapse = resultLines > 50; + + return ( +
    + + +
    +
    + +
    +
    +
    + + {toolName} + + + {timestamp.toLocaleTimeString()} + +
    +
    +
    +
    + + +
    +
    Input:
    +
    +              {JSON.stringify(toolInput, null, 2)}
    +            
    +
    + + {toolResult && ( + +
    +
    + Result: {shouldCollapse && `(${resultLines} lines)`} +
    + + + +
    + + +
    +                  {toolResult}
    +                
    +
    + + {!isOpen && ( +
    +                  
    {toolResult}
    + {shouldCollapse && ( +
    + )} +
    + )} +
    + )} +
    +
    +
    + ); +} diff --git a/claude-agent-github-wiki/components/chat/user-message.tsx b/claude-agent-github-wiki/components/chat/user-message.tsx new file mode 100644 index 0000000..89da3a5 --- /dev/null +++ b/claude-agent-github-wiki/components/chat/user-message.tsx @@ -0,0 +1,16 @@ +import { cn } from "@/lib/utils"; + +interface UserMessageProps { + content: string; + className?: string; +} + +export function UserMessage({ content, className }: UserMessageProps) { + return ( +
    +
    +

    {content}

    +
    +
    + ); +} diff --git a/claude-agent-github-wiki/components/ui/accordion.tsx b/claude-agent-github-wiki/components/ui/accordion.tsx new file mode 100644 index 0000000..84bf2eb --- /dev/null +++ b/claude-agent-github-wiki/components/ui/accordion.tsx @@ -0,0 +1,58 @@ +'use client'; + +import * as React from 'react'; +import * as AccordionPrimitive from '@radix-ui/react-accordion'; +import { ChevronDown } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = 'AccordionItem'; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180', + className + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
    {children}
    +
    +)); + +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/claude-agent-github-wiki/components/ui/alert-dialog.tsx b/claude-agent-github-wiki/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..5cba559 --- /dev/null +++ b/claude-agent-github-wiki/components/ui/alert-dialog.tsx @@ -0,0 +1,141 @@ +'use client'; + +import * as React from 'react'; +import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'; + +import { cn } from '@/lib/utils'; +import { buttonVariants } from '@/components/ui/button'; + +const AlertDialog = AlertDialogPrimitive.Root; + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger; + +const AlertDialogPortal = AlertDialogPrimitive.Portal; + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)); +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
    +); +AlertDialogHeader.displayName = 'AlertDialogHeader'; + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
    +); +AlertDialogFooter.displayName = 'AlertDialogFooter'; + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName; + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +}; diff --git a/claude-agent-github-wiki/components/ui/alert.tsx b/claude-agent-github-wiki/components/ui/alert.tsx new file mode 100644 index 0000000..d2b59cc --- /dev/null +++ b/claude-agent-github-wiki/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from 'react'; +import { cva, type VariantProps } from 'class-variance-authority'; + +import { cn } from '@/lib/utils'; + +const alertVariants = cva( + 'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground', + { + variants: { + variant: { + default: 'bg-background text-foreground', + destructive: + 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive', + }, + }, + defaultVariants: { + variant: 'default', + }, + } +); + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
    +)); +Alert.displayName = 'Alert'; + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
    +)); +AlertTitle.displayName = 'AlertTitle'; + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
    +)); +AlertDescription.displayName = 'AlertDescription'; + +export { Alert, AlertTitle, AlertDescription }; diff --git a/claude-agent-github-wiki/components/ui/aspect-ratio.tsx b/claude-agent-github-wiki/components/ui/aspect-ratio.tsx new file mode 100644 index 0000000..aaabffb --- /dev/null +++ b/claude-agent-github-wiki/components/ui/aspect-ratio.tsx @@ -0,0 +1,7 @@ +'use client'; + +import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'; + +const AspectRatio = AspectRatioPrimitive.Root; + +export { AspectRatio }; diff --git a/claude-agent-github-wiki/components/ui/avatar.tsx b/claude-agent-github-wiki/components/ui/avatar.tsx new file mode 100644 index 0000000..1346957 --- /dev/null +++ b/claude-agent-github-wiki/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +'use client'; + +import * as React from 'react'; +import * as AvatarPrimitive from '@radix-ui/react-avatar'; + +import { cn } from '@/lib/utils'; + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/claude-agent-github-wiki/components/ui/badge.tsx b/claude-agent-github-wiki/components/ui/badge.tsx new file mode 100644 index 0000000..2eb790a --- /dev/null +++ b/claude-agent-github-wiki/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; +import { cva, type VariantProps } from 'class-variance-authority'; + +import { cn } from '@/lib/utils'; + +const badgeVariants = cva( + 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', + { + variants: { + variant: { + default: + 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', + secondary: + 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', + destructive: + 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', + outline: 'text-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, + } +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
    + ); +} + +export { Badge, badgeVariants }; diff --git a/claude-agent-github-wiki/components/ui/breadcrumb.tsx b/claude-agent-github-wiki/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..8b62197 --- /dev/null +++ b/claude-agent-github-wiki/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { ChevronRight, MoreHorizontal } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<'nav'> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>