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.

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