Skip to content
244 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.

Initial g1t: services, event bus, intents and attempts1import { createRequestHandler } from "react-router";
2
Merge branch 'worktree-agent-a8385d293d42c913a'3import { identityClient, isNamespaceShaped } from "@g1t/contracts";
4
Registry answers run nothing in a browser: nosniff, a sandbox policy, and publisher documents as downloads5import { hardenRegistryHeaders } from "../app/lib/content-safety";
Fast pages, required checks on the branch, self-hosted runners, honest incidents6import { finishResponse, withRequestPerf } from "../app/lib/perf.server";
Composer from the workspace's own repositories, and go get from g1t.sh7import { goImport } from "../app/lib/go-get";
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy8import { repositoryOfPage, stillPublic } from "../app/lib/public-cache";
Merge branch 'worktree-agent-a8385d293d42c913a'9import { registryWorkspace, servicePath } from "../app/lib/registry-paths";
Fast pages, required checks on the branch, self-hosted runners, honest incidents10
Initial g1t: services, event bus, intents and attempts11const requestHandler = createRequestHandler(
12 () => import("virtual:react-router/server-build"),
13 import.meta.env.MODE,
14);
15
Workspace names and icons, and a component kit for every control16/** An uploaded avatar, by the SHA-256 of its bytes. */
17const AVATAR_PATH = /^\/avatars\/([0-9a-f]{64})$/;
18/** The only types identity stores, having checked each image's bytes. */
19const AVATAR_TYPES = new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
Docs as their own app; shared theme package20const DOCS = "https://docs.g1t.sh";
Initial g1t: services, event bus, intents and attempts21
Docs as their own app; shared theme package22/** Where the documentation pages that used to live under /docs are now. */
23const MOVED_DOCS: Record<string, string> = {
24 "/docs": "/quickstart/",
25 "/docs/concepts": "/concepts/overview/",
26 "/docs/authentication": "/guides/authentication/",
27 "/docs/git": "/guides/git/",
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent28 "/docs/g1t-agents": "/guides/working-with-g1t/",
Docs as their own app; shared theme package29 "/docs/agents": "/guides/bring-your-own-agent/",
30 "/docs/api": "/reference/api/",
Merge branch 'worktree-agent-ab2e39e11a6493412'31 "/docs/api/reference": "/reference/api/",
Docs as their own app; shared theme package32};
docs.g1t.sh, generated OpenAPI with an interactive reference, full footer33
Initial g1t: services, event bus, intents and attempts34export default {
Icons are cached at the edge35 async fetch(request, env, ctx) {
Docs as their own app; shared theme package36 const { pathname } = new URL(request.url);
Initial g1t: services, event bus, intents and attempts37 // Git over HTTPS shares this hostname but belongs to the repos service.
Agents and memory, checks and conflicts, profiles, slug renames, custom domains38 // Its answer goes back to the git client as it is: a repository under a
39 // renamed workspace's old name answers with a 301, which git follows and
40 // must see, so the redirect is never followed here.
npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token41 // The container registry (`docker login g1t.sh`) and the npm registry
42 // (`g1t.sh/-/npm/`) are the packages
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member43 // service's, handed over the same way.
Composer from the workspace's own repositories, and go get from g1t.sh44 // `go get g1t.sh/<workspace>/<repo>`: where its code is, from the
45 // address alone, so it costs nothing and caches.
46 const go = request.method === "GET" ? goImport(new URL(request.url)) : null;
47 if (go) {
48 return new Response(go, {
49 headers: { "content-type": "text/html; charset=utf-8", "cache-control": "public, max-age=3600" },
50 });
51 }
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member52 const service = servicePath(pathname);
53 if (service === "git") {
Mission control shows where you are needed and what agents landed without you; git answers in about 200ms54 return proxyGit(env, request);
Initial g1t: services, event bus, intents and attempts55 }
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member56 if (service === "packages") {
57 return proxyPackages(env, request);
58 }
Workspace names and icons, and a component kit for every control59 const avatar = AVATAR_PATH.exec(pathname);
60 if (avatar) {
Icons are cached at the edge61 return serveAvatar(env, ctx, request, avatar[1]);
Workspace names and icons, and a component kit for every control62 }
Docs as their own app; shared theme package63 // The documentation is its own site.
64 if (pathname === "/docs" || pathname.startsWith("/docs/")) {
65 const page = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
66 const target = MOVED_DOCS[page] ?? "/";
67 return Response.redirect(DOCS + target, 301);
docs.g1t.sh, generated OpenAPI with an interactive reference, full footer68 }
Fast pages, required checks on the branch, self-hosted runners, honest incidents69 // Every page and data request says where its time went (Server-Timing)
70 // and keeps the reader's D1 bookmarks (app/lib/perf.server.ts).
71 const render = () => withRequestPerf(request, async () => finishResponse(request, await requestHandler(request)));
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy72 if (anonymousPage(request, pathname)) return servePublic(env, request, ctx, render);
Fast pages, required checks on the branch, self-hosted runners, honest incidents73 return render();
Initial g1t: services, event bus, intents and attempts74 },
75} satisfies ExportedHandler<Env>;
Workspace names and icons, and a component kit for every control76
77/**
Fast pages, required checks on the branch, self-hosted runners, honest incidents78 * Public pages as someone signed out sees them: the same for every such
79 * visitor, so kept in this data centre's cache. Reserved first segments
80 * (settings, sign-in, invitations and the like) and workspace pages (`-`)
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy81 * are never kept; docs/PERFORMANCE.md lists the rules. A repository's kept
82 * page is served only while repos says the repository is still public: one
83 * made private or deleted is never served from any data centre's copy.
Fast pages, required checks on the branch, self-hosted runners, honest incidents84 */
85const PUBLIC_TOP = /^\/(?:|_root\.data|pricing|explore|security|support|policies(?:\/[a-z-]+)?)(?:\.data)?$/;
86const PUBLIC_PROJECT =
Merge email confirmation gate: a code and a link, nothing until confirmed (identity 0036)87 /^\/(?!(?:settings|u|auth|oauth|integrations|new|invite|workspaces|device|verify|confirm-email|login|register|logout|forgot|reset|search|status|avatars|docs)\/)[^/]+\/(?!-\/|-$)[^/]+(?:\/(?:code|commits|issues|pulls|pull\/\d+|issues\/\d+|commit\/[0-9a-f]+|tree\/.+|blob\/.+))?(?:\.data)?$/;
Fast pages, required checks on the branch, self-hosted runners, honest incidents88/** Fresh for this long; then served once more while a new copy is made. */
89const PUBLIC_FRESH_SECONDS = 30;
90const PUBLIC_STALE_SECONDS = 300;
91
92function anonymousPage(request: Request, pathname: string): boolean {
93 if (request.method !== "GET") return false;
94 if (/(?:^|;\s*)g1t_session=/.test(request.headers.get("cookie") ?? "")) return false;
95 return PUBLIC_TOP.test(pathname) || PUBLIC_PROJECT.test(pathname);
96}
97
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy98async function servePublic(env: Env, request: Request, ctx: ExecutionContext, render: () => Promise<Response>): Promise<Response> {
Fast pages, required checks on the branch, self-hosted runners, honest incidents99 const cache = (caches as unknown as { default: Cache }).default;
100 const key = new Request(request.url, { method: "GET" });
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy101 const repository = PUBLIC_PROJECT.test(new URL(request.url).pathname) ? repositoryOfPage(new URL(request.url).pathname) : null;
102 // Asked alongside the cache, so a hit waits for one indexed read at most.
103 const [cached, visible] = await Promise.all([cache.match(key), repository ? isStillPublic(env, repository) : Promise.resolve(true)]);
104 if (cached && !visible) {
105 ctx.waitUntil(cache.delete(key).then(() => undefined, () => undefined));
106 return render();
107 }
Fast pages, required checks on the branch, self-hosted runners, honest incidents108 const keptAt = Number(cached?.headers.get("x-g1t-kept-at") ?? 0);
109 const age = Math.round((Date.now() - keptAt) / 1000);
110 const refresh = async () => {
111 const fresh = await render();
112 // Only a plain answer for everyone: nothing that sets a cookie or says
113 // it is private.
114 const cacheable =
115 (fresh.status === 200 || fresh.status === 404) &&
116 !fresh.headers.has("set-cookie") &&
117 !/private|no-store/.test(fresh.headers.get("cache-control") ?? "");
118 if (cacheable) {
119 const copy = new Response(fresh.clone().body, fresh);
120 copy.headers.set("x-g1t-kept-at", String(Date.now()));
121 copy.headers.set("cache-control", `public, max-age=${PUBLIC_STALE_SECONDS}`);
122 ctx.waitUntil(cache.put(key, copy));
123 }
124 return fresh;
125 };
126 if (cached && keptAt > 0 && age < PUBLIC_STALE_SECONDS) {
127 if (age >= PUBLIC_FRESH_SECONDS) ctx.waitUntil(refresh().then(() => undefined, () => undefined));
128 const answer = new Response(cached.body, cached);
129 answer.headers.delete("x-g1t-kept-at");
130 answer.headers.delete("cache-control");
131 answer.headers.set("server-timing", `cache;desc="hit, ${age}s old"`);
132 return answer;
133 }
134 return refresh();
135}
136
Signed-out page cache: a repository's kept page is served only while the repository is still public, so one made private or deleted never shows from any data centre's copy137/** Whether the repository is there and public; anything else, including no answer, is no. */
138async function isStillPublic(env: Env, repository: string): Promise<boolean> {
139 try {
140 const answer = await env.REPOS.fetch("https://service/rpc/visibility", {
141 method: "POST",
142 headers: { "content-type": "application/json" },
143 body: JSON.stringify({ paths: [repository] }),
144 });
145 return answer.ok && stillPublic(await answer.json(), repository);
146 } catch {
147 return false;
148 }
149}
150
Fast pages, required checks on the branch, self-hosted runners, honest incidents151/**
Mission control shows where you are needed and what agents landed without you; git answers in about 200ms152 * A git request, answered by the repos service. Its `Server-Timing` header
153 * gains `repos`: how long the answer took to start from here, so the time
154 * between this Worker and the repos service shows beside the steps the
155 * repos service reports.
156 */
157async function proxyGit(env: Env, request: Request): Promise<Response> {
158 const started = Date.now();
159 const answer = await env.REPOS.fetch(new Request(request, { redirect: "manual" }));
160 const response = new Response(answer.body, answer);
161 response.headers.append("server-timing", `repos;dur=${Date.now() - started}`);
162 return response;
163}
164
165/**
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member166 * A registry request, answered by the packages service as it is: its
167 * redirects (a large blob sent to storage) go back to the client, which
Merge branch 'worktree-agent-a8385d293d42c913a'168 * follows them itself. One that found nothing under a workspace's old name
169 * or an alias staff set (`g1t` for `flagon-io`) is sent to the same path
170 * under the workspace's name: only the not-found answer pays for the lookup.
Registry answers run nothing in a browser: nosniff, a sandbox policy, and publisher documents as downloads171 * Every answer runs nothing in a browser (app/lib/content-safety.ts): what
172 * a registry serves is its publisher's, on this origin.
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member173 */
174async function proxyPackages(env: Env, request: Request): Promise<Response> {
175 const started = Date.now();
176 const answer = await env.PACKAGES.fetch(new Request(request, { redirect: "manual" }));
Merge branch 'worktree-agent-a8385d293d42c913a'177 const moved = answer.status === 404 ? await registryMoved(env, request) : null;
178 const response = moved ?? new Response(answer.body, answer);
Registry answers run nothing in a browser: nosniff, a sandbox policy, and publisher documents as downloads179 hardenRegistryHeaders(response.headers);
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member180 response.headers.append("server-timing", `packages;dur=${Date.now() - started}`);
181 return response;
182}
183
Merge branch 'worktree-agent-a8385d293d42c913a'184/** Where a registry request under an alias or old name goes now, or null. */
185async function registryMoved(env: Env, request: Request): Promise<Response | null> {
186 const url = new URL(request.url);
187 const named = registryWorkspace(url.pathname);
188 if (!named || !isNamespaceShaped(named.slug)) return null;
189 let current: string | null = null;
190 try {
191 current = await identityClient(env.IDENTITY).resolveSlug(named.slug);
192 } catch {
193 return null;
194 }
195 if (!current || current === named.slug) return null;
196 const get = request.method === "GET" || request.method === "HEAD";
197 // 308 keeps a publish a PUT, for the clients that follow it.
198 return new Response(null, { status: get ? 301 : 308, headers: { location: named.under(current) + url.search } });
199}
200
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member201/**
Workspace names and icons, and a component kit for every control202 * An uploaded avatar. Its address is its hash, so it never changes and is
203 * kept for good. It is served as nothing but an image: the stored type,
204 * no sniffing, and a policy that lets nothing in it run.
205 */
Icons are cached at the edge206/**
207 * An uploaded icon. Its address is its content's hash, so it never changes:
208 * each data centre keeps it in its cache after the first view, and storage
209 * is read about once per place, not once per visitor.
210 */
211async function serveAvatar(env: Env, ctx: ExecutionContext, request: Request, hash: string): Promise<Response> {
212 const method = request.method;
Workspace names and icons, and a component kit for every control213 if (method !== "GET" && method !== "HEAD") {
214 return new Response("Method not allowed", { status: 405, headers: { allow: "GET, HEAD" } });
215 }
Agents and memory, checks and conflicts, profiles, slug renames, custom domains216 // The Workers runtime's own cache, which the DOM types do not know.
217 const cache = (caches as unknown as { default: Cache }).default;
Icons are cached at the edge218 const key = new Request(new URL(`/avatars/${hash}`, request.url).toString(), { method: "GET" });
219 const cached = await cache.match(key);
220 if (cached) {
221 return method === "HEAD" ? new Response(null, { headers: cached.headers }) : cached;
222 }
Workspace names and icons, and a component kit for every control223 const { value, metadata } = await env.AVATARS.getWithMetadata<{ contentType?: string }>(hash, {
224 type: "arrayBuffer",
225 cacheTtl: 86400,
226 });
227 const contentType = metadata?.contentType;
228 if (!value || !contentType || !AVATAR_TYPES.has(contentType)) {
229 return new Response("Not found", {
230 status: 404,
231 headers: { "cache-control": "public, max-age=60" },
232 });
233 }
Icons are cached at the edge234 const headers = {
235 "content-type": contentType,
236 "content-length": String(value.byteLength),
237 "cache-control": "public, max-age=31536000, immutable",
238 "x-content-type-options": "nosniff",
239 "content-security-policy": "default-src 'none'; sandbox",
240 "cross-origin-resource-policy": "cross-origin",
241 };
242 ctx.waitUntil(cache.put(key, new Response(value, { headers })));
243 return new Response(method === "HEAD" ? null : value, { headers });
Workspace names and icons, and a component kit for every control244}

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