Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
81da786
Show review progress from GitHub's Viewed toggles
hyanmandian Oct 2, 2026
1a26606
Read GitHub's embedded data, navigate files and conversations, refres…
hyanmandian Oct 2, 2026
504f949
Make filters toggles and tidy the breakdown
hyanmandian Oct 2, 2026
9fb96ca
Show the review time tooltip above its icon, with an arrow
hyanmandian Oct 2, 2026
264b0ee
Merge the breakdown's files and viewed columns
hyanmandian Oct 2, 2026
dde6052
Tighten navigation controls and centre the breakdown
hyanmandian Oct 2, 2026
2aaf81d
Use the shared count badge for conversations
hyanmandian Oct 2, 2026
4b3a33c
Step through conversations from a popover
hyanmandian Oct 2, 2026
383d913
Show conversations as a carousel and glow the one you land on
hyanmandian Oct 2, 2026
45e2251
Show the current conversation with its reply state
hyanmandian Oct 2, 2026
f0ff16c
Compact conversation card, sturdier GitHub selectors and review fixes
hyanmandian Oct 2, 2026
2648ff6
Count only real diffs in the classic view and pluralise partial-count…
hyanmandian Oct 2, 2026
eea4a5c
Release through release-please and check pull request titles
hyanmandian Oct 2, 2026
1d86afc
Size the conversation card to its file name
hyanmandian Oct 2, 2026
cc249ad
Remove Next unviewed
hyanmandian Oct 2, 2026
b9395f5
Give long file names more room in the conversation card
hyanmandian Oct 2, 2026
cdde4ad
Add a one-page site and deploy it to GitHub Pages
hyanmandian Oct 2, 2026
19208e6
Use neutral shadows on the site logo
hyanmandian Oct 2, 2026
381ca14
Open collapsed conversations when jumping to them
hyanmandian Oct 2, 2026
690c993
Ship Chromium, Firefox and Safari builds with every release and expla…
hyanmandian Oct 2, 2026
69d9b9e
Show the manual install steps as browser tabs, opening on the visitor…
hyanmandian Oct 2, 2026
5aa0dac
Keep the conversation card one width and put the position over its ar…
hyanmandian Oct 2, 2026
d08c41f
Open newer-view conversations through GitHub's comment links and show…
hyanmandian Oct 2, 2026
3d1e55f
Point readers to the release notes after a minor or major update
hyanmandian Oct 2, 2026
9bbaf27
Link the project from the settings page and add community health files
hyanmandian Oct 2, 2026
5d5ac03
Split the panel into one module and stylesheet per part
hyanmandian Oct 2, 2026
1cb0fe8
Give each component its own folder
hyanmandian Oct 2, 2026
5e09305
Name component files after their component, merge the GitHub data rea…
hyanmandian Oct 2, 2026
74a038b
Keep only entry points in entrypoints, move the content script's logi…
hyanmandian Oct 2, 2026
7bd85d9
Keep only global styles in assets; buttons and the toast become compo…
hyanmandian Oct 2, 2026
7f9bfd8
Give the code of conduct a reporting address
hyanmandian Oct 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @hyanmandian
75 changes: 75 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Bug report
description: Something in Focus Diff doesn't work as described.
labels: [bug]
body:
- type: markdown
attributes:
value: Thanks for taking the time. Please leave out anything private, like code from a private repository.
- type: textarea
id: what
attributes:
label: What happened?
description: What you saw, and what you expected instead.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
placeholder: |
1. Open a pull request's Files changed tab
2. Pick the "Frontend" filter
3. …
validations:
required: true
- type: input
id: pull-request
attributes:
label: Pull request link
description: A public pull request where it happens, if there is one.
placeholder: https://github.com/owner/repo/pull/123
- type: dropdown
id: view
attributes:
label: GitHub diff view
description: GitHub has two. The newer one shows a "Changes" tab with a file tree on the left.
options:
- Classic (Files changed)
- Newer (Changes)
- Not sure
validations:
required: true
- type: dropdown
id: browser
attributes:
label: Browser
options:
- Chrome
- Edge
- Brave
- Arc
- Another Chromium browser
- Firefox
- Safari
validations:
required: true
- type: input
id: version
attributes:
label: Focus Diff version
description: It's at the bottom of the Focus Diff settings page.
placeholder: '1.0.0'
validations:
required: true
- type: textarea
id: extra
attributes:
label: Screenshots or anything else
description: Errors from the browser console help too.
- type: checkboxes
id: searched
attributes:
label: Before you send it
options:
- label: I searched the existing issues and this isn't one of them.
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Report a security issue
url: https://github.com/hyanmandian/focus-diff/security/advisories/new
about: Please report vulnerabilities privately, not in a public issue.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Idea
description: Suggest something that would make reviewing easier.
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: What's slowing your review down?
description: The situation and the problem, before any solution.
validations:
required: true
- type: textarea
id: idea
attributes:
label: What would help?
description: How you picture it working.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: What do you do today?
description: Workarounds, other tools, or ideas you've ruled out.
21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: monthly
groups:
dev-dependencies:
dependency-type: development
commit-message:
prefix: chore
include: scope
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
groups:
actions:
patterns: ['*']
commit-message:
prefix: ci
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- The title becomes the changelog entry, so write it as a Conventional Commit: `feat: …`, `fix: …`, `docs: …`. -->

