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