coder/coder that groups changes into generated, tests, backend, frontend, and other, with checkboxes to show/hide each category.",
+ "css": true,
+ "screenshot": null
+ },
{
"id": "collapsible-content-button",
"description": "Adds a button in the text editor to insert collapsible content (via <details>).",
diff --git a/build/__snapshots__/imported-features.json b/build/__snapshots__/imported-features.json
index 469e6f68990f..3246f961d7c5 100644
--- a/build/__snapshots__/imported-features.json
+++ b/build/__snapshots__/imported-features.json
@@ -22,6 +22,7 @@
"close-out-of-view-modals",
"closing-remarks",
"cmd-enter",
+ "coder-pr-loc-stats",
"collapsible-content-button",
"comments-time-machine-links",
"confirm-release",
diff --git a/build/features.test.ts b/build/features.test.ts
index 63d89a0c3b90..bf391d3f174f 100755
--- a/build/features.test.ts
+++ b/build/features.test.ts
@@ -31,6 +31,7 @@ const noScreenshotExceptions = new Set([
'monospace-textareas',
'new-tab-links',
'extensible-nav', // No visual or behavior change
+ 'coder-pr-loc-stats', // Fork-only feature, no upstream screenshot
'hide-navigation-hover-highlight', // TODO: Add side-by-side GIF
'hide-inactive-deployments', // TODO: side-by-side PNG
diff --git a/readme.md b/readme.md
index 20e478d37181..a7a999ba50e6 100644
--- a/readme.md
+++ b/readme.md
@@ -231,6 +231,7 @@ https://github.com/refined-github/refined-github/wiki/Contributing#metadata-guid
- [](# "cross-deleted-pr-branches") [Adds a line-through to the deleted branches in PRs.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/256963526-646ac7d0-3e7f-40c6-ba39-014b49bc0063.png)
- [](# "batch-mark-files-as-viewed") [Mark/unmark multiple files as “Viewed” in the PR Files tab. Click on the first checkbox you want to mark/unmark and then `shift`-click another one; all the files between the two checkboxes will be marked/unmarked as “Viewed”.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/257009611-17249bee-d2e2-42ac-bdf0-ebc90029544e.gif)
- [](# "closing-remarks") 🔥 [Shows the first Git tag a merged PR was included in or suggests creating a release if not yet released.](https://user-images.githubusercontent.com/1402241/169497171-85d4a97f-413a-41b4-84ba-885dca2b51cf.png)
+- [](# "coder-pr-loc-stats") Adds a LOC stats panel to the PR Files tab on `coder/coder` that groups changes into generated, tests, backend, frontend, and other, with checkboxes to show/hide each category.
- [](# "pr-jump-to-first-non-viewed-file") [Jumps to first non-viewed file in a PR when clicking on the progress bar.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/257011208-764f509d-fed9-424b-84e9-c01cf2fd428b.gif)
- [](# "view-last-pr-deployment") [Adds a link to open the latest deployment to the PR header.](https://github.com/user-attachments/assets/90d2498d-ef65-45b9-96eb-07e7988bea61)
- [](# "no-unnecessary-split-diff-view") [Always uses unified diffs on files where split diffs aren’t useful.](https://user-images.githubusercontent.com/46634000/121495005-89af8600-c9d9-11eb-822d-77e0b987e3b1.png)
diff --git a/source/features/coder-pr-loc-stats.css b/source/features/coder-pr-loc-stats.css
new file mode 100644
index 000000000000..14c1b2b13fb9
--- /dev/null
+++ b/source/features/coder-pr-loc-stats.css
@@ -0,0 +1,52 @@
+.rgh-coder-loc-stats {
+ position: fixed;
+ inset-block-end: 16px;
+ inset-inline-end: 16px;
+ z-index: 30;
+ max-width: 320px;
+ padding: 8px 12px;
+ font-size: 12px;
+ background: var(--bgColor-default, fuchsia);
+ border: 1px solid var(--borderColor-default, fuchsia);
+ border-radius: 6px;
+ box-shadow: var(--shadow-floating-small, var(--color-shadow-medium));
+}
+
+.rgh-coder-loc-stats summary {
+ cursor: pointer;
+ user-select: none;
+}
+
+.rgh-coder-loc-stats table {
+ margin-top: 8px;
+ border-spacing: 0;
+}
+
+.rgh-coder-loc-stats th {
+ font-weight: var(--base-text-weight-semibold, 600);
+ text-align: start;
+ color: var(--fgColor-muted, fuchsia);
+}
+
+.rgh-coder-loc-stats th,
+.rgh-coder-loc-stats td {
+ padding: 2px 0;
+ padding-inline-end: 12px;
+ white-space: nowrap;
+}
+
+.rgh-coder-loc-stats td:last-child,
+.rgh-coder-loc-stats th:last-child {
+ padding-inline-end: 0;
+}
+
+.rgh-coder-loc-stats label {
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ cursor: pointer;
+}
+
+.rgh-coder-loc-count {
+ color: var(--fgColor-muted, fuchsia);
+}
diff --git a/source/features/coder-pr-loc-stats.tsx b/source/features/coder-pr-loc-stats.tsx
new file mode 100644
index 000000000000..366793ac6514
--- /dev/null
+++ b/source/features/coder-pr-loc-stats.tsx
@@ -0,0 +1,209 @@
+import './coder-pr-loc-stats.css';
+import {onAbort} from 'abort-utils';
+import React from 'dom-chef';
+import * as pageDetect from 'github-url-detection';
+
+import features from '../feature-manager.js';
+import api from '../github-helpers/api.js';
+import {getConversationNumber, getRepo} from '../github-helpers/index.js';
+import {
+ categorizeCoderFile,
+ coderFileCategories,
+ type CoderFileCategory,
+ type GitattributesRule,
+ parseGitattributes,
+} from '../helpers/coder-pr-file-categories.js';
+
+type PrFile = {
+ filename: string;
+ previous_filename?: string;
+ additions: number;
+ deletions: number;
+};
+
+type CategoryStats = {
+ files: number;
+ additions: number;
+ deletions: number;
+ diffIds: string[];
+};
+
+const categoryLabels: Record| Show | +Files | +Added | +Deleted | +
|---|