gh-reloaded

GH Reloaded

Website · License · Contributing

License: MIT Manifest V3 Chrome Web Store version PRs Welcome

A Chrome extension that injects small, focused UI enhancements into github.com, aimed at making GitHub itself more pleasant to use.

It’s a collection of independent features, not a single-purpose tool: each one lives in its own folder under features/ and can be added, removed, or shipped on its own. GitHub covers the fundamentals well; this is for the gaps that are easier to fill from the outside than to wait on.

Install

Install GH Reloaded from the Chrome Web Store, then open Settings: click the extension’s toolbar icon, or from chrome://extensions → the extension’s card → Details → Extension options.

Most features work on public repositories without a token. A token adds private repositories, Projects v2 data and higher rate limits.

Create a GitHub token

Pick one of two supported token types: A (recommended) for most setups, B when your Projects are owned by a personal account.

Go to github.com/settings/personal-access-tokens/new and set:

Scope Permission Used for
Repository Issues sub-issues, dependencies, org-level custom fields (Team / Business Value / Effort), My Issues, confirming a Quick assignment (read-only), Notification reason tags (mentions)
Repository Pull requests (and Commit statuses or Checks for the checks rollup) PR triage, Linked PR status, Notification reason tags (review requests and mentions)
Repository Contents HTML preview and Image gallery of files in private repos (public repos work without a token)
Repository Metadata added by GitHub automatically
Organization Projects Projects v2 Status, Standup mode, My Issues project memberships

Click Generate token and copy it immediately — GitHub shows it exactly once.

Already have a token? Notification reason tags needs no new permission, but a token limited to selected repositories shows Unverifiable on inbox rows from other repositories. Open the tag’s panel: it names the permission (Pull requests: Read or Issues: Read) and links to Settings → GitHub tokens, where Verify access with one of those repositories shows whether the token can read it.

Two GitHub limitations to know about:

If the organization requires approval for fine-grained tokens, the token you create may show as pending until an organization owner approves it, and requests to that organization’s data can come back empty or 404 until then, since GitHub doesn’t otherwise reveal that the resource exists. If the organization has disabled fine-grained personal access tokens altogether, it does not appear in the Resource owner list and you cannot create a token for it: ask an organization owner to allow fine-grained tokens, or use a classic token.

B. Classic token (Projects owned by a personal account)

Use this when the Projects you want to read belong to your personal account, which fine-grained tokens cannot read. Go to github.com/settings/tokens/new?scopes=read:project,public_repo&description=GH%20Reloaded and tick:

The extension only reads, but a leaked classic token could do more than a fine-grained one, so prefer A whenever it covers your setup, and leave repo off unless you need private data. One classic token covers every owner you can reach, so you do not need one per owner.

If an organization enforces SSO, open github.com/settings/tokens and use Configure SSO next to the token to authorize it for that organization; otherwise GitHub answers with empty results or 404.

Connect it

Back in the extension’s Settings page, under GitHub tokens: paste the token (github_pat_… or ghp_…) into Default token, Save tokens, then Test — it should report the GitHub username the token authenticates as.

Verify access. Test only proves the token authenticates. Verify access, next to it on every token card, opens a panel where you name a repository (required) and optionally an issue, a Projects v2 URL and a private file, then Run checks sends at most five read-only requests (authentication, the repository’s issues, the repository’s pull requests, and the optional project and file) with that card’s own token (an unsaved token is used as typed and labelled). Each capability is reported as Available, Access denied (only when GitHub’s answer proves it: an invalid token, SSO not authorized, a missing permission or an organization policy), Not verified (a 403 or 404 that could have several causes, so no permission is blamed), Not checked (nothing to test) or Temporary error (rate limit, network, timeout). Nothing runs on page load, and results are never stored or shown with the token. A Projects URL under /users/<login>/projects/<n> is owned by a personal account: a fine-grained token cannot read it, so any result other than Available points to a classic token with the read:project scope. See the screenshots for light and dark.

