11'use client' ;
2- import { useEffect , useRef } from 'react' ;
32
43const GITHUB_URL = 'https://github.com/sarthakagrawal927/CodeVetter' ;
54const DOWNLOAD_URL = 'https://github.com/sarthakagrawal927/CodeVetter/releases/latest' ;
65
7- function useFadeIn ( ) {
8- const ref = useRef ( null ) ;
9- useEffect ( ( ) => {
10- const el = ref . current ;
11- if ( ! el ) return ;
12- const obs = new IntersectionObserver (
13- ( [ entry ] ) => {
14- if ( entry . isIntersecting ) {
15- el . classList . add ( 'visible' ) ;
16- obs . disconnect ( ) ;
17- }
18- } ,
19- { threshold : 0.12 }
20- ) ;
21- obs . observe ( el ) ;
22- return ( ) => obs . disconnect ( ) ;
23- } , [ ] ) ;
24- return ref ;
25- }
26-
27- function FeatureCard ( { icon, iconBg, title, body } ) {
28- const ref = useFadeIn ( ) ;
29- return (
30- < div className = "feature-card fade-up" ref = { ref } >
31- < div className = "feature-icon" style = { { background : iconBg } } > { icon } </ div >
32- < h3 > { title } </ h3 >
33- < p > { body } </ p >
34- </ div >
35- ) ;
36- }
37-
38- function Step ( { number, title, body } ) {
39- const ref = useFadeIn ( ) ;
40- return (
41- < div className = "step fade-up" ref = { ref } >
42- < div className = "step-number" > { number } </ div >
43- < h3 > { title } </ h3 >
44- < p > { body } </ p >
45- </ div >
46- ) ;
47- }
48-
496export default function LandingPage ( ) {
50- const featuresRef = useFadeIn ( ) ;
51- const stepsRef = useFadeIn ( ) ;
52- const techRef = useFadeIn ( ) ;
53- const ctaRef = useFadeIn ( ) ;
54-
557 return (
568 < >
57- { /* ============ NAV ============ */ }
589 < nav className = "nav" >
5910 < div className = "nav-inner" >
6011 < div className = "nav-logo" >
6112 < div className = "nav-logo-icon" > CV</ div >
6213 CodeVetter
6314 </ div >
64- < div className = "nav-links" >
65- < a href = "#features" > Features</ a >
66- < a href = "#how-it-works" > How It Works</ a >
67- < a href = "#download" > Download</ a >
68- </ div >
6915 < div className = "nav-actions" >
7016 < a href = { GITHUB_URL } className = "btn btn-ghost" target = "_blank" rel = "noopener noreferrer" >
71- < span className = "btn-icon" >
72- < svg width = "18" height = "18" viewBox = "0 0 24 24" fill = "currentColor" > < path d = "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /> </ svg >
73- </ span >
7417 GitHub
7518 </ a >
7619 < a href = { DOWNLOAD_URL } className = "btn btn-primary" > Download</ a >
7720 </ div >
7821 </ div >
7922 </ nav >
8023
81- { /* ============ HERO ============ */ }
8224 < section className = "hero" >
8325 < div className = "hero-badge" >
8426 < span className = "hero-badge-dot" />
85- macOS desktop app
27+ Free · macOS
8628 </ div >
87- < h1 > AI agents that < span className = "hero-highlight" > actually ship code</ span > </ h1 >
29+ < h1 > The quality gate for < span className = "hero-highlight" > AI-generated code</ span > </ h1 >
8830 < p className = "hero-sub" >
89- CodeVetter orchestrates AI coding agents in isolated workspaces. Review findings, manage PRs, and track progress — all from one desktop app.
31+ CodeVetter reviews code from AI agents, catches bloat and hallucinated APIs,
32+ and sends findings back to the agent to fix. Locally or on GitHub PRs.
9033 </ p >
9134 < div className = "hero-actions" >
9235 < a href = { DOWNLOAD_URL } className = "btn btn-primary btn-lg" >
9336 < svg width = "18" height = "18" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2.5" strokeLinecap = "round" strokeLinejoin = "round" > < path d = "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" /> < polyline points = "7 10 12 15 17 10" /> < line x1 = "12" y1 = "15" x2 = "12" y2 = "3" /> </ svg >
9437 Download for macOS
9538 </ a >
9639 < a href = { GITHUB_URL } className = "btn btn-secondary btn-lg" target = "_blank" rel = "noopener noreferrer" >
97- < svg width = "18" height = "18" viewBox = "0 0 24 24" fill = "currentColor" > < path d = "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /> </ svg >
98- View on GitHub
40+ View Source
9941 </ a >
10042 </ div >
101-
102- < div className = "hero-screenshot" >
103- < div className = "hero-screenshot-titlebar" >
104- < span className = "hero-screenshot-dot red" />
105- < span className = "hero-screenshot-dot yellow" />
106- < span className = "hero-screenshot-dot green" />
107- < span className = "hero-screenshot-title" > CodeVetter — workspace</ span >
108- </ div >
109- < div className = "hero-screenshot-body" >
110- App screenshot placeholder
111- </ div >
112- </ div >
11343 </ section >
11444
11545 < hr className = "divider" />
11646
117- { /* ============ FEATURES ============ */ }
118- < section className = "section" id = "features" >
119- < div className = "section-header fade-up" ref = { featuresRef } >
120- < span className = "section-label" > Features</ span >
121- < h2 > Everything you need to ship faster</ h2 >
122- < p > A desktop app that combines AI agents, code review, and project management in one workspace.</ p >
123- </ div >
124- < div className = "feature-grid" >
125- < FeatureCard
126- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--amber)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < rect x = "2" y = "3" width = "20" height = "14" rx = "2" ry = "2" /> < line x1 = "8" y1 = "21" x2 = "16" y2 = "21" /> < line x1 = "12" y1 = "17" x2 = "12" y2 = "21" /> </ svg > }
127- iconBg = "var(--amber-dim)"
128- title = "Workspaces"
129- body = "Branch-based workspaces with built-in chat, terminal, file explorer, and PR management. Each workspace is an isolated coding environment."
130- />
131- < FeatureCard
132- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--purple)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < path d = "M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" /> < circle cx = "9" cy = "7" r = "4" /> < path d = "M23 21v-2a4 4 0 00-3-3.87" /> < path d = "M16 3.13a4 4 0 010 7.75" /> </ svg > }
133- iconBg = "rgba(168, 85, 247, 0.15)"
134- title = "Agent Squad"
135- body = "Define AI personas for different roles — security auditor, backend architect, test writer. Assign tasks and watch them work autonomously."
136- />
137- < FeatureCard
138- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--green)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < path d = "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" /> < polyline points = "14 2 14 8 20 8" /> < line x1 = "16" y1 = "13" x2 = "8" y2 = "13" /> < line x1 = "16" y1 = "17" x2 = "8" y2 = "17" /> </ svg > }
139- iconBg = "rgba(34, 197, 94, 0.15)"
140- title = "Code Review"
141- body = "AI-powered review with severity triage, code suggestions, and one-click GitHub posting. Better than GitHub's built-in review."
142- />
143- < FeatureCard
144- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--blue)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < polyline points = "16 18 22 12 16 6" /> < polyline points = "8 6 2 12 8 18" /> < line x1 = "14" y1 = "4" x2 = "10" y2 = "20" /> </ svg > }
145- iconBg = "rgba(59, 130, 246, 0.15)"
146- title = "Multi-Agent Coordination"
147- body = "CRDT-based coordination ensures agents don't duplicate work. File claiming, live progress indicators, and cleanly merged results."
148- />
149- < FeatureCard
150- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--amber)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < rect x = "3" y = "3" width = "7" height = "7" /> < rect x = "14" y = "3" width = "7" height = "7" /> < rect x = "14" y = "14" width = "7" height = "7" /> < rect x = "3" y = "14" width = "7" height = "7" /> </ svg > }
151- iconBg = "var(--amber-dim)"
152- title = "Task Board"
153- body = "Kanban board with Linear integration. Import issues, assign to agent personas, track from To Do to Done — all without leaving the app."
154- />
155- < FeatureCard
156- icon = { < svg width = "22" height = "22" viewBox = "0 0 24 24" fill = "none" stroke = "var(--purple)" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" > < path d = "M22 12h-4l-3 9L9 3l-3 9H2" /> </ svg > }
157- iconBg = "rgba(168, 85, 247, 0.15)"
158- title = "Session Analytics"
159- body = "Track token usage, costs, and session history across Claude Code, Codex, and other AI tools. Know exactly what your agents are doing."
160- />
161- </ div >
162- </ section >
163-
164- < hr className = "divider" />
165-
166- { /* ============ HOW IT WORKS ============ */ }
167- < section className = "section" id = "how-it-works" >
168- < div className = "section-header fade-up" ref = { stepsRef } >
169- < span className = "section-label" > How It Works</ span >
170- < h2 > From branch to merged PR in minutes</ h2 >
171- < p > Three steps to go from idea to shipped code with AI agents handling the heavy lifting.</ p >
172- </ div >
173- < div className = "steps-grid" >
174- < div className = "steps-connector" />
175- < Step
176- number = "1"
177- title = "Create a workspace"
178- body = "Start from a branch, PR, or blank slate. Each workspace gets its own terminal, file explorer, and chat session."
179- />
180- < Step
181- number = "2"
182- title = "Chat or assign agents"
183- body = "Talk directly to Claude or dispatch tasks to specialized agent personas — security auditor, architect, test writer."
184- />
185- < Step
186- number = "3"
187- title = "Review and merge"
188- body = "Review AI findings with severity triage, accept suggestions, create PRs, and merge — all without leaving the app."
189- />
190- </ div >
191- </ section >
192-
193- < hr className = "divider" />
194-
195- { /* ============ TECH / INTEGRATIONS ============ */ }
19647 < section className = "section" >
197- < div className = "section-header fade-up" ref = { techRef } >
198- < span className = "section-label" > Integrations</ span >
199- < h2 > Built on the tools you already use</ h2 >
200- </ div >
201- < div className = "tech-row" >
202- < span className = "tech-pill" >
203- < span className = "tech-pill-icon" >
204- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "currentColor" > < path d = "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /> </ svg >
205- </ span >
206- GitHub
207- </ span >
208- < span className = "tech-pill" >
209- < span className = "tech-pill-icon" >
210- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" > < circle cx = "12" cy = "12" r = "10" /> < path d = "M12 8v8M8 12h8" /> </ svg >
211- </ span >
212- Claude Code
213- </ span >
214- < span className = "tech-pill" >
215- < span className = "tech-pill-icon" >
216- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" > < rect x = "2" y = "3" width = "20" height = "14" rx = "2" /> < line x1 = "8" y1 = "21" x2 = "16" y2 = "21" /> < line x1 = "12" y1 = "17" x2 = "12" y2 = "21" /> </ svg >
217- </ span >
218- Codex
219- </ span >
220- < span className = "tech-pill" >
221- < span className = "tech-pill-icon" >
222- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" > < polygon points = "5 3 19 12 5 21 5 3" /> </ svg >
223- </ span >
224- Linear
225- </ span >
226- < span className = "tech-pill" >
227- < span className = "tech-pill-icon" >
228- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" > < circle cx = "12" cy = "12" r = "10" /> < path d = "M8 12l2 2 4-4" /> </ svg >
229- </ span >
230- Playwright
231- </ span >
232- < span className = "tech-pill" >
233- < span className = "tech-pill-icon" >
234- < svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" > < path d = "M12 2L2 7l10 5 10-5-10-5z" /> < path d = "M2 17l10 5 10-5" /> < path d = "M2 12l10 5 10-5" /> </ svg >
235- </ span >
236- Tauri + React + Rust
237- </ span >
48+ < div className = "feature-grid" >
49+ < div className = "feature-card" >
50+ < h3 > Review agent code</ h3 >
51+ < p > Runs AI-powered review on local diffs or GitHub PRs. Catches over-engineering, copy-paste, hallucinated APIs, and hardcoded secrets.</ p >
52+ </ div >
53+ < div className = "feature-card" >
54+ < h3 > Feedback loop</ h3 >
55+ < p > When review fails, findings are sent back to the agent as fix instructions. Re-reviews automatically until the code passes or max attempts hit.</ p >
56+ </ div >
57+ < div className = "feature-card" >
58+ < h3 > Orchestrate agents</ h3 >
59+ < p > Kanban board with agent personas. Assign tasks, track progress, manage concurrency. Plan, code, review pipeline runs autonomously.</ p >
60+ </ div >
23861 </ div >
23962 </ section >
24063
24164 < hr className = "divider" />
24265
243- { /* ============ DOWNLOAD CTA ============ */ }
24466 < section className = "cta-section" id = "download" >
245- < div className = "cta-box fade-up" ref = { ctaRef } >
246- < span className = "section-label" > Get Started</ span >
247- < h2 > Download CodeVetter</ h2 >
248- < p > Free and open source. Built for engineers who ship with AI.</ p >
67+ < div className = "cta-box" >
68+ < h2 > Ship better code with AI agents</ h2 >
69+ < p > Free, open source, runs offline. Requires macOS 12+ and an AI provider API key.</ p >
24970 < div className = "cta-actions" >
25071 < a href = { DOWNLOAD_URL } className = "btn btn-primary btn-lg" >
251- < svg width = "18" height = "18" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2.5" strokeLinecap = "round" strokeLinejoin = "round" > < path d = "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" /> < polyline points = "7 10 12 15 17 10" /> < line x1 = "12" y1 = "15" x2 = "12" y2 = "3" /> </ svg >
25272 Download for macOS
25373 </ a >
254- < a href = { GITHUB_URL } className = "btn btn-secondary btn-lg" target = "_blank" rel = "noopener noreferrer" >
255- < svg width = "18" height = "18" viewBox = "0 0 24 24" fill = "currentColor" > < path d = "M12 .3a12 12 0 00-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1.1-.8.1-.7.1-.7 1.2.1 1.9 1.3 1.9 1.3 1.1 1.8 2.8 1.3 3.5 1 .1-.8.4-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-5.9 0-1.3.5-2.4 1.2-3.2-.1-.3-.5-1.5.1-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 016 0c2.3-1.5 3.3-1.2 3.3-1.2.7 1.7.3 2.9.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.4.4.8 1.1.8 2.2v3.3c0 .3.2.7.8.6A12 12 0 0012 .3z" /> </ svg >
256- Star on GitHub
257- </ a >
25874 </ div >
259- < p className = "cta-requirements" > Requires macOS 12+ and Claude Code CLI installed</ p >
26075 </ div >
26176 </ section >
26277
263- { /* ============ FOOTER ============ */ }
26478 < footer className = "footer" >
26579 < div className = "footer-inner" >
26680 < div className = "footer-brand" >
@@ -270,8 +84,6 @@ export default function LandingPage() {
27084 < span className = "footer-copy" > Built by Sarthak Agrawal</ span >
27185 < div className = "footer-links" >
27286 < a href = { GITHUB_URL } target = "_blank" rel = "noopener noreferrer" > GitHub</ a >
273- < a href = "#" > Documentation</ a >
274- < a href = "#" > Changelog</ a >
27587 </ div >
27688 </ div >
27789 </ footer >
0 commit comments