@nkzw/codiff-core 1.11.1 → 1.13.0
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/dist/app/components/ReviewCodeView.d.ts +2 -2
- package/dist/app/hooks/useReviewState.d.ts +2 -2
- package/dist/lib/app-types.d.ts +9 -1
- package/dist/lib/narrative-walkthrough-diff.d.ts +2 -0
- package/dist/lib/narrative-walkthrough-diff.mjs +3 -1
- package/dist/lib/narrative-walkthrough.d.ts +1 -0
- package/dist/lib/review-comments.d.ts +1 -1
- package/dist/lib/review-identity.d.ts +3 -0
- package/dist/react.mjs +199 -58
- package/dist/style.css +13 -4
- package/package.json +3 -3
|
@@ -39,7 +39,7 @@ type HeaderReviewDiffBlock = {
|
|
|
39
39
|
selected?: boolean;
|
|
40
40
|
};
|
|
41
41
|
export type ReviewDiffBlock = FileReviewDiffBlock | HeaderReviewDiffBlock;
|
|
42
|
-
export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle, blocks, bottomInset, codeQualityFindings, collapsed, comments, commitMetadata, diffLineHeight, diffStyle, disableWorkerPool,
|
|
42
|
+
export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle, blocks, bottomInset, codeQualityFindings, collapsed, comments, commitMetadata, diffLineHeight, diffStyle, disableWorkerPool, expandedReviewKeys, files, focusCommentId, focusCommentRequest, forceExpandedPaths, gitIdentity, hunkNavigation, initialMarkdownPreviewSectionIds, isReadOnly, itemVersionByKey, keymap, loadingSectionIds, onActiveBlockChange, onAskCodex, onCommentDraftChange, onCreateComment, onDeleteComment, onFindDefinitions, onLoadImageContent, onLoadSection, onLoadSectionContents, onOpenDefinition, onOpenFile, onRefreshMarkdown, onResolveThread, onSaveCommentEdit, onSelectPathFromScroll, onSubmitComment, onToggleCollapsed, onToggleViewed, onUpdateComment, onUpdateSourceDescription, onUpdateSourceTitle, onUploadSourceDescriptionAsset, reviewIdentityByPath, scrollTarget, searchQuery, selectedPath, showSourceDescription, showWhitespace, source, sourceDescriptionActions, sourceDescriptionFooter, supportsReviewCommentActions, theme, viewed, walkthroughNotes, wordWrap, }: {
|
|
43
43
|
activeSearchMatch: DiffSearchMatch | null;
|
|
44
44
|
agentId: 'codex' | 'claude' | 'opencode' | 'pi';
|
|
45
45
|
agentLabel: string;
|
|
@@ -53,7 +53,7 @@ export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel,
|
|
|
53
53
|
diffLineHeight?: number;
|
|
54
54
|
diffStyle: CodiffDiffStyle;
|
|
55
55
|
disableWorkerPool?: boolean;
|
|
56
|
-
|
|
56
|
+
expandedReviewKeys?: ReadonlySet<string>;
|
|
57
57
|
files: ReadonlyArray<ChangedFile>;
|
|
58
58
|
focusCommentId: string | null;
|
|
59
59
|
focusCommentRequest: number;
|
|
@@ -7,11 +7,11 @@ type UseReviewFileStateOptions = {
|
|
|
7
7
|
export declare function useReviewFileState({ initialSelectedPath, onViewedChange, }?: UseReviewFileStateOptions): {
|
|
8
8
|
bumpItemVersion: (key: string) => void;
|
|
9
9
|
collapsed: Set<string>;
|
|
10
|
-
|
|
10
|
+
expandedReviewKeys: Set<string>;
|
|
11
11
|
itemVersionByKey: Record<string, number>;
|
|
12
12
|
selectedPath: string | null;
|
|
13
13
|
setCollapsed: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
|
|
14
|
-
|
|
14
|
+
setExpandedReviewKeys: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
|
|
15
15
|
setItemVersionByKey: import("react").Dispatch<import("react").SetStateAction<Record<string, number>>>;
|
|
16
16
|
setSelectedPath: import("react").Dispatch<import("react").SetStateAction<string | null>>;
|
|
17
17
|
setViewed: import("react").Dispatch<import("react").SetStateAction<Record<string, string>>>;
|
package/dist/lib/app-types.d.ts
CHANGED
|
@@ -52,6 +52,14 @@ export type ReviewScrollTarget = {
|
|
|
52
52
|
request: number;
|
|
53
53
|
};
|
|
54
54
|
export type ReviewIdentity = {
|
|
55
|
+
coverage?: {
|
|
56
|
+
allHunkIds: ReadonlyArray<string>;
|
|
57
|
+
file: {
|
|
58
|
+
fingerprint: string;
|
|
59
|
+
key: string;
|
|
60
|
+
};
|
|
61
|
+
hunkIds: ReadonlyArray<string>;
|
|
62
|
+
};
|
|
55
63
|
fingerprint: string;
|
|
56
64
|
key: string;
|
|
57
65
|
};
|
|
@@ -106,7 +114,7 @@ export type WalkthroughNote = {
|
|
|
106
114
|
};
|
|
107
115
|
export type SourceSession = {
|
|
108
116
|
collapsed: Set<string>;
|
|
109
|
-
|
|
117
|
+
expandedReviewKeys: Set<string>;
|
|
110
118
|
/** Populated by a generated or pre-authored narrative walkthrough document. */
|
|
111
119
|
narrativeWalkthrough?: NarrativeWalkthrough | null;
|
|
112
120
|
reviewComments: ReadonlyArray<ReviewComment>;
|
|
@@ -26,6 +26,7 @@ declare const extractPatchHunks: (patch: string) => {
|
|
|
26
26
|
added: number;
|
|
27
27
|
deleted: number;
|
|
28
28
|
header: string;
|
|
29
|
+
patch: string;
|
|
29
30
|
}[];
|
|
30
31
|
/** @param {ReadonlyArray<{added: number; deleted: number}>} hunks */
|
|
31
32
|
declare const sumHunkLineCounts: (hunks: ReadonlyArray<{
|
|
@@ -95,6 +96,7 @@ declare const getSectionWalkthroughHunks: (file: {
|
|
|
95
96
|
added: number;
|
|
96
97
|
deleted: number;
|
|
97
98
|
header: string;
|
|
99
|
+
patch: string;
|
|
98
100
|
id: string;
|
|
99
101
|
index: number;
|
|
100
102
|
kind: string;
|
|
@@ -102,6 +102,7 @@ const extractPatchHunks = (patch) => {
|
|
|
102
102
|
index += 1;
|
|
103
103
|
continue;
|
|
104
104
|
}
|
|
105
|
+
const hunkStart = index;
|
|
105
106
|
let additions = 0;
|
|
106
107
|
let deletions = 0;
|
|
107
108
|
index += 1;
|
|
@@ -115,7 +116,8 @@ const extractPatchHunks = (patch) => {
|
|
|
115
116
|
...parsed,
|
|
116
117
|
added: additions,
|
|
117
118
|
deleted: deletions,
|
|
118
|
-
header
|
|
119
|
+
header,
|
|
120
|
+
patch: lines.slice(hunkStart, index).join("\n")
|
|
119
121
|
});
|
|
120
122
|
}
|
|
121
123
|
return hunks;
|
|
@@ -42,6 +42,7 @@ export declare const formatWalkthroughFileLineRows: (items: ReadonlyArray<{
|
|
|
42
42
|
deleted: number;
|
|
43
43
|
path: string;
|
|
44
44
|
}>, maxVisibleFiles?: number) => ReadonlyArray<WalkthroughFileLineRow>;
|
|
45
|
+
export declare const getUncoveredWalkthroughReviewIdentity: (file: ChangedFile, view: WalkthroughView, showWhitespace: boolean) => import("./app-types.ts").ReviewIdentity;
|
|
45
46
|
export declare const getUncoveredWalkthroughFiles: (files: ReadonlyArray<ChangedFile>, view: WalkthroughView, showWhitespace: boolean) => ReadonlyArray<ChangedFile>;
|
|
46
47
|
export declare const getUncoveredWalkthroughFileLineItems: (files: ReadonlyArray<ChangedFile>, view: WalkthroughView, showWhitespace: boolean) => ReadonlyArray<{
|
|
47
48
|
added: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChangedFile, PullRequestExistingReviewComment, PullRequestReviewComment, RepositoryState } from '../types.ts';
|
|
2
2
|
import type { CodeViewInstance, ReviewComment } from './app-types.ts';
|
|
3
3
|
export declare const isInteractiveReviewEvent: (event: PointerEvent) => boolean;
|
|
4
|
-
export declare const hasActiveTextSelection: () => boolean;
|
|
4
|
+
export declare const hasActiveTextSelection: (target?: Node | null) => boolean;
|
|
5
5
|
export declare const isFileReviewComment: (comment: Pick<ReviewComment, 'anchor' | 'lineNumber' | 'side'>) => boolean;
|
|
6
6
|
export declare const isLineReviewComment: (comment: ReviewComment) => comment is ReviewComment & {
|
|
7
7
|
lineNumber: number;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ChangedFile } from '../types.ts';
|
|
2
2
|
import type { ReviewIdentity } from './app-types.ts';
|
|
3
3
|
export declare const getFileReviewIdentity: (file: ChangedFile) => ReviewIdentity;
|
|
4
|
+
export declare const getWalkthroughReviewKeyPrefix: (path: string) => string;
|
|
5
|
+
export declare const getSectionReviewHunkIds: (file: ChangedFile, section: ChangedFile['sections'][number]) => ReadonlyArray<string>;
|
|
6
|
+
export declare const getWalkthroughReviewIdentity: (file: ChangedFile, hunkIds: ReadonlyArray<string>) => ReviewIdentity;
|
|
4
7
|
export declare const getReviewIdentity: (file: ChangedFile, identityByPath?: ReadonlyMap<string, ReviewIdentity>) => ReviewIdentity;
|
|
5
8
|
export declare const isReviewIdentityViewed: (viewed: Readonly<Record<string, string>>, identity: ReviewIdentity) => boolean;
|
|
6
9
|
export declare const updateReviewIdentityViewed: (viewed: Readonly<Record<string, string>>, identity: ReviewIdentity, currentlyViewed: boolean) => Record<string, string>;
|
package/dist/react.mjs
CHANGED
|
@@ -44,7 +44,6 @@ import { ArrowRightIcon } from "@phosphor-icons/react/ArrowRight";
|
|
|
44
44
|
import { CaretLeftIcon } from "@phosphor-icons/react/CaretLeft";
|
|
45
45
|
import { CaretRightIcon } from "@phosphor-icons/react/CaretRight";
|
|
46
46
|
import { ArrowsClockwiseIcon } from "@phosphor-icons/react/ArrowsClockwise";
|
|
47
|
-
import { Terminal, init } from "ghostty-web";
|
|
48
47
|
//#region app/components/Button.tsx
|
|
49
48
|
const buttonVariants = cva("codiff-button", {
|
|
50
49
|
defaultVariants: {
|
|
@@ -2380,9 +2379,31 @@ function MergeRequestCommentsView({ canComment, commenting, draft, editDraft, ed
|
|
|
2380
2379
|
//#endregion
|
|
2381
2380
|
//#region lib/review-comments.ts
|
|
2382
2381
|
const isInteractiveReviewEvent = (event) => event.composedPath().some((target) => target instanceof HTMLElement && (target.closest("button, textarea, input, select, a") || target.closest(".review-comment-thread")));
|
|
2383
|
-
const
|
|
2382
|
+
const rangeIntersectsTarget = (range, target) => {
|
|
2383
|
+
const targetRoot = target.getRootNode();
|
|
2384
|
+
if (range.startContainer.getRootNode() !== targetRoot || range.endContainer.getRootNode() !== targetRoot) return false;
|
|
2385
|
+
const selectionRange = (target.ownerDocument ?? document).createRange();
|
|
2386
|
+
selectionRange.setStart(range.startContainer, range.startOffset);
|
|
2387
|
+
selectionRange.setEnd(range.endContainer, range.endOffset);
|
|
2388
|
+
return selectionRange.intersectsNode(target);
|
|
2389
|
+
};
|
|
2390
|
+
const isExpandedSelection = (selection, target) => {
|
|
2391
|
+
if (selection == null || selection.rangeCount === 0) return false;
|
|
2392
|
+
const range = selection.getRangeAt(0);
|
|
2393
|
+
return (!selection.isCollapsed || selection.toString().length > 0 || !range.collapsed) && (!target || rangeIntersectsTarget(range, target));
|
|
2394
|
+
};
|
|
2395
|
+
const isExpandedRange = (range, target) => range != null && !range.collapsed && (!target || rangeIntersectsTarget(range, target));
|
|
2396
|
+
const hasActiveTextSelection = (target) => {
|
|
2384
2397
|
const selection = window.getSelection();
|
|
2385
|
-
|
|
2398
|
+
const root = target?.getRootNode();
|
|
2399
|
+
const shadowRoot = root && "host" in root ? root : null;
|
|
2400
|
+
if (shadowRoot) {
|
|
2401
|
+
const composedRange = selection?.getComposedRanges?.({ shadowRoots: [shadowRoot] })[0];
|
|
2402
|
+
if (isExpandedRange(composedRange, target)) return true;
|
|
2403
|
+
const shadowSelection = shadowRoot.getSelection?.();
|
|
2404
|
+
if (isExpandedSelection(shadowSelection, target)) return true;
|
|
2405
|
+
}
|
|
2406
|
+
return isExpandedSelection(selection, target);
|
|
2386
2407
|
};
|
|
2387
2408
|
const isFileReviewComment = (comment) => comment.anchor === "file" || comment.lineNumber == null || comment.side == null;
|
|
2388
2409
|
const isLineReviewComment = (comment) => !isFileReviewComment(comment);
|
|
@@ -3924,18 +3945,46 @@ const getFileReviewIdentity = (file) => ({
|
|
|
3924
3945
|
fingerprint: file.fingerprint,
|
|
3925
3946
|
key: file.path
|
|
3926
3947
|
});
|
|
3948
|
+
const getWalkthroughReviewKeyPrefix = (path) => `walkthrough:${JSON.stringify(path)}:`;
|
|
3949
|
+
const getHunkViewedKey = (path, hunkId) => `${getWalkthroughReviewKeyPrefix(path)}${JSON.stringify(hunkId)}`;
|
|
3950
|
+
const getSectionReviewHunkIds = (file, section) => {
|
|
3951
|
+
const ids = getSectionWalkthroughHunks(file, section).map((hunk) => hunk.id);
|
|
3952
|
+
return ids.length > 0 ? ids : [section.id];
|
|
3953
|
+
};
|
|
3954
|
+
const getWalkthroughReviewIdentity = (file, hunkIds) => ({
|
|
3955
|
+
coverage: {
|
|
3956
|
+
allHunkIds: file.sections.flatMap((section) => getSectionReviewHunkIds(file, section)),
|
|
3957
|
+
file: getFileReviewIdentity(file),
|
|
3958
|
+
hunkIds
|
|
3959
|
+
},
|
|
3960
|
+
fingerprint: file.fingerprint,
|
|
3961
|
+
key: `${getWalkthroughReviewKeyPrefix(file.path)}${JSON.stringify(hunkIds)}`
|
|
3962
|
+
});
|
|
3927
3963
|
const getReviewIdentity = (file, identityByPath) => identityByPath?.get(file.path) ?? getFileReviewIdentity(file);
|
|
3928
|
-
const isReviewIdentityViewed = (viewed, identity) =>
|
|
3964
|
+
const isReviewIdentityViewed = (viewed, identity) => {
|
|
3965
|
+
const { coverage } = identity;
|
|
3966
|
+
return coverage ? viewed[coverage.file.key] === coverage.file.fingerprint || coverage.hunkIds.length > 0 && coverage.hunkIds.every((id) => viewed[getHunkViewedKey(coverage.file.key, id)] === coverage.file.fingerprint) : viewed[identity.key] === identity.fingerprint;
|
|
3967
|
+
};
|
|
3929
3968
|
const updateReviewIdentityViewed = (viewed, identity, currentlyViewed) => {
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3969
|
+
const next = { ...viewed };
|
|
3970
|
+
const { coverage } = identity;
|
|
3971
|
+
if (coverage) {
|
|
3972
|
+
const { allHunkIds, file, hunkIds } = coverage;
|
|
3973
|
+
if (viewed[file.key] === file.fingerprint) for (const id of allHunkIds) next[getHunkViewedKey(file.key, id)] = file.fingerprint;
|
|
3974
|
+
for (const id of hunkIds) {
|
|
3975
|
+
const key = getHunkViewedKey(file.key, id);
|
|
3976
|
+
if (currentlyViewed) delete next[key];
|
|
3977
|
+
else next[key] = file.fingerprint;
|
|
3978
|
+
}
|
|
3979
|
+
if (allHunkIds.length > 0 && allHunkIds.every((id) => next[getHunkViewedKey(file.key, id)] === file.fingerprint)) next[file.key] = file.fingerprint;
|
|
3980
|
+
else delete next[file.key];
|
|
3933
3981
|
return next;
|
|
3934
3982
|
}
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3983
|
+
const prefix = getWalkthroughReviewKeyPrefix(identity.key);
|
|
3984
|
+
for (const key of Object.keys(next)) if (key.startsWith(prefix)) delete next[key];
|
|
3985
|
+
if (currentlyViewed) delete next[identity.key];
|
|
3986
|
+
else next[identity.key] = identity.fingerprint;
|
|
3987
|
+
return next;
|
|
3939
3988
|
};
|
|
3940
3989
|
const updateReviewIdentityCollapsed = (collapsed, identity, currentlyCollapsed) => {
|
|
3941
3990
|
const next = new Set(collapsed);
|
|
@@ -4287,6 +4336,7 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4287
4336
|
if (coveredSyntheticSectionIds.has(section.id)) return null;
|
|
4288
4337
|
const hunkIds = getSectionHunkIds(file, section);
|
|
4289
4338
|
if (hunkIds.length === 0) return coveredSectionIds.has(section.id) ? null : {
|
|
4339
|
+
hunkIds: [section.id],
|
|
4290
4340
|
identity: section.id,
|
|
4291
4341
|
section
|
|
4292
4342
|
};
|
|
@@ -4294,11 +4344,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4294
4344
|
if (uncoveredHunkIds.length === 0) return null;
|
|
4295
4345
|
const identity = `${section.id}:${uncoveredHunkIds.join(",")}`;
|
|
4296
4346
|
if (uncoveredHunkIds.length === hunkIds.length) return {
|
|
4347
|
+
hunkIds: uncoveredHunkIds,
|
|
4297
4348
|
identity,
|
|
4298
4349
|
section
|
|
4299
4350
|
};
|
|
4300
4351
|
const patch = filterPatchToHunkIds(section.patch, section.id, uncoveredHunkIds);
|
|
4301
4352
|
return patch ? {
|
|
4353
|
+
hunkIds: uncoveredHunkIds,
|
|
4302
4354
|
identity,
|
|
4303
4355
|
section: {
|
|
4304
4356
|
...section,
|
|
@@ -4306,6 +4358,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4306
4358
|
}
|
|
4307
4359
|
} : null;
|
|
4308
4360
|
};
|
|
4361
|
+
const getUncoveredWalkthroughReviewIdentity = (file, view, showWhitespace) => {
|
|
4362
|
+
const coveredHunkIds = walkthroughCoveredHunkIds(view);
|
|
4363
|
+
const coveredSectionIds = walkthroughCoveredSectionIds(view);
|
|
4364
|
+
const coveredSyntheticSectionIds = walkthroughCoveredSyntheticSectionIds(view);
|
|
4365
|
+
const hunkIds = getVisibleDiffSections(file, showWhitespace).flatMap(({ section }) => getUncoveredWalkthroughSection(file, section, coveredHunkIds, coveredSectionIds, coveredSyntheticSectionIds)?.hunkIds ?? []);
|
|
4366
|
+
return getWalkthroughReviewIdentity(file, hunkIds);
|
|
4367
|
+
};
|
|
4309
4368
|
const getUncoveredWalkthroughFiles = (files, view, showWhitespace) => {
|
|
4310
4369
|
const coveredHunkIds = walkthroughCoveredHunkIds(view);
|
|
4311
4370
|
const coveredSectionIds = walkthroughCoveredSectionIds(view);
|
|
@@ -4952,7 +5011,7 @@ function DiffLineCountBadge({ ariaLabelPrefix, className = "codiff-line-count",
|
|
|
4952
5011
|
//#endregion
|
|
4953
5012
|
//#region app/components/ReviewCodeView.tsx
|
|
4954
5013
|
const emptyMarkdownPreviewSectionIds = /* @__PURE__ */ new Set();
|
|
4955
|
-
const
|
|
5014
|
+
const emptyExpandedReviewKeys = /* @__PURE__ */ new Set();
|
|
4956
5015
|
const markdownPreviewPlugins = [frontmatterPlugin(), imagePlugin({
|
|
4957
5016
|
disableImageResize: true,
|
|
4958
5017
|
disableImageSettingsButton: true
|
|
@@ -5957,8 +6016,9 @@ function ReviewCommentEditor({ agentId, agentLabel, comment, displayName, focusC
|
|
|
5957
6016
|
onSaveCommentEdit
|
|
5958
6017
|
]);
|
|
5959
6018
|
const handleBlur = useCallback(() => {
|
|
5960
|
-
onCommentBlur(
|
|
6019
|
+
onCommentBlur(comment, draft, flushDraft);
|
|
5961
6020
|
}, [
|
|
6021
|
+
comment,
|
|
5962
6022
|
draft,
|
|
5963
6023
|
flushDraft,
|
|
5964
6024
|
onCommentBlur
|
|
@@ -6582,7 +6642,7 @@ const getHunkSelectionRange = (hunk) => {
|
|
|
6582
6642
|
} : null;
|
|
6583
6643
|
};
|
|
6584
6644
|
const isSameSelection = (a, b) => a.start === b.start && a.end === b.end && a.side === b.side;
|
|
6585
|
-
function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle = false, blocks, bottomInset = codeViewLayout.paddingBottom, codeQualityFindings = [], collapsed, comments, commitMetadata, diffLineHeight = 20, diffStyle, disableWorkerPool = false,
|
|
6645
|
+
function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle = false, blocks, bottomInset = codeViewLayout.paddingBottom, codeQualityFindings = [], collapsed, comments, commitMetadata, diffLineHeight = 20, diffStyle, disableWorkerPool = false, expandedReviewKeys = emptyExpandedReviewKeys, files, focusCommentId, focusCommentRequest, forceExpandedPaths, gitIdentity, hunkNavigation, initialMarkdownPreviewSectionIds = emptyMarkdownPreviewSectionIds, isReadOnly = false, itemVersionByKey, keymap, loadingSectionIds, onActiveBlockChange, onAskCodex, onCommentDraftChange, onCreateComment, onDeleteComment, onFindDefinitions, onLoadImageContent, onLoadSection, onLoadSectionContents, onOpenDefinition, onOpenFile, onRefreshMarkdown, onResolveThread = noopResolveThread, onSaveCommentEdit, onSelectPathFromScroll, onSubmitComment, onToggleCollapsed, onToggleViewed, onUpdateComment, onUpdateSourceDescription, onUpdateSourceTitle, onUploadSourceDescriptionAsset, reviewIdentityByPath, scrollTarget, searchQuery, selectedPath, showSourceDescription = true, showWhitespace, source, sourceDescriptionActions, sourceDescriptionFooter, supportsReviewCommentActions, theme = "system", viewed, walkthroughNotes, wordWrap }) {
|
|
6586
6646
|
const codeViewRef = useRef(null);
|
|
6587
6647
|
const markdownEditorRefs = useRef(/* @__PURE__ */ new Map());
|
|
6588
6648
|
const refreshingMarkdownSectionsRef = useRef(/* @__PURE__ */ new Set());
|
|
@@ -6590,6 +6650,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6590
6650
|
const handledScrollRequestRef = useRef(null);
|
|
6591
6651
|
const handledHunkNavRef = useRef(hunkNavigation?.request ?? null);
|
|
6592
6652
|
const emptyCommentDeleteTimersRef = useRef(/* @__PURE__ */ new Map());
|
|
6653
|
+
const activePointerIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
6654
|
+
const pendingCommentBlursRef = useRef(/* @__PURE__ */ new Map());
|
|
6655
|
+
const pendingCommentBlurTimerRef = useRef(null);
|
|
6656
|
+
const focusedCommentEditorIdRef = useRef(null);
|
|
6593
6657
|
const definitionHighlightFrameRef = useRef(null);
|
|
6594
6658
|
const highlightFrameRef = useRef(null);
|
|
6595
6659
|
const ignoreNextLineSelectionEndRef = useRef(false);
|
|
@@ -6703,7 +6767,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6703
6767
|
const reviewIdentity = block.reviewIdentity ?? getReviewIdentity(file, reviewIdentityByPath);
|
|
6704
6768
|
const reviewKey = reviewIdentity.key;
|
|
6705
6769
|
const isViewed = isReviewIdentityViewed(viewed, reviewIdentity);
|
|
6706
|
-
const isCollapsed = !forceExpandedPaths.has(file.path) && !
|
|
6770
|
+
const isCollapsed = !forceExpandedPaths.has(file.path) && !expandedReviewKeys.has(reviewKey) && (isViewed || collapsed.has(reviewKey) || isGeneratedWalkthroughFile(file));
|
|
6707
6771
|
const visibleSections = getVisibleDiffSections(file, showWhitespace);
|
|
6708
6772
|
const lineCount = getDiffLineCountFromVisibleSections(visibleSections);
|
|
6709
6773
|
const sections = isCollapsed ? visibleSections.slice(0, 1) : visibleSections;
|
|
@@ -6865,7 +6929,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6865
6929
|
commentsBySection,
|
|
6866
6930
|
diffLineHeight,
|
|
6867
6931
|
diffStyle,
|
|
6868
|
-
|
|
6932
|
+
expandedReviewKeys,
|
|
6869
6933
|
forceExpandedPaths,
|
|
6870
6934
|
imagePreviewLayoutPassBySection,
|
|
6871
6935
|
isReadOnly,
|
|
@@ -6939,6 +7003,66 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6939
7003
|
}
|
|
6940
7004
|
emptyCommentDeleteTimersRef.current.clear();
|
|
6941
7005
|
}, []);
|
|
7006
|
+
const flushPendingCommentBlurs = useCallback(() => {
|
|
7007
|
+
if (activePointerIdsRef.current.size > 0) return;
|
|
7008
|
+
const callbacks = [...pendingCommentBlursRef.current.values()];
|
|
7009
|
+
pendingCommentBlursRef.current.clear();
|
|
7010
|
+
for (const callback of callbacks) callback();
|
|
7011
|
+
}, []);
|
|
7012
|
+
const schedulePendingCommentBlurFlush = useCallback(() => {
|
|
7013
|
+
if (activePointerIdsRef.current.size > 0 || pendingCommentBlursRef.current.size === 0 || pendingCommentBlurTimerRef.current != null) return;
|
|
7014
|
+
const timer = window.setTimeout(() => {
|
|
7015
|
+
deferredTimersRef.current.delete(timer);
|
|
7016
|
+
pendingCommentBlurTimerRef.current = null;
|
|
7017
|
+
flushPendingCommentBlurs();
|
|
7018
|
+
}, 0);
|
|
7019
|
+
pendingCommentBlurTimerRef.current = timer;
|
|
7020
|
+
deferredTimersRef.current.add(timer);
|
|
7021
|
+
}, [flushPendingCommentBlurs]);
|
|
7022
|
+
useEffect(() => {
|
|
7023
|
+
const activePointerIds = activePointerIdsRef.current;
|
|
7024
|
+
const deferredTimers = deferredTimersRef.current;
|
|
7025
|
+
const pendingCommentBlurs = pendingCommentBlursRef.current;
|
|
7026
|
+
const handlePointerDown = (event) => {
|
|
7027
|
+
const timer = pendingCommentBlurTimerRef.current;
|
|
7028
|
+
if (timer != null) {
|
|
7029
|
+
window.clearTimeout(timer);
|
|
7030
|
+
deferredTimers.delete(timer);
|
|
7031
|
+
pendingCommentBlurTimerRef.current = null;
|
|
7032
|
+
}
|
|
7033
|
+
activePointerIds.add(event.pointerId);
|
|
7034
|
+
};
|
|
7035
|
+
const handlePointerEnd = (event) => {
|
|
7036
|
+
activePointerIds.delete(event.pointerId);
|
|
7037
|
+
schedulePendingCommentBlurFlush();
|
|
7038
|
+
};
|
|
7039
|
+
const handleWindowBlur = () => {
|
|
7040
|
+
activePointerIds.clear();
|
|
7041
|
+
schedulePendingCommentBlurFlush();
|
|
7042
|
+
};
|
|
7043
|
+
window.addEventListener("pointerdown", handlePointerDown, true);
|
|
7044
|
+
window.addEventListener("pointercancel", handlePointerEnd, true);
|
|
7045
|
+
window.addEventListener("pointerup", handlePointerEnd, true);
|
|
7046
|
+
window.addEventListener("blur", handleWindowBlur);
|
|
7047
|
+
return () => {
|
|
7048
|
+
window.removeEventListener("pointerdown", handlePointerDown, true);
|
|
7049
|
+
window.removeEventListener("pointercancel", handlePointerEnd, true);
|
|
7050
|
+
window.removeEventListener("pointerup", handlePointerEnd, true);
|
|
7051
|
+
window.removeEventListener("blur", handleWindowBlur);
|
|
7052
|
+
activePointerIds.clear();
|
|
7053
|
+
pendingCommentBlurs.clear();
|
|
7054
|
+
const timer = pendingCommentBlurTimerRef.current;
|
|
7055
|
+
if (timer != null) {
|
|
7056
|
+
window.clearTimeout(timer);
|
|
7057
|
+
deferredTimers.delete(timer);
|
|
7058
|
+
pendingCommentBlurTimerRef.current = null;
|
|
7059
|
+
}
|
|
7060
|
+
};
|
|
7061
|
+
}, [schedulePendingCommentBlurFlush]);
|
|
7062
|
+
const deferCommentBlurUntilPointerEnd = useCallback((commentId, callback) => {
|
|
7063
|
+
if (activePointerIdsRef.current.size > 0 || pendingCommentBlurTimerRef.current != null) pendingCommentBlursRef.current.set(commentId, callback);
|
|
7064
|
+
else callback();
|
|
7065
|
+
}, []);
|
|
6942
7066
|
const scrollFileItemToTop = useCallback((itemId) => {
|
|
6943
7067
|
const handle = codeViewRef.current;
|
|
6944
7068
|
const viewer = handle?.getInstance();
|
|
@@ -7034,10 +7158,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7034
7158
|
createCommentForRange(range, context);
|
|
7035
7159
|
},
|
|
7036
7160
|
onLineClick: (line, context) => {
|
|
7161
|
+
const lineElement = "lineElement" in line ? line.lineElement : null;
|
|
7037
7162
|
if (isPrimaryModifier(line.event) && onFindDefinitions) {
|
|
7038
7163
|
line.event.preventDefault();
|
|
7039
7164
|
line.event.stopPropagation();
|
|
7040
|
-
const lineElement = "lineElement" in line ? line.lineElement : null;
|
|
7041
7165
|
const identifier = lineElement ? getIdentifierFromPointerEvent(line.event, lineElement) : null;
|
|
7042
7166
|
const meta = itemMetadata.get(context.item.id);
|
|
7043
7167
|
const side = "annotationSide" in line ? line.annotationSide : null;
|
|
@@ -7086,7 +7210,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7086
7210
|
onLoadSection(meta.file, meta.section);
|
|
7087
7211
|
return;
|
|
7088
7212
|
}
|
|
7089
|
-
if (hasActiveTextSelection()) return;
|
|
7213
|
+
if (hasActiveTextSelection(lineElement)) return;
|
|
7090
7214
|
const side = "annotationSide" in line ? line.annotationSide : null;
|
|
7091
7215
|
if (!side) return;
|
|
7092
7216
|
cancelPendingEmptyCommentDeletes();
|
|
@@ -7147,6 +7271,8 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7147
7271
|
wordWrap
|
|
7148
7272
|
]);
|
|
7149
7273
|
const focusComment = useCallback((comment) => {
|
|
7274
|
+
focusedCommentEditorIdRef.current = comment.id;
|
|
7275
|
+
pendingCommentBlursRef.current.delete(comment.id);
|
|
7150
7276
|
onCommentDraftChange?.({
|
|
7151
7277
|
body: comment.body,
|
|
7152
7278
|
id: comment.id
|
|
@@ -7157,25 +7283,32 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7157
7283
|
deferredTimersRef.current.delete(timer);
|
|
7158
7284
|
emptyCommentDeleteTimersRef.current.delete(comment.id);
|
|
7159
7285
|
}, [onCommentDraftChange]);
|
|
7160
|
-
const blurComment = useCallback((comment, body) => {
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
if (existingTimer != null) {
|
|
7166
|
-
window.clearTimeout(existingTimer);
|
|
7167
|
-
deferredTimersRef.current.delete(existingTimer);
|
|
7286
|
+
const blurComment = useCallback((comment, body, flushDraft) => {
|
|
7287
|
+
deferCommentBlurUntilPointerEnd(comment.id, () => {
|
|
7288
|
+
if (focusedCommentEditorIdRef.current === comment.id) {
|
|
7289
|
+
focusedCommentEditorIdRef.current = null;
|
|
7290
|
+
onCommentDraftChange?.(null);
|
|
7168
7291
|
}
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7292
|
+
flushDraft();
|
|
7293
|
+
clearCommentLineHighlight();
|
|
7294
|
+
if (!comment.isReadOnly && body.trim().length === 0) {
|
|
7295
|
+
const existingTimer = emptyCommentDeleteTimersRef.current.get(comment.id);
|
|
7296
|
+
if (existingTimer != null) {
|
|
7297
|
+
window.clearTimeout(existingTimer);
|
|
7298
|
+
deferredTimersRef.current.delete(existingTimer);
|
|
7299
|
+
}
|
|
7300
|
+
const timer = window.setTimeout(() => {
|
|
7301
|
+
deferredTimersRef.current.delete(timer);
|
|
7302
|
+
emptyCommentDeleteTimersRef.current.delete(comment.id);
|
|
7303
|
+
onDeleteComment(comment.id);
|
|
7304
|
+
}, 120);
|
|
7305
|
+
deferredTimersRef.current.add(timer);
|
|
7306
|
+
emptyCommentDeleteTimersRef.current.set(comment.id, timer);
|
|
7307
|
+
}
|
|
7308
|
+
});
|
|
7177
7309
|
}, [
|
|
7178
7310
|
clearCommentLineHighlight,
|
|
7311
|
+
deferCommentBlurUntilPointerEnd,
|
|
7179
7312
|
onCommentDraftChange,
|
|
7180
7313
|
onDeleteComment
|
|
7181
7314
|
]);
|
|
@@ -7883,6 +8016,12 @@ function resolveBackdrop(element) {
|
|
|
7883
8016
|
}
|
|
7884
8017
|
return "#00000000";
|
|
7885
8018
|
}
|
|
8019
|
+
let ghosttyModule = null;
|
|
8020
|
+
const loadGhostty = async () => {
|
|
8021
|
+
const ghostty = await (ghosttyModule ??= import("ghostty-web"));
|
|
8022
|
+
await ghostty.init();
|
|
8023
|
+
return ghostty;
|
|
8024
|
+
};
|
|
7886
8025
|
/**
|
|
7887
8026
|
* Read-only ghostty-web terminal that replays the streamed commit output, so
|
|
7888
8027
|
* ANSI colors and cursor movement from pre-commit hooks render as they would
|
|
@@ -7897,7 +8036,7 @@ function CommitLogTerminal({ output }) {
|
|
|
7897
8036
|
if (!container) return;
|
|
7898
8037
|
let disposed = false;
|
|
7899
8038
|
let instance = null;
|
|
7900
|
-
|
|
8039
|
+
loadGhostty().then(({ Terminal }) => {
|
|
7901
8040
|
if (disposed) return;
|
|
7902
8041
|
const style = getComputedStyle(container);
|
|
7903
8042
|
instance = new Terminal({
|
|
@@ -8354,10 +8493,7 @@ const getFocusedRunDiffs = (item, files) => resolveWalkthroughHunkRuns(item, fil
|
|
|
8354
8493
|
return focused ? [{
|
|
8355
8494
|
file: focused,
|
|
8356
8495
|
note: getWalkthroughRunNote(item, run),
|
|
8357
|
-
reviewIdentity:
|
|
8358
|
-
fingerprint: focused.fingerprint,
|
|
8359
|
-
key: `walkthrough:${run.key}`
|
|
8360
|
-
}
|
|
8496
|
+
reviewIdentity: getWalkthroughReviewIdentity(run.resolved.file, run.hunks.flatMap((hunk) => hunk.kind === "synthetic" ? getSectionReviewHunkIds(run.resolved.file, run.resolved.section) : [hunk.id]))
|
|
8361
8497
|
}] : [];
|
|
8362
8498
|
});
|
|
8363
8499
|
const getWalkthroughNavigationKeyDirection = (event) => {
|
|
@@ -8471,10 +8607,7 @@ const createSupportBlocks = (files, selected, walkthroughView, showWhitespace) =
|
|
|
8471
8607
|
id: blockId,
|
|
8472
8608
|
itemIdPrefix: blockId,
|
|
8473
8609
|
note: "Not included in the generated walkthrough.",
|
|
8474
|
-
reviewIdentity:
|
|
8475
|
-
fingerprint: file.fingerprint,
|
|
8476
|
-
key: blockId
|
|
8477
|
-
}
|
|
8610
|
+
reviewIdentity: getUncoveredWalkthroughReviewIdentity(files.find((candidate) => candidate.path === file.path), walkthroughView, showWhitespace)
|
|
8478
8611
|
});
|
|
8479
8612
|
}
|
|
8480
8613
|
return blocks;
|
|
@@ -9391,7 +9524,7 @@ function useReviewCommentDrafts({ canCreateComment = true, comments, onCommentFi
|
|
|
9391
9524
|
//#region app/hooks/useReviewState.ts
|
|
9392
9525
|
function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {}) {
|
|
9393
9526
|
const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
|
|
9394
|
-
const [
|
|
9527
|
+
const [expandedReviewKeys, setExpandedReviewKeys] = useState(() => /* @__PURE__ */ new Set());
|
|
9395
9528
|
const [itemVersionByKey, setItemVersionByKey] = useState({});
|
|
9396
9529
|
const [selectedPath, setSelectedPath] = useState(initialSelectedPath);
|
|
9397
9530
|
const [viewed, setViewed] = useState({});
|
|
@@ -9404,11 +9537,11 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9404
9537
|
return {
|
|
9405
9538
|
bumpItemVersion,
|
|
9406
9539
|
collapsed,
|
|
9407
|
-
|
|
9540
|
+
expandedReviewKeys,
|
|
9408
9541
|
itemVersionByKey,
|
|
9409
9542
|
selectedPath,
|
|
9410
9543
|
setCollapsed,
|
|
9411
|
-
|
|
9544
|
+
setExpandedReviewKeys,
|
|
9412
9545
|
setItemVersionByKey,
|
|
9413
9546
|
setSelectedPath,
|
|
9414
9547
|
setViewed,
|
|
@@ -9419,9 +9552,9 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9419
9552
|
else next.add(reviewKey);
|
|
9420
9553
|
return next;
|
|
9421
9554
|
});
|
|
9422
|
-
|
|
9555
|
+
setExpandedReviewKeys((current) => {
|
|
9423
9556
|
const next = new Set(current);
|
|
9424
|
-
if (isCollapsed
|
|
9557
|
+
if (isCollapsed) next.add(reviewKey);
|
|
9425
9558
|
else next.delete(reviewKey);
|
|
9426
9559
|
return next;
|
|
9427
9560
|
});
|
|
@@ -9433,12 +9566,20 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9433
9566
|
onViewedChange?.(next);
|
|
9434
9567
|
return next;
|
|
9435
9568
|
});
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9569
|
+
const fileKey = reviewIdentity.coverage?.file.key ?? file.path;
|
|
9570
|
+
const prefix = getWalkthroughReviewKeyPrefix(fileKey);
|
|
9571
|
+
const clearRelatedKeys = (current) => new Set([...current].filter((key) => key !== fileKey && (reviewIdentity.coverage ? key !== reviewIdentity.key : !key.startsWith(prefix))));
|
|
9572
|
+
if (reviewIdentity.coverage || reviewIdentity.key === file.path) {
|
|
9573
|
+
setCollapsed(clearRelatedKeys);
|
|
9574
|
+
setExpandedReviewKeys(clearRelatedKeys);
|
|
9575
|
+
} else {
|
|
9576
|
+
setCollapsed((current) => updateReviewIdentityCollapsed(current, reviewIdentity, isViewed));
|
|
9577
|
+
setExpandedReviewKeys((current) => {
|
|
9578
|
+
const next = new Set(current);
|
|
9579
|
+
next.delete(reviewIdentity.key);
|
|
9580
|
+
return next;
|
|
9581
|
+
});
|
|
9582
|
+
}
|
|
9442
9583
|
bumpItemVersion(reviewIdentity.key);
|
|
9443
9584
|
}, [bumpItemVersion, onViewedChange]),
|
|
9444
9585
|
viewed
|
|
@@ -9471,13 +9612,13 @@ const defaultConfigTemplate = {
|
|
|
9471
9612
|
keymap: {
|
|
9472
9613
|
"askAgent": "Mod+Alt+Enter",
|
|
9473
9614
|
"closeSearch": "Escape",
|
|
9474
|
-
"commandBar": "Mod+
|
|
9615
|
+
"commandBar": "Mod+k",
|
|
9475
9616
|
"diffSearch": "Mod+f",
|
|
9476
9617
|
"discardComment": "Escape",
|
|
9477
9618
|
"fileFilter": "Mod+p",
|
|
9478
9619
|
"nextHunk": ["Ctrl+ArrowDown", "j"],
|
|
9479
9620
|
"nextSearchMatch": "Enter",
|
|
9480
|
-
"openFile": "Mod+
|
|
9621
|
+
"openFile": "Mod+Shift+o",
|
|
9481
9622
|
"prevHunk": ["Ctrl+ArrowUp", "k"],
|
|
9482
9623
|
"prevSearchMatch": "Shift+Enter",
|
|
9483
9624
|
"shortcutsHelp": "Shift+?",
|
|
@@ -9631,7 +9772,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
|
|
|
9631
9772
|
}, [keymap, toggleSidebar]);
|
|
9632
9773
|
const sidebarMode = Boolean(initialMode && onModeChange) && initialMode ? initialMode : uncontrolledSidebarMode;
|
|
9633
9774
|
const [treeScrollTarget, setTreeScrollTarget] = useState(null);
|
|
9634
|
-
const { bumpItemVersion, collapsed,
|
|
9775
|
+
const { bumpItemVersion, collapsed, expandedReviewKeys, itemVersionByKey, selectedPath, setSelectedPath, toggleCollapsed, toggleViewed, viewed } = useReviewFileState({ initialSelectedPath: snapshot.files[0]?.path ?? null });
|
|
9635
9776
|
const { resizeSidebar, sidebarWidth } = useResizableSidebar({
|
|
9636
9777
|
collapseThreshold: 80,
|
|
9637
9778
|
onCollapse: () => {
|
|
@@ -10006,7 +10147,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
|
|
|
10006
10147
|
diffLineHeight,
|
|
10007
10148
|
diffStyle: snapshot.preferences.diffStyle,
|
|
10008
10149
|
disableWorkerPool: true,
|
|
10009
|
-
|
|
10150
|
+
expandedReviewKeys,
|
|
10010
10151
|
focusCommentId,
|
|
10011
10152
|
focusCommentRequest,
|
|
10012
10153
|
gitIdentity,
|
package/dist/style.css
CHANGED
|
@@ -5797,6 +5797,10 @@ html[data-codiff-platform="darwin"] .sidebar {
|
|
|
5797
5797
|
background: var(--sidebar-vibrancy-tint);
|
|
5798
5798
|
}
|
|
5799
5799
|
|
|
5800
|
+
.app-shell.command-bar-open > :not(.command-bar-overlay) {
|
|
5801
|
+
filter: blur(4px);
|
|
5802
|
+
}
|
|
5803
|
+
|
|
5800
5804
|
.merge-request-nav-button {
|
|
5801
5805
|
color: var(--muted);
|
|
5802
5806
|
cursor: pointer;
|
|
@@ -8601,7 +8605,6 @@ diffs-container .review-comment-thread {
|
|
|
8601
8605
|
}
|
|
8602
8606
|
|
|
8603
8607
|
.command-bar-overlay, .open-review-source-overlay {
|
|
8604
|
-
backdrop-filter: blur(4px);
|
|
8605
8608
|
background: #ffffff47;
|
|
8606
8609
|
justify-content: center;
|
|
8607
8610
|
align-items: flex-start;
|
|
@@ -8611,6 +8614,10 @@ diffs-container .review-comment-thread {
|
|
|
8611
8614
|
inset: 0;
|
|
8612
8615
|
}
|
|
8613
8616
|
|
|
8617
|
+
.open-review-source-overlay {
|
|
8618
|
+
backdrop-filter: blur(4px);
|
|
8619
|
+
}
|
|
8620
|
+
|
|
8614
8621
|
.command-bar-overlay {
|
|
8615
8622
|
z-index: 100;
|
|
8616
8623
|
}
|
|
@@ -8638,6 +8645,7 @@ diffs-container .review-comment-thread {
|
|
|
8638
8645
|
flex-direction: column;
|
|
8639
8646
|
width: min(520px, 90vw);
|
|
8640
8647
|
max-height: 400px;
|
|
8648
|
+
padding-top: 6px;
|
|
8641
8649
|
display: flex;
|
|
8642
8650
|
overflow: hidden;
|
|
8643
8651
|
}
|
|
@@ -8645,15 +8653,16 @@ diffs-container .review-comment-thread {
|
|
|
8645
8653
|
.command-bar-input {
|
|
8646
8654
|
color: var(--text);
|
|
8647
8655
|
corner-shape: squircle;
|
|
8648
|
-
font:
|
|
8656
|
+
font: 13px/1.35 var(--font-sans);
|
|
8649
8657
|
background: #7f7f7f1a;
|
|
8650
8658
|
border: 0;
|
|
8651
8659
|
border-radius: 16px;
|
|
8652
8660
|
outline: none;
|
|
8653
8661
|
width: calc(100% - 20px);
|
|
8654
8662
|
height: 34px;
|
|
8655
|
-
|
|
8656
|
-
|
|
8663
|
+
min-height: 34px;
|
|
8664
|
+
margin: 4px 10px 8px;
|
|
8665
|
+
padding: 0 10px;
|
|
8657
8666
|
}
|
|
8658
8667
|
|
|
8659
8668
|
.command-bar-input:focus {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nkzw/codiff-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "A fast diff viewer.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@nkzw/mdx-editor": "^0.
|
|
54
|
+
"@nkzw/mdx-editor": "^1.0.1",
|
|
55
55
|
"@nkzw/use-relative-time": "^1.2.3",
|
|
56
56
|
"@phosphor-icons/react": "^2.1.10",
|
|
57
57
|
"@pierre/diffs": "1.3.6",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@radix-ui/react-slot": "^1.3.3",
|
|
60
60
|
"class-variance-authority": "^0.7.1",
|
|
61
61
|
"ghostty-web": "^0.4.0",
|
|
62
|
-
"lucide-react": "^1.
|
|
62
|
+
"lucide-react": "^1.39.0",
|
|
63
63
|
"valibot": "^1.4.2"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|