Working across several repository owners — organizations or personal accounts — that need their own token? Add owner token for each, with that owner’s login (e.g. acme; a pasted https://github.com/acme works too). A request always uses the token of the repository’s owner, falling back to the default token — never by trying every saved token in turn; with no default set, owners without a token of their own are read anonymously. Saved tokens are never shown again in full, only by their last 4 characters.

Install unpacked (development and manual testing)

To run the code from this repository instead of the Store version:

  1. Clone this repo.
  2. Open chrome://extensions, enable Developer mode (top-right toggle).
  3. Click Load unpacked → select the repo folder.
  4. Open Settings as above and connect a token.

Features

Screenshots below are mockups illustrating each feature’s layout and colors (matched to the extension’s actual dark-theme CSS) — not literal captures of a live GitHub page.

Dependency graph — features/dependency-graph

On a GitHub issue page (or a Projects board’s issue-preview side panel) that has sub-issues, injects a left-to-right dependency graph below the sub-issues list.

Dependency graph mockup: a left-to-right graph of sub-issue cards below a "Sub-issues" heading, with the longest chain highlighted in orange as the critical path and dimmed dashed cards for dependencies outside the sub-issue set, and a header with alignment/external dropdowns plus refresh and full-screen buttons

Quick-create button — features/quick-create

A small floating button (or stack of buttons) on a GitHub Projects board view, each linking straight to “new issue” for a repo you configure in Settings — handy when the repo you actually file work into isn’t the one the board itself lives in. Fully user-defined (label, URL, color, and an optional “only on this board” project match); nothing is preset.

Quick-create button mockup: a project's top bar with two colored "+ New Bug" and "+ New Request" buttons inserted between the native Insights/Workflows icons and the project details button

Board dependency arrows — features/board-dependencies

On a GitHub Projects Board (kanban) view, draws an arrow directly between any two currently-visible cards where one blocks the other — red if the blocker is behind the card it blocks, gray otherwise — no need to open either issue to see the dependency. Arrows run in the gutters beside the cards and pass behind the cards they cross instead of through their text, a link between two closed (or merged) items is not drawn, and hovering or focusing a card highlights its arrows and fades the rest. Off by default; an icon button in the filter row, just left of GitHub’s View button (shown only while a Board view is selected), turns it on, and the choice is remembered (also switchable from Settings).

Board dependency arrows mockup: a four-column kanban board with a red arrow from a Backlog card to an In Review card (blocker behind) and a gray arrow from a Done card to an In Progress card (blocker resolved)

Full-width board — features/full-width-board

On a GitHub Projects Board (kanban) view, uses the full window width and makes every column flexible: columns grow into spare space, then shrink as needed (down to 150px each) so more of the board stays visible before horizontal scrolling is necessary. Boards with too many columns to fit at that minimum still scroll. On narrow windows column titles stay on one line with a tooltip (the count badge gives way first), cards keep their content inside the border, swimlane headers end with the last column, and the board lines up with the filter bar. On by default; switchable from Settings.

Full-width board mockup: a kanban board using spare window space when available and shrinking columns when space is tight, delaying horizontal scrolling until the 150px-per-column minimum is reached

Standup mode — features/standup-mode

On a GitHub Projects Board (kanban) view, adds a Standup button to the filter row, left of the dependency-arrows button and GitHub’s View button, that turns the board into a compact presentation of the whole board. It reclaims the space GitHub’s chrome uses (a slim bar is the only header: GitHub’s title row, the view tabs, the filter bar and the View and other editing controls are hidden, the active filter is shown in the bar as read-only text, each column header shrinks to one row with a single metric pill, the columns fit the window width, and on a board grouped by a field the lane bands stay pinned right under the compact column headers instead of floating over the cards) and points at what needs attention, with a one-line summary at the top (for example “2 stale in review · 1 orphan block”) whose entries jump to the cards:

The stale threshold and the review-like keywords are set in Settings → Advanced → Standup mode. The signals read Projects v2 data through the GitHub API, so they need a token with the read access listed under Install; without one (or without Projects access) the board still gets the space reclaim, a priority chip and a “Blocked” label read from the card, and the API-backed badges are simply absent. The bar says which of these happened: only a refusal from GitHub (HTTP 401/403, or a “Resource not accessible” error) is reported as a token that may lack Projects access; any other failure shows “Board signals could not be loaded” with the detail in the tooltip and the browser console, and a board that is still rendering shows the loading note. When GitHub returns an error for only some of the cards (an archived or inaccessible repository, say), the rest of the board still gets its signals and the bar says some cards could not be read. Draft items have no issue to look up, so they only get those card-read signals and count toward the column shares. The signals are re-read about every 75 seconds while the tab is visible, so edits made in place show up; if some cards cannot be read (for example a token without access to one owner, or a project whose fields that token cannot see), or some dependencies cannot be verified, the bar says so and the bottleneck and critical-path signals (or just the critical path, for dependencies) are turned off rather than computed from partial data. When a project and an issue belong to different owners, each is read with its own owner’s token. On a board that uses Group by, columns are positioned by their heading across all horizontal sections. Exit with the Exit button or Esc. It’s read-only and local to the tab — it never mutates issues, Project fields, or card order, and doesn’t survive a reload. On by default; switchable from Settings.

Standup mode mockup: a kanban board under a slim bar with summary chips for stale reviews, orphan blocks, critical path at risk and bottlenecks, with flagged cards tinted and carrying badges and an outlined bottleneck column

HTML preview — features/html-preview — Experimental

Renders .html/.htm files instead of leaving them as plain source.

HTML preview mockup: a blob page's tab row with an injected "Preview" tab selected next to native Code and Blame tabs, and the rendered file content below — a heading, badges, and a small flow diagram

Fetches the file’s content through the GitHub API at the exact commit/branch shown (working out the right split itself even when a branch name contains a slash, e.g. feature/x), then renders it through two nested, sandboxed layers: an extension page with its own CSP, itself embedding a manifest-declared sandbox page whose separate, permissive-by-default CSP is where the previewed file’s HTML actually lands. That inner page can run scripts and load resources the way a normal webpage would (inline <script>, CDN’d libraries, fonts, images) while still having no access to your GitHub session, cookies, or any extension API — that isolation, not CSP strictness, is what keeps it safe. Works without a token for public repos; a token with Contents: Read-only is needed for private ones. On by default.

Marked experimental: it renders arbitrary third-party HTML/JS, and the inline Preview tab anchors on GitHub’s own (undocumented, redesign-prone) blob-page markup to inject itself — expect it to need upkeep as GitHub’s UI changes.

My Issues by project — features/my-issues

On GitHub’s own My Issues dashboard (github.com/issues), adds a List | Group by project switch next to the native flat list. Switched on, it reorganizes the same issues as a responsive grid of Project tiles (one to three columns, a column being added only while every issue title keeps room to read), each listing its issues by that Project’s real Status — so work spread across several Projects is readable at a glance; switched off, GitHub’s own list is restored untouched. On by default (the switch appears, the native list stays selected until you pick the grouped view). Settings → Advanced lets you set a minimum and a maximum tile width (280–2000 px; the default minimum is 630 px, no maximum), with a Reset to defaults button.

My Issues by project mockup: the My Issues dashboard with a collapsed icon sidebar, a one-line toolbar (summary, Expand all / Collapse all, List / Group by project switch) and a grid of Project tiles, each with a Status distribution bar, a legend and Status groups with issue rows, plus an explicit "No Project" tile

PR triage — features/pr-triage

On a repository’s own Pull requests page (github.com/<owner>/<repo>/pulls), a compact My PR triage panel sits above the search box and groups the open PRs on the current page into Needs my action and Waiting on others. Each entry links to the PR and shows its number and the specific reason (“Review requested”, “Changes requested by sam”, “Waiting on author”). The header counts both groups, plus team requests and PRs that could not be read; five entries per group are shown, with Show more / Show fewer for the rest of the loaded rows. Collapse panel keeps the header and counts visible. The one-label-per-row context stays in the native list below. Search, filters, sorting, pagination, order and actions are untouched. On by default; Hide triage on the page, or the switch in Settings → Features, removes panel and labels through the existing saved preference. Collapse and expanded groups are temporary: they survive filter and page changes in the same repository and reset in another repository or after a reload.

PR triage: two compact groups, Needs my action and Waiting on others, above the search box and the unchanged native Pull requests list. Counts refer only to the current page; each entry links to its PR and gives the personal next-action reason.

Quick assignment (experimental) — features/quick-assign

On a repository issue page, and in the issue side panel of a Projects table or board (user and organization Projects), under GitHub’s own Assignees list, Assign me adds you without removing anyone, or Unassign me removes only you; each assignee row also gets a small ✕ (Remove @user from assignees) at its right end, visible on hover and keyboard focus, while the name and avatar still open the profile. The native gear picker stays as it is. Off by default: switch it on in Settings → Features (it is marked Experimental); switching it off removes everything it added.

Quick assignment: Assign me / Unassign me under the native Assignees list, a ✕ per assignee row, and the Saving, confirmed and failure states.

Linked PR status — features/linked-pr-status

On a Projects Board view, an issue card with at least one pull request explicitly linked to it (the issue’s Development links, whether added by hand or by a closing keyword) gets a one-line muted band at the bottom of the card, under its fields and a thin divider, inside the card’s outline, that starts with the label Linked PRs: (PRs: on narrow cards) followed by PR #317 and one text signal. The signal is the first that applies of Changes requested, Checks failed, Review pending, Checks pending, Approved; draft, merged and closed PRs are neutral, and a PR whose data cannot be read says Status unavailable, never green. Several linked PRs show the count on the left (2 linked PRs, 2 PRs on narrow cards) and, on the right, an attention chip when some need it (1 needs attention); PRs whose status cannot be read are counted too, in a neutral chip with a ? (1 status unavailable, 1 unavailable on narrow cards). A caption at the end of the same line says why (Review feedback blocks progress, Checks are failing); it is cut with an ellipsis when the card is narrow, with the full text in its tooltip and in the modal. When the token can list the links but not read a PR’s status, the card says so, a dismissible hint names the missing permission (Pull requests: Read, plus Commit statuses or Checks) and links to Settings, and the modal repeats it. Click, Enter or Space on the row opens a modal (Esc closes it) with an attention banner (a status summary, not a merge verdict), the issue title in its subtitle and one section per PR: checks and review as separate pills, the names of the failing checks, a plain next step and an Open PR button. Cards without a linked PR, PR items and draft items are untouched. On by default; the switch is in Settings → Features.

Linked PR status: a Projects board with a status row on cards that have linked pull requests, and the details dialog for two PRs, fictional repository acme/web.

GitHub Status — features/github-status

A small status badge on the corner of the GitHub logo on every github.com page, like a presence dot on an avatar, ringed in the header’s own colour: green when githubstatus.com reports no incident, amber for a minor incident or a maintenance in progress, red for a major or critical one (the dot follows the worst of the page indicator, the open incidents and the components, so it is never calmer than the pill), and a gray dot when the status is unknown or older than 15 minutes. Click it (or press Enter or Space) for a panel with the overall status, only the affected components, the open incidents with their latest update, “Checked N min ago”, the attribution “GitHub Status · via GH Reloaded” and a link to githubstatus.com. When an open incident concerns the page you are on (an Actions incident on Actions pages, a Pull Requests one on pull requests, and so on) or has wide impact, a pill with the component and its state appears in the header bar, before the search box, spaced from it by the header’s own 8px gap; ✕ dismisses it until that incident gets a new update, and the panel still lists it. Other incidents only tint the dot. “No incident reported” is never a guarantee that everything works. On by default; the switch is in Settings → Features and Show incident notice in Settings → Advanced → GitHub Status.

GitHub Status: an amber badge on the logo's corner, an incident pill in the header on an Actions page, and the details panel opened from the dot, fictional repository acme/web.

Notifications settings panel — features/notifications

A Triage ▾ button on the inbox at github.com/notifications, right after GitHub’s own Group by control and styled like it (it joins the filter row from 1012px wide and becomes a full-width row below, as GitHub’s own controls do). It opens a compact panel anchored to the button (Esc, a click outside or the button close it) with Show native inbox, one switch each for Triage, Tags and “Why is this here?”, a choice of one Triage layout as three equal cards with a thumbnail and a one-line description (Integrated navigation, in the sidebar, by default; Quick bar; Grouped sections), which stack as rows below 440px wide, a note on missing data or token access while the engine runs, and Restore defaults. Show native inbox pauses every GH Reloaded enrichment at once without touching the saved switches or layout. Modules that are not available in this version, and the layout until Triage is, are shown disabled with the reason, never as selectable. The button is shown on every inbox route whenever the Group by control is found, even when no module runs, so the native inbox is always one click away. On lists without Group by (Saved, Done, Read, reason-filtered) it goes after Sort by instead; if neither control is found nothing is inserted until the next scan.

The Triage button after Group by on the inbox and its settings panel with Show native inbox, the module switches, the three layouts and Restore defaults, fictional data.

Notifications triage view — features/notifications

On the inbox at github.com/notifications, the loaded notifications are sorted into four categories: Needs attention, Waiting, Informational and Unverifiable (the same classification as the engine, never “Needs attention” without evidence). The category counts are shown in the layout you pick in the Triage ▾ panel, one at a time, and GitHub’s native inbox stays one click away. On by default.

The Triage view in its three layouts: Integrated navigation in GitHub's sidebar, the Quick bar and Grouped sections, with the narrow, empty and loading states, fictional data.

On the inbox (github.com/notifications), every row gets a small tag on its own line under the title, starting at the title text’s left edge (past the row’s status icon), that says why it is there: Direct review request, Team review request, Re-review requested, Mention, Subscribed, CI or Unverifiable. Each tag has a color, a text, an icon and an accessible label, and the order of the rows is never changed. Other native reasons (commented, assigned, author, state change…) get no tag.

Notification reason tags: inbox rows with a tag under each title and the "Why is this here?" panel open on a team review request, fictional repositories.

More features will land as their own entries here, each in its own folder under features/ (and background/ for anything they need server-side). See Contributing for the shape a new one takes.

On a repository image file page (PNG, JPEG, WebP, GIF, and SVG in its Preview view), browse the other images of the same folder in a lightbox, without going back to the folder listing.

Image gallery mockup: a file header with a neutral Gallery button before the download button, and the lightbox over it showing 2 of 5 with previous and next, a hint and Open file on GitHub, fictional repository acme/web.

Needs no new permission: public repositories work without a token, and a private repository uses the token already documented for HTML preview (Contents: Read-only, or repo for a classic token).

Known limitations

Troubleshooting

Project layout

manifest.json                       MV3 manifest — wires content scripts and the background service worker
background.js                       Service worker entry point: opens Settings, routes messages to feature modules
lib/github-api.js                   Shared GitHub REST/GraphQL client (auth, caching) used by every feature
background/<feature>.js             One feature's server-side logic (GitHub calls, computation) + its MESSAGE_TYPE
features/<feature>/                 One feature's content-script side: DOM injection, rendering, styling
options/                             Settings page (feature toggles, GitHub tokens, quick-create shortcuts, advanced tuning)
icons/                               Toolbar/extensions-page icons

Releasing

Versioning and releases are automated with Release Please, driven by .github/workflows/release.yml. Regular pull requests never touch manifest.json’s "version"; a bot owns the version number, which is a release decision rather than something each change picks.

The flow:

  1. PR titles are Conventional Commits (feat:, fix:, docs:, …), enforced on every PR by .github/workflows/pr-title.yml. PRs are squash-merged with the commit messages as the body (a single-commit PR takes its commit subject as the title, so keep it equal to the PR title), so each PR becomes one conventional commit on main.
  2. On each push to main, Release Please reads those commits and keeps a single release PR open that bumps manifest.json and .release-please-manifest.json and updates CHANGELOG.md. A feat bumps the minor version, a fix or perf the patch version, and a breaking change (!) the major version, or the minor while below 1.0. Other types (refactor, test, docs, ci, chore, build, style, revert) make no release on their own. See Picking the PR type.
  3. Merging that release PR creates the vX.Y.Z tag and the GitHub Release, then the publish job packages the extension, uploads it to the Chrome Web Store (if the store secrets below are configured), and attaches gh-reloaded-<version>.zip to the release.

The zip bundles manifest.json, background.js, background/, features/, icons/, lib/, and options/ — the same explicit path list as before, so the test harness and docs/ do not ship.

Requesting a milestone version

To jump to a specific version (for example the first stable 1.0.0), end the last commit message of a pull request with a Release-As: 1.0.0 footer and keep that line when squash-merging. Release Please reads footers only from the last block of the message, and GitHub appends --------- and Co-authored-by: lines after the commit messages: delete them in the merge dialog so Release-As: 1.0.0 is the last line. Release Please then rewrites its open release PR to that version. The footer only counts for the commits since the last release, so nothing has to be removed afterwards and normal SemVer resumes. Never fake a feat!: to force a major version. The human release announcement for a milestone lives in docs/releases/, ready to paste above the generated notes; CHANGELOG.md stays generated. The checks made on the 1.0.0 candidate and what stayed open are recorded in docs/releases/1.0.0-verification.md.

Repository settings (one-time, admin)

Release Please needs two repo settings that a workflow file can’t set itself:

The release PR is opened by github-actions[bot] with the built-in GITHUB_TOKEN. By GitHub’s design, PRs and tags created with that token don’t trigger other workflows, so CI doesn’t run on the release PR; that’s fine while no checks are required on main. If required checks are added later, switch Release Please to a repository-owned GitHub App token (see the issue’s “Later ideas”).

One-time store setup

The API can only update an existing Chrome Web Store listing — the first submission has to happen by hand:

  1. Pay the one-time $5 registration fee and create a Chrome Web Store Developer Dashboard account.
  2. Package the extension (zip -r extension.zip manifest.json background.js background features icons lib options), upload it as a new item, fill in the store listing (description, screenshots, privacy practices, single purpose, permission justifications), and submit it for review.
  3. Once it’s accepted, note the Extension ID (from the dashboard item URL) and your Publisher ID (Dashboard → account settings → Publisher (developer) account).
  4. In Google Cloud Console, create an OAuth client (APIs & Services → Credentials → OAuth client ID; the refresh-token helper redirects to a random local port, so a “Web application” client needs that http://127.0.0.1:<port> redirect URI added first, while a “Desktop app” client accepts it as is) and enable the Chrome Web Store API on that project.
  5. Generate a refresh token for that client, authorized for the https://www.googleapis.com/auth/chromewebstore scope against your Web Store account — e.g. via chrome-webstore-upload-cli’s docs, or any OAuth 2.0 installed-app flow.
  6. Create an environment named chrome-web-store (repo Settings → Environments), restrict its deployment branches to main, and add these as environment secrets — not repository secrets, so that a workflow run from any other branch cannot read them:

    Secret Value
    CHROME_EXTENSION_ID Extension ID from step 3
    CHROME_PUBLISHER_ID Publisher ID from step 3
    CHROME_CLIENT_ID OAuth client ID from step 4
    CHROME_CLIENT_SECRET OAuth client secret from step 4
    CHROME_REFRESH_TOKEN Refresh token from step 5

The refresh token expires after 7 days while the Google OAuth app is in “Testing” status: publish the app (Google Auth Platform → Audience → Publish app) so it does not. To recover a failed publish, run the Release workflow manually with the tag to publish (e.g. v0.7.0).

Until all five secrets are set, the workflow still cuts a GitHub Release on every version bump; it just skips the store upload step (with a warning in the run log) rather than failing the run.

Google’s own review queue still sits on top of this either way — a workflow run “publishing” a release means it was submitted, not that it’s instantly live on the store.

Contributing

Start with CONTRIBUTING.md. The full conventions — the shape of a feature, the design rules, how docs stay in sync, the definition of done, and the git/PR workflow — live in AGENTS.md, which both people and coding assistants read. Issues and PRs welcome.

Privacy

See PRIVACY.md — short version: nothing is collected, sold, or sent anywhere except directly to api.github.com with your own token.

License

MIT