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