Skip to content
244 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1import 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,
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail8 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,
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail14 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,
Mission control counts people's direct pushes to the default branch23 pushedCommits,
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail24 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");
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail40});
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);
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail46 }
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", () => {
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail50 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");
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail72});
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"));
A file named test.js or spec.rb counts as a test: confidence no longer says tests not added when they were81 assert.ok(isTestFile("test.js"));
82 assert.ok(isTestFile("lib/spec.rb"));
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail83});
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 => ({
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail86 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"]);
Mission control counts people's direct pushes to the default branch100 // 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" }]);
Mission control counts people's direct pushes to the default branch120});
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" }));
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail159});
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", () => {
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail162 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")],
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail164 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],
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail173 );
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);
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail188});
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]),
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail211 [
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);
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail222 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.");
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail238});
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.