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' | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import { | |
| 5 | type Merged, | |
| Merge branch 'main' into actions-toolkit-oidc-artifacts | 6 | placePushes, |
| Merge branch 'worktree-agent-ab9543c492a7ed481' into spend-guardrails | 7 | 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 | ||
| 28 | const HOUR = 3_600_000; | |
| 29 | const DAY = 24 * HOUR; | |
| 30 | // Monday 2026-10-05, 18:00 UTC. | |
| 31 | const NOW = Date.parse("2026-10-05T18:00:00Z"); | |
| 32 | const repo = { namespace: "acme", name: "web" }; | |
| 33 | ||
| 34 | test("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 | ||
| 42 | test("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. | 49 | test("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. | 68 | test("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 | ||
| 74 | test("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. | 85 | const 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) | 94 | test("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 | ||
| 104 | test("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-guardrails | 122 | test("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. | 138 | test("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 | ||
| 155 | test("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. | 161 | test("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 | ||
| 180 | test("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 | ||
| 190 | test("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 | ||
| 199 | test("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 | ||
| 207 | test("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 | ||
| 219 | test("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. | 233 | test("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 audit | 239 | |
| 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. | 240 | test("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 audit | 242 | 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-artifacts | 244 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.