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 'main' into worktree-agent-a69aeabc4b0deeb97 | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import type { G1tEvent } from "@g1t/contracts"; | |
| 5 | ||
| The Branches page does things to branches now. It has tabs (Overview, Yours, Active, Stale, All, kept in the address as ?tab=) and search; Overview shows the default branch, then the first five of your branches, the active ones and the stale ones, each linking to the rest. Each branch is a row with its name in a code chip with a copy button, who made its latest commit and when, that commit's checks, behind and ahead counts with bars drawn against the largest shown, and its pull request (the open one, else the newest merged or closed) with its state; on a phone the columns fold under the name. Yours is branches whose latest commit is the viewer's; stale is no commit in 90 days. | 6 | import { aboutBranch, activityLine, alignWeeks, count, languageBar, licenseLabel, peak } from "./about.ts"; |
| Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97 | 7 | |
| 8 | test("a license is named by its SPDX id, or not at all", () => { | |
| 9 | assert.equal(licenseLabel({ spdxId: "MIT", name: "MIT License", path: "LICENSE" }), "MIT license"); | |
| 10 | assert.equal(licenseLabel({ spdxId: null, name: "Other", path: "COPYING" }), "View license"); | |
| 11 | }); | |
| 12 | ||
| 13 | test("counts read as words", () => { | |
| 14 | assert.equal(count(1, "star"), "1 star"); | |
| 15 | assert.equal(count(0, "star"), "0 stars"); | |
| 16 | assert.equal(count(1234, "star"), "1.2k stars"); | |
| 17 | assert.equal(count(2000, "star"), "2k stars"); | |
| 18 | assert.equal(count(15_400, "star"), "15k stars"); | |
| 19 | assert.equal(count(3, "watching", "watching"), "3 watching"); | |
| 20 | }); | |
| 21 | ||
| The repository sidebar reads like it should. TSX counts as TypeScript, as JSX already counted as JavaScript, so one language is not split in two (stats version 3, so every repository is read again); the languages list every one down to a tenth of a percent, the largest eight, rather than folding MDX, CSS and Shell into Other; up to five contributors are listed by name, each with their commits and card, more as avatars; and with no release published, Releases says how many tags there are, linked to them. | 22 | test("every language down to a tenth of a percent is listed, at most eight; the rest are Other", () => { |
| Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97 | 23 | const rust = { name: "Rust", color: "#dea584", bytes: 900, percent: 90 }; |
| 24 | const shell = { name: "Shell", color: "#89e051", bytes: 95, percent: 9.5 }; | |
| The repository sidebar reads like it should. TSX counts as TypeScript, as JSX already counted as JavaScript, so one language is not split in two (stats version 3, so every repository is read again); the languages list every one down to a tenth of a percent, the largest eight, rather than folding MDX, CSS and Shell into Other; up to five contributors are listed by name, each with their commits and card, more as avatars; and with no release published, Releases says how many tags there are, linked to them. | 25 | const nix = { name: "Nix", color: "#7e7eff", bytes: 5, percent: 0.05 }; |
| 26 | const css = { name: "CSS", color: "#663399", bytes: 3, percent: 0.3 }; | |
| 27 | assert.deepEqual(languageBar([rust, css, shell]).map((l) => l.name), ["Rust", "Shell", "CSS"], "sorted, and a 0.3% language is shown"); | |
| 28 | const many = Array.from({ length: 10 }, (_, i) => ({ name: `L${i}`, color: null, bytes: 10 - i, percent: 10 - i })); | |
| 29 | const capped = languageBar(many); | |
| 30 | assert.equal(capped.length, 9); | |
| 31 | assert.equal(capped[8]!.name, "Other"); | |
| 32 | assert.equal(capped[8]!.percent, 3); | |
| Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97 | 33 | assert.deepEqual(languageBar([rust, shell]), [rust, shell]); |
| 34 | const bar = languageBar([rust, shell, nix]); | |
| 35 | assert.equal(bar.length, 3); | |
| 36 | assert.equal(bar[2].name, "Other"); | |
| The repository sidebar reads like it should. TSX counts as TypeScript, as JSX already counted as JavaScript, so one language is not split in two (stats version 3, so every repository is read again); the languages list every one down to a tenth of a percent, the largest eight, rather than folding MDX, CSS and Shell into Other; up to five contributors are listed by name, each with their commits and card, more as avatars; and with no release published, Releases says how many tags there are, linked to them. | 37 | assert.equal(bar[2].percent, 0.1); |
| Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97 | 38 | assert.deepEqual(languageBar([rust, { ...nix, percent: 0 }]), [rust], "nothing to show for nothing"); |
| 39 | assert.deepEqual(languageBar([]), []); | |
| 40 | }); | |
| 41 | ||
| 42 | test("weeks line up with the repository's", () => { | |
| 43 | const all = [ | |
| 44 | { week: "2026-09-21", commits: 2 }, | |
| 45 | { week: "2026-09-28", commits: 0 }, | |
| 46 | { week: "2026-10-05", commits: 5 }, | |
| 47 | ]; | |
| 48 | assert.deepEqual(alignWeeks(all, [{ week: "2026-10-05", commits: 3 }]), [0, 0, 3]); | |
| 49 | assert.equal(peak(all), 5); | |
| 50 | assert.equal(peak([]), 1); | |
| 51 | }); | |
| 52 | ||
| 53 | function event(type: string, data: Record<string, unknown>): G1tEvent { | |
| 54 | return { id: "evt_1", type, source: "repos", time: "2026-10-07T10:00:00Z", repoId: "rep_1", actor: "usr_1", data } as unknown as G1tEvent; | |
| 55 | } | |
| 56 | ||
| 57 | test("pushes, tags, merges and renames are activity", () => { | |
| 58 | assert.deepEqual(activityLine(event("git.push", { ref: "refs/heads/main", before: "a", after: "b", defaultBranch: true })), { | |
| 59 | kind: "push", | |
| 60 | branch: "main", | |
| 61 | commit: "b", | |
| 62 | before: "a", | |
| 63 | created: false, | |
| 64 | defaultBranch: true, | |
| 65 | }); | |
| 66 | assert.equal((activityLine(event("git.push", { ref: "refs/heads/feat", after: "b", defaultBranch: false })) as { created: boolean }).created, true); | |
| 67 | assert.deepEqual(activityLine(event("git.push", { ref: "refs/tags/v1.0.0", after: "c", defaultBranch: false })), { kind: "tag", tag: "v1.0.0", commit: "c" }); | |
| 68 | assert.equal(activityLine(event("git.push", { ref: "refs/pull/1/head", after: "c", defaultBranch: false })), null); | |
| 69 | assert.deepEqual(activityLine(event("pull.merged", { number: 7, commit: "d" })), { kind: "merge", number: 7, commit: "d" }); | |
| 70 | assert.deepEqual(activityLine(event("branch.renamed", { from: "master", to: "main" })), { kind: "renamed", from: "master", to: "main" }); | |
| 71 | assert.equal(activityLine(event("repo.default_branch_changed", { from: "master", to: "main", renamed: true })), null); | |
| 72 | assert.equal(activityLine(event("issue.opened", { number: 1 })), null); | |
| 73 | }); | |
| The Branches page does things to branches now. It has tabs (Overview, Yours, Active, Stale, All, kept in the address as ?tab=) and search; Overview shows the default branch, then the first five of your branches, the active ones and the stale ones, each linking to the rest. Each branch is a row with its name in a code chip with a copy button, who made its latest commit and when, that commit's checks, behind and ahead counts with bars drawn against the largest shown, and its pull request (the open one, else the newest merged or closed) with its state; on a phone the columns fold under the name. Yours is branches whose latest commit is the viewer's; stale is no commit in 90 days. | 74 | |
| 75 | test("a deleted branch is activity with the commit that restores it; a deleted tag is not", () => { | |
| 76 | assert.deepEqual(activityLine(event("git.deleted", { ref: "refs/heads/feature/x", before: "abc" })), { kind: "deleted", branch: "feature/x", commit: "abc" }); | |
| 77 | assert.equal(activityLine(event("git.deleted", { ref: "refs/tags/v1", before: "abc" })), null); | |
| 78 | }); | |
| 79 | ||
| 80 | test("activity is about a branch when it pushed, deleted, renamed or merged into it", () => { | |
| 81 | const push = { kind: "push", branch: "feat", commit: "b", before: "a", created: false, defaultBranch: false } as const; | |
| 82 | assert.equal(aboutBranch(push, "feat", "main"), true); | |
| 83 | assert.equal(aboutBranch(push, "main", "main"), false); | |
| 84 | assert.equal(aboutBranch({ kind: "deleted", branch: "feat", commit: "b" }, "feat", "main"), true); | |
| 85 | assert.equal(aboutBranch({ kind: "renamed", from: "old", to: "feat" }, "old", "main"), true); | |
| 86 | assert.equal(aboutBranch({ kind: "merge", number: 1, commit: "c" }, "main", "main"), true); | |
| 87 | assert.equal(aboutBranch({ kind: "merge", number: 1, commit: "c" }, "feat", "main"), false); | |
| 88 | assert.equal(aboutBranch({ kind: "tag", tag: "v1", commit: "c" }, "feat", "main"), false); | |
| 89 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.