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
245 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Merge branch 'main' into worktree-agent-a69aeabc4b0deeb971import { ArrowUpRight, BookMarked, Search } from "lucide-react";
Search across all of g1t, Explore, and a command palette2import type { ReactNode } from "react";
3import { Form, Link } from "react-router";
4
5import type { ExploreRepo } from "@g1t/contracts";
Share the editor settings and Claude Code deploy permissions6
7import type { Route } from "./+types/explore";
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.8import { EmptyState, TimeAgo, notACredential } from "../components/ui";
9import { Badge } from "../components/ui/badge";
10import { Card } from "../components/ui/card";
Social cards for every page: og.g1t.sh11import { page } from "../lib/meta";
Merge branch 'site-fixes' into fast-push12import { DeployLink, host } from "../components/deploy";
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9713import { projects, search } from "../lib/services.server";
Share the editor settings and Claude Code deploy permissions14import { getViewer } from "../lib/session.server";
15
Social cards for every page: og.g1t.sh16export function meta({ loaderData, ...args }: Route.MetaArgs) {
Search across all of g1t, Explore, and a command palette17 const filter = loaderData?.language ?? (loaderData?.topic ? `#${loaderData.topic}` : null);
Social cards for every page: og.g1t.sh18 return page(args, {
Search across all of g1t, Explore, and a command palette19 title: filter ? `${filter} · Explore · g1t` : "Explore · g1t",
20 description: filter
21 ? `Public projects on g1t in ${filter}.`
22 : "Public projects on g1t: recently active, newly created, and by language and topic.",
Social cards for every page: og.g1t.sh23 });
Share the editor settings and Claude Code deploy permissions24}
25
26export async function loader({ request, context }: Route.LoaderArgs) {
Search across all of g1t, Explore, and a command palette27 const url = new URL(request.url);
28 const sort = url.searchParams.get("sort") === "new" ? ("new" as const) : ("active" as const);
29 const language = url.searchParams.get("language")?.trim().toLowerCase() || null;
30 const topic = url.searchParams.get("topic")?.trim().toLowerCase() || null;
31 const pageNumber = Math.min(Math.max(Number(url.searchParams.get("page")) || 1, 1), 50);
32 const explore = await search
33 .explore(getViewer(context), { sort, language, topic, page: pageNumber })
34 .catch(() => null);
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9735 // Each one's homepage or production, from its project; the page shows without them.
36 const links = explore
37 ? await projects.publicLinks(explore.repos.map((repo) => ({ namespace: repo.namespace, name: repo.name }))).catch(() => ({}))
38 : {};
39 return { sort, language, topic, explore, links: links as Record<string, string> };
Search across all of g1t, Explore, and a command palette40}
41
42/** The address of Explore with some of its filters changed. */
43function href(current: { sort: string; language: string | null; topic: string | null }, change: Record<string, string | null>) {
44 const next = { sort: current.sort, language: current.language, topic: current.topic, ...change };
45 const params = new URLSearchParams();
46 if (next.sort && next.sort !== "active") params.set("sort", next.sort);
47 if (next.language) params.set("language", next.language);
48 if (next.topic) params.set("topic", next.topic);
49 if (change.page) params.set("page", change.page);
50 const query = params.toString();
51 return query ? `/explore?${query}` : "/explore";
52}
53
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9754function RepoCard({ repo, link }: { repo: ExploreRepo; link: string | null }) {
Search across all of g1t, Explore, and a command palette55 return (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.56 <Card className="relative flex h-full flex-col p-4 transition-colors hover:border-line-strong">
Search across all of g1t, Explore, and a command palette57 <span className="flex items-center gap-2">
58 <BookMarked size={15} className="shrink-0 text-faint" />
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9759 <Link prefetch="intent" to={`/${repo.namespace}/${repo.name}`} className="truncate font-mono text-sm after:absolute after:inset-0">
Search across all of g1t, Explore, and a command palette60 <span className="text-muted">{repo.namespace}/</span>
61 <span className="font-medium">{repo.name}</span>
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9762 </Link>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look63 {repo.archived && (
64 <span className="ml-auto shrink-0">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.65 <Badge size="md">archived</Badge>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look66 </span>
67 )}
Search across all of g1t, Explore, and a command palette68 </span>
69 <span className="mt-2 line-clamp-2 grow text-sm text-muted">{repo.description ?? "No description."}</span>
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9770 {link && (
Merge branch 'site-fixes' into fast-push71 <DeployLink
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9772 href={link}
Merge branch 'site-fixes' into fast-push73 rel="nofollow"
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9774 className="relative z-10 mt-2 flex min-w-0 items-center gap-1 self-start font-mono text-xs text-muted hover:text-accent"
75 >
76 <span className="truncate">{host(link).replace(/\/$/, "")}</span>
77 <ArrowUpRight size={11} className="shrink-0" />
Merge branch 'site-fixes' into fast-push78 </DeployLink>
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9779 )}
Search across all of g1t, Explore, and a command palette80 {repo.topics.length > 0 && (
81 <span className="mt-3 flex flex-wrap gap-1.5">
82 {repo.topics.slice(0, 4).map((topic) => (
83 <span key={topic} className="rounded-full bg-raised px-2 py-px text-[0.6875rem] text-muted ring-1 ring-line">
84 {topic}
85 </span>
86 ))}
87 </span>
88 )}
89 <span className="mt-3 flex items-center gap-3 text-xs text-faint">
90 {repo.language && <span className="font-mono">{repo.language}</span>}
91 <span className="ml-auto">
92 {repo.pushedAt ? (
93 <>
94 Pushed <TimeAgo at={repo.pushedAt} />
95 </>
96 ) : (
97 <>
98 Created <TimeAgo at={repo.createdAt} />
99 </>
100 )}
101 </span>
102 </span>
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.103 </Card>
Search across all of g1t, Explore, and a command palette104 );
105}
106
107function Chip({ to, current, children }: { to: string; current: boolean; children: ReactNode }) {
108 return (
109 <Link
110 to={to}
111 aria-current={current ? "true" : undefined}
112 className={`rounded-full px-2.5 py-1 text-xs transition-colors ring-1 ${
113 current ? "bg-accent/15 text-fg ring-accent/50" : "text-muted ring-line hover:text-fg hover:ring-line-strong"
114 }`}
115 >
116 {children}
117 </Link>
118 );
Share the editor settings and Claude Code deploy permissions119}
120
Search across all of g1t, Explore, and a command palette121export default function ExplorePage({ loaderData }: Route.ComponentProps) {
122 const { sort, language, topic, explore } = loaderData;
123 const current = { sort, language, topic };
124 const filtered = language || topic;
Share the editor settings and Claude Code deploy permissions125 return (
Search across all of g1t, Explore, and a command palette126 <main className="mx-auto max-w-6xl px-4 py-10 sm:px-6">
127 <h1 className="text-2xl font-semibold tracking-tight">Explore</h1>
Share the editor settings and Claude Code deploy permissions128 <p className="mt-1 text-muted">
Search across all of g1t, Explore, and a command palette129 Public projects on g1t{language ? ` in ${language}` : ""}
130 {topic ? ` about ${topic}` : ""}.
Share the editor settings and Claude Code deploy permissions131 </p>
Search across all of g1t, Explore, and a command palette132 <Form action="/search" role="search" className="relative mt-6 max-w-2xl">
133 <Search size={16} className="pointer-events-none absolute top-1/2 left-3.5 -translate-y-1/2 text-faint" />
Share the editor settings and Claude Code deploy permissions134 <input
135 name="q"
136 {...notACredential()}
Search across all of g1t, Explore, and a command palette137 placeholder="Search repositories, code, issues and people"
138 aria-label="Search g1t"
139 className="h-10 w-full rounded-lg border border-line bg-surface pr-4 pl-10 text-sm outline-none transition-colors placeholder:text-faint hover:border-line-strong focus:border-accent-dim"
Share the editor settings and Claude Code deploy permissions140 />
141 </Form>
Search across all of g1t, Explore, and a command palette142
143 <div className="mt-8 grid gap-8 lg:grid-cols-[minmax(0,1fr)_16rem]">
144 <section>
145 <div className="flex flex-wrap items-center gap-3">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.146 <Card asChild tone="bg" radius="lg" className="flex items-center gap-1 p-1">
147 <nav aria-label="Order">
148 {[
149 { value: "active", label: "Recently active" },
150 { value: "new", label: "New" },
151 ].map((option) => (
152 <Link
153 key={option.value}
154 to={href(current, { sort: option.value })}
155 aria-current={sort === option.value ? "page" : undefined}
156 className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${
157 sort === option.value ? "bg-raised text-fg ring-1 ring-line" : "text-muted hover:text-fg"
158 }`}
159 >
160 {option.label}
161 </Link>
162 ))}
163 </nav>
164 </Card>
Search across all of g1t, Explore, and a command palette165 {filtered && (
166 <Link to={href(current, { language: null, topic: null })} className="text-xs text-muted hover:text-fg">
167 Clear {language ? "language" : "topic"}
168 </Link>
169 )}
170 </div>
171 {!explore ? (
172 <div className="mt-4">
173 <EmptyState title="Explore cannot be reached right now">Try again in a moment.</EmptyState>
174 </div>
175 ) : explore.repos.length === 0 ? (
176 <div className="mt-4">
177 <EmptyState title="No public projects here yet">
178 {filtered ? "Try another language or topic." : "Public projects appear here as they are made."}
179 </EmptyState>
180 </div>
181 ) : (
182 <ul className="mt-4 grid gap-3 sm:grid-cols-2">
183 {explore.repos.map((repo) => (
184 <li key={`${repo.namespace}/${repo.name}`}>
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97185 <RepoCard repo={repo} link={loaderData.links[`${repo.namespace}/${repo.name}`.toLowerCase()] ?? null} />
Search across all of g1t, Explore, and a command palette186 </li>
187 ))}
188 </ul>
189 )}
190 {explore && (explore.page > 1 || explore.more) && (
191 <nav aria-label="Pages" className="mt-6 flex justify-between text-sm">
192 {explore.page > 1 ? (
193 <Link to={href(current, { page: String(explore.page - 1) })} className="text-muted hover:text-fg">
194 Previous
195 </Link>
196 ) : (
197 <span />
198 )}
199 {explore.more && (
200 <Link to={href(current, { page: String(explore.page + 1) })} className="text-muted hover:text-fg">
201 Next
202 </Link>
203 )}
204 </nav>
205 )}
206 </section>
207
208 <aside className="space-y-6">
209 {explore && explore.languages.length > 0 && (
210 <section>
211 <h2 className="text-xs font-medium text-faint">Languages</h2>
212 <div className="mt-2 flex flex-wrap gap-1.5">
213 {explore.languages.map((facet) => (
214 <Chip
215 key={facet.name}
216 to={href(current, { language: language === facet.name ? null : facet.name })}
217 current={language === facet.name}
218 >
219 <span className="font-mono">{facet.name}</span> <span className="text-faint">{facet.count}</span>
220 </Chip>
221 ))}
222 </div>
223 </section>
224 )}
225 {explore && explore.topics.length > 0 && (
226 <section>
227 <h2 className="text-xs font-medium text-faint">Topics</h2>
228 <div className="mt-2 flex flex-wrap gap-1.5">
229 {explore.topics.map((facet) => (
230 <Chip
231 key={facet.name}
232 to={href(current, { topic: topic === facet.name ? null : facet.name })}
233 current={topic === facet.name}
234 >
235 {facet.name} <span className="text-faint">{facet.count}</span>
236 </Chip>
237 ))}
238 </div>
239 </section>
240 )}
241 </aside>
242 </div>
Share the editor settings and Claude Code deploy permissions243 </main>
244 );
245}

This file's history is long; its oldest lines are credited to the oldest commit read.