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,137 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. */
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 Start each day on Home: what landed, what is live, and what needs
422 you next. Behind it, repositories, pull requests, required checks,
423 a merge queue and deployments, with chat and docs for your team.
424 Connect the coding agents you already use, and their work lands
425 through the same checks as everyone&apos;s.
426 </p>
427 <div className="mt-9 flex animate-fade-up flex-wrap items-center justify-center gap-3">
428 <ButtonLink to="/register" size="lg" className="rounded-full">
429 Get started
430 <ArrowRight size={15} />
431 </ButtonLink>
432 <ButtonLink
433 to="#how"
434 variant="outline"
435 size="lg"
436 className="rounded-full"
437 >
438 See how it works
439 </ButtonLink>
440 </div>
441 <p className="mx-auto mt-5 max-w-xl animate-fade-up text-sm text-fg-soft/60 text-balance">
442 Chat and the forge are free, with no card. No seats, ever.
443 </p>
444 </div>
445 <div className="relative mx-auto max-w-5xl px-4 pt-14 pb-2">
446 <div
447 aria-hidden="true"
448 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"
449 />
450 <ProductTour className="relative" />
451 </div>
452 <div
453 aria-hidden="true"
454 className="h-16 bg-linear-to-b from-transparent to-bg"
455 />
456 </section>
457
458 {/* Facts. */}
459 <section className="relative z-10 mx-auto max-w-6xl px-4">
460 <dl className="grid gap-px overflow-hidden rounded-2xl border border-line bg-line sm:grid-cols-2 lg:grid-cols-4">
461 {FACTS.map(([figure, about]) => (
462 <div key={figure} className="bg-bg px-6 py-6">
463 <dt className="font-mono text-2xl font-medium tracking-tight text-fg">
464 {figure}
465 </dt>
466 <dd className="mt-2 text-sm leading-6 text-muted">{about}</dd>
467 </div>
468 ))}
469 </dl>
470 </section>
471
472 {/* Home: where the day starts. */}
473 <section id="home" className="mx-auto max-w-6xl scroll-mt-20 px-4 pt-24">
474 <div className="max-w-3xl">
475 <Eyebrow>Home</Eyebrow>
476 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
477 Start every day knowing where things stand.
478 </h2>
479 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
480 Home is your daily update and your way into the forge. g1t keeps
481 track of everything your team and its coding agents did, clears
482 what resolved itself, tells you in plain English what changed and
483 what is live, and takes you straight to what is yours to decide: a
484 merge, a review, a fix.
485 </p>
486 </div>
487
488 <div className="mt-6 divide-y divide-line">
489 <Pillar
490 eyebrow="Where you're needed"
491 title="Only what still needs you"
492 art={<NeedsYouArt />}
493 points={[
494 "Notifications that settle themselves",
495 "Why each one settled, and who did it",
496 "Pull requests ready for you to merge",
497 "Reviews asked of you, by name",
498 "Start here: the one to do first, and why",
499 ]}
500 more={["Home", `${DOCS}/guides/home/`]}
501 >
502 A notification is done once a later event resolves it: the next run
503 passes, the pull request merges, the fix deploys. g1t settles it
504 for you, and Home shows only what still waits on you. Start here
505 picks the one to do first and opens it.
506 </Pillar>
507
508 <Pillar
509 flip
510 eyebrow="What changed"
511 title="Come back to what changed, in plain English"
512 art={<WhatChangedArt />}
513 points={[
514 "A summary of what landed since you were last here",
515 "Whether each change is live, deploying or failed",
516 "Explain on any change that landed",
517 "Ask a follow-up, in your direct message with g1t",
518 ]}
519 more={["Ask g1t", `${DOCS}/guides/ask/`]}
520 >
521 Home asks &ldquo;What are we building today?&rdquo; Press
522 Summarize and What changed reads the commits, pull requests, deploys
523 and conversations since you were last here, then tells you what
524 changed, why, and what is live. Explain any one change, or ask a
525 follow-up. It runs on your workspace&apos;s own AI provider.
526 </Pillar>
527 </div>
528 </section>
529
530 {/* What a workspace holds. */}
531 <section className="mx-auto max-w-6xl px-4 pt-24">
532 <div className="max-w-3xl">
533 <Eyebrow>One workspace</Eyebrow>
534 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
535 Talk, write it down, ship.
536 </h2>
537 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
538 Home, Code, Chat and Artifacts share one set of members, one
539 sign-in and one bill. The coding agents you connect work as you, through MCP,
540 the g1t CLI and the API.
541 </p>
542 </div>
543 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
544 {MODES.map((mode) => (
545 <Link
546 key={mode.name}
547 to={mode.to}
548 className="group flex flex-col rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
549 >
550 <span className="flex items-center justify-between gap-2">
551 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
552 {mode.icon}
553 </span>
554 {mode.soon && <Soon />}
555 </span>
556 <h3 className="mt-5 text-lg font-semibold">{mode.name}</h3>
557 <p className="mt-2 text-sm leading-6 text-muted">{mode.about}</p>
558 </Link>
559 ))}
560 </div>
561 </section>
562
563 {/* Code. */}
564 <section className="mx-auto max-w-6xl px-4 pt-24">
565 <div className="max-w-3xl">
566 <Eyebrow>Code</Eyebrow>
567 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
568 A forge built for many changes at once.
569 </h2>
570 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
571 Underneath is plain git. Every change, whether you wrote it or
572 your coding agent did, is a pull request: checked, reviewed, and
573 landed through a queue that keeps main passing.
574 </p>
575 </div>
576
577 <div className="mt-6 divide-y divide-line">
578 <Pillar
579 eyebrow="Ship safely"
580 title="Main only moves to what passed"
581 art={<QueueArt className="w-full" />}
582 points={[
583 "Checks in a clean sandbox, or free on your own runners",
584 "Your computer as a runner, with the desktop app",
585 "A merge queue that tests changes together",
586 "Conflicts found on every push, before a merge",
587 "Catch up with main in seconds",
588 "Required reviews, with code owners",
589 ]}
590 more={["The merge queue", `${DOCS}/guides/merge-queue/`]}
591 >
592 Required checks run on g1t&apos;s runners, or free on your own: a
593 server, or your computer while the desktop app is open. The queue
594 tests each change together with what lands ahead of it; one that
595 breaks goes back to its author with what failed, and main never sees
596 it.
597 </Pillar>
598
599 <Pillar
600 flip
601 eyebrow="Context"
602 title="Every line knows why it is there"
603 art={<WhyArt className="w-full" />}
604 points={[
605 "Sessions recorded onto pull requests",
606 "Why-blame on any line",
607 "Decisions recorded with the reasons behind them",
608 "Search across code, issues and people",
609 ]}
610 more={["Sessions and why-blame", `${DOCS}/guides/why-blame/`]}
611 >
612 Pick any line. g1t shows the commit that changed it, the pull
613 request and issue it came from, and the session your coding agent
614 recorded as it worked: what it read, ran and decided. The reasoning
615 stays with the code, for people and for the next agent.
616 </Pillar>
617
618 <Pillar
619 eyebrow="Run it"
620 title="Every change, live on the edge"
621 art={<DeployArt className="w-full" />}
622 points={[
623 "A live preview for every pull request",
624 "Production on every merge to main",
625 "Custom domains, with certificates",
626 "A new app from one sentence on Home",
627 ]}
628 more={["Deployments", `${DOCS}/guides/deployments/`]}
629 >
630 Turn on deployments and every pull request gets its own address on
631 g1t.page; merging ships production. Reviewers click through a
632 change instead of reading a diff. An app nobody visits runs nothing
633 and costs nothing. Or start from Home: ask for something new, and one
634 click makes its repository, starts your coding agent on it and puts
635 the first version live.
636 </Pillar>
637 </div>
638 </section>
639
640 {/* The forge, for people. */}
641 <section className="mx-auto max-w-6xl px-4 py-24">
642 <div className="grid gap-10 lg:grid-cols-[1fr_1.2fr] lg:gap-16">
643 <div>
644 <Eyebrow>Collaborate</Eyebrow>
645 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
646 A complete forge for the people who build
647 </h2>
648 <p className="mt-4 max-w-md leading-7 text-muted">
649 Issues, branches, pull requests and reviews, the way your team
650 already works. Write a change by hand, have your coding agent
651 write it, or both on the same branch.
652 </p>
653 <More to={`${DOCS}/concepts/overview/`}>How g1t works</More>
654 </div>
655 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
656 <p className="text-sm font-medium">Included in every workspace</p>
657 <Tags items={FORGE} />
658 </div>
659 </div>
660 </section>
661
662 {/* Chat, where people talk about the work. */}
663 <section className="mx-auto grid max-w-6xl items-start gap-12 px-4 lg:grid-cols-[1.1fr_1fr] lg:gap-16">
664 <div>
665 <Eyebrow>Chat</Eyebrow>
666 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
667 Just talk to your team.
668 </h2>
669 <p className="mt-4 max-w-xl leading-7 text-muted">
670 Chat is where your team talks about the work, next to the code it
671 is about. Ask a question in a channel, DM a colleague, or reply in
672 a thread. Messages arrive the moment they are sent, and everyone in
673 the company can join for free.
674 </p>
675 <More to={`${DOCS}/guides/chat/`}>How Chat works</More>
676 </div>
677 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
678 <p className="text-sm font-medium">Free on every plan</p>
679 <Points
680 columns={false}
681 points={[
682 "Private, workspace and public channels",
683 "Direct messages",
684 "Threads on any message",
685 "@mentions",
686 "Live delivery, typing and read state",
687 "A desktop app for Windows, macOS and Linux",
688 {
689 text: "An Android app with notifications: scan the QR code on",
690 link: { to: "/download", label: "Download" },
691 },
692 {
693 text: "Pull requests, checks and deploys as cards in the channel",
694 soon: true,
695 },
696 { text: "Chat mentions in Notifications", soon: true },
697 { text: "The phone app on iPhone", soon: true },
698 ]}
699 />
700 </div>
701 </section>
702
703 {/* Agents: they do the work, you make the calls. */}
704 <section id="agents" className="mx-auto max-w-6xl scroll-mt-20 px-4 pt-24">
705 <div className="max-w-3xl">
706 <Eyebrow>Agents</Eyebrow>
707 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
708 Agents do the work. You make the calls.
709 </h2>
710 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
711 Your coding agents push the branches and open the pull requests,
712 and their work lands through the same checks as everyone&apos;s.
713 You decide what they take on and what ships.
714 </p>
715 </div>
716
717 <div className="mt-10 grid gap-4 lg:grid-cols-2">
718 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line sm:p-8">
719 <Eyebrow>Issues</Eyebrow>
720 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
721 Point your coding agent at an issue
722 </h3>
723 <p className="mt-3 text-sm leading-6 text-muted">
724 Your coding agent connects to g1t through MCP and works as you. It
725 reads the issue, pushes a branch, opens the pull request and
726 records its session onto it, and the pull request goes through
727 the same checks and reviews as anyone&apos;s.
728 </p>
729 <ol className="mt-6 space-y-3 text-sm">
730 {[
731 "Open an issue: what should change, and what done looks like",
732 "Work it yourself, or hand it to your coding agent",
733 "The pull request runs your checks and lands through the queue",
734 ].map((step, index) => (
735 <li key={step} className="flex items-start gap-3 text-fg-soft">
736 <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">
737 {index + 1}
738 </span>
739 {step}
740 </li>
741 ))}
742 </ol>
743 <More to={`${DOCS}/guides/bring-your-own-agent/`}>
744 Connect a coding agent
745 </More>
746 </div>
747 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line sm:p-8">
748 <Eyebrow>Coordination</Eyebrow>
749 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
750 Many agents, no collisions
751 </h3>
752 <p className="mt-3 text-sm leading-6 text-muted">
753 Run as many coding agents as you like. Each claims the issue it
754 takes, and every session shows live as it works, so everyone sees
755 who is on what. Two that start changing the same files are told
756 while they work, before either opens a pull request. The merge
757 queue tests changes together with what lands ahead of them, and
758 one that breaks another goes back to the session that caused it,
759 with the change it breaks and the check that failed. Five agents
760 can open pull requests the same afternoon and main still only
761 moves to what passed.
762 </p>
763 <More to={`${DOCS}/guides/sessions/`}>Sessions, claims and overlaps</More>
764 </div>
765 </div>
766 </section>
767
768 {/* Connect */}
769 <section className="mt-24 border-y border-line bg-surface/40">
770 <div className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-24 lg:grid-cols-2">
771 <div>
772 <Eyebrow>Bring your own agent</Eyebrow>
773 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
774 Any agent that speaks MCP works on g1t
775 </h2>
776 <p className="mt-4 max-w-md leading-7 text-muted">
777 Connect Claude Code, Codex, Cursor or any other MCP client and
778 sign in once. It works as you: it reads issues, pushes branches,
779 opens pull requests, and records its session and its decisions
780 onto them.
781 </p>
782 <p className="mt-4 max-w-md leading-7 text-muted">
783 Every action is a REST route and an MCP tool, with an OpenAPI
784 document, OAuth apps, access tokens and signed webhooks for every
785 event. The g1t CLI does the same from a terminal or a script:
786 open a pull request, wait on its checks, read a failed run&apos;s
787 logs.
788 </p>
789 <div className="mt-6 flex flex-wrap gap-3">
790 <ButtonLink
791 to={`${DOCS}/guides/bring-your-own-agent/`}
792 variant="outline"
793 >
794 Connect an agent
795 <ArrowRight size={14} />
796 </ButtonLink>
797 <ButtonLink to={`${DOCS}/guides/cli/`} variant="outline">
798 The g1t CLI
799 </ButtonLink>
800 <ButtonLink to={`${DOCS}/reference/api/`} variant="outline">
801 API reference
802 </ButtonLink>
803 </div>
804 </div>
805 <div className="min-w-0 space-y-3">
806 <p className="text-sm text-muted">
807 Add g1t as a remote MCP server, then sign in through your browser:
808 </p>
809 <CopyLine text="https://mcp.g1t.sh" />
810 <p className="pt-3 text-sm text-muted">
811 Install the CLI, then sign in with{" "}
812 <code className="font-mono text-fg-soft">g1t auth login</code>:
813 </p>
814 <CopyLine prompt text="curl -fsSL https://g1t.sh/install | sh" />
815 <p className="pt-3 text-sm text-muted">
816 Underneath, it is plain git and HTTP:
817 </p>
818 <CopyLine
819 prompt
820 breakAtSlashes
821 text="git clone https://g1t.sh/flagon-io/g1t.git"
822 />
823 <CopyLine
824 prompt
825 breakAtSlashes
826 text="curl https://api.g1t.sh/repos/flagon-io/g1t/queue"
827 />
828 </div>
829 </div>
830 </section>
831
832 {/* Artifacts: the docs the work cites. */}
833 <section className="mx-auto max-w-6xl px-4 pt-24">
834 <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">
835 <div>
836 <Eyebrow>Artifacts</Eyebrow>
837 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
838 A knowledge base that keeps itself true
839 </h2>
840 <p className="mt-4 max-w-xl leading-7 text-muted">
841 Docs, private until you share them or kept in spaces, edited
842 together live, with history, comments and backlinks. When a merged
843 change touches something a doc cites, the doc is flagged for its
844 owner to update.
845 </p>
846 <More to={`${DOCS}/guides/artifacts/`}>How Artifacts work</More>
847 </div>
848 <div>
849 <Points
850 columns={false}
851 points={[
852 "Docs edited together live",
853 "History, comments and backlinks",
854 "Flagged when a merged change touches what they cite",
855 { text: "Slides, designs and dashboards", soon: true },
856 ]}
857 />
858 </div>
859 </div>
860 </section>
861
862 {/* The rails. */}
863 <section className="mx-auto max-w-6xl px-4 py-24">
864 <Eyebrow>The rails</Eyebrow>
865 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
866 Rules decide what lands, not whoever wrote it
867 </h2>
868 <p className="mt-4 max-w-2xl leading-7 text-muted">
869 Scopes, rules, guardrails and audit are set by the workspace and
870 enforced by g1t. They hold the same for a person at a keyboard and
871 for the coding agent working as them.
872 </p>
873 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
874 {RAILS.map((item) => (
875 <Link
876 key={item.title}
877 to={item.to}
878 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
879 >
880 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
881 {item.icon}
882 </span>
883 <h3 className="mt-5 font-semibold">{item.title}</h3>
884 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
885 </Link>
886 ))}
887 </div>
888 </section>
889
890 {/* How it flows */}
891 <section
892 id="how"
893 className="scroll-mt-20 border-y border-line bg-surface/40"
894 >
895 <div className="mx-auto max-w-6xl px-4 py-24">
896 <Eyebrow>How it flows</Eyebrow>
897 <h2 className="mt-3 text-3xl font-semibold tracking-tight">
898 From an issue to main
899 </h2>
900 <Live>
901 <ol className="relative mt-12 grid gap-6 md:grid-cols-5">
902 {/* From the first step's dot to the last one's, and no further: five
903 columns with 1.5rem gaps put the last dot 1rem into the last
904 column, so the line stops one column, less that, from the end. */}
905 <span
906 aria-hidden="true"
907 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"
908 >
909 <span className="flow-runner absolute inset-0">
910 <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)]" />
911 </span>
912 </span>
913 {FLOW.map(([step, about], index) => (
914 <li key={step} className="relative">
915 <span
916 className={`flow-step relative flex size-8 items-center justify-center rounded-full font-mono text-xs ring-1 ${
917 index === FLOW.length - 1
918 ? "bg-success text-bg ring-success"
919 : "bg-bg text-fg-soft ring-line-strong"
920 }`}
921 style={{ "--delay": `${index * 2}s` } as CSSProperties}
922 >
923 {index + 1}
924 </span>
925 <h3 className="mt-4 font-semibold">{step}</h3>
926 <p className="mt-1.5 text-sm leading-6 text-muted">{about}</p>
927 </li>
928 ))}
929 </ol>
930 </Live>
931 </div>
932 </section>
933
934 {/* Secure by default */}
935 <section className="mx-auto max-w-6xl px-4 py-24">
936 <Eyebrow>Secure by default</Eyebrow>
937 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
938 Safe to hand the work to, and healthy without anyone watching
939 </h2>
940 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
941 {SECURE.map((item) => (
942 <Link
943 key={item.title}
944 to={item.to}
945 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
946 >
947 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
948 {item.icon}
949 </span>
950 <h3 className="mt-5 font-semibold">{item.title}</h3>
951 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
952 </Link>
953 ))}
954 </div>
955 </section>
956
957 {/* Switching: what moving in costs, and what holds if g1t goes away. */}
958 <section
959 id="switching"
960 className="mx-auto max-w-6xl scroll-mt-20 px-4 pb-24"
961 >
962 <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">
963 <div>
964 <Eyebrow>Switching</Eyebrow>
965 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
966 Moving in is an import. Leaving is a git clone.
967 </h2>
968 <p className="mt-4 max-w-xl leading-7 text-muted">
969 Bring repositories across from GitHub in a few clicks: every
970 branch and tag with full history, and their issues if you want
971 them. The copy on g1t is then your own.
972 </p>
973 <p className="mt-4 max-w-xl leading-7 text-muted">
974 If g1t went away tomorrow, your code is plain git, the source is
975 MIT licensed, and the core forge runs on your own machine with
976 Docker Compose.
977 </p>
978 <More
979 to={`${DOCS}/guides/github/#import-a-repository`}
980 >
981 Import from GitHub
982 </More>
983 </div>
984 <div className="space-y-6">
985 <div>
986 <p className="text-sm font-medium">What keeps working</p>
987 <Points
988 columns={false}
989 points={[
990 "git over HTTPS, with your history as it is",
991 "GitHub Actions workflows: rename .github to .g1t and push",
992 "The coding agents you use today, through MCP",
993 "Leaving: git clone, and the REST API for the rest",
994 ]}
995 />
996 </div>
997 <div className="rounded-xl border border-dashed border-line-strong px-4 py-3.5 text-sm leading-6 text-muted">
998 <p className="font-medium text-fg-soft">
999 Not a fit yet if you need
1000 </p>
1001 <p className="mt-1.5">
1002 Single sign-on, git over SSH, or chat and deployments on your
1003 own machines: those run only on g1t.sh today. Open pull
1004 requests, issue comments, releases and wikis stay behind on
1005 import.{" "}
1006 <Link
1007 to={`${DOCS}/about/limitations/`}
1008 className="text-fg-soft underline-offset-4 hover:text-accent hover:underline"
1009 >
1010 What g1t can&apos;t do yet
1011 </Link>
1012 </p>
1013 </div>
1014 </div>
1015 </div>
1016 </section>
1017
1018 {/* Pricing, in one band. */}
1019 <section className="mx-auto max-w-6xl px-4 py-24">
1020 <div className="flex flex-wrap items-end justify-between gap-6">
1021 <div>
1022 <Eyebrow>Pricing</Eyebrow>
1023 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
1024 People chat free. Pay for what runs. Never per seat.
1025 </h2>
1026 </div>
1027 <More to="/pricing">See every price</More>
1028 </div>
1029 <div className="mt-10 grid gap-px overflow-hidden rounded-3xl bg-line ring-1 ring-line md:grid-cols-3">
1030 {PRICES.map((item) => (
1031 <div key={item.name} className="bg-surface p-7">
1032 <p className="text-sm text-muted">{item.name}</p>
1033 <p className="mt-3 flex flex-wrap items-baseline gap-x-2">
1034 <span className="text-3xl font-semibold tracking-tight">
1035 {item.price}
1036 </span>
1037 {item.unit && (
1038 <span className="text-sm text-muted">{item.unit}</span>
1039 )}
1040 </p>
1041 <p className="mt-3 text-sm leading-6 text-muted">{item.about}</p>
1042 </div>
1043 ))}
1044 </div>
1045 </section>
1046
1047 {/* Open source */}
1048 <section className="mx-auto max-w-6xl px-4 pb-24">
1049 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1.3fr_1fr]">
1050 <div>
1051 <Eyebrow>Open source</Eyebrow>
1052 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
1053 Open, and built on itself
1054 </h2>
1055 <p className="mt-4 max-w-xl leading-7 text-muted">
1056 g1t is MIT licensed. Its own source lives on g1t, and its changes
1057 land through its own merge queue. Your code is plain git: leaving
1058 is a <code className="font-mono text-fg-soft">git clone</code>.
1059 </p>
1060 <p className="mt-4 max-w-xl leading-7 text-muted">
1061 You can run the core forge yourself with Docker Compose today:
1062 accounts, repositories, issues, pull requests and search. It is an
1063 early version, and chat and deployments still run only on g1t.sh.
1064 </p>
1065 <div className="mt-7 flex flex-wrap gap-3">
1066 <ButtonLink to="/flagon-io/g1t" variant="outline">
1067 Browse the source
1068 </ButtonLink>
1069 <ButtonLink to={`${DOCS}/guides/self-hosting/`} variant="outline">
1070 Run g1t yourself
1071 </ButtonLink>
1072 </div>
1073 </div>
1074 <div className="flex flex-col justify-between gap-6">
1075 <ul className="space-y-3 text-sm">
1076 {[
1077 {
1078 icon: <Bell size={15} />,
1079 text: "One place for mentions, reviews and approvals",
1080 },
1081 {
1082 icon: <ScrollText size={15} />,
1083 text: "One audit log for people and tokens",
1084 },
1085 {
1086 icon: <Wallet size={15} />,
1087 text: "One bill, priced from cost plus 20%",
1088 },
1089 ].map((item) => (
1090 <li
1091 key={item.text}
1092 className="flex items-center gap-3 text-fg-soft"
1093 >
1094 <span className="flex size-7 items-center justify-center rounded-md bg-bg text-accent ring-1 ring-line">
1095 {item.icon}
1096 </span>
1097 {item.text}
1098 </li>
1099 ))}
1100 </ul>
1101 <p className="text-sm leading-6 text-muted">
1102 g1t is made by Flagon, Inc.
1103 </p>
1104 </div>
1105 </div>
1106 </section>
1107
1108 {/* The close. */}
1109 <section className="mx-auto max-w-6xl px-4 pb-8">
1110 <div className="dusk relative overflow-hidden rounded-3xl px-6 py-16 text-center ring-1 ring-line">
1111 <h2 className="mx-auto max-w-2xl text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
1112 Bring your team. Bring your agents.
1113 </h2>
1114 <p className="mx-auto mt-4 max-w-xl text-fg-soft/80 text-balance">
1115 Anyone can sign up. Create a workspace in a minute, push a
1116 repository and connect the coding agent you already use. Chat and
1117 the forge are free.
1118 </p>
1119 <div className="mt-8 flex flex-wrap justify-center gap-3">
1120 <ButtonLink to="/register" size="lg" className="rounded-full">
1121 Get started
1122 <ArrowRight size={15} />
1123 </ButtonLink>
1124 <ButtonLink
1125 to={`${DOCS}/quickstart/`}
1126 variant="outline"
1127 size="lg"
1128 className="rounded-full"
1129 >
1130 Read the quickstart
1131 </ButtonLink>
1132 </div>
1133 </div>
1134 </section>
1135 </main>
1136 );
1137}