Skip to content

Filter by Git Status & Responsive fixes#668

Open
mdo wants to merge 75 commits into
mainfrom
mdo/diffshub-git-status
Open

Filter by Git Status & Responsive fixes#668
mdo wants to merge 75 commits into
mainfrom
mdo/diffshub-git-status

Conversation

@mdo
Copy link
Copy Markdown
Contributor

@mdo mdo commented May 12, 2026

No description provided.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pierre-docs-diffshub Ready Ready Preview May 12, 2026 9:36pm
pierre-docs-trees Ready Ready Preview May 12, 2026 9:36pm
pierrejs-diff-demo Ready Ready Preview May 12, 2026 9:36pm
pierrejs-docs Ready Ready Preview May 12, 2026 9:36pm

Request Review

@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

window.__INSTANCE = this;

P2 Badge Remove global debug hooks from CodeView setup

Avoid assigning window.__INSTANCE/window.__TOGGLE during normal setup() because these hooks run in all builds and keep a strong reference to the viewer instance after mount. In long-lived docs sessions (or repeated mounts/unmounts), this can leak memory and also lets unrelated page scripts mutate the active viewer state through those globals.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mdo mdo changed the title Filter by Git Status Filter by Git Status & Responsive fixes May 12, 2026
amadeus and others added 4 commits May 15, 2026 17:04
* Revert "Virtualization beta release prep"

This reverts commit 484569f.

* Optimize ResizeManager for column updates

* Fix potential double fire bug with UniversalRenderingManager

* Stage 1 of refactor:

Reworking existing VirtualizedFile and VirtualizedFileDiff to work with
both simple and advanced virtualizers

Stuff is stubbed out right now, but not ready for prime time

* Fix bug with recycling and custom css

* calm before the storm

* prep for the hard shit

* First pass at managing dynamic heights

I tried to get AI to do this, but it really sucked, so I did it myself.

The main goal of this commit is to handle the post render
reconciliation.  So utilizing many of the APIs from the simple
virtualizer, with a few tweaks, we can effectively dynamically adjust
the offsets to ensure that we are positioned properly.

This does not include scroll anchoring yet, which is another issue and
it also doesn't manage if things resize between renders, which I think
we'll use a resize observer on the sticker container thing to manage
that, but still more work to be done.

I am noticing pretty heavy render times in some more extreme cases, so
there's probably still a lot of work to do in that regard.

* dumb things

* Detect if code can resize

* Fix virtualization with empty gutter column

* Implement scroll fixing

This might be the final functional thing required for this shit...

Now i need to test if annotations can work...

* mdo was here

* absolute slop pocalypse

* Revert "absolute slop pocalypse"

This reverts commit 6ff638235380b4c546e9aa3967ff2a3474d86795.

* Revert query param for now

* big boi

* Reworking to CodeViewer

This is step 1 of this new idea I had to productize this into a code
viewer component, that can be used to render tons of shit, and
virtualize really nicely

* Add APIs for rendering annotations

* Fix some bugs in annotations in the virtualizer process

* Refactor sticky logic for new CodeViewer world

Adding some new specs for the how to control layout/padding and how it
gets calculated.

At a high level basically we are using margins on the overall height
container to define padding (this makes it much easier to figure out
sticky state).  Then we have a new custom property for gap between
files/diffs, which utilizes flex gap for layout.

This also simplifies a bunch of the math which is quite nice.

Next up we need to rename `fileGap` since it's really now more of an
internal padding thing

* Fix up /gh route for new CodeViewer world

* fileGap -> spacing

* Update docs

* Adding some doc comments n shiii

* phase 1: core api cleanup

some ai slop, and some ai iteration to get things potentially setup for
the react component.

* Refactors CodeViewer APIs to support new incoming data structurs n stuff...

* ResizeManager: misc performance improvements

The main goal here was a bit of a sidequest to get CodeViewer more
performant by doing a better job of batching various dom operations to
hopefully alleviate unneeded layouts in heavy updates.

This is not a perfect solution, but I think on it's own it might offer a
solid number of improvements.

* foundational improvements:

* optimize cleanup
  * The aggressive innerHTML/textContent cleanups are probably not
    necessary and can add much unneeded overhead under aggressively
    scrolled situations
