g1t/apps/web/app/routes/home.tsx

162 lines6,166 bytesCodeBlame

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.

API and MCP server, Rust identity service, registration, site redesign1import { ArrowRight, Plus } from "lucide-react";
Workspaces own repositories2import { Link, redirect } from "react-router";
Initial g1t: services, event bus, intents and attempts3
4import type { Route } from "./+types/home";
API and MCP server, Rust identity service, registration, site redesign5import { Landing } from "../components/landing";
6import { RepoList } from "../components/repo-list";
7import {
8 Avatar,
9 ButtonLink,
10 CopyLine,
11 EmptyState,
12 TimeAgo,
13} from "../components/ui";
Issues and pull requests replace intents and attempts14import { PullIcon } from "../components/work";
Work service in Rust, with RFC 3339 timestamps15import { repos as reposApi, work } from "../lib/services.server";
Initial g1t: services, event bus, intents and attempts16import { getViewer } from "../lib/session.server";
17
18export function meta({}: Route.MetaArgs) {
19 return [
Email verification, password reset, and Git for AI scale positioning20 { title: "g1t — Git for AI scale" },
Initial g1t: services, event bus, intents and attempts21 {
22 name: "description",
23 content:
Issues and pull requests replace intents and attempts24 "A git forge for thousands of agents working on the same code at once: every change isolated, every decision recorded, every change landed in order. Open source, built on Cloudflare.",
Initial g1t: services, event bus, intents and attempts25 },
26 ];
27}
28
29export async function loader({ context }: Route.LoaderArgs) {
30 const viewer = getViewer(context);
Workspaces own repositories31 // Nothing can be created outside a workspace, so a new account starts there.
32 if (viewer?.verified && (viewer.workspaces ?? []).length === 0) {
33 throw redirect("/workspaces/new");
34 }
Issues and pull requests replace intents and attempts35 const [repos, pulls] = await Promise.all([
Workspaces own repositories36 reposApi.list(viewer, { memberOnly: Boolean(viewer) }),
Issues and pull requests replace intents and attempts37 work.listActivePulls(viewer),
Initial g1t: services, event bus, intents and attempts38 ]);
Issues and pull requests replace intents and attempts39 // Mission control links to each pull request under its repo.
40 const pullRepos = await Promise.all(
41 pulls.map(({ pull }) => reposApi.getById(pull.repoId, viewer)),
Initial g1t: services, event bus, intents and attempts42 );
43 return {
44 viewer,
45 repos,
Issues and pull requests replace intents and attempts46 active: pulls.flatMap((item, i) => {
47 const repo = pullRepos[i];
Initial g1t: services, event bus, intents and attempts48 return repo.ok ? [{ ...item, repo: repo.value }] : [];
49 }),
50 };
51}
52
53export default function Home({ loaderData }: Route.ComponentProps) {
54 const { viewer, repos, active } = loaderData;
API and MCP server, Rust identity service, registration, site redesign55 if (!viewer) return <Landing repos={repos} />;
Initial g1t: services, event bus, intents and attempts56
Issues and pull requests replace intents and attempts57 const working = active.filter(({ pull }) => pull.status === "draft");
API and MCP server, Rust identity service, registration, site redesign58 return (
59 <main className="mx-auto grid max-w-6xl gap-10 px-4 py-10 lg:grid-cols-[1fr_20rem]">
60 <div className="min-w-0 space-y-10">
Initial g1t: services, event bus, intents and attempts61 <section>
API and MCP server, Rust identity service, registration, site redesign62 <div className="flex items-center gap-3">
63 <Avatar name={viewer.username} size={36} />
64 <div>
65 <h1 className="text-xl font-semibold tracking-tight">
66 Mission control
67 </h1>
68 <p className="text-sm text-muted">
69 {working.length === 0
Issues and pull requests replace intents and attempts70 ? "Nothing is being worked on right now."
71 : `${working.length} ${working.length === 1 ? "pull request is" : "pull requests are"} being worked on.`}
API and MCP server, Rust identity service, registration, site redesign72 </p>
73 </div>
74 </div>
75 </section>
76
77 <section>
78 <h2 className="text-sm font-medium text-muted">In progress</h2>
79 <div className="mt-3">
80 {active.length === 0 ? (
Issues and pull requests replace intents and attempts81 <EmptyState title="No pull requests in progress">
82 Open an issue on a repository and put an agent on it, or point
83 your own agent at one.
API and MCP server, Rust identity service, registration, site redesign84 </EmptyState>
85 ) : (
86 <ul className="divide-y divide-line overflow-hidden rounded-xl border border-line bg-surface">
Issues and pull requests replace intents and attempts87 {active.map(({ pull, repo }) => (
88 <li key={pull.id}>
API and MCP server, Rust identity service, registration, site redesign89 <Link
Issues and pull requests replace intents and attempts90 to={`/${repo.namespace}/${repo.name}/pull/${pull.number}`}
91 className="flex items-center gap-3 px-4 py-3 transition-colors hover:bg-raised"
API and MCP server, Rust identity service, registration, site redesign92 >
Issues and pull requests replace intents and attempts93 <PullIcon status={pull.status} />
API and MCP server, Rust identity service, registration, site redesign94 <span className="min-w-0 grow">
Issues and pull requests replace intents and attempts95 <span className="block truncate font-medium">{pull.title}</span>
API and MCP server, Rust identity service, registration, site redesign96 <span className="font-mono text-xs text-muted">
Issues and pull requests replace intents and attempts97 {repo.namespace}/{repo.name}#{pull.number}
98 {pull.issue != null && ` · for #${pull.issue}`} · {pull.agent}
API and MCP server, Rust identity service, registration, site redesign99 </span>
100 </span>
Issues and pull requests replace intents and attempts101 <span className="shrink-0 text-xs text-muted">
102 {pull.status === "draft" ? "In progress" : "Ready for review"}
103 </span>
104 <span className="w-14 shrink-0 text-right text-xs text-faint">
105 <TimeAgo at={pull.updatedAt} />
Initial g1t: services, event bus, intents and attempts106 </span>
API and MCP server, Rust identity service, registration, site redesign107 </Link>
108 </li>
109 ))}
110 </ul>
111 )}
112 </div>
Initial g1t: services, event bus, intents and attempts113 </section>
API and MCP server, Rust identity service, registration, site redesign114
Initial g1t: services, event bus, intents and attempts115 <section>
API and MCP server, Rust identity service, registration, site redesign116 <div className="flex items-center justify-between">
117 <h2 className="text-sm font-medium text-muted">Your repositories</h2>
118 <ButtonLink to="/new" variant="quiet">
119 <Plus size={14} />
120 New
121 </ButtonLink>
122 </div>
Initial g1t: services, event bus, intents and attempts123 <RepoList repos={repos} />
124 </section>
API and MCP server, Rust identity service, registration, site redesign125 </div>
Initial g1t: services, event bus, intents and attempts126
API and MCP server, Rust identity service, registration, site redesign127 <aside className="space-y-4">
128 <div className="rounded-xl border border-line bg-surface p-5">
129 <h2 className="font-medium">Connect an agent</h2>
130 <p className="mt-1.5 text-sm text-muted">
OAuth 2.1 sign-in for MCP clients and other applications131 Add g1t to Claude Code, then run /mcp in it to sign in through
132 your browser.
API and MCP server, Rust identity service, registration, site redesign133 </p>
134 <div className="mt-4 space-y-2">
135 <CopyLine
136 prompt
OAuth 2.1 sign-in for MCP clients and other applications137 text="claude mcp add --transport http g1t https://mcp.g1t.sh"
API and MCP server, Rust identity service, registration, site redesign138 />
139 </div>
140 <Link
Docs as their own app; shared theme package141 to="https://docs.g1t.sh/guides/bring-your-own-agent/"
API and MCP server, Rust identity service, registration, site redesign142 className="mt-4 inline-flex items-center gap-1 text-sm text-accent hover:underline"
143 >
144 How it works <ArrowRight size={13} />
145 </Link>
146 </div>
147 <div className="rounded-xl border border-line bg-surface p-5">
148 <h2 className="font-medium">Explore</h2>
149 <p className="mt-1.5 text-sm text-muted">
Issues and pull requests replace intents and attempts150 Browse public repositories and the issues open on them.
API and MCP server, Rust identity service, registration, site redesign151 </p>
152 <Link
153 to="/explore"
154 className="mt-3 inline-flex items-center gap-1 text-sm text-accent hover:underline"
155 >
156 Public repositories <ArrowRight size={13} />
157 </Link>
158 </div>
159 </aside>
Initial g1t: services, event bus, intents and attempts160 </main>
161 );
162}