Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9cd7cd4
Phase 1: Clean up persisted state restoration
amadeus Aug 6, 2026
8357596
Phase 2.1: Fixing up current session related diff for rendering properly
amadeus Aug 7, 2026
30fd7b1
Phase 2.2: Setup shallow clone infra for session edits
amadeus Aug 8, 2026
ba3575a
Phase 2.3: Ensure only sessionDiff is edited
amadeus Aug 9, 2026
d4fab80
Phase 2.4: Ensure sessionDiff is used for all rendering processes
amadeus Aug 9, 2026
03462bb
Phase 2.5: Separate external diff from edited diff
amadeus Aug 9, 2026
32d5123
Phase 2.6: Harden latest vs rendered diff
amadeus Aug 11, 2026
e1dabd9
Phase 2.7: Reconcile external updates during editing
amadeus Aug 11, 2026
75ff91b
Sidequest 1: Fix persist error on homepage
amadeus Aug 11, 2026
28c8293
Sidequest 2: Prime workerpool caches for the AgentUi stuff
amadeus Aug 11, 2026
df8fa69
Persisted Fix 1: Expose cached document contents
amadeus Aug 11, 2026
5a41619
Persisted Fix 2: Initialize edit session from cached contents
amadeus Aug 11, 2026
b95a6ef
Persisted Fix 3: Ensure document properly re-uses history and emits
amadeus Aug 11, 2026
faea7df
Persisted Fix 4: Clean up some tests
amadeus Aug 11, 2026
fa5ba13
Phase 2.8: Bring file inline with FileDiff workflow
amadeus Aug 12, 2026
c50d83e
Phase 2.9: Fix annotation alignment sync bug
amadeus Aug 12, 2026
c98e9a5
Playground Updates
amadeus Aug 12, 2026
45b8137
bugfix: fixes an issue with creating newlines before an annotation
amadeus Aug 12, 2026
a2f09bf
bugfix: fix lines losing their syntax highlighting on newlines
amadeus Aug 12, 2026
c215a7a
tests: fix tests that were outdated in the new architecture
amadeus Aug 12, 2026
ad5b027
bugfix: ensure collapsed codeview items are properly update their ins…
amadeus Aug 12, 2026
c9cf496
tests: fix up some tests to better align with the new architecture
amadeus Aug 12, 2026
7704dde
bugfix: fix yet another test timing issue, that's not a real issue
amadeus Aug 12, 2026
c088ee0
fix: properly handle empty vs new files as undo reset boundaries
amadeus Aug 12, 2026
72f6950
bugfix: regression for initial hydration replacements
amadeus Aug 12, 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
48 changes: 22 additions & 26 deletions apps/docs/app/(diffs)/_home/AgentUi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import { DEFAULT_THEMES, type FileDiffMetadata } from '@pierre/diffs';
import type { EditorOptions } from '@pierre/diffs/edit';
import { File, FileDiff, Virtualizer } from '@pierre/diffs/react';
import {
File,
FileDiff,
useWorkerPool,
Virtualizer,
} from '@pierre/diffs/react';
import {
IconArrow,
IconChevronSm,
Expand Down Expand Up @@ -677,6 +682,7 @@ export function AgentUi({
}: AgentUiProps) {
const session = AUI_SESSIONS[0];
const router = useRouter();
const workerPool = useWorkerPool();

// Expands the windowed card into the fullscreen route, morphing the shared
// `.aui` element via the View Transition.
Expand Down Expand Up @@ -970,16 +976,20 @@ export function AgentUi({
const recordEditedStatsRef = useRef(recordEditedStats);
recordEditedStatsRef.current = recordEditedStats;

// One FileDiffMetadata per changed file, parsed on first visit and reused
// on every revisit. Edit sessions write edits back into the metadata (the
// library treats the host's metadata as the diff's content owner and
// self-heals session-shaped metadata on re-render), so reusing the object
// is what keeps a diff's edited content across file switches — the editor's
// persist-state API covers only selections and scroll for diffs.
// Placeholder File surfaces need no equivalent: with `persistState` on the
// shared editor, the per-cacheKey document cache restores their edited
// contents (and undo history) on re-attach.
const diffsRef = useRef<Map<string, FileDiffMetadata>>(new Map());
// One external diff baseline per changed file, created up front for worker
// priming and reused on every visit so its cache identity remains stable.
// The shared editor's per-cacheKey document cache restores edited contents
// and undo history when a file is revisited.
const [diffs] = useState<Map<string, FileDiffMetadata>>(() => {
const diffs = new Map<string, FileDiffMetadata>();
for (const file of session.changedFiles) {
const diff = getFileDiff(file);
diffs.set(file.path, diff);
void workerPool?.primeDiffHighlightCache(diff);
}
return diffs;
});

// Paths the user has edited. Only consulted to stop an edited file from
// hydrating out of its prerendered (pristine) server HTML on revisit.
const editedPathsRef = useRef<Set<string>>(new Set());
Expand Down Expand Up @@ -1113,6 +1123,7 @@ export function AgentUi({
: null,
[liveSession, activePath]
);
const fileDiff = activeFile != null ? diffs.get(activeFile.path) : undefined;

// When the active path isn't a changed/added file (e.g. browsing the root
// README or another explorer file), open editable placeholder contents
Expand All @@ -1125,21 +1136,6 @@ export function AgentUi({
[activePath, activeFile]
);

// The active file's diff metadata: parsed once on first visit, then reused
// from the cache so revisits render the content the last edit session wrote
// back into it.
const fileDiff = useMemo(() => {
if (activeFile == null) {
return null;
}
let diff = diffsRef.current.get(activeFile.path);
if (diff == null) {
diff = getFileDiff(activeFile);
diffsRef.current.set(activeFile.path, diff);
}
return diff;
}, [activeFile]);

// Server-rendered, already-highlighted HTML for the active diff. Only safe
// when the file is unedited so the markup matches `fileDiff`.
const activePrerenderedHTML =
Expand Down
12 changes: 10 additions & 2 deletions apps/docs/app/(diffs)/_home/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,15 @@ export function getFileDiff(
nextAfter?: string
): FileDiffMetadata {
return parseDiffFromFile(
{ name: file.path, contents: file.before },
{ name: file.path, contents: nextAfter ?? file.after }
{
name: file.path,
contents: file.before,
cacheKey: `${file.path}:before`,
},
{
name: file.path,
contents: nextAfter ?? file.after,
cacheKey: `${file.path}:after`,
}
);
}
Loading