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
124 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.

The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.1/** The audit log's entries, as the workspace's Audit log page shows them. */
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged2
3import { ShieldAlert, ShieldCheck } from "lucide-react";
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.4import { Link } from "react-router";
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged5
6import type { AuditEntry } from "@g1t/contracts";
7
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.8import { actionLabel, ruleLabel, targetLabel } from "../lib/audit";
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.9import { TimeAgo } from "./ui";
10import { Avatar } from "./ui/avatar";
11import { Card } from "./ui/card";
Merge branch 'worktree-agent-ae1299e92e4462012'12import { Hint } from "./ui/hint";
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.13import { UserAvatar } from "./user-card";
14import { PersonLink } from "./work";
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged15
16/** Allowed or denied, and by which rule. */
17export function OutcomeMark({ entry }: { entry: AuditEntry }) {
18 const denied = entry.outcome === "denied";
19 return (
Merge branch 'worktree-agent-ae1299e92e4462012'20 <Hint label={`${entry.outcome}: ${ruleLabel(entry.rule)} (${entry.rule})`}>
21 <span
22 className={`inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-0.5 text-xs ${
23 denied ? "bg-danger/10 text-danger ring-1 ring-danger/30" : "bg-raised text-muted ring-1 ring-line"
24 }`}
25 >
26 {denied ? <ShieldAlert size={11} /> : <ShieldCheck size={11} />}
27 {entry.outcome}
28 </span>
29 </Hint>
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged30 );
31}
32
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.33/**
34 * Who acted, with whoever acted for someone (an app, or an old agent) shown
35 * as working for them. A person wears their own avatar and opens their
36 * card; a workspace its square, never a person's face.
37 */
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged38export function ActorLine({ entry }: { entry: AuditEntry }) {
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.39 const person = entry.actorKind === "person" && !entry.agent;
40 const face = person ? (
41 <UserAvatar username={entry.actor} size={18} />
42 ) : (
43 <Avatar
44 name={entry.agent ?? entry.actor}
45 image={null}
46 size={18}
47 square={entry.actorKind === "workspace"}
48 system={entry.actorKind === "system"}
49 agent={entry.actorKind === "agent" || !!entry.agent}
50 />
51 );
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged52 return (
53 <span className="flex min-w-0 items-center gap-2">
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.54 {face}
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged55 <span className="truncate">
56 {entry.onBehalfOf ? (
57 <>
58 <span className="font-medium">{entry.agent ?? entry.actor}</span>
59 <span className="text-muted"> on behalf of </span>
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.60 <PersonLink name={entry.onBehalfOf} className="font-medium hover:text-accent" />
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged61 </>
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.62 ) : person ? (
63 <PersonLink name={entry.actor} className="font-medium hover:text-accent" />
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged64 ) : (
65 <span className="font-medium">{entry.actor}</span>
66 )}
67 </span>
68 </span>
69 );
70}
71
72/** The workspace's log, one row an entry, newest first. */
73export function AuditTable({ entries, base }: { entries: AuditEntry[]; base: string }) {
74 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.75 <Card asChild divided>
76 <ol>
77 {entries.map((entry) => (
78 <li key={entry.id} className="grid gap-x-4 gap-y-1 px-4 py-3 text-sm sm:grid-cols-[9rem_1fr_auto]">
79 <span className="text-xs leading-5 text-faint">
80 <TimeAgo at={entry.time} />
81 </span>
82 <div className="min-w-0">
83 <div className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1">
84 <ActorLine entry={entry} />
85 <span className="font-mono text-xs text-fg/85">{actionLabel(entry.action)}</span>
86 <span className="truncate font-mono text-xs text-muted">{targetLabel(entry)}</span>
87 </div>
88 <p className="mt-1 flex flex-wrap gap-x-3 text-xs text-faint">
89 <Hint label={entry.rule}>
90 <span>{ruleLabel(entry.rule)}</span>
91 </Hint>
92 <span>{entry.surface.toUpperCase()}</span>
93 {entry.result && entry.result !== "ok" && <span>result: {entry.result}</span>}
94 {entry.runId && (
95 <Link to={`${base}?run=${encodeURIComponent(entry.runId)}`} className="hover:text-fg">
96 everything this run did
97 </Link>
98 )}
99 {entry.credentialId && (
100 <Hint label="Credential">
101 <span className="font-mono">
102 <span className="sr-only">Credential </span>
103 {entry.credentialId}
104 </span>
105 </Hint>
106 )}
107 <Hint label="Request id">
Merge branch 'worktree-agent-ae1299e92e4462012'108 <span className="font-mono">
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.109 <span className="sr-only">Request id </span>
110 {entry.requestId}
Merge branch 'worktree-agent-ae1299e92e4462012'111 </span>
112 </Hint>
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.113 </p>
114 {entry.outcome === "denied" && entry.message && <p className="mt-1 text-xs text-danger">{entry.message}</p>}
115 </div>
116 <span className="sm:text-right">
117 <OutcomeMark entry={entry} />
118 </span>
119 </li>
120 ))}
121 </ol>
122 </Card>
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged123 );
124}

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