From 8baca513c0425f93ce270f4a0aa3f910a3b3ca3f Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 16 May 2026 07:47:15 -0500 Subject: [PATCH] Keep diff renderer dependency in plugin --- ui/package.json | 1 - ui/src/fixtures/diffRendererFixtures.ts | 276 --------------------- ui/src/pages/RunTranscriptUxLab.tsx | 309 +++++------------------- 3 files changed, 56 insertions(+), 530 deletions(-) delete mode 100644 ui/src/fixtures/diffRendererFixtures.ts diff --git a/ui/package.json b/ui/package.json index 9b17bdad581..7286053f523 100644 --- a/ui/package.json +++ b/ui/package.json @@ -45,7 +45,6 @@ "@paperclipai/adapter-pi-local": "workspace:*", "@paperclipai/adapter-utils": "workspace:*", "@paperclipai/shared": "workspace:*", - "@pierre/diffs": "^1.1.22", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/typography": "^0.5.19", "@tanstack/react-query": "^5.90.21", diff --git a/ui/src/fixtures/diffRendererFixtures.ts b/ui/src/fixtures/diffRendererFixtures.ts deleted file mode 100644 index 7d8e2a15fbc..00000000000 --- a/ui/src/fixtures/diffRendererFixtures.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { parsePatchFiles } from "@pierre/diffs"; -import type { FileDiffMetadata } from "@pierre/diffs"; - -const smallDiffPatch = `diff --git a/src/pagination.ts b/src/pagination.ts -index 6c2a1f4..e91d2ac 100644 ---- a/src/pagination.ts -+++ b/src/pagination.ts -@@ -1,8 +1,12 @@ - export type PageRequest = { - limit: number; -+ cursor?: string; - offset: number; - }; - - export function buildOffset(offset: number, limit: number) { -- return { offset, limit }; -+ return { -+ offset, -+ limit, -+ hasMore: limit > 0, -+ }; - } -`; - -const largeDiffPatch = `diff --git a/tmp/pierre-large-old.ts b/tmp/pierre-large-new.ts -index 6ea4ef1..9449233 100644 ---- a/tmp/pierre-large-old.ts -+++ b/tmp/pierre-large-new.ts -@@ -1,160 +1,163 @@ - export const value_001 = '1'; - export const value_002 = '2'; --export const value_003 = '3'; -+export const value_003 = '6'; - export const value_004 = '4'; - export const value_005 = '5'; --export const value_006 = '6'; -+export const value_006 = '12'; - export const value_007 = '7'; - export const value_008 = '8'; --export const value_009 = '9'; -+export const value_009 = '18'; - export const value_010 = '10'; - export const value_011 = '11'; --export const value_012 = '12'; -+export const value_012 = '24'; - export const value_013 = '13'; - export const value_014 = '14'; --export const value_015 = '15'; -+export const value_015 = '30'; - export const value_016 = '16'; - export const value_017 = '17'; --export const value_018 = '18'; -+export const value_018 = '36'; - export const value_019 = '19'; - export const value_020 = '20'; -+export function isEven(n: number) { -+ return n % 2 === 0; -+} - --export const value_021 = '21'; -+export const value_021 = '42'; - export const value_022 = '22'; - export const value_023 = '23'; --export const value_024 = '24'; -+export const value_024 = '48'; - export const value_025 = '25'; - export const value_026 = '26'; --export const value_027 = '27'; -+export const value_027 = '54'; - export const value_028 = '28'; - export const value_029 = '29'; --export const value_030 = '30'; -+export const value_030 = '60'; - export const value_031 = '31'; - export const value_032 = '32'; --export const value_033 = '33'; -+export const value_033 = '66'; - export const value_034 = '34'; - export const value_035 = '35'; --export const value_036 = '36'; -+export const value_036 = '72'; - export const value_037 = '37'; - export const value_038 = '38'; --export const value_039 = '39'; -+export const value_039 = '78'; - export const value_040 = '40'; - export const value_041 = '41'; --export const value_042 = '42'; -+export const value_042 = '84'; - export const value_043 = '43'; - export const value_044 = '44'; --export const value_045 = '45'; -+export const value_045 = '90'; - export const value_046 = '46'; - export const value_047 = '47'; --export const value_048 = '48'; -+export const value_048 = '96'; - export const value_049 = '49'; - export const value_050 = '50'; --export const value_051 = '51'; -+export const value_051 = '102'; - export const value_052 = '52'; - export const value_053 = '53'; --export const value_054 = '54'; -+export const value_054 = '108'; - export const value_055 = '55'; - export const value_056 = '56'; --export const value_057 = '57'; -+export const value_057 = '114'; - export const value_058 = '58'; - export const value_059 = '59'; --export const value_060 = '60'; -+export const value_060 = '120'; - export const value_061 = '61'; - export const value_062 = '62'; --export const value_063 = '63'; -+export const value_063 = '126'; - export const value_064 = '64'; - export const value_065 = '65'; --export const value_066 = '66'; -+export const value_066 = '132'; - export const value_067 = '67'; - export const value_068 = '68'; --export const value_069 = '69'; -+export const value_069 = '138'; - export const value_070 = '70'; - export const value_071 = '71'; --export const value_072 = '72'; -+export const value_072 = '144'; - export const value_073 = '73'; - export const value_074 = '74'; --export const value_075 = '75'; -+export const value_075 = '150'; - export const value_076 = '76'; - export const value_077 = '77'; --export const value_078 = '78'; -+export const value_078 = '156'; - export const value_079 = '79'; - export const value_080 = '80'; --export const value_081 = '81'; -+export const value_081 = '162'; - export const value_082 = '82'; - export const value_083 = '83'; --export const value_084 = '84'; -+export const value_084 = '168'; - export const value_085 = '85'; - export const value_086 = '86'; --export const value_087 = '87'; -+export const value_087 = '174'; - export const value_088 = '88'; - export const value_089 = '89'; --export const value_090 = '90'; -+export const value_090 = '180'; - export const value_091 = '91'; - export const value_092 = '92'; --export const value_093 = '93'; -+export const value_093 = '186'; - export const value_094 = '94'; - export const value_095 = '95'; --export const value_096 = '96'; -+export const value_096 = '192'; - export const value_097 = '97'; - export const value_098 = '98'; --export const value_099 = '99'; -+export const value_099 = '198'; - export const value_100 = '100'; - export const value_101 = '101'; --export const value_102 = '102'; -+export const value_102 = '204'; - export const value_103 = '103'; - export const value_104 = '104'; --export const value_105 = '105'; -+export const value_105 = '210'; - export const value_106 = '106'; - export const value_107 = '107'; --export const value_108 = '108'; -+export const value_108 = '216'; - export const value_109 = '109'; - export const value_110 = '110'; --export const value_111 = '111'; -+export const value_111 = '222'; - export const value_112 = '112'; - export const value_113 = '113'; --export const value_114 = '114'; -+export const value_114 = '228'; - export const value_115 = '115'; - export const value_116 = '116'; --export const value_117 = '117'; -+export const value_117 = '234'; - export const value_118 = '118'; - export const value_119 = '119'; --export const value_120 = '120'; -+export const value_120 = '240'; - export const value_121 = '121'; - export const value_122 = '122'; --export const value_123 = '123'; -+export const value_123 = '246'; - export const value_124 = '124'; - export const value_125 = '125'; --export const value_126 = '126'; -+export const value_126 = '252'; - export const value_127 = '127'; - export const value_128 = '128'; --export const value_129 = '129'; -+export const value_129 = '258'; - export const value_130 = '130'; - export const value_131 = '131'; --export const value_132 = '132'; -+export const value_132 = '264'; - export const value_133 = '133'; - export const value_134 = '134'; --export const value_135 = '135'; -+export const value_135 = '270'; - export const value_136 = '136'; - export const value_137 = '137'; --export const value_138 = '138'; -+export const value_138 = '276'; - export const value_139 = '139'; - export const value_140 = '140'; --export const value_141 = '141'; -+export const value_141 = '282'; - export const value_142 = '142'; - export const value_143 = '143'; --export const value_144 = '144'; -+export const value_144 = '288'; - export const value_145 = '145'; - export const value_146 = '146'; --export const value_147 = '147'; -+export const value_147 = '294'; - export const value_148 = '148'; - export const value_149 = '149'; --export const value_150 = '150'; -+export const value_150 = '300'; - export const value_151 = '151'; - export const value_152 = '152'; --export const value_153 = '153'; -+export const value_153 = '306'; - export const value_154 = '154'; - export const value_155 = '155'; --export const value_156 = '156'; -+export const value_156 = '312'; - export const value_157 = '157'; - export const value_158 = '158'; --export const value_159 = '159'; -+export const value_159 = '318'; - export const value_160 = '160'; -`; - -function parsePatchFilesOrEmpty(patch: string): FileDiffMetadata[] { - return parsePatchFiles(patch).flatMap((entry) => entry.files); -} - -export type DiffRendererFixtureId = "small" | "large"; - -export interface DiffRendererFixture { - id: DiffRendererFixtureId; - label: string; - patch: string; - fileDiffs: FileDiffMetadata[]; -} - -export const DIFF_RENDERER_FIXTURES: DiffRendererFixture[] = [ - { - id: "small", - label: "Small mixed edit fixture", - patch: smallDiffPatch, - fileDiffs: parsePatchFilesOrEmpty(smallDiffPatch), - }, - { - id: "large", - label: "Large 160-line patch fixture", - patch: largeDiffPatch, - fileDiffs: parsePatchFilesOrEmpty(largeDiffPatch), - }, -]; - diff --git a/ui/src/pages/RunTranscriptUxLab.tsx b/ui/src/pages/RunTranscriptUxLab.tsx index a1354c044a4..80759cf9da3 100644 --- a/ui/src/pages/RunTranscriptUxLab.tsx +++ b/ui/src/pages/RunTranscriptUxLab.tsx @@ -1,30 +1,22 @@ import { useState } from "react"; -import { FileDiff, PatchDiff } from "@pierre/diffs/react"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { cn, formatDateTime } from "../lib/utils"; -import { DIFF_RENDERER_FIXTURES, type DiffRendererFixtureId } from "../fixtures/diffRendererFixtures"; import { Identity } from "../components/Identity"; import { StatusBadge } from "../components/StatusBadge"; import { RunTranscriptView, type TranscriptDensity, type TranscriptMode } from "../components/transcript/RunTranscriptView"; import { runTranscriptFixtureEntries, runTranscriptFixtureMeta } from "../fixtures/runTranscriptFixtures"; -import { ExternalLink, FlaskConical, LayoutPanelLeft, MonitorCog, PanelsTopLeft, RadioTower, GitCompare } from "lucide-react"; +import { ExternalLink, FlaskConical, LayoutPanelLeft, MonitorCog, PanelsTopLeft, RadioTower } from "lucide-react"; -type SurfaceId = "detail" | "live" | "dashboard" | "diffs"; -type DiffComponentMode = "patch" | "file"; -type DiffStyle = "unified" | "split"; -type DiffOverflow = "scroll" | "wrap"; -type DiffThemeType = "system" | "light" | "dark"; +type SurfaceId = "detail" | "live" | "dashboard"; -type SurfaceOption = { +const surfaceOptions: Array<{ id: SurfaceId; label: string; eyebrow: string; description: string; icon: typeof LayoutPanelLeft; -}; - -const surfaceOptions: SurfaceOption[] = [ +}> = [ { id: "detail", label: "Run Detail", @@ -46,13 +38,6 @@ const surfaceOptions: SurfaceOption[] = [ description: "The active-agents dashboard card, tuned for compact scanning while keeping the same transcript language.", icon: PanelsTopLeft, }, - { - id: "diffs", - label: "Diff Renderer", - eyebrow: "@pierre/diffs", - description: "A spike harness for `PatchDiff` and `FileDiff` with realistic fixtures and rendering options.", - icon: GitCompare, - }, ]; function previewEntries(surface: SurfaceId) { @@ -175,9 +160,7 @@ function DashboardPreview({
@@ -207,111 +190,12 @@ function DashboardPreview({ ); } -function DiffRendererPreview({ - fixtureId, - componentMode, - diffStyle, - overflow, - showLineNumbers, - disableBackground, - themeType, -}: { - fixtureId: DiffRendererFixtureId; - componentMode: DiffComponentMode; - diffStyle: DiffStyle; - overflow: DiffOverflow; - showLineNumbers: boolean; - disableBackground: boolean; - themeType: DiffThemeType; -}) { - const fixture = DIFF_RENDERER_FIXTURES.find((item) => item.id === fixtureId) ?? DIFF_RENDERER_FIXTURES[0]; - const firstFileDiff = fixture.fileDiffs[0]; - - const options = { - diffStyle, - overflow, - disableLineNumbers: !showLineNumbers, - disableBackground, - themeType, - }; - - return ( -
-
-
- - Diff Render - - - {fixture.label} - -
-
- {componentMode === "patch" ? "PatchDiff" : "FileDiff"} • {diffStyle.toUpperCase()} • {fixture.fileDiffs.length} file(s) -
-
-
-
- {componentMode === "file" && !firstFileDiff ? ( -
- Parsed fixture did not produce a file diff payload for `FileDiff`. -
- ) : componentMode === "patch" ? ( - - ) : ( - - )} -
-
-
- ); -} - -function ToggleButtonGroup({ - selected, - options, - onSelect, -}: { - selected: T; - options: Array<{ - id: T; - label: string; - }>; - onSelect: (next: T) => void; -}) { - return ( -
- {options.map((option) => ( - - ))} -
- ); -} - export function RunTranscriptUxLab() { const [selectedSurface, setSelectedSurface] = useState("detail"); const [detailMode, setDetailMode] = useState("nice"); const [streaming, setStreaming] = useState(true); const [density, setDensity] = useState("comfortable"); - const [diffComponentMode, setDiffComponentMode] = useState("file"); - const [diffFixture, setDiffFixture] = useState(DIFF_RENDERER_FIXTURES[0]?.id ?? "small"); - const [diffStyle, setDiffStyle] = useState("unified"); - const [diffOverflow, setDiffOverflow] = useState("scroll"); - const [diffShowLineNumbers, setDiffShowLineNumbers] = useState(true); - const [diffDisableBackground, setDiffDisableBackground] = useState(false); - const [diffThemeType, setDiffThemeType] = useState("system"); - const selected = surfaceOptions.find((option) => option.id === selectedSurface) ?? surfaceOptions[0]; return ( @@ -326,7 +210,7 @@ export function RunTranscriptUxLab() {

Run Transcript Fixtures

- Built from real Paperclip development data, with a focused spike surface for diff rendering controls. + Built from a real Paperclip development run, then sanitized so no secrets, local paths, or environment details survive into the fixture.

@@ -377,129 +261,58 @@ export function RunTranscriptUxLab() {

-
- {selectedSurface === "diffs" ? ( - <> - - Controls - - - selected={diffComponentMode} - options={[ - { id: "patch", label: "PatchDiff" }, - { id: "file", label: "FileDiff" }, - ]} - onSelect={setDiffComponentMode} - /> - - selected={diffFixture} - options={DIFF_RENDERER_FIXTURES.map((fixture) => ({ - id: fixture.id, - label: fixture.label, - }))} - onSelect={setDiffFixture} - /> - - selected={diffStyle} - options={[ - { id: "unified", label: "Unified" }, - { id: "split", label: "Split" }, - ]} - onSelect={setDiffStyle} - /> - - selected={diffOverflow} - options={[{ id: "scroll", label: "Scroll" }, { id: "wrap", label: "Wrap" }]} - onSelect={setDiffOverflow} - /> - - - - selected={diffThemeType} - options={[ - { id: "system", label: "Auto" }, - { id: "light", label: "Light" }, - { id: "dark", label: "Dark" }, - ]} - onSelect={setDiffThemeType} - /> - - ) : ( - <> - - Controls - -
- {(["nice", "raw"] as const).map((mode) => ( - - ))} -
-
- {(["comfortable", "compact"] as const).map((nextDensity) => ( - - ))} -
- - - )} +
+ + Source run {runTranscriptFixtureMeta.sourceRunId.slice(0, 8)} + + + {runTranscriptFixtureMeta.issueIdentifier} +
- + +
+ + Controls + +
+ {(["nice", "raw"] as const).map((mode) => ( + + ))} +
+
+ {(["comfortable", "compact"] as const).map((nextDensity) => ( + + ))} +
+
{selectedSurface === "detail" ? ( @@ -510,18 +323,8 @@ export function RunTranscriptUxLab() {
- ) : selectedSurface === "dashboard" ? ( - ) : ( - + )}