* apis to allow manager setups to be deferred (to avoid some layout
  thrashing)
  * enableLineSelection does cause some thrash if there are no
    selections, so we should look into muxing that prop in better
    instead of applying it as a dom write after the update...

* useless changes to UniversalRenderingManager

* CodeViewer React Component

Alright, this one was definitely a doozy, I had to add a lot of stuff to
be able to properly support react components, but I think that also
it'll really help out with the vanilla JS implementations.

I will probably need to eventually add a good testbed for CodeViewer
vanilla js as well so we can easily go between.

This does not include a more imperative implementation for data right
now, forcing user to manually update the entire data structure... which
isn't great. That might be the next case that I'll want to utilize

* Fix renderCustomMetadata on file to renderHeaderMetadata

Wasn't matching diffs, lol, what a flub

* Implement all callbacks and overloads

* Hook up renderGutterUtility properly

Also remove a bunch of the deprecated HoverUtility stuff

* Internal versioning system to better emit state updates in the future

* bugfix: regression of line annotation rows having a min-height

* Dont cursor the number column when interactive

* mb update nextjs

* Basic commenting and new layout system

* WIP before the scrollTo AI Storm

* update trees based on hustle work by the team

unclear if this is the right way, but it appears to work for now

* Fixed scrollTo item API

There were a bunch of issues unfortunately around fitPerfectly
calculations and also misc problems with scroll anchoring that this
change mostly resolves (I think).

* FileTree Polish

* Ensure a custom tree is only built on fetch (not on annotation change
  like before)
* Hooked up git status to make the list more descriptive
* Misc rebase fixes

file tree refactor fix

* First pass that new scrollTo architecture (to support smooth scroll)

* Working Smooth ScrollTo, lfgggg

* Improved math only scroll fix logic

Less DOM thrash, better mental model for virtualization, and can work in
noisier situations when animating scroll

* mdo specialty: tightening up the density of the file tree

* Add sticky header support for line/position scrollto stuff

* Initial pass at adding comment list/scroll too navigation

* Add `smooth-auto` behavior

A quick algo that will fall back to instant if the distance is more than
10 viewports away

* Fix filetree sort to match the patch file order

Seems to work great, and requires minimal work... lfgggg

* Trees: fix search from local library updates

* Apply scroll fixing when setOptions is called

fix a legit bug in scroll anchor

things were falling back to the file/item when a line wasn't fully visible

* sidequest: fix CodeViewer constructor setup

* add `stickyHeader` props to File/FileDiff

A mix of a feature request probably and the ability to make CodeViewer
far more elegant in handling of sticky headers

* codeviewer anchor fix: favor deletion lines over addition lines

makes the changes much more stable

* CodeViewer perf optimization on setOptions

calling instanceChanged on setOptions is probably not worth it since we
control the lifecycle with CodeViewer

* Massive anchoring refactor/improvements

* Adds a new stickyHeaders prop to CodeViewer
* Found a ton of issues in the numeric version of scroll anchoring, that
  should hopefully now be resolved.
* Fixed a ton of misc issues related to how different alignments worked
* Fixed tons of bugs with setOptions triggering pendingLayoutAnchor
* Fixed a bug where maxScroll did not include padding

* header fix

* Fix (and test) potential bug with mismatched trim columns

mb fix flakey test?

Actually fix the column out of sync bug

squash me

* implement new more customizeable virtualization metrics

* Adding paddingTop/Bottom that add flexibility as well remain backwards
  compatible

* Initial pass at a universal selection manager

Along with proper controlled selection behavior

* hacky controlled selection test

* Tweaks to comment ux to add ranges and stufffff

* Make the options a shared type

* Quick hack to disable syntax highlighting on massive files/diffs

* Make patch fetcher be plain text only

doing json stuff for this type of thing is not the jam, unfort

* fix broken test

* Disable pointer events while scrolling

optimize pointer events to sticky container

* docs v1

* Suggested commit message:
Improve GH viewer mobile experience

Adds a mobile file tree overlay with backdrop/close controls, keeps GH
viewer scroll panes from chaining to body scroll, and syncs
split/unified mode with the mobile breakpoint. Also lowers worker pool
and AST LRU cache limits on mobile browsers.

