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