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

Merge branch 'worktree-agent-a1b995daa94e4e1b7'1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import {
5 type Merged,
Merge branch 'main' into actions-toolkit-oidc-artifacts6 placePushes,
Merge branch 'worktree-agent-ab9543c492a7ed481' into spend-guardrails7 historyCovers,
Merge branch 'worktree-agent-a1b995daa94e4e1b7'8 change,
9 checksFact,
10 dayKey,
11 isTestFile,
12 landedToday,
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.13 mergedAutomatically,
Merge branch 'worktree-agent-a1b995daa94e4e1b7'14 parseSort,
15 parseTab,
16 pullFacts,
17 reachesBack,
18 reasonFor,
19 signedPercent,
20 sortRows,
21 summaryLine,
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)22 pushedByPerson,
Merge branch 'worktree-agent-a1b995daa94e4e1b7'23 pushedCommits,
24 weekOf,
25 whyFor,
26} from "./mission-control.ts";
27
28const HOUR = 3_600_000;
29const DAY = 24 * HOUR;
30// Monday 2026-10-05, 18:00 UTC.
31const NOW = Date.parse("2026-10-05T18:00:00Z");
32const repo = { namespace: "acme", name: "web" };
33
34test("each kind of need gets its reason chip", () => {
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.35 assert.equal(reasonFor({ kind: "deploy" }), "blocking");
36 assert.equal(reasonFor({ kind: "review" }), "needs_review");
37 assert.equal(reasonFor({ kind: "invitation" }), "invited");
38 assert.equal(reasonFor({ kind: "checks" }), "checks_failing");
39 assert.equal(reasonFor({ kind: "runner" }), "stalled");
Merge branch 'worktree-agent-a1b995daa94e4e1b7'40});
41
42test("why a need needs a person is said for every reason", () => {
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.43 for (const kind of ["deploy", "invitation", "review", "stuck", "checks", "ready", "conflict", "stalled", "runner"] as const) {
44 const need = { kind };
45 assert.ok(whyFor(reasonFor(need), need).length > 15, kind);
Merge branch 'worktree-agent-a1b995daa94e4e1b7'46 }
47});
48
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.49test("what is known lists only what is known", () => {
Merge branch 'worktree-agent-a1b995daa94e4e1b7'50 const facts = pullFacts({
51 checkStatus: "failed",
52 files: [
53 { path: "src/retry.ts", additions: 40, deletions: 2 },
54 { path: "src/retry.test.ts", additions: 60, deletions: 0 },
55 ],
56 });
57 const by = Object.fromEntries(facts.map((f) => [f.label, f]));
58 assert.equal(by["Required checks"].value, "Failed in the merge queue");
59 assert.equal(by["Required checks"].tone, "bad");
60 assert.equal(by["Files changed"].value, "2");
61 assert.equal(by.Lines.value, "+100 −2");
62 assert.equal(by.Tests.value, "1 file");
63
64 const bare = pullFacts({ checkStatus: null, files: [] });
65 assert.deepEqual(bare, [{ label: "Required checks", value: "Not known yet", tone: null }]);
66});
67
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.68test("the required checks are read from the pull request's check status", () => {
69 assert.deepEqual(checksFact("running"), { label: "Required checks", value: "Running", tone: null });
70 assert.equal(checksFact("passed").tone, "good");
71 assert.equal(checksFact("failed").value, "Failed in the merge queue");
Merge branch 'worktree-agent-a1b995daa94e4e1b7'72});
73
74test("test files are recognised by the names test runners use", () => {
75 assert.ok(isTestFile("src/a.test.ts"));
76 assert.ok(isTestFile("src/__tests__/a.ts"));
77 assert.ok(isTestFile("tests/api.rs"));
78 assert.ok(isTestFile("pkg/store_test.go"));
79 assert.ok(!isTestFile("src/testing-utils.ts"));
80 assert.ok(!isTestFile("src/contest.ts"));
81 assert.ok(isTestFile("test.js"));
82 assert.ok(isTestFile("lib/spec.rb"));
83});
84
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.85const merged = (daysAgo: number, mergedBy: string | null, number = 1): Merged => ({
Merge branch 'worktree-agent-a1b995daa94e4e1b7'86 repo,
87 number,
88 title: `Change ${number}`,
89 mergedBy,
90 mergedAt: new Date(NOW - daysAgo * DAY).toISOString(),
91 files: [],
92});
93
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)94test("a push to the default branch counts a person's own commits, not merges or g1t's", () => {
95 const c = (hash: string, email: string, parents = 1) => ({ hash, author: { name: "g1t", email }, parents: Array(parents).fill("p") });
96 // Every commit is named "g1t": the name decides nothing, the address does.
97 const history = [c("e", "chase@example.com"), c("d", "agent@g1t.sh"), c("m", "chase@example.com", 2), c("b", "chase@example.com"), c("a", "chase@example.com")];
98 const byG1t = (commit: { author: { email: string } }) => commit.author.email === "agent@g1t.sh";
99 assert.deepEqual(pushedCommits(history, "a", byG1t).map((x) => x.hash), ["e", "b"]);
Merge branch 'worktree-agent-a1b995daa94e4e1b7'100 // Where it pointed before was not read: everything read counts.
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)101 assert.deepEqual(pushedCommits(history, "zz", byG1t).map((x) => x.hash), ["e", "b", "a"]);
102});
103
104test("who pushed is the account that signed in, not the name on the commits", () => {
105 assert.ok(pushedByPerson({ actor: "usr_chase", data: {} }));
106 assert.ok(pushedByPerson({ actor: null, data: {} }));
107 assert.ok(!pushedByPerson({ actor: "usr_g1t_agent", data: {} }));
108 assert.ok(!pushedByPerson({ actor: "g1t_policy", data: {} }));
109 // A workflow job's own token is not a person either.
110 assert.ok(!pushedByPerson({ actor: "usr_chase", data: { causedByJob: "run_1" } }));
111
112 const c = (hash: string, name: string) => ({ hash, parents: ["p"], author: { name, email: `${hash}@example.com` } });
113 // A person whose git name is "g1t" pushed m1; g1t pushed w1 under a person's name.
114 const history = [c("w1", "Chase Pierce"), c("m1", "g1t"), c("old", "Chase Pierce")];
115 const pushes = [
116 { time: "2026-10-07T12:00:00Z", actor: "usr_g1t_agent", data: { after: "w1", before: "m1" } },
117 { time: "2026-10-05T12:00:00Z", actor: "usr_chase", data: { after: "m1", before: "old" } },
118 ];
119 assert.deepEqual(placePushes(history, pushes), [{ hash: "m1", at: "2026-10-05T12:00:00Z" }]);
Merge branch 'worktree-agent-a1b995daa94e4e1b7'120});
121
Merge branch 'worktree-agent-ab9543c492a7ed481' into spend-guardrails122test("a short read of the branch is enough when it reaches the oldest push", () => {
123 const h = (...hashes: string[]) => hashes.map((hash) => ({ hash }));
124 const pushes = [
125 { time: "2026-10-07T12:00:00Z", data: { after: "c1", before: "c2" } },
126 { time: "2026-10-05T12:00:00Z", data: { after: "c2", before: "c3" } },
127 ];
128 // Holds the oldest push's before.
129 assert.ok(historyCovers(h("c1", "c2", "c3"), pushes, 3));
130 // Full, and the oldest push reaches past it: read further.
131 assert.ok(!historyCovers(h("c1", "c2", "x"), pushes, 3));
132 // Shorter than asked: the whole branch.
133 assert.ok(historyCovers(h("c1", "c2"), pushes, 3));
134 // The oldest push made the branch: only the whole branch will do.
135 assert.ok(!historyCovers(h("c1", "c2", "c3"), [{ time: "", data: { after: "c1" } }], 3));
136});
137
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.138test("each push to the default branch places the commits it brought, at its time, from one read of the history", () => {
139 const c = (hash: string, parents = ["p"], email = "chase@example.com") => ({ hash, parents, author: { name: "Chase Pierce", email } });
140 // Newest first: a Wednesday push of two, a Monday push of one, a merge, and g1t's own commit.
141 const history = [c("w2"), c("w1"), c("m1"), c("merge", ["a", "b"]), c("bot", ["p"], "g1t@users.noreply.g1t.sh"), c("old")];
142 const pushes = [
143 { time: "2026-10-07T12:00:00Z", actor: "usr_chase", data: { after: "w2", before: "m1" } },
144 { time: "2026-10-05T12:00:00Z", actor: "usr_chase", data: { after: "m1", before: "old" } },
145 { time: "2026-10-01T12:00:00Z", actor: "usr_chase", data: { after: "gone", before: "older" } },
146 ];
147 const byG1t = (commit: { author: { email: string } }) => commit.author.email.endsWith("@users.noreply.g1t.sh");
148 assert.deepEqual(placePushes(history, pushes, byG1t), [
149 { hash: "m1", at: "2026-10-05T12:00:00Z" },
150 { hash: "w2", at: "2026-10-07T12:00:00Z" },
151 { hash: "w1", at: "2026-10-07T12:00:00Z" },
152 ]);
153});
154
155test("a change merged automatically when g1t merged it", () => {
156 assert.ok(mergedAutomatically({ mergedBy: "g1t" }));
157 assert.ok(mergedAutomatically({ mergedBy: null }));
158 assert.ok(!mergedAutomatically({ mergedBy: "syntaqx" }));
Merge branch 'worktree-agent-a1b995daa94e4e1b7'159});
160
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.161test("the week is seven days of landed changes, with the week before", () => {
Merge branch 'worktree-agent-a1b995daa94e4e1b7'162 const week = weekOf(
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.163 [merged(0, "g1t"), merged(0, "syntaqx"), merged(0, "syntaqx", 2), merged(1, "g1t", 3), merged(1, "g1t"), merged(6, "g1t"), merged(8, "g1t"), merged(10, "alex"), merged(20, "g1t")],
Merge branch 'worktree-agent-a1b995daa94e4e1b7'164 NOW,
165 "UTC",
166 );
167 assert.equal(week.days.length, 7);
168 assert.equal(week.days[6].key, "2026-10-05");
169 assert.equal(week.days[6].label, "Mon");
170 assert.deepEqual(
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.171 week.days.map((d) => d.count),
172 [1, 0, 0, 0, 0, 2, 3],
Merge branch 'worktree-agent-a1b995daa94e4e1b7'173 );
174 assert.equal(week.total, 6);
175 assert.equal(week.previous, 2);
176 // Not knowing the week before is not the same as nothing in it.
177 assert.equal(weekOf([merged(0, "g1t")], NOW, "UTC", false).previous, null);
178});
179
180test("days follow the viewer's time zone", () => {
181 // 02:00 UTC on the 5th is still the 4th in Los Angeles.
182 const late = Date.parse("2026-10-05T02:00:00Z");
183 assert.equal(dayKey(late, "America/Los_Angeles"), "2026-10-04");
184 assert.equal(dayKey(late, "UTC"), "2026-10-05");
185 assert.equal(dayKey(late, "Not/AZone"), "2026-10-05");
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.186 const week = weekOf([{ mergedAt: new Date(late).toISOString() }], NOW, "America/Los_Angeles");
187 assert.equal(week.days.find((d) => d.key === "2026-10-04")?.count, 1);
Merge branch 'worktree-agent-a1b995daa94e4e1b7'188});
189
190test("the change from last week, and how it reads", () => {
191 assert.equal(change(12, 10), 0.2);
192 assert.equal(change(5, 0), null);
193 assert.equal(change(5, null), null);
194 assert.equal(signedPercent(0.2), "+20%");
195 assert.equal(signedPercent(-0.054), "−5%");
196 assert.equal(signedPercent(0.001), "0%");
197});
198
199test("a repository's merged list reaches back when it is not full or its oldest is old enough", () => {
200 const since = NOW - 14 * DAY;
201 const at = (days: number) => ({ mergedAt: new Date(NOW - days * DAY).toISOString(), updatedAt: new Date(NOW).toISOString() });
202 assert.ok(reachesBack([at(1), at(2)], since, 100));
203 assert.ok(reachesBack([at(1), at(20)], since, 2));
204 assert.ok(!reachesBack([at(1), at(3)], since, 2));
205});
206
207test("landed today is the viewer's calendar day, newest first", () => {
208 const rows = landedToday([merged(0.1, "g1t", 3), merged(0.5, "syntaqx", 4), merged(1, "g1t", 2)], NOW, "UTC");
209 assert.deepEqual(
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.210 rows.map((r) => [r.ref, r.automatic]),
Merge branch 'worktree-agent-a1b995daa94e4e1b7'211 [
212 ["#3", true],
213 ["#4", false],
214 ],
215 );
216 assert.equal(rows[1].by?.name, "syntaqx");
217});
218
219test("tabs and sorting come from the address", () => {
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.220 assert.equal(parseTab("landed"), "landed");
221 assert.equal(parseTab("waiting"), null);
Merge branch 'worktree-agent-a1b995daa94e4e1b7'222 assert.equal(parseTab("nope"), null);
223 assert.equal(parseSort("newest"), "newest");
224 assert.equal(parseSort(null), "impact");
225 const rows = [{ at: 1 }, { at: 3 }, { at: 2 }];
226 assert.deepEqual(sortRows(rows, "impact"), rows);
227 assert.deepEqual(
228 sortRows(rows, "newest").map((r) => r.at),
229 [3, 2, 1],
230 );
231});
232
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.233test("the summary says the week plainly", () => {
234 assert.equal(summaryLine({ total: 47, needs: 0 }), "47 changes landed in the last 7 days.");
235 assert.equal(summaryLine({ total: 1, needs: 2 }), "1 change landed in the last 7 days.");
236 assert.equal(summaryLine({ total: 0, needs: 2 }), "Nothing has landed this week. What is waiting on you is below.");
237 assert.equal(summaryLine({ total: 0, needs: 0 }), "Nothing has landed this week yet.");
Merge branch 'worktree-agent-a1b995daa94e4e1b7'238});
Usage, Billing settings and prepaid AI credit; fixes from the UX audit239
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.240test("a job waiting for a self-hosted runner says so", () => {
241 const runner = { kind: "runner" as const };
Usage, Billing settings and prepaid AI credit; fixes from the UX audit242 assert.equal(reasonFor(runner), "stalled");
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.243 assert.match(whyFor(reasonFor(runner), runner), /self-hosted runner/);
Merge branch 'main' into actions-toolkit-oidc-artifacts244});

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