Skip to content

Commit 7a27c2a

Browse files
Initialized repository for project codebase-context-utility
Co-authored-by: Ivan Roman <[email protected]>
0 parents  commit 7a27c2a

68 files changed

Lines changed: 9216 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# dependencies
2+
/node_modules
3+
/.pnp
4+
.pnp.js
5+
.yarn/install-state.gz
6+
7+
# testing
8+
/coverage
9+
10+
# next.js
11+
/.next/
12+
/out/
13+
14+
# production
15+
/build
16+
17+
# misc
18+
.DS_Store
19+
*.pem
20+
21+
# debug
22+
npm-debug.log*
23+
yarn-debug.log*
24+
yarn-error.log*
25+
26+
# local env files
27+
.env*.local
28+
29+
# vercel
30+
.vercel
31+
32+
# typescript
33+
*.tsbuildinfo
34+
next-env.d.ts

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Codebase Context Utility
2+
3+
A tool for generating LLM-ready context from your codebase. This utility helps you analyze, understand, and prepare your code for AI-assisted development.
4+
5+
## Features
6+
7+
- **File System Integration**: Open and explore local directories and files
8+
- **Drag-and-Drop Functionality**: Easily add files to the project
9+
- **Context Generation**: Create LLM-ready context from your codebase
10+
- **LLM Integration**: Send generated context to various LLM providers
11+
- **Code Analysis**: Syntax highlighting and structure analysis
12+
- **Export Options**: JSON, Markdown, or Plain Text formats
13+
- **Token Estimation**: Calculate token usage for different LLM models
14+
15+
## How Context Generation Works in the Codebase Context Utility
16+
17+
```mermaid
18+
Context Generation Process.download-icon {
19+
cursor: pointer;
20+
transform-origin: center;
21+
}
22+
.download-icon .arrow-part {
23+
transition: transform 0.35s cubic-bezier(0.35, 0.2, 0.14, 0.95);
24+
transform-origin: center;
25+
}
26+
button:has(.download-icon):hover .download-icon .arrow-part, button:has(.download-icon):focus-visible .download-icon .arrow-part {
27+
transform: translateY(-1.5px);
28+
}
29+
#mermaid-diagram-rh05{font-family:var(--font-geist-sans);font-size:12px;fill:#000000;}#mermaid-diagram-rh05 .error-icon{fill:#552222;}#mermaid-diagram-rh05 .error-text{fill:#552222;stroke:#552222;}#mermaid-diagram-rh05 .edge-thickness-normal{stroke-width:1px;}#mermaid-diagram-rh05 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-diagram-rh05 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-diagram-rh05 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-diagram-rh05 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-diagram-rh05 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-diagram-rh05 .marker{fill:#666;stroke:#666;}#mermaid-diagram-rh05 .marker.cross{stroke:#666;}#mermaid-diagram-rh05 svg{font-family:var(--font-geist-sans);font-size:12px;}#mermaid-diagram-rh05 p{margin:0;}#mermaid-diagram-rh05 .label{font-family:var(--font-geist-sans);color:#000000;}#mermaid-diagram-rh05 .cluster-label text{fill:#333;}#mermaid-diagram-rh05 .cluster-label span{color:#333;}#mermaid-diagram-rh05 .cluster-label span p{background-color:transparent;}#mermaid-diagram-rh05 .label text,#mermaid-diagram-rh05 span{fill:#000000;color:#000000;}#mermaid-diagram-rh05 .node rect,#mermaid-diagram-rh05 .node circle,#mermaid-diagram-rh05 .node ellipse,#mermaid-diagram-rh05 .node polygon,#mermaid-diagram-rh05 .node path{fill:#eee;stroke:#999;stroke-width:1px;}#mermaid-diagram-rh05 .rough-node .label text,#mermaid-diagram-rh05 .node .label text{text-anchor:middle;}#mermaid-diagram-rh05 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-diagram-rh05 .node .label{text-align:center;}#mermaid-diagram-rh05 .node.clickable{cursor:pointer;}#mermaid-diagram-rh05 .arrowheadPath{fill:#333333;}#mermaid-diagram-rh05 .edgePath .path{stroke:#666;stroke-width:2.0px;}#mermaid-diagram-rh05 .flowchart-link{stroke:#666;fill:none;}#mermaid-diagram-rh05 .edgeLabel{background-color:white;text-align:center;}#mermaid-diagram-rh05 .edgeLabel p{background-color:white;}#mermaid-diagram-rh05 .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#mermaid-diagram-rh05 .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#mermaid-diagram-rh05 .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#mermaid-diagram-rh05 .cluster text{fill:#333;}#mermaid-diagram-rh05 .cluster span{color:#333;}#mermaid-diagram-rh05 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:var(--font-geist-sans);font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-diagram-rh05 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#mermaid-diagram-rh05 .flowchart-link{stroke:hsl(var(--gray-400));stroke-width:1px;}#mermaid-diagram-rh05 .marker,#mermaid-diagram-rh05 marker,#mermaid-diagram-rh05 marker *{fill:hsl(var(--gray-400))!important;stroke:hsl(var(--gray-400))!important;}#mermaid-diagram-rh05 .label,#mermaid-diagram-rh05 text,#mermaid-diagram-rh05 text>tspan{fill:hsl(var(--black))!important;color:hsl(var(--black))!important;}#mermaid-diagram-rh05 .background,#mermaid-diagram-rh05 rect.relationshipLabelBox{fill:hsl(var(--white))!important;}#mermaid-diagram-rh05 .entityBox,#mermaid-diagram-rh05 .attributeBoxEven{fill:hsl(var(--gray-150))!important;}#mermaid-diagram-rh05 .attributeBoxOdd{fill:hsl(var(--white))!important;}#mermaid-diagram-rh05 .label-container,#mermaid-diagram-rh05 rect.actor{fill:hsl(var(--white))!important;stroke:hsl(var(--gray-400))!important;}#mermaid-diagram-rh05 line{stroke:hsl(var(--gray-400))!important;}#mermaid-diagram-rh05 :root{--mermaid-font-family:var(--font-geist-sans);}Format &amp; ExportContext GenerationFile System ProcessingUser Loads FilesFile System ProcessingContext GenerationFormat &amp; ExportScan Directory StructureRead File ContentsFilter Files (Skip node_modules, .git,etc.)Process File MetadataMap Dependencies Between FilesGenerate Architecture OverviewApply User SettingsEstimate Token CountFormat as JSON/Markdown/PlainTextApply Token LimitsGenerate Final Context

app/globals.css

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 8%;
8+
--foreground: 0 0% 95%;
9+
10+
--card: 0 0% 12%;
11+
--card-foreground: 0 0% 95%;
12+
13+
--popover: 0 0% 12%;
14+
--popover-foreground: 0 0% 95%;
15+
16+
--primary: 0 0% 20%;
17+
--primary-foreground: 0 0% 98%;
18+
19+
--secondary: 0 0% 16%;
20+
--secondary-foreground: 0 0% 90%;
21+
22+
--muted: 0 0% 14%;
23+
--muted-foreground: 0 0% 70%;
24+
25+
--accent: 0 0% 18%;
26+
--accent-foreground: 0 0% 95%;
27+
28+
--destructive: 0 84.2% 60.2%;
29+
--destructive-foreground: 0 0% 98%;
30+
31+
--border: 0 0% 22%;
32+
--input: 0 0% 18%;
33+
--ring: 0 0% 35%;
34+
35+
--radius: 0.5rem;
36+
37+
--sidebar-background: 0 0% 10%;
38+
--sidebar-foreground: 0 0% 90%;
39+
--sidebar-primary: 0 0% 25%;
40+
--sidebar-primary-foreground: 0 0% 98%;
41+
--sidebar-accent: 0 0% 16%;
42+
--sidebar-accent-foreground: 0 0% 95%;
43+
--sidebar-border: 0 0% 20%;
44+
--sidebar-ring: 0 0% 40%;
45+
}
46+
47+
.dark {
48+
--background: 0 0% 6%;
49+
--foreground: 0 0% 98%;
50+
51+
--card: 0 0% 10%;
52+
--card-foreground: 0 0% 98%;
53+
54+
--popover: 0 0% 10%;
55+
--popover-foreground: 0 0% 98%;
56+
57+
--primary: 0 0% 25%;
58+
--primary-foreground: 0 0% 98%;
59+
60+
--secondary: 0 0% 14%;
61+
--secondary-foreground: 0 0% 95%;
62+
63+
--muted: 0 0% 12%;
64+
--muted-foreground: 0 0% 75%;
65+
66+
--accent: 0 0% 20%;
67+
--accent-foreground: 0 0% 98%;
68+
69+
--destructive: 0 62.8% 30.6%;
70+
--destructive-foreground: 0 0% 98%;
71+
72+
--border: 0 0% 18%;
73+
--input: 0 0% 16%;
74+
--ring: 0 0% 40%;
75+
76+
--sidebar-background: 0 0% 8%;
77+
--sidebar-foreground: 0 0% 95%;
78+
--sidebar-primary: 0 0% 30%;
79+
--sidebar-primary-foreground: 0 0% 98%;
80+
--sidebar-accent: 0 0% 14%;
81+
--sidebar-accent-foreground: 0 0% 98%;
82+
--sidebar-border: 0 0% 16%;
83+
--sidebar-ring: 0 0% 45%;
84+
}
85+
}
86+
87+
@layer base {
88+
* {
89+
@apply border-border;
90+
}
91+
body {
92+
@apply bg-background text-foreground;
93+
}
94+
}
95+
96+
/* Custom scrollbar styles */
97+
::-webkit-scrollbar {
98+
width: 10px;
99+
height: 10px;
100+
}
101+
102+
::-webkit-scrollbar-track {
103+
background: hsl(0 0% 12%);
104+
border-radius: 5px;
105+
}
106+
107+
::-webkit-scrollbar-thumb {
108+
background: hsl(0 0% 25%);
109+
border-radius: 5px;
110+
}
111+
112+
::-webkit-scrollbar-thumb:hover {
113+
background: hsl(0 0% 35%);
114+
}
115+
116+
/* Add no-scrollbar utility class */
117+
@layer utilities {
118+
.no-scrollbar::-webkit-scrollbar {
119+
display: none;
120+
}
121+
122+
.no-scrollbar {
123+
-ms-overflow-style: none; /* IE and Edge */
124+
scrollbar-width: none; /* Firefox */
125+
}
126+
}

app/layout.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type React from "react"
2+
import type { Metadata } from "next"
3+
import { Inter } from "next/font/google"
4+
import { ThemeProvider } from "@/components/theme-provider"
5+
import { ToastProvider } from "@/components/toast-provider"
6+
import { FileSystemProvider } from "@/components/file-system-provider"
7+
import { Header } from "@/components/header"
8+
import "./globals.css"
9+
10+
const inter = Inter({ subsets: ["latin"] })
11+
12+
export const metadata: Metadata = {
13+
title: "Codebase Context Utility",
14+
description: "A tool for generating LLM context from your codebase",
15+
generator: 'v0.app'
16+
}
17+
18+
export default function RootLayout({
19+
children,
20+
}: {
21+
children: React.ReactNode
22+
}) {
23+
return (
24+
<html lang="en" suppressHydrationWarning>
25+
<body className={inter.className}>
26+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
27+
<FileSystemProvider>
28+
<div className="flex min-h-screen flex-col">
29+
<Header />
30+
<main className="flex-1">{children}</main>
31+
</div>
32+
</FileSystemProvider>
33+
<ToastProvider />
34+
</ThemeProvider>
35+
</body>
36+
</html>
37+
)
38+
}

app/page.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Dashboard } from "@/components/dashboard"
2+
import { FileSystemProvider } from "@/components/file-system-provider"
3+
import { ToastProvider } from "@/components/toast-provider"
4+
import { ThemeProvider } from "@/components/theme-provider"
5+
6+
export default function Home() {
7+
return (
8+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
9+
<FileSystemProvider>
10+
<main className="flex min-h-screen flex-col">
11+
<Dashboard />
12+
</main>
13+
</FileSystemProvider>
14+
<ToastProvider />
15+
</ThemeProvider>
16+
)
17+
}

components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "tailwind.config.ts",
8+
"css": "app/globals.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

components/advanced-search.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"use client"
2+
3+
import { useState } from "react"
4+
import { Input } from "@/components/ui/input"
5+
import { Button } from "@/components/ui/button"
6+
import { useFileSystem, type FileEntry } from "@/components/file-system-provider"
7+
8+
export function AdvancedSearch() {
9+
const { fileTree, setSelectedFile } = useFileSystem()
10+
const [searchTerm, setSearchTerm] = useState("")
11+
const [searchResults, setSearchResults] = useState<string[]>([])
12+
13+
const searchFiles = async () => {
14+
if (!searchTerm.trim()) return
15+
16+
const results: string[] = []
17+
18+
const searchInTree = async (tree: Record<string, FileEntry>, basePath = "") => {
19+
for (const [name, entry] of Object.entries(tree)) {
20+
const path = basePath ? `${basePath}/${name}` : name
21+
22+
if (entry.type === "file") {
23+
if (name.toLowerCase().includes(searchTerm.toLowerCase())) {
24+
results.push(path)
25+
} else {
26+
// Search in file content
27+
const content = await entry.handle?.getFile().then((file) => file.text())
28+
if (content && content.toLowerCase().includes(searchTerm.toLowerCase())) {
29+
results.push(path)
30+
}
31+
}
32+
} else if (entry.type === "directory" && entry.children) {
33+
await searchInTree(entry.children, path)
34+
}
35+
}
36+
}
37+
38+
await searchInTree(fileTree)
39+
setSearchResults(results)
40+
}
41+
42+
return (
43+
<div className="space-y-4">
44+
<div className="flex space-x-2">
45+
<Input value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} placeholder="Search files..." />
46+
<Button onClick={searchFiles}>Search</Button>
47+
</div>
48+
{searchResults.length > 0 && (
49+
<div className="space-y-2">
50+
<h4 className="font-medium">Search Results:</h4>
51+
<ul className="space-y-1">
52+
{searchResults.map((result) => (
53+
<li key={result} className="cursor-pointer hover:underline" onClick={() => setSelectedFile(result)}>
54+
{result}
55+
</li>
56+
))}
57+
</ul>
58+
</div>
59+
)}
60+
</div>
61+
)
62+
}

0 commit comments

Comments
 (0)