Skip to content

[editor] Beta 1.3#749

Draft
amadeus wants to merge 101 commits into
mainfrom
beta-1.3
Draft

[editor] Beta 1.3#749
amadeus wants to merge 101 commits into
mainfrom
beta-1.3

Conversation

@amadeus

@amadeus amadeus commented May 29, 2026

Copy link
Copy Markdown
Member

Used to track editor beta versions. Will be periodically rebased on main.

@vercel

vercel Bot commented May 29, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
pierre-docs-diffs Ready Ready Preview Jul 1, 2026 6:01am
pierre-docs-diffshub Ready Ready Preview Jul 1, 2026 6:01am
pierre-docs-trees Ready Ready Preview Jul 1, 2026 6:01am
pierrejs-diff-demo Ready Ready Preview Jul 1, 2026 6:01am
pierrejs-docs Ready Ready Preview Jul 1, 2026 6:01am

Request Review

@amadeus amadeus mentioned this pull request May 29, 2026
15 tasks
amadeus and others added 16 commits June 24, 2026 16:25
* Revamp some AUI demo code, streamline a few things, update selection action

* streamline the aui

* fix playground theme flash when toggling review/edit

* Track live diff stats in AgentUi Changes tree

Recompute each file's added/removed line counts from in-editor edits and
update the +/- decorations in the Changes tree so they reflect the live
diff rather than the static snapshot counts.

* fix(docs): render heading anchor inline with FeatureHeader titles

Drop the flex layout on the FeatureHeader h2 so the injected "#" anchor
flows inline after the title text instead of floating beside wrapped
multi-line headings.

* fix hint coloring on light mode, plus fix playground theme flash
more mobile related bugs
In edit mode, click or drag to select code on either side of a split or
unified diff. A caret highlights only its own line, on the side it sits
on, instead of also lighting up the paired line in the read-only
deletions pane. Selecting text drops the full-line background and keeps
only the caret line's number highlighted, so the selection itself is the
line-level marker. Deleted text is selectable and copyable: clicking a
line number selects that whole line's text on either side, and in split
view dragging across the deletion line numbers selects the block, the
same as on the additions side.

Previously the active-line highlight leaked onto the read-only deletions
pane, the full-line background competed with a text selection, deleted
text could not be selected, and line-number gestures behaved differently
per side. The editor now confines the active-line highlight to the
caret's side, paints deleted-text selection with the native selection
(revealed only while selecting deleted text), highlights just the focus
line's number during a gutter drag, and stops a transparent-span rule
from hiding the word-level diff highlights.
fix(diffs): clear bufferBefore and bufferAfter on reset
The diff editor's "system" themeType follows the OS prefers-color-scheme
(its shadow root declares `color-scheme: light dark`), so it drifted from
the app whenever the app theme differed from the OS. Resolve "system" to
the app's scheme from @pierre/theming so the editor stays in sync; the
switcher stays editor-only and "light"/"dark" remain independent overrides.
Rename the useTheme() binding and every consumer to the controller's
vocabulary so the docs match the library, not just one file:

  resolvedTheme -> resolvedColorScheme
  theme         -> colorMode
  setTheme      -> setColorMode
  systemTheme   -> systemColorScheme
  themes        -> colorModes

Also rename the playground's local switcher state (themeType -> colorMode,
the diffs `themeType` option key is unchanged) and the pre-paint bootstrap
script's locals. Pure rename — no behavior change.
Editing a scrolled unified diff snaps the view back to the top. To
reproduce:

1. Open the editor on a unified diff.
2. Scroll down within the editor.
3. Edit a visible line (type a character, press Enter, etc.).

The view jumps to the top of the diff instead of staying where you
were. Split diffs are unaffected.

On every edit a unified diff re-renders its rows in place:
FileDiff.refreshDiffView rewrites the content column's innerHTML,
which detaches the line elements the editor cached for caret
geometry. The editor then measures a detached row (offsetTop 0) and
places the caret at the top, so the follow-up scrollIntoView pulls
the viewport up to it.

Reset the editor's line-geometry caches after a diff rebuilds its
rows, so the caret re-measures against the fresh DOM and the
viewport stays put.
On the homepage editor demo, scroll a changed file down, then open a
different file from the Changes list: it opens scrolled to the previous
file's offset instead of at the top.

The demo reuses one FileDiff surface across files (never remounted, so
the prerendered markup survives), and the scroll lives on the host
`.aui-surface-wrap` container, which nothing reset on a file switch.
Reset its scrollTop to 0 whenever the active file changes, in a layout
effect so the new diff never paints at the old offset.
updateRenderCache is now a token-content sync that returns the addition
lines whose text changed; the hunk recompute moves to a dedicated
recomputeContentHunks method. The host drives the recompute explicitly
per edit: applyContentEdit (recompute + refresh) for visible content
edits, recomputeContentHunks (recompute only) for content edits the
background tokenizer delivers offscreen, and applyDocumentChange (full)
for line-count changes. Removes the skipDiffRecompute and
shouldRefreshView parameters and the coordination they required. No
behavior change.
@socket-security