Staged changes include:
- GH page responsive grid and mobile file tree sheet.
- Mobile header action row with file tree toggle.
- Backdrop and close button owned by CodeViewerSidebar.
- Overscroll containment for code viewer, file tree, and comments panes.
- Responsive split/unified switching at 767px.
- Mobile-aware worker pool/cache limits.

* Move WorkerPoolStatus into sidebar

Also changed it to CodeViewer Status

* Add commit hashes as top level folders

* sticky headers are cool for the file tree

* nothingburger

* Redo item file selection

the llm did some crazy dom checking stuff that wasn't necessary, and
exhibited a few bugs

* First pass at supporting collapsed with CodeViewer

* Add collapse-y boi to /gh

* Fix `getAdvancedStickySpecs` when collapsed

* Improve instance apis and such for collapsing behavior.

* getWindowSpecs was a dumb thing to add a handle for
* Improve instance APIs to better allow scroll fixing on collapse changes
* Add further tests to it all

* Add scroll fix UX to collapse actions

* Don't modify the built in item version, lol

* Auto collapse files by default

* Collapse mega files by default...

* Attempt to setup a sort of test harness thing to see if we can optimize
shit...

* Fix a couple broken contain settings

* Some poor mans AI research on performance

* CodeViewer -> CodeView

Basically beta release prep, simplifying the name and all that

* Add a regression test...

* Fix theme style override in CodeView

* Add CodeView to demo app

This gives us a vanilla js implementation to poke around with

* Properly dispose of highlighter after any tests that use them

I think this can sometimes result in flakey tests

* Fix needless layout calculations

* some performance optimization on pathologically large files/hunks

Basically we create some computation checkpoints to start calculating
things from so we don't have to re-compute everything

---------

Co-authored-by: Mark Otto <markdotto@gmail.com>
amadeus and others added 27 commits May 16, 2026 02:32
…le/Diffs (#687)

Fix computation with 'simple' hunkSeparators
ResizeManager: use shared ResizeObserver
* Improve layout recalculation costs
* Add imperative id update API to CodeView
* Improve memory usage when parsing large diffs
* Fix computation with simple hunkSeparators
* Use a shared ResizeObserver for all ResizeManager instances
…680)

* [diffs] respect prefers-reduced-motion and prewarm scrollTo target

Library-internal improvements to the new CodeView component

