Version: 1.1.0 | Type: Chrome/Edge Browser Extension (Manifest V3)
PRitty brings Azure DevOps-style pull request experience to GitHub — quick actions, reversed timelines, and streamlined navigation.
Activates on: https://github.com/*/pull/* (PR features) and https://github.com/*/* (repo features)
| # | Feature | Code Location | Docs |
|---|---|---|---|
| 0 | Branches Nav Button | src/modules/Repo/branches-nav-button.js |
Inline below |
| 1 | Action Buttons Bar | src/modules/PR/action-buttons-bar/ |
action-buttons-bar.md |
| 2 | Scroll to Top | src/modules/PR/scroll-top.js, styles/base.css |
scroll-to-top.md |
| 3 | Conversation Tab Changes | src/modules/PR/Conversation/timeline-reorder.js, styles/base.css |
conversation-tab.md |
| 4 | Commits Tab Changes | styles/base.css |
Inline below |
| 5 | Files Changed Tab Changes | styles/base.css |
Inline below |
| 6 | File Tree Enhancements | src/modules/PR/File Changes/ |
file-tree-enhancements.md |
| 7 | Diff Navigation | src/modules/PR/File Changes/diff-nav-buttons.js, styles/base.css |
Inline below |
| 8 | Split Diff Resizer | src/modules/PR/File Changes/split-diff-resizer.js, styles/base.css |
split-diff-resizer.md |
| 9 | Azure Checks Re-Run | src/modules/PR/checks-rerun.js, styles/buttons.css |
Inline below |
| 10 | Comment Shortcut | src/modules/PR/comment-shortcut.js |
comment-shortcut.md |
| — | Core Infrastructure | src/core/, src/modules/PR/action-buttons-bar/github-state.js, src/content.js |
core-infrastructure.md |
Injects a "Branches" tab into GitHub's repository-level nav bar (Code / Issues / Pull requests / Actions / …), positioned immediately after the "Code" tab. Activates on all repo pages (github.com/*/*).
- Navigates to
/{owner}/{repo}/branches - Highlights with
aria-current="page"when on the branches page or any sub-path - Persists through GitHub's SPA (Turbo) navigation via MutationObserver
Implementation: Clones the "Code" <li> element rather than building from scratch — inherits all of GitHub's CSS classes automatically, so the tab always looks correct even after class renames.
Code: src/modules/Repo/branches-nav-button.js
Selector used: PRitty.Selectors.REPO_NAV (nav[aria-label="Repository"])
Self-bootstraps — has its own content_scripts entry in manifest.json; not orchestrated by content.js.
A floating bar fixed to the top-right corner of the page containing two buttons:
- PR Actions (green) — context-aware dropdown with merge, publish, or convert-to-draft actions depending on PR state
- Submit Review (blue) — navigates to Files Changed tab and opens the native review dialog
Code: src/modules/PR/action-buttons-bar/ (dedicated folder)
pr-actions-button.js— PR Actions dropdown button + context-aware actionsreview-button.js— Submit Review button + tab switching logicheader-actions.js— assembles both buttons into the floating bar container
Styling: styles/buttons.css, styles/base.css (.pritty-actions container)
Detailed docs: action-buttons-bar.md
A circular floating button fixed to the bottom-right corner. Clicking it smooth-scrolls the page to the top. Starts at 60% opacity, fully visible on hover.
Code: src/modules/PR/scroll-top.js, styles/base.css
Detailed docs: scroll-to-top.md
Multiple enhancements to the PR conversation tab:
- Timeline reordering — newest comments appear first (CSS
column-reversehandles reversal; JS only moves PR description to top) - Hidden noise elements — labels_updated, projects_updated, milestone_updated timeline badges are hidden
- Comment box cleanup — GitHub's suggestion/guideline boxes below the comment input are hidden
- Merge actions repositioning — merge area and comment box get
margin-left: -56pxadjustment - Reviewer name magnification — reviewer names displayed at
1.25remfont size
Code: src/modules/PR/Conversation/timeline-reorder.js, styles/base.css (Conversation Tab section)
Detailed docs: conversation-tab.md
Reverses the commit list to show newest commits first using pure CSS. Located in styles/base.css under the Commits Tab section comment.
/* Reverse commit date groups and individual commit lists */
[data-testid="commits-list"] > div {
flex-direction: column-reverse;
ul {
display: flex;
flex-direction: column-reverse;
li {
border-bottom: var(--borderWidth-thin) solid var(--borderColor-muted);
}
}
}DOM structure targeted:
[data-testid="commits-list"]
└── div ← reversed (commit date groups)
└── ul ← reversed (individual commits)
├── li (newest) ← now appears first
└── li (oldest) ← now appears last
No JS involved — pure CSS flex-direction: column-reverse survives SPA navigation automatically.
Reverses the "Select commits to view" dropdown in the Files Changed tab so newest commits appear first. Located in styles/base.css under the Files Changes Tab section comment.
/* Primary selector — semantic aria-label */
ul[aria-label="Select a range of commits"] {
display: flex;
flex-direction: column-reverse;
}
/* Fallback — GitHub's internal class (in case label changes) */
ul.prc-ActionList-GroupList-V5B3- {
display: flex;
flex-direction: column-reverse;
}Two selectors for resilience: aria-label is stable and semantic, the class-based one acts as fallback.
No JS involved — pure CSS.
See also: File Tree Enhancements for JS-based enhancements to the file tree sidebar.
Two JS-based enhancements for the file tree sidebar in the Files Changed tab:
- Viewed checkboxes — each file and folder in the tree gets a checkbox that syncs bidirectionally with GitHub's native "Viewed" buttons
- Enhanced file click — clicking a file auto-expands collapsed diffs and reveals full file content
Code: src/modules/PR/File Changes/file-tree-enhancements.js, styles/base.css
Detailed docs: file-tree-enhancements.md
Two buttons (previous/next) injected into GitHub's native Pull Request Files Toolbar (sticky header on the Files Changed tab). They navigate between change hunks — groups of consecutive added/deleted lines in the diff view.
Injection point: Start of the toolbar's right-side controls div (2nd child of the toolbar <section>).
Navigation logic:
- Collects all
code.diff-text.additionandcode.diff-text.deletionelements - Groups consecutive changed
tr.diff-line-rowelements into "hunks" - Navigates to the first row of each hunk, with offset for the sticky toolbar
Code: src/modules/PR/File Changes/diff-nav-buttons.js, styles/base.css (Diff Navigation Buttons section)
Selectors used: PRitty.Selectors.PR_FILES_TOOLBAR, PRitty.Selectors.DIFF_CHANGED_LINE
A draggable vertical separator between the left (old code) and right (new code) panes in GitHub PR split view — matching the Azure DevOps experience.
- Drag the handle to resize both panes simultaneously across all diff tables
- Double-click resets to 50/50
- Ratio is preserved as you scroll; lazily-loaded tables are pre-resized at the current ratio
- Switching to unified view destroys handles and resets col widths; switching back re-injects them
Code: src/modules/PR/File Changes/split-diff-resizer.js, styles/base.css (Split Diff Resizer section)
Detailed docs: split-diff-resizer.md
Removes the "Start a review" button from inline diff comment forms and makes Ctrl+Enter post a direct comment immediately instead of queuing a review.
- "Start a review" is removed from the DOM on every MutationObserver tick (as GitHub re-renders inline forms dynamically).
- Ctrl+Enter is intercepted in capture phase; the extension clicks "Reply", "Add single comment", or "Comment" depending on the form context.
- Controlled by the
commentShortcuttoggle in the PRitty popup (toolbar icon).
Code: src/modules/PR/comment-shortcut.js
Settings: src/core/settings.js + popup/popup.html / popup/popup.js / popup/popup.css
Detailed docs: comment-shortcut.md
A re-run button (sync icon) injected into each Azure Pipelines check row in the expanded checks list. Hovering a row reveals the button; clicking it auto-posts /azp run <pipeline_name> as a PR comment.
- Detection: A check row is treated as Azure if its
<h4>contains an<a>whosehrefincludesvisualstudio.comordev.azure.com - Pipeline name: Taken from the
<span>text inside that anchor (e.g.,"Crew (App Stores) - CI") - Button placement: Injected as
afterbeginof[class*="ActionBar-module__container"]— before the existing kebab menu button - Comment posting: Fills and submits GitHub's native comment textarea. If on a non-Conversation tab, switches there first, then posts
- Re-injection safety: Button presence (
.pritty-rerun-btn) is the de-duplication guard — these buttons do NOT carrydata-pritty-injectedto avoid conflicting withinject()'s cleanup cycle
Code: src/modules/PR/checks-rerun.js, styles/buttons.css
Shared modules that all features depend on. Full details in core-infrastructure.md.
| Module | File | Purpose |
|---|---|---|
| Namespace | src/core/namespace.js |
Creates window.PRitty global + PRitty.Selectors (GitHub DOM selectors) |
| Settings | src/core/settings.js |
Loads feature toggles from chrome.storage.sync; provides synchronous get() after load() |
| Icons | src/core/icons.js |
SVG icon strings (merge, review, check, x, pending, chevronUp, chevronDown) |
| Utils | src/core/utils.js |
DOM helpers: waitForElement, findTab, findButtonByText, findButtonByPrefix, isPRittyElement |
| GitHub State | src/modules/PR/action-buttons-bar/github-state.js |
Reads live PR state: getChecksInfo(), getPRState(), getCurrentTab() |
| Entry Point | src/content.js |
Bootstraps everything, handles SPA re-injection via MutationObserver |
manifest.json ← Extension config, load order, URL matching
├── src/
│ ├── core/
│ │ ├── namespace.js ← Global PRitty namespace + DOM selectors
│ │ ├── settings.js ← Feature toggles (chrome.storage.sync)
│ │ ├── icons.js ← SVG icon library
│ │ └── utils.js ← Shared DOM helpers
│ ├── modules/
│ │ ├── Repo/ ← Repository-level modules
│ │ │ └── branches-nav-button.js ← Branches tab in repo nav (Feature 0)
│ │ └── PR/ ← All PR-page modules
│ │ ├── Conversation/ ← Conversation-tab features
│ │ │ └── timeline-reorder.js ← JS timeline reversal (Feature 3)
│ │ ├── File Changes/ ← Files-Changed-tab features
│ │ │ ├── diff-nav-buttons.js ← Diff hunk navigation buttons (Feature 7)
│ │ │ ├── file-tree-enhancements.js ← Viewed checkboxes + enhanced file click (Feature 6)
│ │ │ └── split-diff-resizer.js ← Draggable split view separator (Feature 8)
│ │ ├── action-buttons-bar/ ← Floating action bar (Feature 1)
│ │ │ ├── github-state.js ← Reads live PR state (PR Actions + Submit Review)
│ │ │ ├── pr-actions-button.js ← PR Actions dropdown
│ │ │ ├── review-button.js ← Submit Review button
│ │ │ └── header-actions.js ← Assembles the floating bar
│ │ ├── checks-rerun.js ← Azure pipeline re-run button (Feature 9)
│ │ ├── comment-shortcut.js ← Remove "Start a review" + Ctrl+Enter (Feature 10)
│ │ └── scroll-top.js ← Scroll-to-top button (Feature 2)
│ └── content.js ← Entry point, lifecycle manager
├── popup/
│ ├── popup.html ← Extension settings popup
│ ├── popup.js ← Toggle read/write via chrome.storage.sync
│ └── popup.css ← Popup styling
├── styles/
│ ├── base.css ← Layout + Conversation/Commits/Files tab CSS (Features 2-5)
│ └── buttons.css ← Button & dropdown styling (Feature 1)
└── icons/ ← Extension icons (16/48/128px)
Repo pages (github.com/*/*) — first content_scripts entry:
namespace.js→Repo/branches-nav-button.js
PR pages (github.com/*/pull/*) — second content_scripts entry (both entries run; namespace.js is idempotent):
namespace.js→settings.js→icons.js→utils.js(core)PR/action-buttons-bar/github-state.js(state reader)PR/checks-rerun.js→PR/comment-shortcut.js→PR/action-buttons-bar/pr-actions-button.js→PR/action-buttons-bar/review-button.js(action bar modules)PR/Conversation/timeline-reorder.js→PR/scroll-top.js→PR/File Changes/diff-nav-buttons.js→PR/File Changes/split-diff-resizer.js→PR/File Changes/file-tree-enhancements.js(PR modules)PR/action-buttons-bar/header-actions.js(feature assembly)content.js(bootstrap)
CSS (base.css, buttons.css) is injected before any JS runs.
Page loads on github.com/*/pull/*
↓
content.js init() verifies URL matches /pull/\d+/
↓
PRitty.Settings.load() → awaits chrome.storage.sync
↓
inject() → cleans old PRitty elements → appends floating action bar
↓
ScrollTop.create() → appends scroll button
↓
CommentShortcut.init() + removeStartReviewButtons() [if enabled]
↓
MutationObserver watches document.body
├── SPA navigation detected → re-runs inject()
├── Discussion container reset → re-applies TimelineReorder
└── removeStartReviewButtons() on each tick [if enabled]
| File | Covers |
|---|---|
styles/base.css |
Floating bar layout, scroll button, conversation tab CSS, commits tab CSS, files changed tab CSS |
styles/buttons.css |
PR Actions button, Submit Review button, dropdown menu, disabled states |
Z-index layers: 999 (action bar) > 100 (dropdown) > 99 (scroll button)