socket-security Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​pierre/​icons@​0.7.1771007897100

View full report

amadeus and others added 13 commits June 29, 2026 15:35
* Sidequest: Rework how old/new files and parsing works

This was a to do that will make the partial diff hydration work a lot
more reasonable

* Phase 1: Types and helpers

Flesh out the core hydration utility function, setup types for the
loaders, and add tests to make sure hydration works properly

* Phase 2: Rework how `isExpandable` works

* Phase 3 & 4: Hook up the actual hydration actions

* Phase 5: Add basic error throwing

* Phase 6: Rounding out some final tests

* Phase 7: Scaffolding for forgotten bottom region...

* Phase 8: Render the new faux bottom hunk lad

* Phase 9: Add some hardening tests

* Phase 10: Update virtualized components to properly account for final separator

* Phase 11: More tests

And some cleanup

* Fix expansion in CodeView

This was actually a big bug from before, where we didn't properly handle
the changes

* Update demo to test different hydration situations with CodeView

* Phase 12: Make priming awaitable

* Phase 13: Actually prime the cache if there's a worker pool

* Phase 13b: Quick timeout in case the highlight is pathological

* Phase 14: Tests n shit

* Misc fixes

* Codex review fix

* Hopefully fix some flakey tests

* Phase 15: Setup hydration guards

Mostly some prep work to ensure you can never go from non isPartial to
isPartial... since it will create a ton of UX issues

* Phase 16: Add some basic hydration handling for react lifecycle

* Phase 17: New options based callback implementation for React

* Phase 18: Ensure react uses the new hydrated diff

* Phase 19: Some misc wiring to ensure react isn't fully out

* Phase 20: Update/fix tests

* Some more demo improvements for codeview testing

* bugfix: ensure we don't show expansions on new/deleted files

* WIP SLOP

* Add initial support for github tokens

* Misc polish items for the token interface

* Refactor everything to use mutability...

* Refactored implementation

The goal here is to feel a bit less gross around the react components,
therefore I'm relying on mutation for default components normally, but
then for CodeView we opt into a cloned/copied variant

* Naming tweaks

* Misc review cleanup

* Diffshub tweaks:

* only allow expansion if a token is provided (the api rate limits way
  to quick)
* fix some pr feedback, unclear what it was fixing

* Fix base sha fix from code review

* Fix a subtle console.log issue with NextJS and the shared CodeView options prototypes

* Fix for the precise windowing bug i discovered on expansion

* Improve tests a bit more

* Fix bug with url parsing

* Improve cacheKey logic a bit

* Modestly improve re-fetches...

Won't really fix anything in practice because AI is dumb

* Phase 1: Update misc docs surrounding the new null semantics

* Sidequest: Fix up exported types and stuff, harden a few things as well

* Basically realized that the docs were inheriting some pretty garbage
  annotation examples because we weren't properly hydrating.
* Also realized some tests were pretty dumb

* Phase 3: Vanilla JS API docs

* Phase 4: CodeView content updates

* Phase 5: Core types documentation updates

* Phase 7: Few more cacheKey tweaks and stuff

There was no need for phase 6

* Fix types in diffshub with new types rework
…881)

* bugfix: Allow virtualized filediff to accept FileDiffMetadata updates

A pretty big derp with how the diff is resolved lived here, mostly
didn't notice it because CodeView was not susceptible to it...

* Fix bug with hydration

* Add a regression test

* Fix hydration derp
* fix(diffs): fix cursor movement handling for backward multi-line selection

* Fix selection merging

* test(diffs): cover backward direction when merging selections

When overlapping selections merge, the result takes its direction from
the most recently created selection, so the merged caret stays where
the user last put it. Two paths had no tests: when the latest selection
is already backward, and when a later bare caret lands on the merged
start and the direction is derived as backward.

Add a test for each so this focus-preserving behavior is locked in.

---------

Co-authored-by: Nicolas Gallagher <239676+necolas@users.noreply.github.com>
* Smol fixes

* Fix styles that will break codeview
* Add an easy commented out field for the dev check

* Prevent rendering of CodeView before worker pool is initialized

* Add test for worker readiness

* Smol corrections for annotation errors

* Be able to handle a failing worker pool gracefully

* PR Review Feedback: Fix up test to use spyOn

* PR review feedback: trigger an initialization for the worker pool if needed
In packages/diffs/src/react/EditorContext.tsx, Editor was imported as a
value but is only ever used in type positions; the sole runtime use is
editor.cleanUp() on the editor parameter, not the Editor class.

Convert it to a type-only import so the binding is guaranteed erased from
the JS output under verbatimModuleSyntax. This removes any static runtime
coupling from @pierre/diffs/react to the editor module graph (and its
top-level Intl.Segmenter side effect in editor/selection.ts) for
consumers that never use the editor. EditorContext/EditorProvider/useEditor
remain functional.

Co-authored-by: Claude <noreply@anthropic.com>
To reproduce, in the diff editor on Safari:

1. Click into the additions side and type text on a line.
2. Press cmd+Backspace.

Nothing is deleted, though cmd+Backspace deletes to the line start in
Chrome.

Safari reports cmd+Backspace as the deleteHardLineBackward input type
where Chrome reports deleteSoftLineBackward; the editor only handled the
latter, so Safari's cmd+Backspace was dropped. Route both to the same
handler. They differ only on a wrapped line (hard deletes to the logical
line start, soft to the visual one), and Chrome's soft behavior is the
one we match.
…ed wait) (#919)

* diffs: deflake editor active-line-highlight test (poll instead of fixed wait)

The active-line-highlight tests asserted the highlight DOM after a fixed
10ms wait. Under load the async shiki + decoration pass hadn't applied the
data-selected-line attributes (or even initialized the editor's text
document) within 10ms, so the assertions saw empty results and flaked.

Add a poll-until-settled waitFor helper to the test harness and replace the
fixed waits before each highlight assertion (and the fixture's post-edit
wait) with polls on the actual expected DOM condition. Test-only change; no
production code touched.

* diffs: gate active-line-highlight selection setup on editor doc init

The deflake poll waited only for rendered content rows before
setSelections(). But fileDiff.render() renders rows synchronously
(from a worker/render cache or a plain-text fallback) while the
editor's text document is created later, inside the async
initializeHighlighter().then(editor.__syncRenderView) callback in
FileDiff.syncRenderViewToEditor(). Until that callback runs,
setSelections() throws "Text document is not initialized", so a slow
highlighter load could still flake CI.

__syncRenderView sets contentEditable = 'true' on the [data-content]
element in the same synchronous block that assigns the text document,
so poll on the content element becoming contenteditable (with rows
present) — a direct proxy for the document being initialized and
setSelections being safe.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Open the editor docs page (/edit) and, a moment after it loads, the
page scrolls itself down to the find-and-replace demo instead of
staying at the top.

The demo opened the find panel and seeded a query on load. Running
that search makes the editor reveal the first match with
scrollIntoView, which scrolls every ancestor up to the page, so
while the demo sat below the fold the page jumped down to it. Leave
the search input blank instead: with no query there is no match to
scroll to, so nothing moves. The panel still opens empty as the
reader reaches it, ready to type.
* [diffs/editor] fix page jitter when add/removel line

* Fix refreshDiffView function

* Fix `moveCursorToDocEnd` command for diff edit

* Fix scrollToLine method

* Refactor

* render separators

* refactor

* fix render range

* fix scroll to end line

* fix `recomputeEmptyDocumentDiff` function

* Remove 'rerenderFromDocument'  logic, force use file name as the cache key

* fix updateRenderCache method

* fix cache key

* fix testings

* refactor

* fix test

* fix test

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix `isLineVisible` for diff view

* Improve `isLineVisible` method

* fix caret scrolling

* Improve `applyDocumentChange` method

* Enhance `getDocumentBoundarySelection` to correctly handle trailing blank lines and add corresponding unit tests

* rebase onto beta-1.3

* Add `ensureCacheKey` method to streamline cacheKey assignment logic

* revert chnages on  test/editorDisplayOptionResync.test.ts

* fix rebase

* Update playground

* Fix live edtting demo

* refactor

* Refactor EditorTokenizer to centralize grammar loading logic with #ensureGrammar method and add unit test for dynamic grammar loading

* fix(diffs): render edits after the editor detaches and re-attaches

On the /edit demo, toggle Edit mode off and back on, or switch the
surface between File and Diff, then type: the caret appears but the
typed characters never show up, even though the document records them.

Detaching the editor (cleanUp) tears down the tokenizer but left the
parsed document and its file identity in place. On re-attach,
__syncRenderView saw the same file name, lang, and cacheKey, treated
the file as unchanged, and skipped the rebuild that recreates the
tokenizer; with none, #rerender bailed before painting. Release the
document and file info in cleanUp so the next edit() rebuilds both
from the host's current contents.

Also drop a stale LiveEditing comment about recreating the editor per
control change, which the dependency array no longer does.

* Fix & refactor

- alway ensure change even no editor attended
- remove `applyContentEdit` and `recomputeContentHunks`

* fxi setSelectedLines function

* Fix find demo

* Fix scrolling of setSelections

---------

Co-authored-by: Nicolas Gallagher <239676+necolas@users.noreply.github.com>
* v2 of agent ui fullscreen

* make it nice

* tweaks

* better

* feedback

* fix transition
* Blend the edit mode backgrounds

* trim comments

* fix(diffs): recompute selection corner masks after theme changes

Rounded selection corner masks capture the resolved line-background color
when the selection is drawn, so a theme swap (light/dark toggle or theme
name change) left them showing wrong-colored corners on diff-colored lines
until the selection moved. The tokenizer now fires an onThemeChange callback
from #emitThemeChange (covering the system observer, matchMedia, and
syncTheme paths, and the editor re-renders the selection overlay on the
next frame so the corners recompute against the new colors.
EOF
)
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.

5 participants