@paperclipai/plugin-workspace-diff 0.1.0 → 2026.620.0-canary.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/contracts.d.ts +6 -6
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +274 -73
- package/dist/ui/index.js.map +3 -3
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +21 -9
- package/dist/worker.js.map +1 -1
- package/dist/workspace-diff.d.ts.map +1 -1
- package/dist/workspace-diff.js +53 -2
- package/dist/workspace-diff.js.map +1 -1
- package/package.json +4 -12
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Paperclip AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/contracts.d.ts
CHANGED
|
@@ -192,6 +192,7 @@ export declare const workspaceDiffFileSchema: z.ZodObject<{
|
|
|
192
192
|
message: string;
|
|
193
193
|
path: string | null;
|
|
194
194
|
}[];
|
|
195
|
+
sizeBytes: number | null;
|
|
195
196
|
untracked: boolean;
|
|
196
197
|
staged: boolean;
|
|
197
198
|
unstaged: boolean;
|
|
@@ -201,7 +202,6 @@ export declare const workspaceDiffFileSchema: z.ZodObject<{
|
|
|
201
202
|
oversized: boolean;
|
|
202
203
|
truncated: boolean;
|
|
203
204
|
oldPath: string | null;
|
|
204
|
-
sizeBytes: number | null;
|
|
205
205
|
patches: {
|
|
206
206
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
207
207
|
warnings: {
|
|
@@ -224,6 +224,7 @@ export declare const workspaceDiffFileSchema: z.ZodObject<{
|
|
|
224
224
|
message: string;
|
|
225
225
|
path: string | null;
|
|
226
226
|
}[];
|
|
227
|
+
sizeBytes: number | null;
|
|
227
228
|
untracked: boolean;
|
|
228
229
|
staged: boolean;
|
|
229
230
|
unstaged: boolean;
|
|
@@ -233,7 +234,6 @@ export declare const workspaceDiffFileSchema: z.ZodObject<{
|
|
|
233
234
|
oversized: boolean;
|
|
234
235
|
truncated: boolean;
|
|
235
236
|
oldPath: string | null;
|
|
236
|
-
sizeBytes: number | null;
|
|
237
237
|
patches: {
|
|
238
238
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
239
239
|
warnings: {
|
|
@@ -371,6 +371,7 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
371
371
|
message: string;
|
|
372
372
|
path: string | null;
|
|
373
373
|
}[];
|
|
374
|
+
sizeBytes: number | null;
|
|
374
375
|
untracked: boolean;
|
|
375
376
|
staged: boolean;
|
|
376
377
|
unstaged: boolean;
|
|
@@ -380,7 +381,6 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
380
381
|
oversized: boolean;
|
|
381
382
|
truncated: boolean;
|
|
382
383
|
oldPath: string | null;
|
|
383
|
-
sizeBytes: number | null;
|
|
384
384
|
patches: {
|
|
385
385
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
386
386
|
warnings: {
|
|
@@ -403,6 +403,7 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
403
403
|
message: string;
|
|
404
404
|
path: string | null;
|
|
405
405
|
}[];
|
|
406
|
+
sizeBytes: number | null;
|
|
406
407
|
untracked: boolean;
|
|
407
408
|
staged: boolean;
|
|
408
409
|
unstaged: boolean;
|
|
@@ -412,7 +413,6 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
412
413
|
oversized: boolean;
|
|
413
414
|
truncated: boolean;
|
|
414
415
|
oldPath: string | null;
|
|
415
|
-
sizeBytes: number | null;
|
|
416
416
|
patches: {
|
|
417
417
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
418
418
|
warnings: {
|
|
@@ -506,6 +506,7 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
506
506
|
message: string;
|
|
507
507
|
path: string | null;
|
|
508
508
|
}[];
|
|
509
|
+
sizeBytes: number | null;
|
|
509
510
|
untracked: boolean;
|
|
510
511
|
staged: boolean;
|
|
511
512
|
unstaged: boolean;
|
|
@@ -515,7 +516,6 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
515
516
|
oversized: boolean;
|
|
516
517
|
truncated: boolean;
|
|
517
518
|
oldPath: string | null;
|
|
518
|
-
sizeBytes: number | null;
|
|
519
519
|
patches: {
|
|
520
520
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
521
521
|
warnings: {
|
|
@@ -571,6 +571,7 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
571
571
|
message: string;
|
|
572
572
|
path: string | null;
|
|
573
573
|
}[];
|
|
574
|
+
sizeBytes: number | null;
|
|
574
575
|
untracked: boolean;
|
|
575
576
|
staged: boolean;
|
|
576
577
|
unstaged: boolean;
|
|
@@ -580,7 +581,6 @@ export declare const workspaceDiffResponseSchema: z.ZodObject<{
|
|
|
580
581
|
oversized: boolean;
|
|
581
582
|
truncated: boolean;
|
|
582
583
|
oldPath: string | null;
|
|
583
|
-
sizeBytes: number | null;
|
|
584
584
|
patches: {
|
|
585
585
|
kind: "head" | "untracked" | "staged" | "unstaged";
|
|
586
586
|
warnings: {
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAgSvE,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,2CA6BA;AAuFD,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CA6Z3D"}
|
package/dist/ui/index.js
CHANGED
|
@@ -24845,7 +24845,14 @@ function mergeFileDiffOptions({ options, hasCustomHeader, hasGutterRenderUtility
|
|
|
24845
24845
|
}
|
|
24846
24846
|
|
|
24847
24847
|
// src/ui/index.tsx
|
|
24848
|
-
import {
|
|
24848
|
+
import {
|
|
24849
|
+
createElement,
|
|
24850
|
+
useCallback as useCallback4,
|
|
24851
|
+
useEffect as useEffect3,
|
|
24852
|
+
useMemo,
|
|
24853
|
+
useRef as useRef3,
|
|
24854
|
+
useState as useState3
|
|
24855
|
+
} from "react";
|
|
24849
24856
|
|
|
24850
24857
|
// src/diff-model.ts
|
|
24851
24858
|
var STATUS_LABELS = {
|
|
@@ -24932,6 +24939,11 @@ function initialExpandedFileSet(files) {
|
|
|
24932
24939
|
|
|
24933
24940
|
// src/ui/index.tsx
|
|
24934
24941
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
24942
|
+
var DEFAULT_FILE_SIDEBAR_WIDTH = 280;
|
|
24943
|
+
var MIN_FILE_SIDEBAR_WIDTH = 220;
|
|
24944
|
+
var MAX_FILE_SIDEBAR_WIDTH = 520;
|
|
24945
|
+
var FILE_SIDEBAR_WIDTH_STEP = 16;
|
|
24946
|
+
var FILE_SIDEBAR_WIDTH_STORAGE_KEY = "paperclip.workspace-diff.files-sidebar-width";
|
|
24935
24947
|
function makeLucideIcon(paths) {
|
|
24936
24948
|
return function LucideIcon({ size = 16 }) {
|
|
24937
24949
|
return /* @__PURE__ */ jsx3(
|
|
@@ -24962,6 +24974,10 @@ function readInitialView() {
|
|
|
24962
24974
|
if (typeof window === "undefined") return "working-tree";
|
|
24963
24975
|
return new URLSearchParams(window.location.search).get("diffView") === "head" ? "head" : "working-tree";
|
|
24964
24976
|
}
|
|
24977
|
+
function hasInitialViewParam() {
|
|
24978
|
+
if (typeof window === "undefined") return false;
|
|
24979
|
+
return new URLSearchParams(window.location.search).has("diffView");
|
|
24980
|
+
}
|
|
24965
24981
|
function readInitialBaseRef() {
|
|
24966
24982
|
if (typeof window === "undefined") return "";
|
|
24967
24983
|
return new URLSearchParams(window.location.search).get("baseRef") ?? "";
|
|
@@ -24978,6 +24994,41 @@ function iconButtonClass(active = false) {
|
|
|
24978
24994
|
active ? "border-foreground/20 bg-foreground text-background" : "border-border bg-background text-muted-foreground hover:text-foreground"
|
|
24979
24995
|
].join(" ");
|
|
24980
24996
|
}
|
|
24997
|
+
function clampFileSidebarWidth(width) {
|
|
24998
|
+
return Math.min(MAX_FILE_SIDEBAR_WIDTH, Math.max(MIN_FILE_SIDEBAR_WIDTH, width));
|
|
24999
|
+
}
|
|
25000
|
+
function readStoredFileSidebarWidth() {
|
|
25001
|
+
if (typeof window === "undefined") return DEFAULT_FILE_SIDEBAR_WIDTH;
|
|
25002
|
+
try {
|
|
25003
|
+
const stored = window.localStorage.getItem(FILE_SIDEBAR_WIDTH_STORAGE_KEY);
|
|
25004
|
+
if (!stored) return DEFAULT_FILE_SIDEBAR_WIDTH;
|
|
25005
|
+
const parsed = Number.parseInt(stored, 10);
|
|
25006
|
+
return Number.isFinite(parsed) ? clampFileSidebarWidth(parsed) : DEFAULT_FILE_SIDEBAR_WIDTH;
|
|
25007
|
+
} catch {
|
|
25008
|
+
return DEFAULT_FILE_SIDEBAR_WIDTH;
|
|
25009
|
+
}
|
|
25010
|
+
}
|
|
25011
|
+
function writeStoredFileSidebarWidth(width) {
|
|
25012
|
+
if (typeof window === "undefined") return;
|
|
25013
|
+
try {
|
|
25014
|
+
window.localStorage.setItem(FILE_SIDEBAR_WIDTH_STORAGE_KEY, String(clampFileSidebarWidth(width)));
|
|
25015
|
+
} catch {
|
|
25016
|
+
}
|
|
25017
|
+
}
|
|
25018
|
+
function useIsDesktopDiffLayout() {
|
|
25019
|
+
const [isDesktop, setIsDesktop] = useState3(() => {
|
|
25020
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
25021
|
+
return window.matchMedia("(min-width: 1024px)").matches;
|
|
25022
|
+
});
|
|
25023
|
+
useEffect3(() => {
|
|
25024
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
25025
|
+
const query = window.matchMedia("(min-width: 1024px)");
|
|
25026
|
+
const update = () => setIsDesktop(query.matches);
|
|
25027
|
+
query.addEventListener("change", update);
|
|
25028
|
+
return () => query.removeEventListener("change", update);
|
|
25029
|
+
}, []);
|
|
25030
|
+
return isDesktop;
|
|
25031
|
+
}
|
|
24981
25032
|
function warningText(file) {
|
|
24982
25033
|
if (file.binary) return "Binary file";
|
|
24983
25034
|
if (file.oversized) return "Too large to render";
|
|
@@ -25127,7 +25178,8 @@ function ErrorState({
|
|
|
25127
25178
|
}
|
|
25128
25179
|
function FileDiffPanel({
|
|
25129
25180
|
file,
|
|
25130
|
-
mode
|
|
25181
|
+
mode,
|
|
25182
|
+
lineWrap
|
|
25131
25183
|
}) {
|
|
25132
25184
|
const warning = warningText(file);
|
|
25133
25185
|
if (warning) {
|
|
@@ -25147,7 +25199,7 @@ function FileDiffPanel({
|
|
|
25147
25199
|
patch: patch.patch,
|
|
25148
25200
|
options: {
|
|
25149
25201
|
diffStyle: mode,
|
|
25150
|
-
overflow: "scroll",
|
|
25202
|
+
overflow: lineWrap ? "wrap" : "scroll",
|
|
25151
25203
|
disableLineNumbers: false,
|
|
25152
25204
|
themeType: "system"
|
|
25153
25205
|
}
|
|
@@ -25182,24 +25234,37 @@ function CollapsedFilePanel({
|
|
|
25182
25234
|
function ChangesTab({ context }) {
|
|
25183
25235
|
const toast = usePluginToast();
|
|
25184
25236
|
const [mode, setMode] = useState3("split");
|
|
25237
|
+
const [lineWrap, setLineWrap] = useState3(false);
|
|
25185
25238
|
const [view, setView] = useState3(() => readInitialView());
|
|
25186
25239
|
const [baseRef, setBaseRef] = useState3(() => readInitialBaseRef());
|
|
25187
25240
|
const baseRefTouchedRef = useRef3(Boolean(baseRef.trim()));
|
|
25241
|
+
const viewTouchedRef = useRef3(hasInitialViewParam());
|
|
25188
25242
|
const [includeUntracked, setIncludeUntracked] = useState3(false);
|
|
25189
25243
|
const [expandedFiles, setExpandedFiles] = useState3(() => /* @__PURE__ */ new Set());
|
|
25190
25244
|
const [selectedPath, setSelectedPath] = useState3(null);
|
|
25245
|
+
const [fileSidebarWidth, setFileSidebarWidth] = useState3(() => readStoredFileSidebarWidth());
|
|
25246
|
+
const [fileSidebarResizing, setFileSidebarResizing] = useState3(false);
|
|
25247
|
+
const fileSidebarWidthRef = useRef3(fileSidebarWidth);
|
|
25248
|
+
const fileSidebarDragRef = useRef3(null);
|
|
25191
25249
|
const fileSectionRefs = useRef3(/* @__PURE__ */ new Map());
|
|
25192
25250
|
const diffScrollRef = useRef3(null);
|
|
25193
25251
|
const scrollSyncFrameRef = useRef3(null);
|
|
25252
|
+
const usesDesktopDiffLayout = useIsDesktopDiffLayout();
|
|
25253
|
+
const requestedBaseRef = baseRef.trim();
|
|
25254
|
+
const effectiveView = view === "head" && !requestedBaseRef ? "working-tree" : view;
|
|
25255
|
+
const fileSidebarStyle = useMemo(
|
|
25256
|
+
() => usesDesktopDiffLayout ? { width: `${fileSidebarWidth}px` } : void 0,
|
|
25257
|
+
[fileSidebarWidth, usesDesktopDiffLayout]
|
|
25258
|
+
);
|
|
25194
25259
|
const params = useMemo(() => ({
|
|
25195
25260
|
workspaceId: context.entityId,
|
|
25196
25261
|
companyId: context.companyId ?? "",
|
|
25197
25262
|
projectId: context.projectId ?? "",
|
|
25198
25263
|
entityType: context.entityType,
|
|
25199
|
-
view,
|
|
25200
|
-
baseRef:
|
|
25264
|
+
view: effectiveView,
|
|
25265
|
+
baseRef: requestedBaseRef || null,
|
|
25201
25266
|
includeUntracked
|
|
25202
|
-
}), [
|
|
25267
|
+
}), [context.companyId, context.entityId, context.entityType, context.projectId, effectiveView, includeUntracked, requestedBaseRef]);
|
|
25203
25268
|
const { data, loading, error, refresh } = usePluginData("workspace-diff", params);
|
|
25204
25269
|
const files = useMemo(() => toFileViewModels(data), [data]);
|
|
25205
25270
|
const summary = useMemo(() => diffSummary(data), [data]);
|
|
@@ -25244,11 +25309,61 @@ function ChangesTab({ context }) {
|
|
|
25244
25309
|
syncSelectedPathFromScroll();
|
|
25245
25310
|
});
|
|
25246
25311
|
}, [syncSelectedPathFromScroll]);
|
|
25312
|
+
const commitFileSidebarWidth = useCallback4((nextWidth) => {
|
|
25313
|
+
const clamped = clampFileSidebarWidth(nextWidth);
|
|
25314
|
+
fileSidebarWidthRef.current = clamped;
|
|
25315
|
+
setFileSidebarWidth(clamped);
|
|
25316
|
+
writeStoredFileSidebarWidth(clamped);
|
|
25317
|
+
}, []);
|
|
25318
|
+
const handleFileSidebarPointerDown = useCallback4((event) => {
|
|
25319
|
+
if (!usesDesktopDiffLayout) return;
|
|
25320
|
+
event.preventDefault();
|
|
25321
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
25322
|
+
fileSidebarDragRef.current = {
|
|
25323
|
+
startX: event.clientX,
|
|
25324
|
+
startWidth: fileSidebarWidthRef.current
|
|
25325
|
+
};
|
|
25326
|
+
setFileSidebarResizing(true);
|
|
25327
|
+
}, [usesDesktopDiffLayout]);
|
|
25328
|
+
const handleFileSidebarPointerMove = useCallback4((event) => {
|
|
25329
|
+
const drag = fileSidebarDragRef.current;
|
|
25330
|
+
if (!drag) return;
|
|
25331
|
+
const nextWidth = clampFileSidebarWidth(drag.startWidth + event.clientX - drag.startX);
|
|
25332
|
+
fileSidebarWidthRef.current = nextWidth;
|
|
25333
|
+
setFileSidebarWidth(nextWidth);
|
|
25334
|
+
}, []);
|
|
25335
|
+
const endFileSidebarResize = useCallback4(() => {
|
|
25336
|
+
if (!fileSidebarDragRef.current) return;
|
|
25337
|
+
fileSidebarDragRef.current = null;
|
|
25338
|
+
setFileSidebarResizing(false);
|
|
25339
|
+
writeStoredFileSidebarWidth(fileSidebarWidthRef.current);
|
|
25340
|
+
}, []);
|
|
25341
|
+
const handleFileSidebarKeyDown = useCallback4((event) => {
|
|
25342
|
+
if (!usesDesktopDiffLayout) return;
|
|
25343
|
+
if (event.key === "ArrowLeft") {
|
|
25344
|
+
event.preventDefault();
|
|
25345
|
+
commitFileSidebarWidth(fileSidebarWidth - FILE_SIDEBAR_WIDTH_STEP);
|
|
25346
|
+
} else if (event.key === "ArrowRight") {
|
|
25347
|
+
event.preventDefault();
|
|
25348
|
+
commitFileSidebarWidth(fileSidebarWidth + FILE_SIDEBAR_WIDTH_STEP);
|
|
25349
|
+
} else if (event.key === "Home") {
|
|
25350
|
+
event.preventDefault();
|
|
25351
|
+
commitFileSidebarWidth(MIN_FILE_SIDEBAR_WIDTH);
|
|
25352
|
+
} else if (event.key === "End") {
|
|
25353
|
+
event.preventDefault();
|
|
25354
|
+
commitFileSidebarWidth(MAX_FILE_SIDEBAR_WIDTH);
|
|
25355
|
+
}
|
|
25356
|
+
}, [commitFileSidebarWidth, fileSidebarWidth, usesDesktopDiffLayout]);
|
|
25247
25357
|
useEffect3(() => {
|
|
25248
25358
|
const defaultBaseRef = data?.defaultBaseRef?.trim();
|
|
25249
|
-
if (!defaultBaseRef
|
|
25250
|
-
|
|
25251
|
-
|
|
25359
|
+
if (!defaultBaseRef) return;
|
|
25360
|
+
if (!baseRef.trim() && !baseRefTouchedRef.current) {
|
|
25361
|
+
setBaseRef(defaultBaseRef);
|
|
25362
|
+
}
|
|
25363
|
+
if (view === "working-tree" && !viewTouchedRef.current) {
|
|
25364
|
+
setView("head");
|
|
25365
|
+
}
|
|
25366
|
+
}, [baseRef, data?.defaultBaseRef, view]);
|
|
25252
25367
|
useEffect3(() => {
|
|
25253
25368
|
if (files.length === 0) {
|
|
25254
25369
|
setExpandedFiles(/* @__PURE__ */ new Set());
|
|
@@ -25265,6 +25380,17 @@ function ChangesTab({ context }) {
|
|
|
25265
25380
|
}
|
|
25266
25381
|
};
|
|
25267
25382
|
}, []);
|
|
25383
|
+
useEffect3(() => {
|
|
25384
|
+
if (!fileSidebarResizing || typeof document === "undefined") return;
|
|
25385
|
+
const previousCursor = document.body.style.cursor;
|
|
25386
|
+
const previousUserSelect = document.body.style.userSelect;
|
|
25387
|
+
document.body.style.cursor = "col-resize";
|
|
25388
|
+
document.body.style.userSelect = "none";
|
|
25389
|
+
return () => {
|
|
25390
|
+
document.body.style.cursor = previousCursor;
|
|
25391
|
+
document.body.style.userSelect = previousUserSelect;
|
|
25392
|
+
};
|
|
25393
|
+
}, [fileSidebarResizing]);
|
|
25268
25394
|
const copyPath = async (filePath) => {
|
|
25269
25395
|
try {
|
|
25270
25396
|
await navigator.clipboard.writeText(filePath);
|
|
@@ -25292,9 +25418,45 @@ function ChangesTab({ context }) {
|
|
|
25292
25418
|
/* @__PURE__ */ jsx3("button", { type: "button", className: buttonClass(mode === "split"), onClick: () => setMode("split"), children: "Split" }, "split"),
|
|
25293
25419
|
/* @__PURE__ */ jsx3("button", { type: "button", className: buttonClass(mode === "unified"), onClick: () => setMode("unified"), children: "Unified" }, "unified")
|
|
25294
25420
|
] }, "layout"),
|
|
25421
|
+
/* @__PURE__ */ jsx3(
|
|
25422
|
+
"button",
|
|
25423
|
+
{
|
|
25424
|
+
type: "button",
|
|
25425
|
+
className: buttonClass(lineWrap),
|
|
25426
|
+
onClick: () => setLineWrap((value) => !value),
|
|
25427
|
+
title: lineWrap ? "Disable line wrapping" : "Enable line wrapping",
|
|
25428
|
+
"aria-pressed": lineWrap,
|
|
25429
|
+
children: lineWrap ? "Wrap on" : "Wrap lines"
|
|
25430
|
+
},
|
|
25431
|
+
"line-wrap"
|
|
25432
|
+
),
|
|
25295
25433
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex gap-1", "aria-label": "Diff comparison", children: [
|
|
25296
|
-
/* @__PURE__ */ jsx3(
|
|
25297
|
-
|
|
25434
|
+
/* @__PURE__ */ jsx3(
|
|
25435
|
+
"button",
|
|
25436
|
+
{
|
|
25437
|
+
type: "button",
|
|
25438
|
+
className: buttonClass(effectiveView === "working-tree"),
|
|
25439
|
+
onClick: () => {
|
|
25440
|
+
viewTouchedRef.current = true;
|
|
25441
|
+
setView("working-tree");
|
|
25442
|
+
},
|
|
25443
|
+
children: "Working tree"
|
|
25444
|
+
},
|
|
25445
|
+
"working-tree"
|
|
25446
|
+
),
|
|
25447
|
+
/* @__PURE__ */ jsx3(
|
|
25448
|
+
"button",
|
|
25449
|
+
{
|
|
25450
|
+
type: "button",
|
|
25451
|
+
className: buttonClass(effectiveView === "head"),
|
|
25452
|
+
onClick: () => {
|
|
25453
|
+
viewTouchedRef.current = true;
|
|
25454
|
+
setView("head");
|
|
25455
|
+
},
|
|
25456
|
+
children: "Against ref"
|
|
25457
|
+
},
|
|
25458
|
+
"head"
|
|
25459
|
+
)
|
|
25298
25460
|
] }, "view"),
|
|
25299
25461
|
view === "head" ? /* @__PURE__ */ jsx3(
|
|
25300
25462
|
"input",
|
|
@@ -25334,27 +25496,59 @@ function ChangesTab({ context }) {
|
|
|
25334
25496
|
)
|
|
25335
25497
|
] }, "actions")
|
|
25336
25498
|
] }, "toolbar"),
|
|
25337
|
-
loading ? /* @__PURE__ */ jsx3(LoadingState, {}) : error ? /* @__PURE__ */ jsx3(ErrorState, { message: error.message, onRetry: refresh }) : files.length === 0 ? /* @__PURE__ */ jsx3(EmptyState, {}) : /* @__PURE__ */ jsxs("div", { className: "
|
|
25338
|
-
/* @__PURE__ */ jsxs(
|
|
25339
|
-
|
|
25340
|
-
|
|
25341
|
-
|
|
25342
|
-
|
|
25343
|
-
|
|
25344
|
-
|
|
25345
|
-
|
|
25346
|
-
|
|
25347
|
-
|
|
25348
|
-
|
|
25349
|
-
|
|
25350
|
-
|
|
25351
|
-
|
|
25352
|
-
|
|
25499
|
+
loading ? /* @__PURE__ */ jsx3(LoadingState, {}) : error ? /* @__PURE__ */ jsx3(ErrorState, { message: error.message, onRetry: refresh }) : files.length === 0 ? /* @__PURE__ */ jsx3(EmptyState, {}) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:h-[70vh] lg:min-h-[560px] lg:max-h-[820px] lg:flex-row", children: [
|
|
25500
|
+
/* @__PURE__ */ jsxs(
|
|
25501
|
+
"aside",
|
|
25502
|
+
{
|
|
25503
|
+
className: "relative flex min-w-0 flex-col border border-border bg-background lg:h-full lg:shrink-0 lg:overflow-hidden",
|
|
25504
|
+
style: fileSidebarStyle,
|
|
25505
|
+
children: [
|
|
25506
|
+
/* @__PURE__ */ jsx3("div", { className: "border-b border-border px-3 py-2 text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground", children: "Files" }, "heading"),
|
|
25507
|
+
/* @__PURE__ */ jsx3("div", { className: "max-h-[70vh] overflow-auto lg:max-h-none lg:flex-1", children: files.map((file, index) => /* @__PURE__ */ jsx3(
|
|
25508
|
+
FileRow,
|
|
25509
|
+
{
|
|
25510
|
+
file,
|
|
25511
|
+
active: file.path === selectedFile?.path,
|
|
25512
|
+
expanded: expandedFiles.has(file.path),
|
|
25513
|
+
onSelect: () => selectFile(file.path),
|
|
25514
|
+
onToggle: () => setExpandedFiles((current) => nextExpandedFileSet(current, file.path)),
|
|
25515
|
+
onCopy: () => void copyPath(file.path)
|
|
25516
|
+
},
|
|
25517
|
+
`${file.path}:${index}`
|
|
25518
|
+
)) }, "list"),
|
|
25519
|
+
/* @__PURE__ */ jsx3(
|
|
25520
|
+
"div",
|
|
25521
|
+
{
|
|
25522
|
+
role: "separator",
|
|
25523
|
+
"aria-label": "Resize file list",
|
|
25524
|
+
"aria-orientation": "vertical",
|
|
25525
|
+
"aria-valuemin": MIN_FILE_SIDEBAR_WIDTH,
|
|
25526
|
+
"aria-valuemax": MAX_FILE_SIDEBAR_WIDTH,
|
|
25527
|
+
"aria-valuenow": fileSidebarWidth,
|
|
25528
|
+
tabIndex: 0,
|
|
25529
|
+
className: [
|
|
25530
|
+
"absolute inset-y-0 right-0 z-20 hidden w-3 cursor-col-resize touch-none outline-none lg:block",
|
|
25531
|
+
"before:absolute before:inset-y-0 before:left-1/2 before:w-px before:-translate-x-1/2 before:bg-transparent before:transition-colors",
|
|
25532
|
+
"hover:before:bg-border focus-visible:before:bg-ring",
|
|
25533
|
+
fileSidebarResizing ? "before:bg-ring" : ""
|
|
25534
|
+
].join(" "),
|
|
25535
|
+
onPointerDown: handleFileSidebarPointerDown,
|
|
25536
|
+
onPointerMove: handleFileSidebarPointerMove,
|
|
25537
|
+
onPointerUp: endFileSidebarResize,
|
|
25538
|
+
onPointerCancel: endFileSidebarResize,
|
|
25539
|
+
onLostPointerCapture: endFileSidebarResize,
|
|
25540
|
+
onKeyDown: handleFileSidebarKeyDown
|
|
25541
|
+
}
|
|
25542
|
+
)
|
|
25543
|
+
]
|
|
25544
|
+
},
|
|
25545
|
+
"files"
|
|
25546
|
+
),
|
|
25353
25547
|
/* @__PURE__ */ jsx3(
|
|
25354
25548
|
"main",
|
|
25355
25549
|
{
|
|
25356
25550
|
ref: diffScrollRef,
|
|
25357
|
-
className: "max-h-[70vh] min-w-0 space-y-3 overflow-auto lg:h-full lg:max-h-none lg:pr-1",
|
|
25551
|
+
className: "max-h-[70vh] min-w-0 flex-1 space-y-3 overflow-auto lg:h-full lg:max-h-none lg:pr-1",
|
|
25358
25552
|
onScroll: handleDiffScroll,
|
|
25359
25553
|
children: files.map((file, index) => /* @__PURE__ */ jsxs(
|
|
25360
25554
|
"section",
|
|
@@ -25362,51 +25556,58 @@ function ChangesTab({ context }) {
|
|
|
25362
25556
|
ref: setFileSectionRef(file.path),
|
|
25363
25557
|
className: file.path === selectedFile?.path ? "scroll-mt-2" : void 0,
|
|
25364
25558
|
children: [
|
|
25365
|
-
/* @__PURE__ */ jsxs(
|
|
25366
|
-
|
|
25367
|
-
|
|
25368
|
-
|
|
25369
|
-
|
|
25370
|
-
|
|
25371
|
-
|
|
25372
|
-
|
|
25373
|
-
|
|
25374
|
-
|
|
25375
|
-
|
|
25376
|
-
|
|
25377
|
-
|
|
25378
|
-
|
|
25379
|
-
|
|
25380
|
-
|
|
25381
|
-
|
|
25382
|
-
|
|
25383
|
-
|
|
25384
|
-
|
|
25385
|
-
|
|
25386
|
-
|
|
25387
|
-
|
|
25388
|
-
|
|
25389
|
-
|
|
25390
|
-
|
|
25391
|
-
|
|
25392
|
-
|
|
25393
|
-
|
|
25394
|
-
|
|
25395
|
-
|
|
25396
|
-
|
|
25397
|
-
|
|
25398
|
-
|
|
25399
|
-
|
|
25400
|
-
className:
|
|
25401
|
-
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25405
|
-
|
|
25406
|
-
|
|
25407
|
-
|
|
25408
|
-
|
|
25409
|
-
|
|
25559
|
+
/* @__PURE__ */ jsxs(
|
|
25560
|
+
"div",
|
|
25561
|
+
{
|
|
25562
|
+
className: "sticky top-0 z-30 flex min-w-0 items-center justify-between gap-3 border border-b-0 border-border bg-background px-3 py-2 shadow-sm",
|
|
25563
|
+
children: [
|
|
25564
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [
|
|
25565
|
+
/* @__PURE__ */ jsx3(
|
|
25566
|
+
"button",
|
|
25567
|
+
{
|
|
25568
|
+
type: "button",
|
|
25569
|
+
className: "mt-0.5 text-muted-foreground hover:text-foreground",
|
|
25570
|
+
title: expandedFiles.has(file.path) ? "Collapse file" : "Expand file",
|
|
25571
|
+
"aria-label": expandedFiles.has(file.path) ? `Collapse ${file.path}` : `Expand ${file.path}`,
|
|
25572
|
+
onClick: () => setExpandedFiles((current) => nextExpandedFileSet(current, file.path)),
|
|
25573
|
+
children: expandedFiles.has(file.path) ? "\u2212" : "+"
|
|
25574
|
+
},
|
|
25575
|
+
"collapse"
|
|
25576
|
+
),
|
|
25577
|
+
/* @__PURE__ */ jsxs(
|
|
25578
|
+
"button",
|
|
25579
|
+
{
|
|
25580
|
+
type: "button",
|
|
25581
|
+
className: "min-w-0 text-left",
|
|
25582
|
+
onClick: () => selectFile(file.path),
|
|
25583
|
+
children: [
|
|
25584
|
+
/* @__PURE__ */ jsx3("div", { className: "truncate text-sm font-medium", children: file.path }, "path"),
|
|
25585
|
+
file.oldPath ? /* @__PURE__ */ jsxs("div", { className: "truncate font-mono text-[11px] text-muted-foreground", children: [
|
|
25586
|
+
"from ",
|
|
25587
|
+
file.oldPath
|
|
25588
|
+
] }, "old-path") : null
|
|
25589
|
+
]
|
|
25590
|
+
},
|
|
25591
|
+
"select"
|
|
25592
|
+
)
|
|
25593
|
+
] }, "left"),
|
|
25594
|
+
/* @__PURE__ */ jsx3("div", { className: "flex shrink-0 items-center gap-1", children: /* @__PURE__ */ jsx3(
|
|
25595
|
+
"button",
|
|
25596
|
+
{
|
|
25597
|
+
type: "button",
|
|
25598
|
+
className: iconButtonClass(false),
|
|
25599
|
+
title: "Copy path",
|
|
25600
|
+
"aria-label": `Copy ${file.path}`,
|
|
25601
|
+
onClick: () => void copyPath(file.path),
|
|
25602
|
+
children: "\u29C9"
|
|
25603
|
+
},
|
|
25604
|
+
"copy"
|
|
25605
|
+
) }, "actions")
|
|
25606
|
+
]
|
|
25607
|
+
},
|
|
25608
|
+
"header"
|
|
25609
|
+
),
|
|
25610
|
+
expandedFiles.has(file.path) ? /* @__PURE__ */ jsx3(FileDiffPanel, { file, mode, lineWrap }, "diff") : /* @__PURE__ */ jsx3(
|
|
25410
25611
|
CollapsedFilePanel,
|
|
25411
25612
|
{
|
|
25412
25613
|
file,
|