## What and why

<!-- What changes for the reader, and what problem it solves. Link the issue: "Closes #123". -->

## How it was tested

<!-- Screenshots or a short recording for anything visible on GitHub or the settings pages. -->

- [ ] `npm run check`, `npm test` and `npm run e2e` pass
- [ ] Tried on a real pull request (say which view: classic or newer)
- [ ] New text is in both `en.json` and `pt_BR.json`
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- run: npx playwright install --with-deps chromium
- run: npm run e2e
- run: npm run lint:firefox
- run: npm run zip && npm run zip:firefox
- run: npm run zip && npm run zip:firefox && npm run zip:safari
- uses: actions/upload-artifact@v4
with:
name: extension
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Pull request title

# Release notes and version bumps come from squash-merged pull request titles, so they follow Conventional Commits.
on:
pull_request:
types: [opened, edited, synchronize, reopened]

permissions:
pull-requests: read

jobs:
conventional:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ github.token }}
44 changes: 30 additions & 14 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
name: Release

# Every merge to main updates a release pull request with the next version and its changelog, worked out from the
# conventional pull request titles. Merging that pull request tags the release, attaches the builds and publishes them.
on:
push:
tags: ['v*']
branches: [main]

permissions:
contents: write
pull-requests: write

jobs:
release:
release-please:
runs-on: ubuntu-latest
outputs:
created: ${{ steps.release.outputs.release_created }}
tag: ${{ steps.release.outputs.tag_name }}
steps:
- id: release
uses: googleapis/release-please-action@v4
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json

publish:
needs: release-please
if: needs.release-please.outputs.created == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -17,26 +34,25 @@ jobs:
node-version: 22
cache: npm
- run: npm ci

- name: Check the tag matches the package version
run: |
version=$(node -p "require('./package.json').version")
if [ "v$version" != "$GITHUB_REF_NAME" ]; then
echo "::error::Tag $GITHUB_REF_NAME doesn't match package.json version $version"
exit 1
fi

- run: npm run check
- run: npm test
- run: npx playwright install --with-deps chromium
- run: npm run e2e
- run: npm run lint:firefox
- run: npm run zip && npm run zip:firefox
- run: npm run zip && npm run zip:firefox && npm run zip:safari