1. TP to destination when prefers-reduced-motion is on
2. prewarm scrollTo targets to ⚡️blazing-fast™ TPs (item/line/range,
   [see this comment](#680 (comment)))
3. prefersReducedMotion() exported so consumers can reuse it

* Rework prewarmWorkerHighlight

* prewarming is actually responsibility of the renderer, not the component
* ensure that we never kick off a prewarming job if we're already highlighted
* Added a bit more safety to worker pool to not kick off a highlight
  task if we have a valid cache
* utils'd a few functions

* clean up prewarm api

* it shouldn't take a file/diff, because it invites a scenario where
  things get out of sync
* virtualizedfile/filediff always have their appropriate content on
  their instance, so this will ensure consistency

* fix ai slop from an earlier iteration

* Fix recycling with Files for CodeView

* reviewed changes...

* Refactored prime cache system.

This is the new improved cache primer.

* Safely idempotent (will not fire if the file/diff is already in the
  LRU cache)
* Only works with LRU cache, for good reason
* No mucking around with file/diff components to make a confusing API
* New system to ensure that request for elements with a highlightKey can
  be shared
  * highlightKey is an amalgamation of the type (file/diff), the
    cacheKey, and a version for renderOptions

* prewarm -> prime stragglers

* pr feedback

(probably safety that isn't actually applicable, but its probably good
to have)

* lol fine

---------

Co-authored-by: Amadeus Demarzi <amadeusdemarzi@gmail.com>
Disable overflow scroll while scrolling

This appears to fix a pretty gnarly safari crash under aggressive
scrolling scenarios
…697)

IntersectionObserver delivers entries asynchronously, so the callback can
fire for a target the Virtualizer has already released via disconnect() or
releaseElement() — at which point the target is no longer in
this.observers and the previous code threw.

Replace the throw with continue so stale entries are ignored. The
target-not-HTMLElement throw above is left as-is since real browsers
won't deliver non-Element targets.
…own (#700)

Streaming a large compare (e.g. torvalds/linux v6.0..v7.0) made the Diff
Stats counter tick more slowly the longer the stream ran, and stuttered
scroll on every tick. Each streamed batch published a fresh
CodeViewFileTreeSource, and CodeViewFileTree responded by calling
`model.resetPaths(source.paths)` — which constructs a brand new
PathStore over the full accumulated path list. Per publish that is
O(N log N) where N is total paths streamed so far, so across ~80
publishes the total work is roughly O(N² log N) on the main thread and
each publish blocks input proportionally to N. The trees model already
exposes a localized mutation fast path via `model.batch` / `model.add`;
diffshub just wasn't using it.

Link each tree-source snapshot to the prior one through a new
`previousSource` field. The accumulator now also owns a persistent
`rankByPath` map and a stable sort comparator over it, so we stop
rebuilding the comparator's rank map on every snapshot. When
CodeViewFileTree sees a snapshot whose `previousSource` matches the one
it last applied, it batches the tail of new paths into the model with
`{ type: 'add', path }` ops instead of resetting. `resetPaths` is now
reserved for the initial mount and any non-append change (e.g. a new
request).

This drops per-publish tree work from O(N) to O(delta), keeps the
counter incrementing at a steady rate as the stream progresses, and
removes the recurring long task that was starving scroll during
streaming.
#701)

Every tree publish allocated a fresh `paths.slice()` and a fresh `new
Map(pathToItemId)`. For the torvalds/linux v6.0..v7.0 stream that is roughly a
~640 KB array copy and a ~4 MB Map clone per publish, ~370 MB of GC churn.

`snapshotCodeViewTreeSource` now aliases the accumulator's live `paths`
and `pathToItemId` directly. To stay race-free against later in-place
growth, the snapshot also captures the exclusive upper bound for the
array as `pathCount`. CodeViewFileTree reads bounds for the
incremental-add delta and for the fallback `resetPaths` slice from
`pathCount` instead of `paths.length`, and the initial path list handed
to useFileTree is captured once in a ref so re-renders don't re-slice
the growing live array. `pathToItemId` is read at click time through
the same live reference (`sourceRef`), which is what the typed
ReadonlyMap was already implying.

Per-publish allocations shrink from O(N) to O(M) (only the small
added/deleted/renamed gitStatus array still copies), removing a sizable
allocation in the streaming hot path.
* New OG and icons

* Opaque layers
Map `/owner/repo/pull/N/(changes|files)/{sha}` to `/owner/repo/commit/{sha}`
so a GitHub PR URL scoped to a specific commit resolves to the standalone
commit view, which is the only form the diff loader can fetch.

The rewrite runs in two places:
- `normalizeGitHubPath` covers form input via `getPatchViewerHref`.
- The catch-all viewer route now redirects to the canonical path when
  someone navigates directly, fixing the "couldn't load the diff" failure
  on pasted URLs.

Extracts `resolveDiffshubViewerRoute` from the route page so the
redirect/render decision is unit-testable.
* Update to Pierre Soft themes

* fix

* fixes across the board to only use soft themes on diffshub

* Update snapshots to reflect latest theme colors

* feedback from review
Add new home page diff demo
- Show a numeric count badge on the sidebar comment icon when there
  are saved comments, sized so the icon-only button widens just
  enough to fit the count.
- Make each file-path header in the comments list a clickable button
  that scrolls the viewer to that file (reusing the existing
  onSelectItem flow), and allow drag-selecting text inside the path
  and comment rows by guarding onClick against a non-empty
  window.getSelection().
- Classify each saved comment's anchor line as 'change' or 'context'
  at save time by walking the hunkContent, and render context-line
  comments as a muted "Line N" instead of a misleading "Line +N" /
  "Line -N".
* More home fixes, remove that

* more edits

* chef kiss

* maybe fix favicon

* transparent favicon

* format

* tweak
svh prevents dvh jitter on scroll
* [diffshub] add external-link button next to URL form clear

* move icon to the header and the right

* fix bg color while we're here

* fixes

---------

Co-authored-by: Mark Otto <markdotto@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@mdo mdo force-pushed the mdo/diffshub-git-status branch from 872a241 to d36198e Compare May 20, 2026 05:26
Base automatically changed from beta-1.2 to main May 20, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants