Rules and conventions for anyone (human or AI agent) changing DiffSanity. Read this before making changes.
What DiffSanity is: a Chrome/Edge MV3 extension. It adds a button to each file on a GitHub pull request’s Files changed tab and opens that file in a focused review tab (whole file as one diff, syntax highlighting, minimap, themes, GitHub comment hand-off). See README.md for features, the architecture diagram, the module table, how files are fetched and every GitHub selector the extension relies on. Keep those sections up to date instead of copying them here.
These are product promises. Do not break them without the owner’s explicit approval.
manifest.json.eval, new Function, remote scripts or CDN assets. The CSP is script-src 'self'. Store reviews depend on this.PRIVACY.md and the justifications in docs/store/README.md in the same change.https://github.com and https://<enterprise>.ghe.com, checked by isAllowedOrigin in src/shared/githubContext.ts. The manifest’s *.ghe.com pattern also matches ghe.com itself, so code must still check isAllowedOrigin. GitHub Enterprise Server (any domain) is not supported.src/content/github.ts. If GitHub changes its markup, that file (plus the commit regexes in src/shared/githubContext.ts) should be the only place to fix. Update the “GitHub DOM dependencies” table in the README when selectors change./pull/N/files and /pull/N/changes. Support both, and add a test fixture for each.turbo:load and popstate; injection must be idempotent.data-*, href shapes, ids) over generated class names. If a class substring is unavoidable, have a fallback.src/shared/ is pure and framework-free: URL parsing, validation, shared types. Message types live in src/shared/types.ts and are prefixed diffsanity:.FileDiff model (src/shared/types.ts), not on GitHub data. Renderer, minimap and comments stay separate modules.diffsanity- prefix and Primer CSS variables with fallbacks (styles/github.css). The review page is styled with Tailwind CSS v4, compiled at build time from styles/review.css: use utilities in review.html for layout, and ds- component classes in @layer components for anything reused or set from TypeScript. Colours come from the theme variables (bg-canvas, text-muted, border-line, …), never fixed values. Themes are :root[data-theme="…"] CSS variable blocks; add a theme there and in src/review/themes.ts.strict (see tsconfig.json); no any, no unused code. Match the surrounding code: 2-space indent, single quotes, semicolons.SCAN_DELAY_MS, ADD_COMMENT_BUTTON) over magic values.diff (jsdiff) and prismjs only. Tailwind is a build-time dev dependency; nothing from it runs in the extension except the compiled CSS.| Command | When |
|---|---|
npm run typecheck |
Every change |
npm test |
Every change. Vitest + jsdom, tests in test/ |
npm run build |
Every change; output goes to dist/ |
npm run e2e |
Any change to src/content, src/review or manifest.json. Runs dist/ against live public PRs (~3 min, 21 checks) |
test/github.test.ts); add a fixture when GitHub’s markup changes.npm run e2e overwrites docs/screenshots/. Revert them (git checkout -- docs/screenshots) unless you mean to update the README images.dist/ to try changes by hand. After changing manifest.json, reload the extension while it is enabled, or new host permissions are not granted.| Change | Update |
|---|---|
| New or changed feature | README feature list, Tested and Known limitations; store description in docs/store/README.md |
| GitHub selectors | README “GitHub DOM dependencies” table |
| Data, hosts or permissions | PRIVACY.md (and its Last updated date), docs/store/README.md justifications and privacy answers |
| Build or scripts | README Development table |
PRIVACY.md is published by GitHub Pages (repo root, master) at https://zubeirom.github.io/DiffSanity/PRIVACY.html, which is the URL in both stores. Do not rename or move it. Exclude non-site files (sources, scripts, build output) from Pages in _config.yml.
dist/, release/ or scratch files (probe scripts, local screenshots of private code).version in both manifest.json and package.json (semver: minor for features, patch for fixes). The stores reject a version they have already seen, and npm run package fails if the two differ.master.npm run package creates release/diffsanity-<version>.zip.gh release create v<version> release/diffsanity-<version>.zip --repo zubeirom/DiffSanity --title "v<version>" --notes "<what changed, in plain words>".For README, store text, release notes, UI strings and messages to the owner: plain, simple English, short sentences, no jargon, no filler. Say what something does, not how clever it is.
The review tab now covers the whole pull request: a GitHub-style file list on the left switches files in place, using the existing FileDiff model, renderer and minimap. Build new review features on those modules rather than a parallel implementation. Next ideas (syncing GitHub’s “Viewed” state, j/k change navigation, word-level highlighting) are listed under Known limitations in the README.