Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

1,120 linesCodeBlameRaw
1import {
2 ArrowRight,
3 BookOpen,
4 Bot,
5 Check,
6 CircleDashed,
7 Code2,
8 Eye,
9 Handshake,
10 Bell,
11 KeyRound,
12 Lock,
13 MessagesSquare,
14 PackageCheck,
15 ScanSearch,
16 ScrollText,
17 ShieldCheck,
18 Wallet,
19} from "lucide-react";
20import type { CSSProperties, ReactNode } from "react";
21import { Link } from "react-router";
22
23import { DeployArt, Live, QueueArt, WhyArt } from "./art";
24import { NeedsYouArt, WhatChangedArt } from "./landing-home";
25import { ProductTour } from "./product-tour";
26import { ButtonLink, CopyLine } from "./ui";
27
28const DOCS = "https://docs.g1t.sh";
29
30/** A small label above a heading, in the mono face. */
31function Eyebrow({ children }: { children: ReactNode }) {
32 return (
33 <p className="font-mono text-xs tracking-[0.2em] text-accent uppercase">
34 {children}
35 </p>
36 );
37}
38
39/** Marks something planned and not built yet, wherever it is mentioned. */
40function Soon({ className = "" }: { className?: string }) {
41 return (
42 <span
43 className={`inline-flex shrink-0 items-center rounded-full bg-raised px-2 py-0.5 align-middle font-mono text-[0.625rem] font-medium tracking-wide whitespace-nowrap text-muted uppercase ring-1 ring-line-strong ${className}`}
44 >
45 Coming soon
46 </span>
47 );
48}
49
50function Tags({ items }: { items: string[] }) {
51 return (
52 <ul className="mt-6 flex flex-wrap gap-1.5">
53 {items.map((item) => (
54 <li
55 key={item}
56 className="rounded-full bg-bg/80 px-2.5 py-1 font-mono text-[0.6875rem] tracking-wide text-muted uppercase ring-1 ring-line"
57 >
58 {item}
59 </li>
60 ))}
61 </ul>
62 );
63}
64
65/** A link in running copy that leads to the docs or another page. */
66function More({ to, children }: { to: string; children: ReactNode }) {
67 return (
68 <Link
69 to={to}
70 className="group mt-7 inline-flex items-center gap-1.5 text-sm font-medium text-fg hover:text-accent"
71 >
72 {children}
73 <ArrowRight
74 size={14}
75 className="transition-transform group-hover:translate-x-0.5"
76 />
77 </Link>
78 );
79}
80
81/**
82 * A point in a list: a check, a check whose words link somewhere, or a
83 * "Coming soon" tag for what is not built yet.
84 */
85type Point =
86 | string
87 | { text: string; link: { to: string; label: string } }
88 | { text: string; soon: true };
89
90function Points({
91 points,
92 columns = true,
93}: {
94 points: Point[];
95 columns?: boolean;
96}) {
97 const now = points.filter((point) => typeof point === "string" || !("soon" in point));
98 const later = points
99 .filter((point) => typeof point !== "string" && "soon" in point)
100 .map((point) => (point as { text: string }).text);
101 return (
102 <>
103 <ul
104 className={`mt-6 grid gap-2.5 text-sm ${columns ? "sm:grid-cols-2" : ""}`}
105 >
106 {now.map((point) =>
107 typeof point === "string" ? (
108 <li key={point} className="flex gap-2.5 text-fg-soft">
109 <Check size={15} className="mt-0.5 shrink-0 text-accent" />
110 <span>{point}</span>
111 </li>
112 ) : (
113 "link" in point && (
114 <li key={point.text} className="flex gap-2.5 text-fg-soft">
115 <Check size={15} className="mt-0.5 shrink-0 text-accent" />
116 <span>
117 {point.text}{" "}
118 <Link
119 to={point.link.to}
120 className="text-fg underline underline-offset-4 hover:text-accent"
121 >
122 {point.link.label}
123 </Link>
124 </span>
125 </li>
126 )
127 ),
128 )}
129 </ul>
130 {later.length > 0 && (
131 <div className="mt-5 rounded-xl border border-dashed border-line-strong px-4 py-3.5">
132 <Soon />
133 <ul
134 className={`mt-3 grid gap-2 text-sm ${columns ? "sm:grid-cols-2" : ""}`}
135 >
136 {later.map((text) => (
137 <li key={text} className="flex gap-2.5 text-muted">
138 <CircleDashed
139 size={14}
140 className="mt-0.5 shrink-0 text-faint"
141 />
142 <span>{text}</span>
143 </li>
144 ))}
145 </ul>
146 </div>
147 )}
148 </>
149 );
150}
151
152/** A drawing in its own card, on the page's dark gray. */
153function ArtFrame({ children }: { children: ReactNode }) {
154 return (
155 <Live className="relative overflow-hidden rounded-3xl bg-surface/60 px-4 py-6 ring-1 ring-line sm:px-8">
156 <div
157 aria-hidden="true"
158 className="pointer-events-none absolute inset-x-0 -bottom-24 h-48 bg-[radial-gradient(50%_60%_at_50%_100%,rgb(182_168_255/0.08),transparent)]"
159 />
160 <div className="relative mx-auto max-w-lg">{children}</div>
161 </Live>
162 );
163}
164
165/**
166 * One part of Code: what it does, the features that prove it, and a
167 * drawing of the idea, on alternating sides.
168 */
169function Pillar({
170 eyebrow,
171 title,
172 art,
173 points,
174 more,
175 flip,
176 children,
177}: {
178 eyebrow: string;
179 title: string;
180 art: ReactNode;
181 points: string[];
182 more: [string, string];
183 flip?: boolean;
184 children: ReactNode;
185}) {
186 return (
187 <article className="grid items-center gap-10 py-14 lg:grid-cols-2 lg:gap-16">
188 <div className={flip ? "lg:order-2" : undefined}>
189 <Eyebrow>{eyebrow}</Eyebrow>
190 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance sm:text-3xl">
191 {title}
192 </h3>
193 <p className="mt-4 max-w-xl leading-7 text-muted">{children}</p>
194 <Points points={points} />
195 <More to={more[1]}>{more[0]}</More>
196 </div>
197 <div className={flip ? "lg:order-1" : undefined}>
198 <ArtFrame>{art}</ArtFrame>
199 </div>
200 </article>
201 );
202}
203
204/** Facts under the opening, each one true today. */
205const FACTS: [string, string][] = [
206 [
207 "$0",
208 "for people to chat. Every plan, the free one too, with no history cutoff.",
209 ],
210 [
211 "0 seats",
212 "Everyone in the company joins at one workspace price, never per person.",
213 ],
214 [
215 "+20%",
216 "on what compute costs g1t: checks, workflows and deployments. Your own runners are free.",
217 ],
218 [
219 "MIT",
220 "licensed. g1t's own source lives on g1t and lands through its own queue.",
221 ],
222];
223
224/** What a workspace holds, and the coding agents it works with. */
225const MODES: {
226 icon: ReactNode;
227 name: string;
228 about: string;
229 soon?: boolean;
230 to: string;
231}[] = [
232 {
233 icon: <Code2 size={18} />,
234 name: "Code",
235 about:
236 "Repositories, issues, pull requests, checks, a merge queue and deployments. For the people who build.",
237 to: `${DOCS}/concepts/overview/`,
238 },
239 {
240 icon: <MessagesSquare size={18} />,
241 name: "Chat",
242 about:
243 "Channels, direct messages and threads, live, for everyone in the company.",
244 to: `${DOCS}/guides/chat/`,
245 },
246 {
247 icon: <Bot size={18} />,
248 name: "Your coding agents",
249 about:
250 "Claude Code, Codex, Cursor or any MCP client, working as you through MCP, the g1t CLI or the API, with only the access you give them.",
251 to: `${DOCS}/guides/bring-your-own-agent/`,
252 },
253 {
254 icon: <BookOpen size={18} />,
255 name: "Artifacts",
256 about:
257 "Docs now, and slides, designs and dashboards next, made together live.",
258 to: `${DOCS}/guides/artifacts/`,
259 },
260];
261
262const RAILS: { icon: ReactNode; title: string; about: string; to: string }[] = [
263 {
264 icon: <KeyRound size={18} />,
265 title: "Scopes",
266 about:
267 "A token or an OAuth app gets only the scopes you grant it, and never does more than you could do yourself.",
268 to: `${DOCS}/guides/authentication/#access-tokens`,
269 },
270 {
271 icon: <Handshake size={18} />,
272 title: "Rules",
273 about:
274 "Protected branches, required checks and required approvals apply to every push and every merge, whoever made it.",
275 to: `${DOCS}/guides/rules/`,
276 },
277 {
278 icon: <Eye size={18} />,
279 title: "Guardrails",
280 about:
281 "How long a project's checks and merge queue may run, enforced in g1t's sandboxes.",
282 to: `${DOCS}/guides/guardrails/`,
283 },
284 {
285 icon: <ScrollText size={18} />,
286 title: "Audit",
287 about:
288 "Every action by people and tokens: who did it, through what, whether it was allowed and the rule that decided.",
289 to: `${DOCS}/guides/audit-log/`,
290 },
291];
292
293const FLOW: [string, string][] = [
294 [
295 "Ask",
296 "Open an issue, or raise it in a channel: what should change, and what done looks like.",
297 ],
298 [
299 "Change",
300 "You or your coding agent push a branch and open a pull request. The agent's session is recorded onto it.",
301 ],
302 [
303 "Check",
304 "Required checks run on g1t's runners or your own, and the pull request gets a live preview.",
305 ],
306 [
307 "Review",
308 "A person reviews and approves. Rules and protected branches apply to everyone.",
309 ],
310 [
311 "Main",
312 "The queue tests each change with what lands before it. Production follows main.",
313 ],
314];
315
316/** The forge itself, for the people who build. */
317const FORGE = [
318 "Git over HTTPS",
319 "Public and private repositories",
320 "Issues and labels",
321 "Pull requests and forks",
322 "Line comments and reviews",
323 "Protected branches",
324 "Required approvals",
325 "Workspaces and roles",
326 "Teams",
327 "Search and Explore",
328 "Webhooks",
329 "Import from any git host",
330 "REST API and OpenAPI",
331 "MCP server",
332 "The g1t CLI",
333];
334
335const SECURE: { icon: ReactNode; title: string; about: string; to: string }[] =
336 [
337 {
338 icon: <ShieldCheck size={18} />,
339 title: "Push protection",
340 about:
341 "A push that adds a key or a token is refused before it lands, and the history is scanned for ones already there.",
342 to: `${DOCS}/guides/security/secret-protection/`,
343 },
344 {
345 icon: <PackageCheck size={18} />,
346 title: "Dependency upkeep",
347 about:
348 "Each vulnerable dependency that has a fixed version becomes an upgrade, landed through the same checks as any change.",
349 to: `${DOCS}/guides/security/#security-updates`,
350 },
351 {
352 icon: <ScanSearch size={18} />,
353 title: "Code scanning",
354 about:
355 "Static analysis results become alerts, comments on the pull request that caused them, and a check that can block the merge.",
356 to: `${DOCS}/guides/security/code-scanning/`,
357 },
358 {
359 icon: <Lock size={18} />,
360 title: "Supply chain",
361 about:
362 "The dependency graph, an SBOM of it, and dependency review on every pull request that changes what you depend on.",
363 to: `${DOCS}/guides/security/supply-chain/`,
364 },
365 ];
366
367const PRICES: { name: string; price: string; unit?: string; about: string }[] =
368 [
369 {
370 name: "People",
371 price: "$0",
372 unit: "to chat",
373 about:
374 "Channels, DMs, threads and the forge are included on every plan, free too. No seats and no history cutoff.",
375 },
376 {
377 name: "The g1t plan",
378 price: "$21",
379 unit: "a month per workspace",
380 about:
381 "$10 of usage included. Unlimited members. Checks, workflows, the merge queue and deployments.",
382 },
383 {
384 name: "Usage",
385 price: "From cost + 20%",
386 about:
387 "Checks, workflows, deployments and storage, priced from what they cost g1t plus 20%. Time on your own runners costs nothing.",
388 },
389 ];
390
391/**
392 * The signed-out home page: what g1t is, what it does, and how to start.
393 * It lists no one's repositories; those are a click away under Explore.
394 */
395export function Landing() {
396 return (
397 <main className="overflow-x-clip">
398 {/* The opening. */}
399 <section className="dusk relative">
400 <div
401 aria-hidden="true"
402 className="dusk-planet pointer-events-none absolute -top-120 left-1/2 size-240 translate-x-[-10%] rounded-full"
403 />
404 <div className="relative mx-auto max-w-6xl px-4 pt-20 text-center sm:pt-24">
405 <Link
406 to={`${DOCS}/guides/bring-your-own-agent/`}
407 className="inline-flex animate-fade-up items-center gap-2 rounded-full bg-bg/50 px-3 py-1 text-xs whitespace-nowrap text-fg-soft ring-1 ring-line backdrop-blur transition-colors hover:bg-bg/70"
408 >
409 <span className="size-1.5 shrink-0 rounded-full bg-accent" />
410 <span className="sm:hidden">Works with Claude Code, Codex and Cursor</span>
411 <span className="hidden sm:inline">Works with Claude Code, Codex, Cursor and any MCP client</span>
412 <ArrowRight size={12} className="shrink-0" />
413 </Link>
414 <h1 className="mx-auto mt-7 max-w-4xl animate-fade-up text-[2.75rem] leading-[1.04] font-semibold tracking-tight text-balance sm:text-7xl">
415 Where your team&apos;s code{" "}
416 <span className="bg-linear-to-r from-fg via-accent-high to-accent bg-clip-text text-transparent">
417 lands, whoever wrote it.
418 </span>
419 </h1>
420 <p className="mx-auto mt-7 max-w-2xl animate-fade-up text-lg leading-8 text-fg-soft/80 text-balance">
421 Repositories, pull requests, required checks, a merge queue and
422 deployments, with chat and docs for your team. Connect the coding
423 agents you already use, and their work lands through the same
424 checks as everyone&apos;s.
425 </p>
426 <div className="mt-9 flex animate-fade-up flex-wrap items-center justify-center gap-3">
427 <ButtonLink to="/register" size="lg" className="rounded-full">
428 Get started
429 <ArrowRight size={15} />
430 </ButtonLink>
431 <ButtonLink
432 to="#how"
433 variant="outline"
434 size="lg"
435 className="rounded-full"
436 >
437 See how it works
438 </ButtonLink>
439 </div>
440 <p className="mx-auto mt-5 max-w-xl animate-fade-up text-sm text-fg-soft/60 text-balance">
441 Chat and the forge are free, with no card. No seats, ever.
442 </p>
443 </div>
444 <div className="relative mx-auto max-w-5xl px-4 pt-14 pb-2">
445 <div
446 aria-hidden="true"
447 className="pointer-events-none absolute inset-x-10 top-10 bottom-0 rounded-[3rem] bg-[radial-gradient(60%_60%_at_50%_40%,rgb(182_168_255/0.14),transparent)] blur-2xl"
448 />
449 <ProductTour className="relative" />
450 </div>
451 <div
452 aria-hidden="true"
453 className="h-16 bg-linear-to-b from-transparent to-bg"
454 />
455 </section>
456
457 {/* Facts, each one true today. */}
458 <section className="relative z-10 mx-auto max-w-6xl px-4">
459 <dl className="grid gap-px overflow-hidden rounded-2xl border border-line bg-line sm:grid-cols-2 lg:grid-cols-4">
460 {FACTS.map(([figure, about]) => (
461 <div key={figure} className="bg-bg px-6 py-6">
462 <dt className="font-mono text-2xl font-medium tracking-tight text-fg">
463 {figure}
464 </dt>
465 <dd className="mt-2 text-sm leading-6 text-muted">{about}</dd>
466 </div>
467 ))}
468 </dl>
469 </section>
470
471 {/* What a workspace holds. */}
472 <section className="mx-auto max-w-6xl px-4 pt-24">
473 <div className="max-w-3xl">
474 <Eyebrow>One workspace</Eyebrow>
475 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
476 Talk, write it down, ship.
477 </h2>
478 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
479 Code, Chat and Artifacts share one set of members, one sign-in and
480 one bill. The coding agents you connect work as you, through MCP,
481 the g1t CLI and the API.
482 </p>
483 </div>
484 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
485 {MODES.map((mode) => (
486 <Link
487 key={mode.name}
488 to={mode.to}
489 className="group flex flex-col rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
490 >
491 <span className="flex items-center justify-between gap-2">
492 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
493 {mode.icon}
494 </span>
495 {mode.soon && <Soon />}
496 </span>
497 <h3 className="mt-5 text-lg font-semibold">{mode.name}</h3>
498 <p className="mt-2 text-sm leading-6 text-muted">{mode.about}</p>
499 </Link>
500 ))}
501 </div>
502 </section>
503
504 {/* Code. */}
505 <section className="mx-auto max-w-6xl px-4 pt-24">
506 <div className="max-w-3xl">
507 <Eyebrow>Code</Eyebrow>
508 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
509 A forge built for many changes at once.
510 </h2>
511 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
512 Underneath is plain git. Every change, whether you wrote it or
513 your coding agent did, is a pull request: checked, reviewed, and
514 landed through a queue that keeps main passing.
515 </p>
516 </div>
517
518 <div className="mt-6 divide-y divide-line">
519 <Pillar
520 eyebrow="Ship safely"
521 title="Main only moves to what passed"
522 art={<QueueArt className="w-full" />}
523 points={[
524 "Checks in a clean sandbox, or free on your own runners",
525 "Your computer as a runner, with the desktop app",
526 "A merge queue that tests changes together",
527 "Conflicts found on every push, before a merge",
528 "Catch up with main in seconds",
529 "Required reviews, with code owners",
530 ]}
531 more={["The merge queue", `${DOCS}/guides/merge-queue/`]}
532 >
533 Required checks run on g1t&apos;s runners, or free on your own: a
534 server, or your computer while the desktop app is open. The queue
535 tests each change together with what lands ahead of it; one that
536 breaks goes back to its author with what failed, and main never sees
537 it.
538 </Pillar>
539
540 <Pillar
541 flip
542 eyebrow="Context"
543 title="Every line knows why it is there"
544 art={<WhyArt className="w-full" />}
545 points={[
546 "Sessions recorded onto pull requests",
547 "Why-blame on any line",
548 "Decisions recorded with the reasons behind them",
549 "Search across code, issues and people",
550 ]}
551 more={["Sessions and why-blame", `${DOCS}/guides/why-blame/`]}
552 >
553 Pick any line. g1t shows the commit that changed it, the pull
554 request and issue it came from, and the session your coding agent
555 recorded as it worked: what it read, ran and decided. The reasoning
556 stays with the code, for people and for the next agent.
557 </Pillar>
558
559 <Pillar
560 eyebrow="Run it"
561 title="Every change, live on the edge"
562 art={<DeployArt className="w-full" />}
563 points={[
564 "A live preview for every pull request",
565 "Production on every merge to main",
566 "Custom domains, with certificates",
567 "A new app from one sentence on Home",
568 ]}
569 more={["Deployments", `${DOCS}/guides/deployments/`]}
570 >
571 Turn on deployments and every pull request gets its own address on
572 g1t.page; merging ships production. Reviewers click through a
573 change instead of reading a diff. An app nobody visits runs nothing
574 and costs nothing. Or start from Home: ask for something new, and one
575 click makes its repository, starts your coding agent on it and puts
576 the first version live.
577 </Pillar>
578 </div>
579 </section>
580
581 {/* The forge, for people. */}
582 <section className="mx-auto max-w-6xl px-4 py-24">
583 <div className="grid gap-10 lg:grid-cols-[1fr_1.2fr] lg:gap-16">
584 <div>
585 <Eyebrow>Collaborate</Eyebrow>
586 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
587 A complete forge for the people who build
588 </h2>
589 <p className="mt-4 max-w-md leading-7 text-muted">
590 Issues, branches, pull requests and reviews, the way your team
591 already works. Write a change by hand, have your coding agent
592 write it, or both on the same branch.
593 </p>
594 <More to={`${DOCS}/concepts/overview/`}>How g1t works</More>
595 </div>
596 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
597 <p className="text-sm font-medium">Included in every workspace</p>
598 <Tags items={FORGE} />
599 </div>
600 </div>
601 </section>
602
603 {/* Chat, where people talk about the work. */}
604 <section className="mx-auto grid max-w-6xl items-start gap-12 px-4 lg:grid-cols-[1.1fr_1fr] lg:gap-16">
605 <div>
606 <Eyebrow>Chat</Eyebrow>
607 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
608 Just talk to your team.
609 </h2>
610 <p className="mt-4 max-w-xl leading-7 text-muted">
611 Chat is where your team talks about the work, next to the code it
612 is about. Ask a question in a channel, DM a colleague, or reply in
613 a thread. Messages arrive the moment they are sent, and everyone in
614 the company can join for free.
615 </p>
616 <More to={`${DOCS}/guides/chat/`}>How Chat works</More>
617 </div>
618 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
619 <p className="text-sm font-medium">Free on every plan</p>
620 <Points
621 columns={false}
622 points={[
623 "Private, workspace and public channels",
624 "Direct messages",
625 "Threads on any message",
626 "@mentions",
627 "Live delivery, typing and read state",
628 "A desktop app for Windows, macOS and Linux",
629 {
630 text: "An Android app with notifications: scan the QR code on",
631 link: { to: "/download", label: "Download" },
632 },
633 {
634 text: "Pull requests, checks and deploys as cards in the channel",
635 soon: true,
636 },
637 { text: "Chat mentions in Notifications", soon: true },
638 { text: "The phone app on iPhone", soon: true },
639 ]}
640 />
641 </div>
642 </section>
643
644 {/* Agents: they do the work, you make the calls. */}
645 <section id="agents" className="mx-auto max-w-6xl scroll-mt-20 px-4 pt-24">
646 <div className="max-w-3xl">
647 <Eyebrow>Agents</Eyebrow>
648 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
649 Agents do the work. You make the calls.
650 </h2>
651 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
652 Your coding agents push the branches and open the pull requests.
653 g1t keeps track of all of it, clears what resolved itself, and asks
654 you only for what is yours to decide: a merge, a review, a fix.
655 </p>
656 </div>
657
658 <div className="mt-6 divide-y divide-line">
659 <Pillar
660 eyebrow="Where you're needed"
661 title="Only what still needs you"
662 art={<NeedsYouArt />}
663 points={[
664 "Notifications that settle themselves",
665 "Why each one settled, and who did it",
666 "Pull requests ready for you to merge",
667 "Reviews asked of you, by name",
668 "Start here: the one to do first, and why",
669 ]}
670 more={["Home", `${DOCS}/guides/home/`]}
671 >
672 A notification is done once a later event resolves it: the next run
673 passes, the pull request merges, the fix deploys. g1t settles it
674 for you, and Home shows only what still waits on you. Start here
675 picks the one to do first and opens it.
676 </Pillar>
677
678 <Pillar
679 flip
680 eyebrow="What changed"
681 title="Come back to what changed, in plain English"
682 art={<WhatChangedArt />}
683 points={[
684 "A summary of what landed since you were last here",
685 "Whether each change is live, deploying or failed",
686 "Explain on any change that landed",
687 "Ask a follow-up, in your direct message with g1t",
688 ]}
689 more={["Ask g1t", `${DOCS}/guides/ask/`]}
690 >
691 Home asks &ldquo;What are we building today?&rdquo; Press
692 Summarize and What changed reads the commits, pull requests, deploys
693 and conversations since you were last here, then tells you what
694 changed, why, and what is live. Explain any one change, or ask a
695 follow-up. It runs on your workspace&apos;s own AI provider.
696 </Pillar>
697 </div>
698
699 <div className="mt-10 grid gap-4 lg:grid-cols-2">
700 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line sm:p-8">
701 <Eyebrow>Issues</Eyebrow>
702 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
703 Point your coding agent at an issue
704 </h3>
705 <p className="mt-3 text-sm leading-6 text-muted">
706 Your coding agent connects to g1t through MCP and works as you. It
707 reads the issue, pushes a branch, opens the pull request and
708 records its session onto it, and the pull request goes through
709 the same checks and reviews as anyone&apos;s.
710 </p>
711 <ol className="mt-6 space-y-3 text-sm">
712 {[
713 "Open an issue: what should change, and what done looks like",
714 "Work it yourself, or hand it to your coding agent",
715 "The pull request runs your checks and lands through the queue",
716 ].map((step, index) => (
717 <li key={step} className="flex items-start gap-3 text-fg-soft">
718 <span className="flex size-6 shrink-0 items-center justify-center rounded-full bg-bg font-mono text-xs text-faint ring-1 ring-line">
719 {index + 1}
720 </span>
721 {step}
722 </li>
723 ))}
724 </ol>
725 <More to={`${DOCS}/guides/bring-your-own-agent/`}>
726 Connect a coding agent
727 </More>
728 </div>
729 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line sm:p-8">
730 <Eyebrow>Coordination</Eyebrow>
731 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
732 Many agents, no collisions
733 </h3>
734 <p className="mt-3 text-sm leading-6 text-muted">
735 Run as many coding agents as you like. Each claims the issue it
736 takes, and every session shows live as it works, so everyone sees
737 who is on what. Two that start changing the same files are told
738 while they work, before either opens a pull request. The merge
739 queue tests changes together with what lands ahead of them, and
740 one that breaks another goes back to the session that caused it,
741 with the change it breaks and the check that failed. Five agents
742 can open pull requests the same afternoon and main still only
743 moves to what passed.
744 </p>
745 <More to={`${DOCS}/guides/sessions/`}>Sessions, claims and overlaps</More>
746 </div>
747 </div>
748 </section>
749
750 {/* Connect */}
751 <section className="mt-24 border-y border-line bg-surface/40">
752 <div className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-24 lg:grid-cols-2">
753 <div>
754 <Eyebrow>Bring your own agent</Eyebrow>
755 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
756 Any agent that speaks MCP works on g1t
757 </h2>
758 <p className="mt-4 max-w-md leading-7 text-muted">
759 Connect Claude Code, Codex, Cursor or any other MCP client and
760 sign in once. It works as you: it reads issues, pushes branches,
761 opens pull requests, and records its session and its decisions
762 onto them.
763 </p>
764 <p className="mt-4 max-w-md leading-7 text-muted">
765 Every action is a REST route and an MCP tool, with an OpenAPI
766 document, OAuth apps, access tokens and signed webhooks for every
767 event. The g1t CLI does the same from a terminal or a script:
768 open a pull request, wait on its checks, read a failed run&apos;s
769 logs.
770 </p>
771 <div className="mt-6 flex flex-wrap gap-3">
772 <ButtonLink
773 to={`${DOCS}/guides/bring-your-own-agent/`}
774 variant="outline"
775 >
776 Connect an agent
777 <ArrowRight size={14} />
778 </ButtonLink>
779 <ButtonLink to={`${DOCS}/guides/cli/`} variant="outline">
780 The g1t CLI
781 </ButtonLink>
782 <ButtonLink to={`${DOCS}/reference/api/`} variant="outline">
783 API reference
784 </ButtonLink>
785 </div>
786 </div>
787 <div className="min-w-0 space-y-3">
788 <p className="text-sm text-muted">
789 Add g1t as a remote MCP server, then sign in through your browser:
790 </p>
791 <CopyLine text="https://mcp.g1t.sh" />
792 <p className="pt-3 text-sm text-muted">
793 Install the CLI, then sign in with{" "}
794 <code className="font-mono text-fg-soft">g1t auth login</code>:
795 </p>
796 <CopyLine prompt text="curl -fsSL https://g1t.sh/install | sh" />
797 <p className="pt-3 text-sm text-muted">
798 Underneath, it is plain git and HTTP:
799 </p>
800 <CopyLine
801 prompt
802 breakAtSlashes
803 text="git clone https://g1t.sh/flagon-io/g1t.git"
804 />
805 <CopyLine
806 prompt
807 breakAtSlashes
808 text="curl https://api.g1t.sh/repos/flagon-io/g1t/queue"
809 />
810 </div>
811 </div>
812 </section>
813
814 {/* Artifacts: the docs the work cites. */}
815 <section className="mx-auto max-w-6xl px-4 pt-24">
816 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1fr_1.1fr] lg:gap-16">
817 <div>
818 <Eyebrow>Artifacts</Eyebrow>
819 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
820 A knowledge base that keeps itself true
821 </h2>
822 <p className="mt-4 max-w-xl leading-7 text-muted">
823 Docs, private until you share them or kept in spaces, edited
824 together live, with history, comments and backlinks. When a merged
825 change touches something a doc cites, the doc is flagged for its
826 owner to update.
827 </p>
828 <More to={`${DOCS}/guides/artifacts/`}>How Artifacts work</More>
829 </div>
830 <div>
831 <Points
832 columns={false}
833 points={[
834 "Docs edited together live",
835 "History, comments and backlinks",
836 "Flagged when a merged change touches what they cite",
837 { text: "Slides, designs and dashboards", soon: true },
838 ]}
839 />
840 </div>
841 </div>
842 </section>
843
844 {/* The rails. */}
845 <section className="mx-auto max-w-6xl px-4 py-24">
846 <Eyebrow>The rails</Eyebrow>
847 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
848 Rules decide what lands, not whoever wrote it
849 </h2>
850 <p className="mt-4 max-w-2xl leading-7 text-muted">
851 Scopes, rules, guardrails and audit are set by the workspace and
852 enforced by g1t. They hold the same for a person at a keyboard and
853 for the coding agent working as them.
854 </p>
855 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
856 {RAILS.map((item) => (
857 <Link
858 key={item.title}
859 to={item.to}
860 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
861 >
862 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
863 {item.icon}
864 </span>
865 <h3 className="mt-5 font-semibold">{item.title}</h3>
866 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
867 </Link>
868 ))}
869 </div>
870 </section>
871
872 {/* How it flows */}
873 <section
874 id="how"
875 className="scroll-mt-20 border-y border-line bg-surface/40"
876 >
877 <div className="mx-auto max-w-6xl px-4 py-24">
878 <Eyebrow>How it flows</Eyebrow>
879 <h2 className="mt-3 text-3xl font-semibold tracking-tight">
880 From an issue to main
881 </h2>
882 <Live>
883 <ol className="relative mt-12 grid gap-6 md:grid-cols-5">
884 {/* From the first step's dot to the last one's, and no further: five
885 columns with 1.5rem gaps put the last dot 1rem into the last
886 column, so the line stops one column, less that, from the end. */}
887 <span
888 aria-hidden="true"
889 className="absolute top-4 right-[calc((100%-6rem)/5-1rem)] left-4 hidden h-px bg-linear-to-r from-accent/50 via-warn/50 to-success/70 md:block"
890 >
891 <span className="flow-runner absolute inset-0">
892 <span className="absolute -top-0.75 left-[-3.5px] size-1.75 rounded-full bg-accent shadow-[0_0_12px_2px_rgb(182_168_255/0.6)]" />
893 </span>
894 </span>
895 {FLOW.map(([step, about], index) => (
896 <li key={step} className="relative">
897 <span
898 className={`flow-step relative flex size-8 items-center justify-center rounded-full font-mono text-xs ring-1 ${
899 index === FLOW.length - 1
900 ? "bg-success text-bg ring-success"
901 : "bg-bg text-fg-soft ring-line-strong"
902 }`}
903 style={{ "--delay": `${index * 2}s` } as CSSProperties}
904 >
905 {index + 1}
906 </span>
907 <h3 className="mt-4 font-semibold">{step}</h3>
908 <p className="mt-1.5 text-sm leading-6 text-muted">{about}</p>
909 </li>
910 ))}
911 </ol>
912 </Live>
913 </div>
914 </section>
915
916 {/* Secure by default */}
917 <section className="mx-auto max-w-6xl px-4 py-24">
918 <Eyebrow>Secure by default</Eyebrow>
919 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
920 Safe to hand the work to, and healthy without anyone watching
921 </h2>
922 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
923 {SECURE.map((item) => (
924 <Link
925 key={item.title}
926 to={item.to}
927 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
928 >
929 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
930 {item.icon}
931 </span>
932 <h3 className="mt-5 font-semibold">{item.title}</h3>
933 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
934 </Link>
935 ))}
936 </div>
937 </section>
938
939 {/* Switching: what moving in costs, and what holds if g1t goes away. */}
940 <section
941 id="switching"
942 className="mx-auto max-w-6xl scroll-mt-20 px-4 pb-24"
943 >
944 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1fr_1.1fr] lg:gap-16">
945 <div>
946 <Eyebrow>Switching</Eyebrow>
947 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
948 Moving in is an import. Leaving is a git clone.
949 </h2>
950 <p className="mt-4 max-w-xl leading-7 text-muted">
951 Bring repositories across from GitHub in a few clicks: every
952 branch and tag with full history, and their issues if you want
953 them. The copy on g1t is then your own.
954 </p>
955 <p className="mt-4 max-w-xl leading-7 text-muted">
956 If g1t went away tomorrow, your code is plain git, the source is
957 MIT licensed, and the core forge runs on your own machine with
958 Docker Compose.
959 </p>
960 <More
961 to={`${DOCS}/guides/github/#import-a-repository`}
962 >
963 Import from GitHub
964 </More>
965 </div>
966 <div className="space-y-6">
967 <div>
968 <p className="text-sm font-medium">What keeps working</p>
969 <Points
970 columns={false}
971 points={[
972 "git over HTTPS, with your history as it is",
973 "GitHub Actions workflows: rename .github to .g1t and push",
974 "The coding agents you use today, through MCP",
975 "Leaving: git clone, and the REST API for the rest",
976 ]}
977 />
978 </div>
979 <div className="rounded-xl border border-dashed border-line-strong px-4 py-3.5 text-sm leading-6 text-muted">
980 <p className="font-medium text-fg-soft">
981 Not a fit yet if you need
982 </p>
983 <p className="mt-1.5">
984 Single sign-on, git over SSH, or chat and deployments on your
985 own machines: those run only on g1t.sh today. Open pull
986 requests, issue comments, releases and wikis stay behind on
987 import.{" "}
988 <Link
989 to={`${DOCS}/about/limitations/`}
990 className="text-fg-soft underline-offset-4 hover:text-accent hover:underline"
991 >
992 What g1t can&apos;t do yet
993 </Link>
994 </p>
995 </div>
996 </div>
997 </div>
998 </section>
999
1000 {/* Pricing, in one band. */}
1001 <section className="mx-auto max-w-6xl px-4 py-24">
1002 <div className="flex flex-wrap items-end justify-between gap-6">
1003 <div>
1004 <Eyebrow>Pricing</Eyebrow>
1005 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
1006 People chat free. Pay for what runs. Never per seat.
1007 </h2>
1008 </div>
1009 <More to="/pricing">See every price</More>
1010 </div>
1011 <div className="mt-10 grid gap-px overflow-hidden rounded-3xl bg-line ring-1 ring-line md:grid-cols-3">
1012 {PRICES.map((item) => (
1013 <div key={item.name} className="bg-surface p-7">
1014 <p className="text-sm text-muted">{item.name}</p>
1015 <p className="mt-3 flex flex-wrap items-baseline gap-x-2">
1016 <span className="text-3xl font-semibold tracking-tight">
1017 {item.price}
1018 </span>
1019 {item.unit && (
1020 <span className="text-sm text-muted">{item.unit}</span>
1021 )}
1022 </p>
1023 <p className="mt-3 text-sm leading-6 text-muted">{item.about}</p>
1024 </div>
1025 ))}
1026 </div>
1027 </section>
1028
1029 {/* Open source */}
1030 <section className="mx-auto max-w-6xl px-4 pb-24">
1031 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1.3fr_1fr]">
1032 <div>
1033 <Eyebrow>Open source</Eyebrow>
1034 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
1035 Open, and built on itself
1036 </h2>
1037 <p className="mt-4 max-w-xl leading-7 text-muted">
1038 g1t is MIT licensed. Its own source lives on g1t, and its changes
1039 land through its own merge queue. Your code is plain git: leaving
1040 is a <code className="font-mono text-fg-soft">git clone</code>.
1041 </p>
1042 <p className="mt-4 max-w-xl leading-7 text-muted">
1043 You can run the core forge yourself with Docker Compose today:
1044 accounts, repositories, issues, pull requests and search. It is an
1045 early version, and chat and deployments still run only on g1t.sh.
1046 </p>
1047 <div className="mt-7 flex flex-wrap gap-3">
1048 <ButtonLink to="/flagon-io/g1t" variant="outline">
1049 Browse the source
1050 </ButtonLink>
1051 <ButtonLink to={`${DOCS}/guides/self-hosting/`} variant="outline">
1052 Run g1t yourself
1053 </ButtonLink>
1054 </div>
1055 </div>
1056 <div className="flex flex-col justify-between gap-6">
1057 <ul className="space-y-3 text-sm">
1058 {[
1059 {
1060 icon: <Bell size={15} />,
1061 text: "One place for mentions, reviews and approvals",
1062 },
1063 {
1064 icon: <ScrollText size={15} />,
1065 text: "One audit log for people and tokens",
1066 },
1067 {
1068 icon: <Wallet size={15} />,
1069 text: "One bill, priced from cost plus 20%",
1070 },
1071 ].map((item) => (
1072 <li
1073 key={item.text}
1074 className="flex items-center gap-3 text-fg-soft"
1075 >
1076 <span className="flex size-7 items-center justify-center rounded-md bg-bg text-accent ring-1 ring-line">
1077 {item.icon}
1078 </span>
1079 {item.text}
1080 </li>
1081 ))}
1082 </ul>
1083 <p className="text-sm leading-6 text-muted">
1084 g1t is made by Flagon, Inc., a small, independent software company
1085 founded by Chase Pierce.
1086 </p>
1087 </div>
1088 </div>
1089 </section>
1090
1091 {/* The close. */}
1092 <section className="mx-auto max-w-6xl px-4 pb-8">
1093 <div className="dusk relative overflow-hidden rounded-3xl px-6 py-16 text-center ring-1 ring-line">
1094 <h2 className="mx-auto max-w-2xl text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
1095 Bring your team. Bring your agents.
1096 </h2>
1097 <p className="mx-auto mt-4 max-w-xl text-fg-soft/80 text-balance">
1098 Anyone can sign up. Create a workspace in a minute, push a
1099 repository and connect the coding agent you already use. Chat and
1100 the forge are free.
1101 </p>
1102 <div className="mt-8 flex flex-wrap justify-center gap-3">
1103 <ButtonLink to="/register" size="lg" className="rounded-full">
1104 Get started
1105 <ArrowRight size={15} />
1106 </ButtonLink>
1107 <ButtonLink
1108 to={`${DOCS}/quickstart/`}
1109 variant="outline"
1110 size="lg"
1111 className="rounded-full"
1112 >
1113 Read the quickstart
1114 </ButtonLink>
1115 </div>
1116 </div>
1117 </section>
1118 </main>
1119 );
1120}