import React, { useEffect, useRef, useState } from "react"; import "./landing.css"; // Premium GitPilot landing page — dark, minimal, animated. // Public page only: "Get started" / "Sign in" route to the separate /auth page. const GITHUB_URL = "https://github.com/ruslanmv/gitpilot"; const DOCS_URL = "https://ruslanmv.com/gitpilot/"; // --- tiny inline icons (no dependencies) ---------------------------------- const I = { shield: , target: , code: , brain: , map: , bolt: , check2: , bot: , home: , flow: , gear: , copy: , ext: , lock: , arrowL: , arrowR: , ask: , play: , eye: , git: , }; // The multi-agent pipeline — the heart of GitPilot, shown as a carousel. const AGENTS = [ { n: "01", name: "Explorer", role: "Context", ic: I.brain, title: "It reads your repo before it writes a line.", desc: "Explorer scans your full repository, git history, test suite, and dependencies — so every plan starts from real knowledge, not guesses.", mock: (
explorer
), }, { n: "02", name: "Planner", role: "Strategy", ic: I.map, title: "A step-by-step plan you approve first.", desc: "Planner drafts a safe, reviewable plan with diffs and surfaces risks before any file is touched. Nothing runs until you say go.", mock: (
plan · 3 steps
  1. 1 Add validateEmail() to login.ts
  2. 2 Wire validation into the submit handler
  3. 3 Add 2 unit tests for edge cases
Approve & ExecuteDismiss
), }, { n: "03", name: "Coder", role: "Execution", ic: I.bolt, title: "It writes the code and runs your tests.", desc: "Coder applies the plan, runs your test suite, and self-corrects on failure — iterating until everything passes. Diffs are shown before they're applied.", mock: (
login.ts
          + if (!validateEmail(email)) {"{"}
          +   return error("Enter a valid email");
          + {"}"}
            await signIn(email, password);
        
npm test — 3 passed
), }, { n: "04", name: "Reviewer", role: "Quality", ic: I.check2, title: "It reviews the work and ships it.", desc: "Reviewer validates the output, re-runs the suite, and drafts your commit message and pull-request summary — ready for you to merge.", mock: (
pull request
feat(auth): validate email on login
), }, ]; const MODES = [ { ic: I.ask, t: "Ask", tag: "Default", d: "Approve every dangerous action. You see the diff and click Allow or Deny before anything is written." }, { ic: I.play, t: "Auto", tag: "Fastest", d: "Trust the plan and let every tool run automatically — no prompts. Best for experienced users." }, { ic: I.eye, t: "Plan", tag: "Read-only", d: "Generate and display the full plan with diffs, but block all file writes and commands." }, ]; const STEPS = [ { t: "Connect a repository", d: "Authorize GitPilot securely with GitHub device flow — or run fully local with Ollama." }, { t: "Describe the task", d: "Ask in plain language. Explorer and Planner turn it into a reviewable plan." }, { t: "Approve & ship", d: "Coder writes and tests the change; Reviewer drafts the commit and PR. You stay in control." }, ]; // Reveal-on-scroll wrapper (IntersectionObserver, no dependency). function Reveal({ children, className = "", style, delay = 0 }) { const ref = useRef(null); const [shown, setShown] = useState(false); useEffect(() => { const el = ref.current; if (!el) return undefined; if (typeof IntersectionObserver === "undefined") { setShown(true); return undefined; } const io = new IntersectionObserver( ([e]) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }, { threshold: 0.12 } ); io.observe(el); return () => io.disconnect(); }, []); return (
{children}
); } function AgentCarousel() { const [active, setActive] = useState(0); const [paused, setPaused] = useState(false); const n = AGENTS.length; useEffect(() => { if (paused) return undefined; const t = setInterval(() => setActive((a) => (a + 1) % n), 5200); return () => clearInterval(t); }, [paused, n]); const go = (i) => setActive(((i % n) + n) % n); const cur = AGENTS[active]; return (
setPaused(true)} onMouseLeave={() => setPaused(false)} >
{cur.ic}Agent {cur.n} · {cur.role}
{cur.n} / {String(n).padStart(2, "0")}
{AGENTS.map((a) => (
{a.name}

{a.title}

{a.desc}

{a.mock}
))}
{AGENTS.map((a, i) => (
); } // Real GitPilot app screens, shown as a carousel inside the hero preview box. const SCREENS = [ { key: "workspace", label: "Workspace", body: ( <>
Connect a repositoryWrite access ✓
ai-doctor/medical-data main · 26 files
gitpilot
signalforge
matrix-builder
{I.git} Connect with GitHub
), }, { key: "agents", label: "Agent workflow", body: (
User request
Task Router
ExplorerPlannerCoderReviewer
), }, { key: "plan", label: "Plan & approve", body: ( <>
Action planReplace README.md
1 create1 modify1 delete
STEP 1 Delete existing README.md
STEP 2 Rename README.md.new → README.md
Approve & executeDismiss
), }, { key: "exec", label: "Execution", body: ( <>
Execution log
Successfully executed 2 steps
), }, { key: "review", label: "Review & PR", body: ( <>
Pull requestReady
feat(auth): validate email on login
), }, ]; // Animated carousel that lives inside the existing hero preview window. function PreviewCarousel() { const [i, setI] = useState(0); const [paused, setPaused] = useState(false); const n = SCREENS.length; useEffect(() => { if (paused) return undefined; const t = setInterval(() => setI((p) => (p + 1) % n), 4200); return () => clearInterval(t); }, [paused, n]); const go = (k) => setI(((k % n) + n) % n); return (
setPaused(true)} onMouseLeave={() => setPaused(false)} >
{SCREENS[i].label}
{SCREENS.map((s) => (
{s.body}
))}
{SCREENS.map((s, k) => (
); } export default function LandingPage() { // The app shell sets `body { overflow: hidden }` for the fixed workspace // layout, which freezes mouse-wheel scrolling on this public page. Allow the // page to scroll while the landing is mounted; restore on unmount. useEffect(() => { const prevBody = document.body.style.overflow; const prevHtml = document.documentElement.style.overflow; document.body.style.overflow = "auto"; document.documentElement.style.overflow = "auto"; return () => { document.body.style.overflow = prevBody; document.documentElement.style.overflow = prevHtml; }; }, []); return (
{/* sticky top bar — keeps brand/home reachable from anywhere on the page */}
{/* above-the-fold: hero + capabilities occupy one viewport */}
{/* hero — vertically centered in the remaining fold space */}
The first open-source multi-agent coding assistant

Your AI engineering
team, under your control.

Specialized agents — in configurable topologies — read your repo, plan changes you approve, write code, and run your tests. On any LLM. Open source.

{I.shield} Apache 2.0 open source {I.check2} 854 tests passing {I.lock} Private by default
{/* product preview — animated carousel of real GitPilot app screens */}
{/* capabilities — enterprise value prop, no brand names */}
Any LLM, Zero Lock-In
Proprietary Cloud APIs  •  Local & Private Models  •  Open-Source Weights  •  Custom Deployments
{/* /gp-fold */} {/* agent carousel */}
Multi-agent topologies

One request. A whole engineering team.

Most AI tools are a single model behind a chat box. GitPilot orchestrates configurable agent topologies — routing dispatch, ReAct loops with subagents, and task pipelines — so specialized roles explore, plan, build, and review your code.

{/* execution modes */}
You hold the controls

Three modes. You decide how far it goes.

Switch per session. Diffs are shown before they're applied; tests run before anything is committed. No surprises.

{MODES.map((m, i) => (
{m.ic}
{m.tag}

{m.t}

{m.d}

))}
{/* how it works */}

From idea to pull request

{STEPS.map((s, i) => (
{i + 1}

{s.t}

{s.d}

))}
{/* CTA band */}

Ship better code, without giving up control.

Start free and local with Ollama, or bring your own OpenAI, Claude, or watsonx key.

{/* footer */}
); }