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

Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API1/**
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily2 * Security, as a project's page shows it: open alerts by severity, the
3 * secrets found in pushes and history, vulnerable dependencies with the
4 * security update g1t opened for each, and what happened to every alert.
5 * The page posts the intents in `routes/repo/security.tsx`'s action.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API6 */
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily7import {
8 Bot,
9 CircleAlert,
10 CircleCheck,
11 CircleDot,
12 CircleSlash,
13 ExternalLink,
14 GitBranch,
15 GitMerge,
16 GitPullRequest,
17 GitPullRequestClosed,
18 History,
19 KeyRound,
20 Loader,
21 Package,
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.22 PauseCircle,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily23 ShieldAlert,
24 ShieldCheck,
25} from "lucide-react";
26import { type ReactNode, useEffect, useRef, useState } from "react";
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API27import { Link, useFetcher } from "react-router";
28
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily29import {
30 type AlertActivity,
31 type AlertState,
32 DEPENDENCY_DISMISS_REASONS,
33 type DismissReason,
34 SECRET_DISMISS_REASONS,
35 SEVERITIES,
36 type PullStatus,
37 type SecretFinding,
38 type SecurityUpdate,
39 type Severity,
40 type SeverityCounts,
41 type Vulnerability,
42 dismissLabel,
43} from "@g1t/contracts";
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API44
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily45import {
46 type ActivityEntry,
47 type PackageGroup,
48 UPDATE_STATES,
49 alertActivity,
50 groupByPackage,
51 highestFix,
52 latestUpdate,
53 splitSecrets,
54 worstSeverity,
55} from "../lib/security-alerts";
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.56import { TimeAgo } from "./ui";
57import { Avatar } from "./ui/avatar";
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API58import { Badge, type BadgeTone } from "./ui/badge";
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.59import { Button } from "./ui/button";
60import { Card } from "./ui/card";
Merge branch 'worktree-agent-ae1299e92e4462012'61import { Hint } from "./ui/hint";
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API62import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog";
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily63import { RadioGroup, RadioOption } from "./ui/radio-group";
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API64
65type Done = { ok: boolean; error?: string } | undefined;
66
67const SEVERITY: Record<Severity, { label: string; tone: BadgeTone }> = {
68 critical: { label: "Critical", tone: "danger" },
69 high: { label: "High", tone: "warn" },
70 medium: { label: "Medium", tone: "merged" },
71 low: { label: "Low", tone: "info" },
72 unknown: { label: "Unrated", tone: "neutral" },
73};
74
75
76export function SeverityBadge({ severity }: { severity: Severity }) {
77 return <Badge tone={SEVERITY[severity].tone}>{SEVERITY[severity].label}</Badge>;
78}
79
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily80/** Open alerts by severity, one tile each. */
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API81export function SeverityCountsGrid({ counts }: { counts: SeverityCounts }) {
82 return (
83 <div className="grid grid-cols-2 gap-3 sm:grid-cols-5">
84 {SEVERITIES.map((severity) => (
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.85 <Card key={severity} className="px-4 py-3">
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API86 <p className="text-xs text-muted">{SEVERITY[severity].label}</p>
87 <p className={`mt-1 text-2xl font-semibold tabular-nums ${counts[severity] > 0 && severity === "critical" ? "text-danger" : ""}`}>
88 {counts[severity]}
89 </p>
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.90 </Card>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API91 ))}
92 </div>
93 );
94}
95
96/** A compact row of severity counts, for a list of projects. */
97export function SeverityCountsInline({ counts }: { counts: SeverityCounts }) {
98 const shown = SEVERITIES.filter((severity) => counts[severity] > 0);
99 if (shown.length === 0) {
100 return (
Merge branch 'worktree-agent-ad7c6d88d93adc817'101 <span className="inline-flex items-center gap-1 text-xs text-success">
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API102 <ShieldCheck size={13} />
103 Nothing open
104 </span>
105 );
106 }
107 return (
108 <span className="flex flex-wrap gap-1.5">
109 {shown.map((severity) => (
110 <Badge key={severity} tone={SEVERITY[severity].tone}>
111 {counts[severity]} {SEVERITY[severity].label.toLowerCase()}
112 </Badge>
113 ))}
114 </span>
115 );
116}
117
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily118const STATE_FILTERS: { state: AlertState; label: string; icon: ReactNode }[] = [
119 { state: "open", label: "Open", icon: <CircleDot size={14} /> },
120 { state: "dismissed", label: "Dismissed", icon: <CircleSlash size={14} /> },
121 { state: "fixed", label: "Fixed", icon: <CircleCheck size={14} /> },
122];
123
124/** Open, Dismissed and Fixed, with how many alerts each holds. */
125export function StateFilter({
126 counts,
127 value,
128 onChange,
129}: {
130 counts: Record<AlertState, number>;
131 value: AlertState;
132 onChange: (state: AlertState) => void;
133}) {
134 return (
135 <div role="group" aria-label="Filter alerts" className="flex flex-wrap items-center gap-x-4 gap-y-1 text-sm">
136 {STATE_FILTERS.map(({ state, label, icon }) => (
137 <button
138 key={state}
139 type="button"
140 aria-pressed={value === state}
141 onClick={() => onChange(state)}
142 className={`inline-flex items-center gap-1.5 transition-colors ${
143 value === state ? "font-medium text-fg" : "text-muted hover:text-fg"
144 }`}
145 >
146 {icon}
147 {counts[state]} {label}
148 </button>
149 ))}
150 </div>
151 );
152}
153
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API154const TEXTAREA =
155 "w-full rounded-md border border-line bg-bg px-3 py-2 text-sm outline-none transition-colors placeholder:text-faint hover:border-line-strong focus:border-accent-dim";
156
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily157const SMALL_BUTTON =
158 "rounded-md border border-line px-2.5 py-1 text-xs font-medium text-muted transition-colors hover:border-line-strong hover:text-fg disabled:opacity-50";
159
160/** Dismiss an alert with one of `reasons` and an optional comment. */
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar161export function DismissDialog({
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily162 id,
163 title,
164 detail,
165 reasons,
166 note,
167 action,
168 defaultReason,
169 trigger = "Dismiss",
170}: {
171 id: string;
172 title: string;
173 /** What the alert is, in a line of code type. */
174 detail: string;
175 reasons: { reason: DismissReason; label: string; about: string }[];
176 note?: string;
177 action: string;
178 defaultReason?: DismissReason;
179 trigger?: string;
180}) {
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API181 const fetcher = useFetcher<Done>();
182 const [open, setOpen] = useState(false);
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily183 const [reason, setReason] = useState<string>(defaultReason ?? "");
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API184 useEffect(() => {
185 if (fetcher.state === "idle" && fetcher.data?.ok) setOpen(false);
186 }, [fetcher.state, fetcher.data]);
187 return (
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily188 <Dialog
189 open={open}
190 onOpenChange={(next) => {
191 setOpen(next);
192 if (next) setReason(defaultReason ?? "");
193 }}
194 >
195 <DialogTrigger className={SMALL_BUTTON}>{trigger}</DialogTrigger>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API196 <DialogContent>
197 <DialogHeader>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily198 <DialogTitle>{title}</DialogTitle>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API199 <DialogDescription>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily200 Say why it can stay. The alert keeps your name, the reason and your comment, and anyone with access can reopen it.
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API201 </DialogDescription>
202 </DialogHeader>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily203 <fetcher.Form method="post" action={action} className="space-y-4">
204 <input type="hidden" name="intent" value="dismiss" />
205 <input type="hidden" name="id" value={id} />
206 <p className="font-mono text-xs break-all text-muted">{detail}</p>
207 <fieldset>
208 <legend className="text-xs font-medium text-muted">Reason</legend>
209 <RadioGroup name="reason" value={reason} onValueChange={setReason} required className="mt-2 gap-3">
210 {reasons.map((option) => (
211 <RadioOption key={option.reason} value={option.reason} label={option.label} description={option.about} />
212 ))}
213 </RadioGroup>
214 </fieldset>
215 {note && <p className="rounded-md border border-warn/30 bg-warn/5 px-3 py-2 text-xs text-warn">{note}</p>}
216 <label className="block">
217 <span className="mb-1.5 block text-xs font-medium text-muted">Comment (optional)</span>
218 <textarea name="comment" rows={3} maxLength={500} placeholder="What someone reading this later should know." className={TEXTAREA} />
219 </label>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API220 <div className="flex justify-end">
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.221 <Button
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API222 type="submit"
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.223 disabled={fetcher.state !== "idle" || !reason}>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily224 {fetcher.state !== "idle" ? "Dismissing…" : "Dismiss alert"}
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.225 </Button>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API226 </div>
227 {fetcher.data?.error && <p className="text-sm text-danger">{fetcher.data.error}</p>}
228 </fetcher.Form>
229 </DialogContent>
230 </Dialog>
231 );
232}
233
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar234export function ReopenButton({ id, action }: { id: string; action: string }) {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily235 const fetcher = useFetcher<Done>();
236 return (
237 <span className="flex flex-col items-end gap-1">
238 <button
239 type="button"
240 disabled={fetcher.state !== "idle"}
241 onClick={() => fetcher.submit({ intent: "reopen", id }, { method: "post", action })}
242 className={SMALL_BUTTON}
243 >
244 {fetcher.state !== "idle" ? "Reopening…" : "Reopen"}
245 </button>
246 {fetcher.data?.error && <span className="text-xs text-danger">{fetcher.data.error}</span>}
247 </span>
248 );
249}
250
251/** What happened to an alert, oldest first, folded away until asked for. */
252function ActivityLog({ entries, base, open }: { entries: ActivityEntry[]; base: string; open?: boolean }) {
253 if (entries.length === 0) return null;
254 return (
255 <details className="group mt-2" open={open}>
256 <summary className="inline-flex cursor-pointer list-none items-center gap-1.5 text-xs text-muted hover:text-fg [&::-webkit-details-marker]:hidden">
257 <History size={12} />
258 <span className="group-open:hidden">Show activity ({entries.length})</span>
259 <span className="hidden group-open:inline">Hide activity</span>
260 </summary>
261 <ol className="mt-2 space-y-2 border-l border-line pl-3">
262 {entries.map((entry) => (
263 <li key={entry.key} className="text-xs">
264 <p className="flex flex-wrap items-center gap-x-1.5 gap-y-1 text-muted">
265 {entry.actor ? (
266 <>
267 <Avatar name={entry.actor} size={16} />
268 <span className="font-medium text-fg">{entry.actor}</span>
269 </>
270 ) : (
271 <CircleDot size={12} className="text-faint" />
272 )}
273 <span>{entry.text}</span>
274 {entry.ref && (
275 <Link
276 to={`${base}/${entry.ref.kind === "pull" ? "pull" : "issues"}/${entry.ref.number}`}
277 className="font-medium text-fg-soft hover:text-fg hover:underline"
278 >
279 #{entry.ref.number}
280 </Link>
281 )}
282 {entry.reason && <Badge>{dismissLabel(entry.reason)}</Badge>}
283 <span className="text-faint">
284 <TimeAgo at={entry.at} />
285 </span>
286 </p>
287 {entry.comment && <p className="mt-1 text-fg-soft wrap-anywhere">“{entry.comment}”</p>}
288 </li>
289 ))}
290 </ol>
291 </details>
292 );
293}
294
295function useFocus<T extends HTMLElement>(focused: boolean) {
296 const ref = useRef<T>(null);
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API297 useEffect(() => {
298 if (focused) ref.current?.scrollIntoView({ block: "center" });
299 }, [focused]);
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily300 return ref;
301}
302
303const FOCUSED = "bg-accent/5 ring-1 ring-accent/40 ring-inset";
304
305function secretBadge(finding: SecretFinding): { label: string; tone: BadgeTone; about: string } {
306 if (finding.state === "dismissed") {
307 return {
308 label: "Dismissed",
309 tone: "neutral",
310 about: finding.status === "allowed" ? "Pushes carrying it go through." : "Dismissed.",
311 };
312 }
Merge branch 'worktree-agent-ad7c6d88d93adc817'313 if (finding.state === "fixed") return { label: "Revoked", tone: "success", about: "Revoked or rotated." };
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily314 if (finding.status === "blocked") {
315 return { label: "Push blocked", tone: finding.testValue ? "neutral" : "warn", about: "A push carrying it was refused, so it never landed." };
316 }
317 return {
318 label: "In history",
319 tone: finding.testValue ? "neutral" : "danger",
320 about: "In the repository's history. Rotate it with whoever issued it, then dismiss it as revoked.",
321 };
322}
323
324function SecretItem({
325 finding,
326 activity,
327 base,
328 action,
329 focused,
330 canDismiss,
331}: {
332 finding: SecretFinding;
333 activity: AlertActivity[];
334 base: string;
335 action: string;
336 focused: boolean;
337 canDismiss: boolean;
338}) {
339 const ref = useFocus<HTMLLIElement>(focused);
340 const badge = secretBadge(finding);
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API341 const landed = finding.source === "history" || finding.status === "open";
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily342 const where = `${finding.path}:${finding.line}`;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API343 return (
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily344 <li ref={ref} id={finding.id} className={`flex flex-col gap-3 px-4 py-3 sm:flex-row sm:items-start ${focused ? FOCUSED : ""}`}>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API345 <KeyRound size={15} className="mt-0.5 hidden shrink-0 text-muted sm:block" />
346 <div className="min-w-0 grow">
347 <div className="flex flex-wrap items-center gap-2">
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar348 <Link to={`${base}/security/secret-scanning/${finding.id}`} className="text-sm font-medium first-letter:uppercase hover:underline">
349 {finding.label}
350 </Link>
Merge branch 'worktree-agent-ae1299e92e4462012'351 <Hint label={badge.about}>
352 <Badge tone={badge.tone}>{badge.label}</Badge>
353 </Hint>
354 {finding.testValue && (
355 <Hint label={finding.testValue}>
356 <Badge>Likely test value</Badge>
357 </Hint>
358 )}
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar359 {finding.validity === "active" && (
Merge branch 'worktree-agent-ae1299e92e4462012'360 <Hint label="Its issuer says it still works">
361 <Badge tone="danger">Active</Badge>
362 </Hint>
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar363 )}
Merge branch 'worktree-agent-ae1299e92e4462012'364 {finding.validity === "inactive" && (
365 <Hint label="Its issuer refused it: revoked or expired">
366 <Badge>Inactive</Badge>
367 </Hint>
368 )}
369 {finding.bypass && (
370 <Hint label={`Bypassed by ${finding.bypass.by}`}>
371 <Badge tone="warn">Bypassed</Badge>
372 </Hint>
373 )}
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily374 {finding.state === "dismissed" && finding.dismissedReason && <Badge>{dismissLabel(finding.dismissedReason)}</Badge>}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API375 </div>
376 <p className="mt-1 truncate font-mono text-xs">
377 {landed ? (
378 <Link to={`${base}/blob/${finding.commit}/${finding.path}#L${finding.line}`} className="text-fg-soft hover:text-fg hover:underline">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily379 {where}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API380 </Link>
381 ) : (
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily382 <span className="text-fg-soft">{where}</span>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API383 )}
384 <span className="text-faint"> · {finding.preview}</span>
385 </p>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily386 {finding.testValue && <p className="mt-1 text-xs text-muted">{finding.testValue}</p>}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API387 <p className="mt-1.5 flex flex-wrap gap-x-3 gap-y-1 text-xs text-faint">
388 <span>
389 {finding.source === "push" ? "in a push" : "in history"}
390 {finding.foundBy && <> by {finding.foundBy}</>}, commit{" "}
391 {landed ? (
392 <Link to={`${base}/commit/${finding.commit}`} className="font-mono hover:text-fg">
393 {finding.commit.slice(0, 7)}
394 </Link>
395 ) : (
396 <span className="font-mono">{finding.commit.slice(0, 7)}</span>
397 )}
398 </span>
399 <span>
400 found <TimeAgo at={finding.foundAt} />
401 </span>
402 </p>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily403 <ActivityLog entries={alertActivity(finding, activity)} base={base} open={focused && finding.state !== "open"} />
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API404 </div>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily405 {canDismiss && (
406 <div className="flex shrink-0 items-center gap-1.5">
407 {finding.state === "open" ? (
408 <DismissDialog
409 id={finding.id}
410 title={`Dismiss ${finding.label}`}
411 detail={`${where} · ${finding.preview}`}
412 reasons={SECRET_DISMISS_REASONS}
413 note={
414 finding.status === "blocked" && !finding.testValue
415 ? "Dismissing it lets the same push through, unless you dismiss it as revoked."
416 : undefined
417 }
418 action={action}
419 />
420 ) : (
421 <ReopenButton id={finding.id} action={action} />
422 )}
423 </div>
424 )}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API425 </li>
426 );
427}
428
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily429function Empty({ title, children }: { title: string; children: ReactNode }) {
430 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.431 <Card tone="plain" className="border-dashed px-6 py-10 text-center">
Merge branch 'worktree-agent-ad7c6d88d93adc817'432 <ShieldCheck size={22} className="mx-auto text-success" />
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily433 <p className="mt-2 font-medium">{title}</p>
434 <p className="mt-1 text-sm text-muted">{children}</p>
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.435 </Card>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily436 );
437}
438
439const LIST = "divide-y divide-line overflow-hidden rounded-xl border border-line bg-surface";
440
441/** The secret alerts in one state: on Open, real ones first, then likely test values. */
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API442export function SecretsList({
443 secrets,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily444 state,
445 activity,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API446 base,
447 action,
448 focus,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily449 canDismiss,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API450}: {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily451 /** Already filtered to `state`. */
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API452 secrets: SecretFinding[];
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily453 state: AlertState;
454 activity: AlertActivity[];
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API455 base: string;
456 action: string;
457 focus: string | null;
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily458 /** Whether the viewer may dismiss and reopen secret alerts (Admin). */
459 canDismiss: boolean;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API460}) {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily461 const item = (finding: SecretFinding) => (
462 <SecretItem
463 key={finding.id}
464 finding={finding}
465 activity={activity}
466 base={base}
467 action={action}
468 focused={finding.id === focus}
469 canDismiss={canDismiss}
470 />
471 );
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API472 if (secrets.length === 0) {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily473 return state === "open" ? (
474 <Empty title="No open secret alerts">
475 Pushes that add a key or a token are refused before they land, and the history is scanned once in the background.
476 </Empty>
477 ) : (
478 <Empty title={state === "dismissed" ? "No dismissed secret alerts" : "No revoked secrets"}>
479 {state === "dismissed"
480 ? "Alerts someone dismissed as a false positive, a test value or accepted are listed here."
481 : "Secrets dismissed as revoked are listed here."}
482 </Empty>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API483 );
484 }
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily485 if (state !== "open") return <ul className={LIST}>{secrets.map(item)}</ul>;
486 const { real, tests } = splitSecrets(secrets);
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API487 return (
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily488 <div className="space-y-5">
489 {real.length > 0 ? (
490 <ul className={LIST}>{real.map(item)}</ul>
491 ) : (
492 <Empty title="No secrets that look real">Only likely test values are open, and they never block a push.</Empty>
493 )}
494 {tests.length > 0 && (
495 <section>
496 <h4 className="text-sm font-medium">Likely test values</h4>
497 <p className="mt-0.5 mb-2 text-xs text-muted">
498 These look made for tests or documentation. They never block a push and are not counted as critical; dismiss them
499 to clear the list.
500 </p>
501 <ul className={LIST}>{tests.map(item)}</ul>
502 </section>
503 )}
504 </div>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API505 );
506}
507
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily508/** Where the legacy upgrade issue for a package stands, as the page loads it. */
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API509export type UpgradeFix = {
510 number: number;
511 state: "open" | "closed";
512 /** The newest pull request for the issue, if any. */
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily513 pull: { number: number; status: PullStatus; agent: string | null } | null;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API514 resolvedBy: number | null;
515};
516
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily517/** A security update's pull request as the page loads it. */
518export type PullInfo = { number: number; status: PullStatus; title: string };
519
520function FixLink({ issue, fix, base }: { issue: number; fix: UpgradeFix | undefined; base: string }) {
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API521 const pull = fix?.pull;
522 return (
523 <span className="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily524 <span className="text-muted">Upgrade issue</span>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API525 <Link to={`${base}/issues/${issue}`} className="inline-flex items-center gap-1 text-fg-soft hover:text-fg">
Merge branch 'worktree-agent-ad7c6d88d93adc817'526 {fix?.state === "closed" ? <CircleCheck size={12} className="text-merged" /> : <CircleDot size={12} className="text-success" />}#{issue}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API527 </Link>
528 {pull && (
529 <Link to={`${base}/pull/${pull.number}`} className="inline-flex items-center gap-1 text-muted hover:text-fg">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily530 {pull.agent ? <Bot size={12} /> : <GitPullRequest size={12} />}#{pull.number} {pull.status === "draft" ? "in progress" : pull.status}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API531 </Link>
532 )}
533 </span>
534 );
535}
536
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily537const PULL_ICON: Record<PullStatus, ReactNode> = {
538 draft: <GitPullRequest size={13} className="text-muted" />,
Merge branch 'worktree-agent-ad7c6d88d93adc817'539 open: <GitPullRequest size={13} className="text-success" />,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily540 merged: <GitMerge size={13} className="text-merged" />,
541 closed: <GitPullRequestClosed size={13} className="text-danger" />,
542};
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API543
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.544/**
545 * Where g1t's security update for a package stands. On a mirror g1t does
546 * not lead (`updatesWait`, the reason), an update that has not opened a
547 * pull request waits: nothing is made or pushed there until a takeover.
548 */
549function UpdateStatus({ update, name, pulls, base, updatesWait }: {
550 update: SecurityUpdate;
551 name: string;
552 pulls: Record<number, PullInfo>;
553 base: string;
554 updatesWait?: string | null;
555}) {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily556 const meta = UPDATE_STATES[update.state];
557 const pull = update.pull != null ? pulls[update.pull] : undefined;
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.558 if (updatesWait && (update.state === "requested" || update.state === "failed" || update.state === "needs_code")) {
559 return (
560 <Card tone="plain" radius="lg" className="mt-2.5 bg-bg/40 px-3 py-2 text-xs sm:ml-7">
561 <div className="flex flex-wrap items-center gap-x-2.5 gap-y-1.5">
562 <PauseCircle size={13} className="text-muted" />
563 <Badge>Security update waiting</Badge>
564 <span className="text-faint">
565 <TimeAgo at={update.updatedAt} />
566 </span>
567 </div>
568 <p className="mt-1 text-muted wrap-anywhere">
569 Raising {name} to {update.target} is on hold until {base.replace(/^\//, "")} is taken over or moved to g1t.
570 </p>
571 </Card>
572 );
573 }
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily574 const about: Record<SecurityUpdate["state"], ReactNode> = {
575 requested: <>A sandbox is raising {name} to {update.target}.</>,
576 open: <>It raises {name} to {update.target} and lands through your branch's required checks.</>,
577 merged: <>{name} was raised to {update.target}.</>,
578 closed: <>The pull request was closed without merging.</>,
579 superseded: <>A newer update replaced it, or the package is no longer vulnerable, so g1t closed it.</>,
580 needs_code: (
581 <>
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent582 Raising {name} to {update.target} needs code changes, so g1t opened an issue to make them
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily583 {update.issue != null && (
584 <>
585 :{" "}
586 <Link to={`${base}/issues/${update.issue}`} className="font-medium text-fg-soft hover:text-fg hover:underline">
587 #{update.issue}
588 </Link>
589 </>
590 )}
591 .
592 </>
593 ),
594 failed: <>{update.error ?? "g1t could not make the change."}</>,
595 };
596 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.597 <Card tone="plain" radius="lg" className="mt-2.5 bg-bg/40 px-3 py-2 text-xs sm:ml-7">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily598 <div className="flex flex-wrap items-center gap-x-2.5 gap-y-1.5">
599 {update.state === "requested" ? (
600 <Loader size={13} className="animate-spin text-info motion-reduce:animate-none" />
601 ) : update.state === "failed" || update.state === "needs_code" ? (
602 <CircleAlert size={13} className={update.state === "failed" ? "text-danger" : "text-warn"} />
603 ) : (
604 PULL_ICON[pull?.status ?? (update.state === "merged" ? "merged" : update.state === "open" ? "open" : "closed")]
605 )}
606 <Badge tone={meta.tone}>{meta.label}</Badge>
607 {update.pull != null && (
608 <Link to={`${base}/pull/${update.pull}`} className="font-medium text-fg-soft hover:text-fg hover:underline">
609 #{update.pull}
610 {pull && <span className="font-normal text-muted"> {pull.status === "draft" ? "draft" : pull.status}</span>}
611 </Link>
612 )}
613 {update.branch && (
614 <span className="inline-flex min-w-0 items-center gap-1 font-mono text-muted">
615 <GitBranch size={12} className="shrink-0" />
616 <span className="truncate">{update.branch}</span>
617 </span>
618 )}
619 <span className="text-faint">
620 <TimeAgo at={update.updatedAt} />
621 </span>
622 </div>
623 <p className={`mt-1 ${update.state === "failed" ? "text-danger" : "text-muted"} wrap-anywhere`}>{about[update.state]}</p>
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.624 </Card>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily625 );
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API626}
627
628export function VulnerabilityList({
629 vulnerabilities,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily630 state,
631 activity,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API632 fixes,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily633 pulls,
634 upkeep,
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.635 updatesWait,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API636 base,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily637 action,
638 focus,
639 canDismiss,
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API640}: {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily641 /** Already filtered to `state`. */
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API642 vulnerabilities: Vulnerability[];
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily643 state: AlertState;
644 activity: AlertActivity[];
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API645 fixes: Record<number, UpgradeFix>;
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily646 pulls: Record<number, PullInfo>;
647 /** Whether security updates are on. */
648 upkeep: boolean;
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.649 /** Why no update opens now: the repository is a mirror g1t does not lead (lib/mirror.ts). */
650 updatesWait?: string | null;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API651 base: string;
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily652 action: string;
653 focus: string | null;
654 /** Whether the viewer may dismiss and reopen dependency alerts (Write). */
655 canDismiss: boolean;
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API656}) {
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily657 const packages = groupByPackage(vulnerabilities);
658 if (packages.length === 0) {
659 return state === "open" ? (
660 <Empty title="No known vulnerabilities">
661 Every package the lockfiles resolve is checked against the OSV database on each push to the default branch, and daily.
662 </Empty>
663 ) : (
664 <Empty title={state === "dismissed" ? "No dismissed dependency alerts" : "Nothing fixed yet"}>
665 {state === "dismissed"
666 ? "Alerts someone dismissed, with their reason, are listed here."
667 : "Alerts whose package was upgraded, or is no longer vulnerable, are listed here."}
668 </Empty>
669 );
670 }
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API671 return (
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily672 <ul className={LIST}>
673 {packages.map((group) => (
674 <PackageItem
675 key={group.key}
676 group={group}
677 activity={activity}
678 fixes={fixes}
679 pulls={pulls}
680 upkeep={upkeep}
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.681 updatesWait={updatesWait}
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily682 base={base}
683 action={action}
684 focus={focus}
685 canDismiss={canDismiss}
686 />
687 ))}
688 </ul>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API689 );
690}
691
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily692function PackageItem({
693 group,
694 activity,
695 fixes,
696 pulls,
697 upkeep,
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.698 updatesWait,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily699 base,
700 action,
701 focus,
702 canDismiss,
703}: {
704 group: PackageGroup;
705 activity: AlertActivity[];
706 fixes: Record<number, UpgradeFix>;
707 pulls: Record<number, PullInfo>;
708 upkeep: boolean;
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.709 updatesWait?: string | null;
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily710 base: string;
711 action: string;
712 focus: string | null;
713 canDismiss: boolean;
714}) {
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API715 const versions = [...new Set(group.vulns.map((vuln) => vuln.version))];
716 const manifests = [...new Set(group.vulns.map((vuln) => vuln.manifest))];
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily717 const target = highestFix(group.vulns);
718 const update = latestUpdate(group.vulns);
719 const issue = update ? null : (group.vulns.find((vuln) => vuln.issue != null)?.issue ?? null);
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API720 return (
721 <li className="px-4 py-3">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily722 <div className="flex items-start gap-3">
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API723 <Package size={15} className="mt-0.5 hidden shrink-0 text-muted sm:block" />
724 <div className="min-w-0 grow">
725 <div className="flex flex-wrap items-center gap-2">
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily726 <span className="font-mono text-sm font-medium break-all">{group.name}</span>
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API727 <span className="font-mono text-xs text-muted">{versions.join(", ")}</span>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily728 <Badge>{group.ecosystem}</Badge>
729 <SeverityBadge severity={worstSeverity(group.vulns)} />
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API730 </div>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily731 <p className="mt-1 text-xs text-faint wrap-anywhere">
732 {target ? <>Fixed in {target}</> : "No patched version"} · locked in{" "}
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API733 <span className="font-mono">{manifests.join(", ")}</span>
734 </p>
735 </div>
736 </div>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.737 {update && <UpdateStatus update={update} name={group.name} pulls={pulls} base={base} updatesWait={updatesWait} />}
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily738 {issue != null && (
739 <div className="mt-2 sm:ml-7">
740 <FixLink issue={issue} fix={fixes[issue]} base={base} />
741 </div>
742 )}
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.743 <Card asChild tone="plain" radius="lg" className="mt-2.5 space-y-px overflow-hidden sm:ml-7">
744 <ul>
745 {group.vulns.map((vuln) => (
746 <AdvisoryItem
747 key={vuln.id}
748 vuln={vuln}
749 showManifest={manifests.length > 1}
750 activity={activity}
751 upkeep={upkeep}
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.752 updatesWait={updatesWait}
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.753 base={base}
754 action={action}
755 focused={vuln.id === focus}
756 canDismiss={canDismiss}
757 />
758 ))}
759 </ul>
760 </Card>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily761 </li>
762 );
763}
764
765function AdvisoryItem({
766 vuln,
767 showManifest,
768 activity,
769 upkeep,
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.770 updatesWait,
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily771 base,
772 action,
773 focused,
774 canDismiss,
775}: {
776 vuln: Vulnerability;
777 showManifest: boolean;
778 activity: AlertActivity[];
779 upkeep: boolean;
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.780 updatesWait?: string | null;
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily781 base: string;
782 action: string;
783 focused: boolean;
784 canDismiss: boolean;
785}) {
786 const ref = useFocus<HTMLLIElement>(focused);
787 const osv = `https://osv.dev/vulnerability/${vuln.osvId}`;
788 const dismiss = (reason?: DismissReason, trigger?: string) => (
789 <DismissDialog
790 id={vuln.id}
791 title={`Dismiss ${vuln.advisory}`}
792 detail={`${vuln.package} ${vuln.version} · ${vuln.manifest}`}
793 reasons={DEPENDENCY_DISMISS_REASONS}
794 action={action}
795 defaultReason={reason}
796 trigger={trigger}
797 />
798 );
799 return (
800 <li ref={ref} id={vuln.id} className={`bg-bg/30 px-3 py-2.5 not-first:border-t not-first:border-line ${focused ? FOCUSED : ""}`}>
801 <div className="flex flex-col gap-2 sm:flex-row sm:items-start">
802 <div className="min-w-0 grow text-xs">
803 <p className="flex flex-wrap items-center gap-x-2 gap-y-1">
804 <a href={osv} target="_blank" rel="noreferrer" className="inline-flex items-center gap-1 font-mono text-fg-soft hover:text-fg">
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API805 {vuln.advisory}
806 <ExternalLink size={10} />
807 </a>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily808 <SeverityBadge severity={vuln.severity} />
809 {vuln.fixedVersion && <span className="text-faint">fixed in {vuln.fixedVersion}</span>}
810 {showManifest && <span className="font-mono text-faint">{vuln.manifest}</span>}
811 {vuln.state === "dismissed" && vuln.dismissedReason && <Badge>{dismissLabel(vuln.dismissedReason)}</Badge>}
812 </p>
813 <p className="mt-1 text-muted wrap-anywhere">{vuln.summary}</p>
814 </div>
815 {canDismiss && vuln.state !== "fixed" && (
816 <div className="flex shrink-0 items-center gap-1.5">
817 {vuln.state === "open" ? dismiss() : <ReopenButton id={vuln.id} action={action} />}
818 </div>
819 )}
820 </div>
821 {vuln.state === "open" && !vuln.fixedVersion && (
822 <div className="mt-2 rounded-md border border-warn/30 bg-warn/5 px-3 py-2 text-xs">
823 <p className="flex items-center gap-1.5 font-medium text-warn">
824 <ShieldAlert size={13} />
825 No patched version available
826 </p>
827 <p className="mt-1 text-muted">
828 No release fixes this yet. Dependencies are checked again daily
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.829 {updatesWait
830 ? ". A fix is applied once the repository is taken over or moved to g1t."
831 : upkeep
832 ? ", and g1t opens a pull request when a fix is published."
833 : "; turn on security updates and g1t opens a pull request when a fix is published."}
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily834 </p>
835 <div className="mt-2 flex flex-wrap items-center gap-2">
836 <a href={osv} target="_blank" rel="noreferrer" className="inline-flex items-center gap-1 text-fg-soft hover:text-fg hover:underline">
837 Read the advisory
838 <ExternalLink size={10} />
839 </a>
840 {canDismiss && dismiss("tolerable_risk", "Dismiss as tolerable risk")}
841 </div>
842 </div>
843 )}
844 <ActivityLog entries={alertActivity(vuln, activity)} base={base} open={focused && vuln.state !== "open"} />
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API845 </li>
846 );
847}
848
849export function ScanSummary({
850 scan,
851}: {
852 scan: { history: string; commitsScanned: number; historyFinishedAt: string | null; dependenciesScannedAt: string | null; dependenciesError: string | null; lockfiles: string[] };
853}) {
854 const history =
855 scan.history === "done" ? (
856 <>
857 History scanned: {scan.commitsScanned.toLocaleString()} commits
858 {scan.historyFinishedAt && (
859 <>
860 , <TimeAgo at={scan.historyFinishedAt} />
861 </>
862 )}
863 </>
864 ) : scan.history === "stopped" ? (
865 "History scan paused: the workspace reached its spending limit"
866 ) : scan.history === "running" ? (
867 `Scanning history: ${scan.commitsScanned.toLocaleString()} commits so far`
868 ) : (
869 "History scan queued"
870 );
871 return (
872 <div className="flex flex-wrap gap-x-5 gap-y-1 text-xs text-muted">
873 <span className="inline-flex items-center gap-1.5">
874 <KeyRound size={12} />
875 {history}
876 </span>
877 <span className="inline-flex items-center gap-1.5">
878 <Package size={12} />
879 {scan.dependenciesScannedAt ? (
880 <>
881 Dependencies read <TimeAgo at={scan.dependenciesScannedAt} />
882 {scan.lockfiles.length > 0 ? <> from {scan.lockfiles.join(", ")}</> : " (no lockfiles found)"}
883 </>
884 ) : (
885 "Dependencies not read yet"
886 )}
887 </span>
888 {scan.dependenciesError && (
889 <span className="inline-flex items-center gap-1.5 text-warn">
890 <ShieldAlert size={12} />
891 {scan.dependenciesError}
892 </span>
Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily893 )}
894 </div>
895 );
896}

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