flagon-io/g1t

public

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/apps/status/src/components.ts

215 lines7,327 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.

status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1/**
2 * The parts of g1t the page lists, and how each is checked. Every address
3 * comes from the Worker's vars, so an installation of its own names its own
4 * hosts; a part whose address is empty is not part of that installation
5 * and is left off the page.
6 *
7 * Checks go over the public internet, as people reach g1t, so they measure
8 * what people see. Billing has no public address of its own, so it is the
9 * one part checked through a service binding, when there is one.
10 */
11
12/** The Worker's vars that say where things are. */
13export type Targets = {
14 /** The site: `https://g1t.sh`. */
15 SITE_URL: string;
16 /** The API: `https://api.g1t.sh`. */
17 API_URL: string;
18 MCP_URL: string;
19 DOCS_URL: string;
20 /** Where deployed apps live: `https://g1t.page`. */
21 PAGES_URL: string;
22 MODELS_URL: string;
23 /** A public repository that always exists, `owner/name`, to fetch refs of. */
24 PROBE_REPO: string;
25 /** The site as browsers reach it, when the checks reach it another way. */
26 PUBLIC_SITE_URL?: string;
27};
28
29/** One request a check makes, and the answer that means the part works. */
30export type Step = {
31 url: string;
32 headers?: Record<string, string>;
33 /** The status that means it works; any 2xx when absent. */
34 expect?: number;
35};
36
37export type Check =
38 | { kind: "http"; steps: Step[] }
39 /** Billing, through its binding: reading its price book. */
40 | { kind: "billing" }
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily41 /** Git storage, through the repos service binding: how the store answered lately. */
42 | { kind: "storage" }
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas43 /** No check yet: the page says so rather than showing green. */
44 | { kind: "none" };
45
46export type ComponentInfo = {
47 key: string;
48 name: string;
49 address: string;
50 checks: string;
51 /** Whether g1t as a whole is down when this is. */
52 core: boolean;
53 check: Check;
Fast pages, required checks on the branch, self-hosted runners, honest incidents54 /** Slower than this, it counts as degraded; `SLOW_MS` when absent. */
55 slowMs?: number;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas56};
57
Fast pages, required checks on the branch, self-hosted runners, honest incidents58/**
59 * The page-speed budget the status page holds the site to: the slower of a
60 * public project page and Explore, to the first byte of the answer, from a
61 * Cloudflare data centre. docs/PERFORMANCE.md has the targets.
62 */
63export const SPEED_BUDGET_MS = 800;
64
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas65/** A token no one holds: the API asks identity about it and refuses it. */
66export const NO_TOKEN = `g1t_${"0".repeat(40)}`;
67
68function host(url: string): string {
69 try {
70 return new URL(url).host;
71 } catch {
72 return url;
73 }
74}
75
76const trim = (url: string | undefined) => (url ?? "").trim().replace(/\/+$/, "");
77
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily78/** Git storage counts as degraded when its calls took longer than this on average. */
79export const STORAGE_SLOW_MS = 1500;
80
81/** The parts, in the order the page lists them. `storage`: whether the repos service is bound. */
82export function components(vars: Partial<Targets>, billing = true, storage = false): ComponentInfo[] {
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas83 const site = trim(vars.SITE_URL);
84 const api = trim(vars.API_URL);
85 const mcp = trim(vars.MCP_URL);
86 const docs = trim(vars.DOCS_URL);
87 const pages = trim(vars.PAGES_URL);
88 const models = trim(vars.MODELS_URL);
89 const repo = (vars.PROBE_REPO ?? "").trim();
90 // What the page shows as the site's address: where people reach it.
91 const shown = host(trim(vars.PUBLIC_SITE_URL) || site);
92 const list: (ComponentInfo | null)[] = [
93 site
94 ? {
95 key: "site",
96 name: "Website and sign-in",
97 address: shown,
98 checks: api
99 ? "The sign-in page loading, and the account service answering an access token through the API."
100 : "The sign-in page loading.",
101 core: true,
102 check: {
103 kind: "http",
104 steps: [
105 { url: `${site}/login` },
106 ...(api ? [{ url: `${api}/v1/user`, headers: { authorization: `Bearer ${NO_TOKEN}` }, expect: 401 }] : []),
107 ],
108 },
109 }
110 : null,
111 api
112 ? {
113 key: "api",
114 name: "API",
115 address: host(api),
116 checks: "The API's front page.",
117 core: true,
118 check: { kind: "http", steps: [{ url: `${api}/` }] },
119 }
120 : null,
121 site && repo
122 ? {
123 key: "git",
124 name: "Git and repositories",
125 address: `${shown}/<owner>/<repo>.git`,
126 checks: "Listing the branches of a public repository over HTTPS, the first step of every clone.",
127 core: true,
128 check: { kind: "http", steps: [{ url: `${site}/${repo}.git/info/refs?service=git-upload-pack` }] },
129 }
130 : null,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily131 storage && site
132 ? {
133 key: "storage",
134 name: "Git storage",
135 address: "Where every repository is kept",
136 checks: `How g1t's git storage answered over the last five minutes, as g1t saw it: failures, rate limits, and how long calls took. Rate limited, or slower than ${STORAGE_SLOW_MS} ms on average, counts as degraded.`,
137 core: false,
138 check: { kind: "storage" },
139 slowMs: STORAGE_SLOW_MS,
140 }
141 : null,
Fast pages, required checks on the branch, self-hosted runners, honest incidents142 site && repo
143 ? {
144 key: "speed",
145 name: "Page speed",
146 address: `${shown}/${repo}`,
147 checks: `A public project page and Explore each answering within ${SPEED_BUDGET_MS} ms. Slower counts as degraded.`,
148 core: false,
149 check: { kind: "http", steps: [{ url: `${site}/${repo}` }, { url: `${site}/explore` }] },
150 slowMs: SPEED_BUDGET_MS,
151 }
152 : null,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas153 mcp
154 ? {
155 key: "mcp",
156 name: "MCP server",
157 address: host(mcp),
158 checks: "The MCP server's description.",
159 core: false,
160 check: { kind: "http", steps: [{ url: `${mcp}/`, headers: { accept: "application/json" } }] },
161 }
162 : null,
163 docs
164 ? {
165 key: "docs",
166 name: "Documentation",
167 address: host(docs),
168 checks: "The documentation's front page.",
169 core: false,
170 check: { kind: "http", steps: [{ url: `${docs}/` }] },
171 }
172 : null,
173 pages
174 ? {
175 key: "deployments",
176 name: "Deployments",
177 address: `*.${host(pages)}`,
178 checks: `${host(pages)} answering. Each deployed app is not checked one by one.`,
179 core: false,
180 check: { kind: "http", steps: [{ url: `${pages}/` }] },
181 }
182 : null,
183 models
184 ? {
185 key: "agents",
186 name: "Agents' model proxy",
187 address: host(models),
188 checks: "The proxy agents reach their model through. The model providers behind it are not checked.",
189 core: false,
190 check: { kind: "http", steps: [{ url: `${models}/` }] },
191 }
192 : null,
193 models
194 ? {
195 key: "sandboxes",
196 name: "Sandboxes",
197 address: "Agents, checks, workflows and builds",
198 checks: "Starting a sandbox costs money and takes seconds, so it is not checked from here yet.",
199 core: false,
200 check: { kind: "none" },
201 }
202 : null,
203 billing && site
204 ? {
205 key: "billing",
206 name: "Billing",
207 address: `${shown}/<workspace>/-/billing`,
208 checks: "The billing service reading its price book. Stripe itself is not checked.",
209 core: false,
210 check: { kind: "billing" },
211 }
212 : null,
213 ];
214 return list.filter((c): c is ComponentInfo => c != null);
215}