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
86 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 'worktree-agent-a985c01f43538af01'1import { Form, Link, redirect } from "react-router";
The plan says what g1t is for without measuring it against other products2
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers3import { USERNAME_PATTERN } from "@g1t/contracts";
4
The plan says what g1t is for without measuring it against other products5import type { Route } from "./+types/auth-github-username";
6import { AuthCard } from "../components/auth-card";
7import { GithubMark } from "../components/github";
Merge branch 'worktree-agent-a985c01f43538af01'8import { ErrorText, Field, Input, SubmitButton } from "../components/ui";
The plan says what g1t is for without measuring it against other products9import { PENDING_COOKIE, cookie, readCookie } from "../lib/github";
10import { githubSignIn } from "../lib/github.server";
11import { page } from "../lib/meta";
12import { safeNext } from "../lib/next";
13import { assertSameOrigin, startSession } from "../lib/session.server";
14
15export function meta(args: Route.MetaArgs) {
16 return page(args, { title: "Choose a username · g1t" });
17}
18
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.19/** A new account from GitHub, once its username is settled. */
The plan says what g1t is for without measuring it against other products20export async function loader({ request }: Route.LoaderArgs) {
21 const pending = readCookie(request.headers.get("cookie"), PENDING_COOKIE);
22 if (!pending) throw redirect("/register");
23 const found = await githubSignIn.pending(pending);
24 if (!found.ok || found.value.kind !== "username") {
25 throw redirect("/register", { headers: { "set-cookie": cookie(PENDING_COOKIE, "", 0) } });
26 }
27 return found.value;
28}
29
30export async function action({ request }: Route.ActionArgs) {
31 assertSameOrigin(request);
32 const pending = readCookie(request.headers.get("cookie"), PENDING_COOKIE);
33 if (!pending) throw redirect("/register");
34 const form = await request.formData();
35 // Where to go afterwards, read before the pending sign-in is used up.
36 const found = await githubSignIn.pending(pending).catch(() => null);
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.37 const result = await githubSignIn.signUp(pending, String(form.get("username") ?? ""));
The plan says what g1t is for without measuring it against other products38 if (!result.ok) return { error: result.error.message };
39 const headers = new Headers({ "set-cookie": startSession(result.value.sessionToken) });
40 headers.append("set-cookie", cookie(PENDING_COOKIE, "", 0));
41 throw redirect(safeNext(found?.ok ? found.value.next : "/"), { headers });
42}
43
44export default function GithubUsername({ loaderData, actionData }: Route.ComponentProps) {
45 return (
46 <AuthCard
47 title="Create your account"
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.48 subtitle="Choose your username"
The plan says what g1t is for without measuring it against other products49 footer={
50 <>
51 Have an account already?{" "}
52 <Link to="/login?github=link" className="text-fg underline underline-offset-4">
53 Sign in to link GitHub
54 </Link>
55 </>
56 }
57 >
58 <p className="mb-6 flex items-center gap-2 text-sm text-muted">
59 <GithubMark />
60 Signed in to GitHub as <span className="font-mono text-fg">@{loaderData.login}</span>
61 </p>
62 <Form method="post" className="space-y-4">
63 <Field
64 label="Username"
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers65 hint="Letters, digits and single hyphens. It is how others see you on g1t, in the case you type it."
The plan says what g1t is for without measuring it against other products66 >
67 <Input
68 name="username"
69 autoComplete="username"
70 required
71 autoFocus
72 maxLength={39}
73 defaultValue={loaderData.suggestion ?? ""}
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers74 pattern={USERNAME_PATTERN}
The plan says what g1t is for without measuring it against other products75 />
76 </Field>
77 <ErrorText>{actionData?.error}</ErrorText>
78 <div className="pt-2 *:w-full">
Merge branch 'worktree-agent-a985c01f43538af01'79 <SubmitButton pending="Creating account…">
The plan says what g1t is for without measuring it against other products80 Create account
Merge branch 'worktree-agent-a985c01f43538af01'81 </SubmitButton>
The plan says what g1t is for without measuring it against other products82 </div>
83 </Form>
84 </AuthCard>
85 );
86}

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