- name: Create the GitHub release
# Fixed names, so the site can link to the latest release's files: one build for every Chromium browser
# (Chrome, Edge, Brave, Arc, Opera), one for Firefox and the browsers built on it, one for Safari.
- name: Attach the builds to the release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$GITHUB_REF_NAME" .output/*.zip --title "$GITHUB_REF_NAME" --generate-notes
run: |
mkdir release
cp .output/*-chrome.zip release/focus-diff-chromium.zip
cp .output/*-firefox.zip release/focus-diff-firefox.zip
cp .output/*-safari.zip release/focus-diff-safari.zip
cp .output/*-sources.zip release/focus-diff-sources.zip
gh release upload "${{ needs.release-please.outputs.tag }}" release/*.zip --clobber

- name: Publish to the stores
env:
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Site

on:
push:
branches: [main]
paths: ['site/**', '.github/workflows/site.yml']
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: site
- id: deployment
uses: actions/deploy-pages@v4
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "1.0.0"
}
5 changes: 5 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Code of conduct

Focus Diff follows the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). In short: be kind, assume good intent, and keep discussions about the work.

Report unacceptable behaviour to [contact@hyan.com.br](mailto:contact@hyan.com.br). Every report is reviewed and kept confidential.
47 changes: 47 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Contributing

Thanks for helping make reviews calmer. Bug reports, ideas and pull requests are all welcome; for anything bigger than a small fix, open an [issue](https://github.com/hyanmandian/focus-diff/issues/new/choose) first so we can agree on the approach.

By taking part, you agree to the [code of conduct](CODE_OF_CONDUCT.md).

## Development

Focus Diff is built with [WXT](https://wxt.dev) and TypeScript, and has no runtime dependencies.

```sh
npm install # also generates WXT's types
npm run dev # Chrome with the extension loaded and hot reload (dev:firefox for Firefox)
npm run check # types, Oxlint and Oxfmt
npm test # unit tests with Vitest
npm run e2e # builds, then runs Playwright against the real extension, with axe accessibility checks
npm run fmt # format everything
npm run zip # store zips in .output/ (zip:firefox also packs the sources for review)
```

```text
src/
entrypoints/ what the browser loads: background, the GitHub content script, options and welcome pages
content/ the content script's logic: reading the page, filtering it, moving between conversations
components/ the UI: functions that build elements and return how to update them. A component with
its own CSS gets a folder; panel/ lays the others out in a shadow root
assets/ global.css: the extension pages' colours, reset and type
utils/ filters, storage, the GitHub page adapter, formatting
locales/ English and Brazilian Portuguese messages
tests/
unit/ Vitest with WXT's fake browser
e2e/ Playwright, on a local copy of a pull request page
```

The end-to-end tests serve a saved pull request page in place of github.com, so they don't depend on the network.

## Releasing

Pull requests are squash-merged, and their titles follow [Conventional Commits](https://www.conventionalcommits.org) (`feat: …`, `fix: …`), which a check enforces. Every merge to `main` updates a release pull request with the next version and its changelog. Merging it tags the release, attaches the Chrome and Firefox builds, and publishes them to the stores when their credentials are set as repository secrets.

## Pull requests

- Keep each pull request to one change, and its title a [Conventional Commit](https://www.conventionalcommits.org): it becomes the changelog entry.
- Add or update tests: unit tests for logic, end-to-end tests for anything on the page.
- Put new text in both `src/locales/en.json` and `src/locales/pt_BR.json`.
- Prefer selectors GitHub is unlikely to change: roles, ARIA attributes, ids and `data-` attributes, not generated class names.
- Check the panel in GitHub's light and dark themes, and with the keyboard.
49 changes: 15 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ Large pull requests mix the code you need to read with tests, stories, generated
- **Your own filters.** Each filter is a button with an _Include_ regex and an optional _Exclude_ regex, tested against the full file path. **All** is always there.
- **Everywhere or per repository.** Keep filters for every pull request, and add extra ones for `owner/name` or a whole `owner/*`.
- **Real numbers.** Files changed and the line totals show only what the filter keeps, and update as GitHub loads more files.
- **Combine filters.** Shift-click to look at several filters at once, like _Frontend + Docs_.
- **See where the changes are.** The breakdown shows how much of the pull request falls under each filter before you start.
- **Review time.** A rough estimate next to the line totals, at about 400 changed lines per hour.
- **Combine filters.** Turn on as many as you like, like _Frontend + Docs_. Turn them all off and you're back on **All**.
- **See where the changes are.** The breakdown shows, per filter, how many files you've marked as viewed, the lines changed and the time left.
- **Review time left.** An estimate next to the line totals, from about 400 changed lines per hour, that drops as you mark files as viewed.
- **Conversations.** Step through review threads one by one. Each shows its file and line, and whether it's waiting on you, answered or resolved.
- **Keyboard friendly.** Arrow keys inside the bar, plus global shortcuts.
- **Made to share.** Copy your filters and send them to a teammate, who imports them in one step.
- **Feels like GitHub.** Follows your GitHub theme, checked against WCAG 2.1 AA, respects reduced motion, and speaks English and Portuguese.
Expand Down Expand Up @@ -54,37 +55,17 @@ On a Mac, <kbd>Alt</kbd> is <kbd>Option</kbd>. Change them at `chrome://extensio

## Install

Store listings are on the way. Until then, build it from source with `npm install` and:

- **Chrome or Edge:** run `npm run build`, open `chrome://extensions` (or `edge://extensions`), turn on **Developer mode**, click **Load unpacked** and pick `.output/chrome-mv3`.
- **Firefox:** run `npm run build:firefox`, open `about:debugging#/runtime/this-firefox`, click **Load Temporary Add-on** and pick `.output/firefox-mv3/manifest.json`.

## Development

Focus Diff is built with [WXT](https://wxt.dev) and TypeScript, and has no runtime dependencies.

```sh
npm install # also generates WXT's types
npm run dev # Chrome with the extension loaded and hot reload (dev:firefox for Firefox)
npm run check # types, Oxlint and Oxfmt
npm test # unit tests with Vitest
npm run e2e # builds, then runs Playwright against the real extension, with axe accessibility checks
npm run fmt # format everything
npm run zip # store zips in .output/ (zip:firefox also packs the sources for review)
```

```text
src/
entrypoints/ background, the GitHub content script, options and welcome pages
components/panel/ the floating bar, rendered in a shadow root
utils/ filters, storage, the GitHub page adapter, formatting
locales/ English and Brazilian Portuguese messages
tests/
unit/ Vitest with WXT's fake browser
e2e/ Playwright, on a local copy of a pull request page
```

The end-to-end tests serve a saved pull request page in place of github.com, so they don't depend on the network.
Store listings are on the way. Meanwhile, every [release](https://github.com/hyanmandian/focus-diff/releases/latest) has builds you can load yourself:

- **Chrome, Edge, Brave, Arc and other Chromium browsers:** unzip `focus-diff-chromium.zip`, open `chrome://extensions` (or `edge://extensions`), turn on **Developer mode**, click **Load unpacked** and pick the unzipped folder.
- **Firefox and browsers built on it:** open `about:debugging#/runtime/this-firefox`, click **Load Temporary Add-on** and pick `focus-diff-firefox.zip`. It stays until Firefox restarts.
- **Safari (Mac with Xcode):** unzip `focus-diff-safari.zip`, run `xcrun safari-web-extension-converter focus-diff-safari --app-name "Focus Diff" --macos-only` and click **Run** in Xcode. In Safari, turn on **Settings › Advanced › Show features for web developers**, then **Develop › Allow Unsigned Extensions**, and enable Focus Diff in **Settings › Extensions**.

To build from source instead, run `npm install` and `npm run build` (or `build:firefox`, `build:safari`); the builds land in `.output/`.

## Contributing

Bug reports, ideas and pull requests are welcome. [CONTRIBUTING.md](CONTRIBUTING.md) explains how to run it locally, test it and cut a release. Please report security issues [privately](SECURITY.md).

## License

Expand Down
Loading
Loading