@nkzw/codiff-core 1.12.0 → 1.14.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.
@@ -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, expandedGenerated, 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, }: {
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
- expandedGenerated?: ReadonlySet<string>;
56
+ expandedReviewKeys?: ReadonlySet<string>;
57
57
  files: ReadonlyArray<ChangedFile>;
58
58
  focusCommentId: string | null;
59
59
  focusCommentRequest: number;
@@ -0,0 +1,3 @@
1
+ import type { LineAnnotation } from '@pierre/diffs';
2
+ import type { ReviewAnnotationMetadata } from '../../lib/app-types.ts';
3
+ export declare function useCodeViewAnnotations(): (id: string, key: string, annotations: Array<LineAnnotation<ReviewAnnotationMetadata>>) => LineAnnotation<ReviewAnnotationMetadata>[];
@@ -0,0 +1,2 @@
1
+ import type { FileContents } from '@pierre/diffs';
2
+ export declare function useCodeViewPlaceholderFile(): (name: string, contents?: '' | ' ') => FileContents;
@@ -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
- expandedGenerated: Set<string>;
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
- setExpandedGenerated: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
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>>>;
@@ -31,7 +31,7 @@ type WalkthroughHeaderAnnotationMetadata = {
31
31
  type: 'walkthrough-header';
32
32
  };
33
33
  export type ReviewAnnotationMetadata = CodeQualityAnnotationMetadata | ImagePreviewAnnotationMetadata | MarkdownPreviewAnnotationMetadata | ReviewCommentAnnotationMetadata | WalkthroughHeaderAnnotationMetadata;
34
- export type CodeViewInstance = NonNullable<ReturnType<CodeViewHandle<ReviewAnnotationMetadata>['getInstance']>>;
34
+ export type CodeViewInstance = NonNullable<ReturnType<CodeViewHandle<ReviewAnnotationMetadata, undefined>['getInstance']>>;
35
35
  export type DiffSearchMatch = {
36
36
  filePath: string;
37
37
  itemId: string;
@@ -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
- expandedGenerated: Set<string>;
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>;
@@ -3,6 +3,7 @@ export type IdentifierAtOffset = {
3
3
  start: number;
4
4
  };
5
5
  export declare const isNavigableIdentifierToken: (text: string) => boolean;
6
+ export declare const clearIdentifierNavigationWrappers: (root: ParentNode) => void;
6
7
  export declare const applyIdentifierNavigationState: (renderedItems: ReadonlyArray<{
7
8
  element: HTMLElement;
8
9
  }>, active: boolean) => void;
@@ -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;
@@ -29,5 +29,6 @@ export declare const getCommentKey: (comment: Pick<ReviewComment, 'anchor' | 'li
29
29
  export declare const getReviewCommentsDigest: (comments: ReadonlyArray<ReviewComment>) => string;
30
30
  export declare const buildReviewCommentsMarkdown: (files: ReadonlyArray<ChangedFile>, comments: ReadonlyArray<ReviewComment>, showWhitespace: boolean, prefix?: string) => string;
31
31
  export declare const getReviewCommentsFromState: (state: RepositoryState) => ReadonlyArray<ReviewComment>;
32
+ export declare const getRefreshedReviewComments: (state: RepositoryState, currentComments: ReadonlyArray<ReviewComment>) => ReadonlyArray<ReviewComment>;
32
33
  export declare const getVisibleReviewComments: (comments: ReadonlyArray<ReviewComment>, showOutdated: boolean) => ReadonlyArray<ReviewComment>;
33
34
  export declare const shouldDiscardReviewCommentOnEscape: (body: string, confirmDiscard?: (message: string) => boolean) => boolean;
@@ -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
@@ -1505,7 +1505,7 @@ const parseSectionDiffWithOptions = (file, section, showWhitespace) => {
1505
1505
  }
1506
1506
  else if (section.patch.trim().length === 0) fileDiff = createEmptyFileDiff(file, section);
1507
1507
  else {
1508
- const parsedFileDiff = parsePatchFiles(section.patch)[0]?.files[0];
1508
+ const parsedFileDiff = parsePatchFiles(section.patch, cacheKey)[0]?.files[0];
1509
1509
  if (parsedFileDiff) {
1510
1510
  const loaded = parsedFileDiff.isPartial ? getLoadedSectionContents(file, section) : void 0;
1511
1511
  let hydrated = null;
@@ -3887,11 +3887,10 @@ const wrapIdentifierNavigationText = (root) => {
3887
3887
  };
3888
3888
  const applyIdentifierNavigationState = (renderedItems, active) => {
3889
3889
  for (const { element } of renderedItems) {
3890
- element.toggleAttribute(definitionModifierAttribute, active);
3891
3890
  const root = element.shadowRoot;
3892
- if (!root) continue;
3893
- clearIdentifierNavigationWrappers(root);
3894
- if (active) wrapIdentifierNavigationText(root);
3891
+ const enabled = active && !hasActiveTextSelection(root);
3892
+ element.toggleAttribute(definitionModifierAttribute, enabled);
3893
+ if (root && enabled) wrapIdentifierNavigationText(root);
3895
3894
  }
3896
3895
  };
3897
3896
  const getIdentifierAtOffset = (text, offset) => {
@@ -3945,18 +3944,46 @@ const getFileReviewIdentity = (file) => ({
3945
3944
  fingerprint: file.fingerprint,
3946
3945
  key: file.path
3947
3946
  });
3947
+ const getWalkthroughReviewKeyPrefix = (path) => `walkthrough:${JSON.stringify(path)}:`;
3948
+ const getHunkViewedKey = (path, hunkId) => `${getWalkthroughReviewKeyPrefix(path)}${JSON.stringify(hunkId)}`;
3949
+ const getSectionReviewHunkIds = (file, section) => {
3950
+ const ids = getSectionWalkthroughHunks(file, section).map((hunk) => hunk.id);
3951
+ return ids.length > 0 ? ids : [section.id];
3952
+ };
3953
+ const getWalkthroughReviewIdentity = (file, hunkIds) => ({
3954
+ coverage: {
3955
+ allHunkIds: file.sections.flatMap((section) => getSectionReviewHunkIds(file, section)),
3956
+ file: getFileReviewIdentity(file),
3957
+ hunkIds
3958
+ },
3959
+ fingerprint: file.fingerprint,
3960
+ key: `${getWalkthroughReviewKeyPrefix(file.path)}${JSON.stringify(hunkIds)}`
3961
+ });
3948
3962
  const getReviewIdentity = (file, identityByPath) => identityByPath?.get(file.path) ?? getFileReviewIdentity(file);
3949
- const isReviewIdentityViewed = (viewed, identity) => viewed[identity.key] === identity.fingerprint;
3963
+ const isReviewIdentityViewed = (viewed, identity) => {
3964
+ const { coverage } = identity;
3965
+ 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;
3966
+ };
3950
3967
  const updateReviewIdentityViewed = (viewed, identity, currentlyViewed) => {
3951
- if (currentlyViewed) {
3952
- const next = { ...viewed };
3953
- delete next[identity.key];
3968
+ const next = { ...viewed };
3969
+ const { coverage } = identity;
3970
+ if (coverage) {
3971
+ const { allHunkIds, file, hunkIds } = coverage;
3972
+ if (viewed[file.key] === file.fingerprint) for (const id of allHunkIds) next[getHunkViewedKey(file.key, id)] = file.fingerprint;
3973
+ for (const id of hunkIds) {
3974
+ const key = getHunkViewedKey(file.key, id);
3975
+ if (currentlyViewed) delete next[key];
3976
+ else next[key] = file.fingerprint;
3977
+ }
3978
+ if (allHunkIds.length > 0 && allHunkIds.every((id) => next[getHunkViewedKey(file.key, id)] === file.fingerprint)) next[file.key] = file.fingerprint;
3979
+ else delete next[file.key];
3954
3980
  return next;
3955
3981
  }
3956
- return {
3957
- ...viewed,
3958
- [identity.key]: identity.fingerprint
3959
- };
3982
+ const prefix = getWalkthroughReviewKeyPrefix(identity.key);
3983
+ for (const key of Object.keys(next)) if (key.startsWith(prefix)) delete next[key];
3984
+ if (currentlyViewed) delete next[identity.key];
3985
+ else next[identity.key] = identity.fingerprint;
3986
+ return next;
3960
3987
  };
3961
3988
  const updateReviewIdentityCollapsed = (collapsed, identity, currentlyCollapsed) => {
3962
3989
  const next = new Set(collapsed);
@@ -4011,6 +4038,7 @@ const highlightTextContainer = (container, normalizedQuery, activeMatch) => {
4011
4038
  const applySearchHighlights = (renderedItems, query, activeMatch) => {
4012
4039
  const normalizedQuery = query.trim().toLowerCase();
4013
4040
  for (const { element, id } of renderedItems) for (const root of getSearchableRoots(element)) {
4041
+ if (normalizedQuery) clearIdentifierNavigationWrappers(root);
4014
4042
  clearSearchHighlights(root);
4015
4043
  if (!normalizedQuery) continue;
4016
4044
  const matchForItem = activeMatch && activeMatch.itemId === id ? activeMatch : null;
@@ -4024,6 +4052,45 @@ const getSourceKey = (source) => source.type === "commit" ? `commit:${source.ref
4024
4052
  const getShortRef = (ref) => ref.slice(0, 7);
4025
4053
  const getSourceLabel = (source) => source.type === "commit" ? getShortRef(source.ref) : source.type === "branch" || source.type === "branch-diff" ? `Branch vs ${source.ref}` : source.type === "branch-working-tree" ? `Local + branch vs ${source.ref}` : source.type === "range" ? rangeLabel(source) : source.type === "pull-request" ? source.number ? `${source.provider === "gitlab" ? "MR" : "PR"} #${source.number}` : source.provider === "gitlab" ? "Merge request" : "Pull request" : "Uncommitted";
4026
4054
  //#endregion
4055
+ //#region app/hooks/useCodeViewAnnotations.ts
4056
+ function useCodeViewAnnotations() {
4057
+ const [getAnnotations] = useState(() => {
4058
+ const cache = /* @__PURE__ */ new Map();
4059
+ return (id, key, annotations) => {
4060
+ const previous = cache.get(id);
4061
+ if (previous?.key === key) return previous.annotations;
4062
+ cache.set(id, {
4063
+ annotations,
4064
+ key
4065
+ });
4066
+ return annotations;
4067
+ };
4068
+ });
4069
+ return getAnnotations;
4070
+ }
4071
+ //#endregion
4072
+ //#region app/hooks/useCodeViewPlaceholderFile.ts
4073
+ function useCodeViewPlaceholderFile() {
4074
+ const [getPlaceholderFile] = useState(() => {
4075
+ const files = /* @__PURE__ */ new Map();
4076
+ return (name, contents = " ") => {
4077
+ const cacheKey = `placeholder:${contents.length}:${name}`;
4078
+ let file = files.get(cacheKey);
4079
+ if (!file) {
4080
+ file = {
4081
+ cacheKey,
4082
+ contents,
4083
+ lang: "text",
4084
+ name
4085
+ };
4086
+ files.set(cacheKey, file);
4087
+ }
4088
+ return file;
4089
+ };
4090
+ });
4091
+ return getPlaceholderFile;
4092
+ }
4093
+ //#endregion
4027
4094
  //#region app/components/DefinitionPopover.tsx
4028
4095
  function DefinitionPopover({ anchor, getDestination, identifier, onClose, onOpen, result }) {
4029
4096
  const popoverRef = useRef(null);
@@ -4308,6 +4375,7 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
4308
4375
  if (coveredSyntheticSectionIds.has(section.id)) return null;
4309
4376
  const hunkIds = getSectionHunkIds(file, section);
4310
4377
  if (hunkIds.length === 0) return coveredSectionIds.has(section.id) ? null : {
4378
+ hunkIds: [section.id],
4311
4379
  identity: section.id,
4312
4380
  section
4313
4381
  };
@@ -4315,11 +4383,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
4315
4383
  if (uncoveredHunkIds.length === 0) return null;
4316
4384
  const identity = `${section.id}:${uncoveredHunkIds.join(",")}`;
4317
4385
  if (uncoveredHunkIds.length === hunkIds.length) return {
4386
+ hunkIds: uncoveredHunkIds,
4318
4387
  identity,
4319
4388
  section
4320
4389
  };
4321
4390
  const patch = filterPatchToHunkIds(section.patch, section.id, uncoveredHunkIds);
4322
4391
  return patch ? {
4392
+ hunkIds: uncoveredHunkIds,
4323
4393
  identity,
4324
4394
  section: {
4325
4395
  ...section,
@@ -4327,6 +4397,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
4327
4397
  }
4328
4398
  } : null;
4329
4399
  };
4400
+ const getUncoveredWalkthroughReviewIdentity = (file, view, showWhitespace) => {
4401
+ const coveredHunkIds = walkthroughCoveredHunkIds(view);
4402
+ const coveredSectionIds = walkthroughCoveredSectionIds(view);
4403
+ const coveredSyntheticSectionIds = walkthroughCoveredSyntheticSectionIds(view);
4404
+ const hunkIds = getVisibleDiffSections(file, showWhitespace).flatMap(({ section }) => getUncoveredWalkthroughSection(file, section, coveredHunkIds, coveredSectionIds, coveredSyntheticSectionIds)?.hunkIds ?? []);
4405
+ return getWalkthroughReviewIdentity(file, hunkIds);
4406
+ };
4330
4407
  const getUncoveredWalkthroughFiles = (files, view, showWhitespace) => {
4331
4408
  const coveredHunkIds = walkthroughCoveredHunkIds(view);
4332
4409
  const coveredSectionIds = walkthroughCoveredSectionIds(view);
@@ -4973,7 +5050,7 @@ function DiffLineCountBadge({ ariaLabelPrefix, className = "codiff-line-count",
4973
5050
  //#endregion
4974
5051
  //#region app/components/ReviewCodeView.tsx
4975
5052
  const emptyMarkdownPreviewSectionIds = /* @__PURE__ */ new Set();
4976
- const emptyExpandedGenerated = /* @__PURE__ */ new Set();
5053
+ const emptyExpandedReviewKeys = /* @__PURE__ */ new Set();
4977
5054
  const markdownPreviewPlugins = [frontmatterPlugin(), imagePlugin({
4978
5055
  disableImageResize: true,
4979
5056
  disableImageSettingsButton: true
@@ -5185,28 +5262,48 @@ const formatBytes = (size) => {
5185
5262
  }
5186
5263
  return `${size} B`;
5187
5264
  };
5188
- function MarkdownPreview({ contents, editable, layoutKey, onEditorRef, onLayoutReady, path, sectionId }) {
5189
- useLayoutEffect(() => {
5190
- onLayoutReady(sectionId);
5265
+ function MarkdownPreview({ cacheKey, contents, editable, heightCache, onEditorRef, onLayoutReady, path, sectionId }) {
5266
+ const contentRef = useRef(null);
5267
+ const [ready, setReady] = useState(false);
5268
+ const measure = useCallback((reportedHeight) => {
5269
+ const content = contentRef.current;
5270
+ if (!content?.isConnected || content.querySelector(".codiff-markdown-editor-message:not(.error), .codiff-readonly-markdown-loading")) return;
5271
+ const height = content.getBoundingClientRect().height || reportedHeight;
5272
+ if (height == null || height <= 0) return;
5273
+ setReady(true);
5274
+ if (heightCache.get(cacheKey) !== height) {
5275
+ heightCache.set(cacheKey, height);
5276
+ onLayoutReady(sectionId);
5277
+ }
5191
5278
  }, [
5192
- layoutKey,
5279
+ cacheKey,
5280
+ heightCache,
5193
5281
  onLayoutReady,
5194
5282
  sectionId
5195
5283
  ]);
5196
- return editable ? /* @__PURE__ */ jsx("div", {
5197
- className: "codiff-markdown-preview editable",
5198
- children: /* @__PURE__ */ jsx(RepositoryMarkdownEditor, {
5199
- onHeightChange: () => onLayoutReady(sectionId),
5200
- path,
5201
- ref: (editor) => onEditorRef(sectionId, editor)
5202
- })
5203
- }) : /* @__PURE__ */ jsx("div", {
5204
- className: "codiff-markdown-preview",
5205
- children: /* @__PURE__ */ jsx(ReadOnlyMarkdown, {
5206
- ariaLabel: `Preview ${path}`,
5207
- className: "codiff-markdown-preview-editor",
5208
- onHeightChange: () => onLayoutReady(sectionId),
5209
- value: contents
5284
+ useLayoutEffect(() => {
5285
+ const content = contentRef.current;
5286
+ if (!content) return;
5287
+ const observer = new ResizeObserver(() => measure());
5288
+ observer.observe(content);
5289
+ measure();
5290
+ return () => observer.disconnect();
5291
+ }, [measure]);
5292
+ return /* @__PURE__ */ jsx("div", {
5293
+ style: { minHeight: ready ? void 0 : heightCache.get(cacheKey) },
5294
+ children: /* @__PURE__ */ jsx("div", {
5295
+ className: `codiff-markdown-preview${editable ? " editable" : ""}`,
5296
+ ref: contentRef,
5297
+ children: editable ? /* @__PURE__ */ jsx(RepositoryMarkdownEditor, {
5298
+ onHeightChange: measure,
5299
+ path,
5300
+ ref: (editor) => onEditorRef(sectionId, editor)
5301
+ }) : /* @__PURE__ */ jsx(ReadOnlyMarkdown, {
5302
+ ariaLabel: `Preview ${path}`,
5303
+ className: "codiff-markdown-preview-editor",
5304
+ onHeightChange: measure,
5305
+ value: contents
5306
+ })
5210
5307
  })
5211
5308
  });
5212
5309
  }
@@ -6604,8 +6701,11 @@ const getHunkSelectionRange = (hunk) => {
6604
6701
  } : null;
6605
6702
  };
6606
6703
  const isSameSelection = (a, b) => a.start === b.start && a.end === b.end && a.side === b.side;
6607
- function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle = false, blocks, bottomInset = codeViewLayout.paddingBottom, codeQualityFindings = [], collapsed, comments, commitMetadata, diffLineHeight = 20, diffStyle, disableWorkerPool = false, expandedGenerated = emptyExpandedGenerated, 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 }) {
6704
+ 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 }) {
6608
6705
  const codeViewRef = useRef(null);
6706
+ const getPlaceholderFile = useCodeViewPlaceholderFile();
6707
+ const getAnnotations = useCodeViewAnnotations();
6708
+ const [markdownPreviewHeights] = useState(() => /* @__PURE__ */ new Map());
6609
6709
  const markdownEditorRefs = useRef(/* @__PURE__ */ new Map());
6610
6710
  const refreshingMarkdownSectionsRef = useRef(/* @__PURE__ */ new Set());
6611
6711
  const deferredTimersRef = useRef(/* @__PURE__ */ new Set());
@@ -6713,12 +6813,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6713
6813
  }
6714
6814
  }],
6715
6815
  collapsed: false,
6716
- file: {
6717
- cacheKey: `walkthrough-header:${block.id}`,
6718
- contents: " ",
6719
- lang: "text",
6720
- name: headerId
6721
- },
6816
+ file: getPlaceholderFile(headerId),
6722
6817
  id: headerId,
6723
6818
  type: "file",
6724
6819
  version: getItemVersion(`${block.id}:walkthrough-header`)
@@ -6729,7 +6824,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6729
6824
  const reviewIdentity = block.reviewIdentity ?? getReviewIdentity(file, reviewIdentityByPath);
6730
6825
  const reviewKey = reviewIdentity.key;
6731
6826
  const isViewed = isReviewIdentityViewed(viewed, reviewIdentity);
6732
- const isCollapsed = !forceExpandedPaths.has(file.path) && !expandedGenerated.has(reviewKey) && (collapsed.has(reviewKey) || isGeneratedWalkthroughFile(file));
6827
+ const isCollapsed = !forceExpandedPaths.has(file.path) && !expandedReviewKeys.has(reviewKey) && (isViewed || collapsed.has(reviewKey) || isGeneratedWalkthroughFile(file));
6733
6828
  const visibleSections = getVisibleDiffSections(file, showWhitespace);
6734
6829
  const lineCount = getDiffLineCountFromVisibleSections(visibleSections);
6735
6830
  const sections = isCollapsed ? visibleSections.slice(0, 1) : visibleSections;
@@ -6823,12 +6918,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6823
6918
  }
6824
6919
  }],
6825
6920
  collapsed: isCollapsed,
6826
- file: {
6827
- cacheKey: `image-preview:${file.fingerprint}:${section.id}`,
6828
- contents: " ",
6829
- lang: "text",
6830
- name: file.path
6831
- },
6921
+ file: getPlaceholderFile(file.path),
6832
6922
  id,
6833
6923
  type: "file",
6834
6924
  version: getItemVersion(`${reviewVersionPrefix}:image:${sectionStateVersionKey}:${imagePreviewLayoutPassBySection[section.id] ?? 0}`)
@@ -6839,7 +6929,12 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6839
6929
  const markdownPreviewAddedLinesDigest = getAddedLinesDigest(markdownPreview.addedLines);
6840
6930
  const markdownPreviewLayoutKey = `${section.id}:${markdownPreview.contents.length}:${markdownPreviewAddedLinesDigest}`;
6841
6931
  nextItems.push({
6842
- annotations: [...fileCommentAnnotations, {
6932
+ annotations: getAnnotations(id, JSON.stringify([
6933
+ markdownPreview.contents,
6934
+ markdownPreviewAddedLinesDigest,
6935
+ canEditMarkdown,
6936
+ fileCommentAnnotations
6937
+ ]), [...fileCommentAnnotations, {
6843
6938
  lineNumber: 1,
6844
6939
  metadata: {
6845
6940
  addedLines: markdownPreview.addedLines,
@@ -6850,14 +6945,9 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6850
6945
  sectionId: section.id,
6851
6946
  type: "markdown-preview"
6852
6947
  }
6853
- }],
6948
+ }]),
6854
6949
  collapsed: isCollapsed,
6855
- file: {
6856
- cacheKey: `markdown-preview:${section.newFile?.cacheKey ?? file.fingerprint}:${markdownPreview.contents.length}:${markdownPreviewAddedLinesDigest}`,
6857
- contents: " ",
6858
- lang: "text",
6859
- name: file.path
6860
- },
6950
+ file: getPlaceholderFile(file.path),
6861
6951
  id,
6862
6952
  type: "file",
6863
6953
  version: getItemVersion(`${reviewVersionPrefix}:markdown:${sectionStateVersionKey}:${markdownPreviewLayoutKey}:${markdownPreviewLayoutPassBySection[section.id] ?? 0}`)
@@ -6891,8 +6981,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6891
6981
  commentsBySection,
6892
6982
  diffLineHeight,
6893
6983
  diffStyle,
6894
- expandedGenerated,
6984
+ expandedReviewKeys,
6895
6985
  forceExpandedPaths,
6986
+ getAnnotations,
6987
+ getPlaceholderFile,
6896
6988
  imagePreviewLayoutPassBySection,
6897
6989
  isReadOnly,
6898
6990
  itemVersionByKey,
@@ -6911,16 +7003,12 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6911
7003
  if (items.length > 0 || !sourceDescriptionItemId) return items;
6912
7004
  return [{
6913
7005
  collapsed: true,
6914
- file: {
6915
- cacheKey: sourceDescriptionItemId,
6916
- contents: "",
6917
- lang: "text",
6918
- name: shouldShowCommitMessage ? "commit-message.md" : "source-description.md"
6919
- },
7006
+ file: getPlaceholderFile(shouldShowCommitMessage ? "commit-message.md" : "source-description.md", ""),
6920
7007
  id: sourceDescriptionItemId,
6921
7008
  type: "file"
6922
7009
  }];
6923
7010
  }, [
7011
+ getPlaceholderFile,
6924
7012
  items,
6925
7013
  shouldShowCommitMessage,
6926
7014
  sourceDescriptionItemId
@@ -7583,30 +7671,44 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
7583
7671
  ]);
7584
7672
  useEffect(() => {
7585
7673
  if (!onFindDefinitions) return;
7674
+ let pointerDown = false;
7586
7675
  const updateDefinitionModifierState = (active) => {
7587
7676
  if (definitionModifierActiveRef.current === active) return;
7588
7677
  definitionModifierActiveRef.current = active;
7589
7678
  updateRenderedIdentifierNavigation(active);
7590
7679
  };
7591
7680
  const handleModifierChange = (event) => {
7592
- updateDefinitionModifierState(isPrimaryModifier(event));
7681
+ updateDefinitionModifierState(isPrimaryModifier(event) && !pointerDown);
7593
7682
  };
7594
7683
  const handleModifierPointer = (event) => {
7595
- updateDefinitionModifierState(isPrimaryModifier(event));
7684
+ pointerDown = (event.buttons & 1) !== 0;
7685
+ updateDefinitionModifierState(isPrimaryModifier(event) && !pointerDown);
7686
+ };
7687
+ const handleSelectionChange = () => {
7688
+ updateRenderedIdentifierNavigation(definitionModifierActiveRef.current);
7689
+ };
7690
+ const clearDefinitionModifierState = () => {
7691
+ pointerDown = false;
7692
+ updateDefinitionModifierState(false);
7596
7693
  };
7597
- const clearDefinitionModifierState = () => updateDefinitionModifierState(false);
7598
7694
  window.addEventListener("keydown", handleModifierChange);
7599
7695
  window.addEventListener("keyup", handleModifierChange);
7600
7696
  window.addEventListener("pointerdown", handleModifierPointer);
7601
7697
  window.addEventListener("pointermove", handleModifierPointer);
7698
+ window.addEventListener("pointerup", handleModifierPointer);
7699
+ window.addEventListener("pointercancel", clearDefinitionModifierState);
7602
7700
  window.addEventListener("blur", clearDefinitionModifierState);
7701
+ document.addEventListener("selectionchange", handleSelectionChange);
7603
7702
  return () => {
7604
7703
  clearDefinitionModifierState();
7605
7704
  window.removeEventListener("keydown", handleModifierChange);
7606
7705
  window.removeEventListener("keyup", handleModifierChange);
7607
7706
  window.removeEventListener("pointerdown", handleModifierPointer);
7608
7707
  window.removeEventListener("pointermove", handleModifierPointer);
7708
+ window.removeEventListener("pointerup", handleModifierPointer);
7709
+ window.removeEventListener("pointercancel", clearDefinitionModifierState);
7609
7710
  window.removeEventListener("blur", clearDefinitionModifierState);
7711
+ document.removeEventListener("selectionchange", handleSelectionChange);
7610
7712
  };
7611
7713
  }, [onFindDefinitions, updateRenderedIdentifierNavigation]);
7612
7714
  const invalidateDefinitionLookup = useCallback(() => {
@@ -7720,9 +7822,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
7720
7822
  }) : null;
7721
7823
  }
7722
7824
  if (annotation.metadata.type === "markdown-preview") return /* @__PURE__ */ jsx(MarkdownPreview, {
7825
+ cacheKey: `${sourceKey}:${item.id}`,
7723
7826
  contents: annotation.metadata.contents,
7724
7827
  editable: annotation.metadata.editable,
7725
- layoutKey: annotation.metadata.layoutKey,
7828
+ heightCache: markdownPreviewHeights,
7726
7829
  onEditorRef: setMarkdownEditorRef,
7727
7830
  onLayoutReady: markMarkdownPreviewLayoutReady,
7728
7831
  path: annotation.metadata.path,
@@ -7764,6 +7867,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
7764
7867
  itemMetadata,
7765
7868
  keymap,
7766
7869
  markMarkdownPreviewLayoutReady,
7870
+ markdownPreviewHeights,
7767
7871
  markImagePreviewLayoutReady,
7768
7872
  markCommentLayoutChanged,
7769
7873
  onAskCodex,
@@ -7777,6 +7881,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
7777
7881
  replyToThread,
7778
7882
  setMarkdownEditorRef,
7779
7883
  source,
7884
+ sourceKey,
7780
7885
  supportsReviewCommentActions
7781
7886
  ]);
7782
7887
  const handleScroll = useCallback((_scrollTop, viewer) => {
@@ -8455,10 +8560,7 @@ const getFocusedRunDiffs = (item, files) => resolveWalkthroughHunkRuns(item, fil
8455
8560
  return focused ? [{
8456
8561
  file: focused,
8457
8562
  note: getWalkthroughRunNote(item, run),
8458
- reviewIdentity: {
8459
- fingerprint: focused.fingerprint,
8460
- key: `walkthrough:${run.key}`
8461
- }
8563
+ reviewIdentity: getWalkthroughReviewIdentity(run.resolved.file, run.hunks.flatMap((hunk) => hunk.kind === "synthetic" ? getSectionReviewHunkIds(run.resolved.file, run.resolved.section) : [hunk.id]))
8462
8564
  }] : [];
8463
8565
  });
8464
8566
  const getWalkthroughNavigationKeyDirection = (event) => {
@@ -8572,10 +8674,7 @@ const createSupportBlocks = (files, selected, walkthroughView, showWhitespace) =
8572
8674
  id: blockId,
8573
8675
  itemIdPrefix: blockId,
8574
8676
  note: "Not included in the generated walkthrough.",
8575
- reviewIdentity: {
8576
- fingerprint: file.fingerprint,
8577
- key: blockId
8578
- }
8677
+ reviewIdentity: getUncoveredWalkthroughReviewIdentity(files.find((candidate) => candidate.path === file.path), walkthroughView, showWhitespace)
8579
8678
  });
8580
8679
  }
8581
8680
  return blocks;
@@ -9492,7 +9591,7 @@ function useReviewCommentDrafts({ canCreateComment = true, comments, onCommentFi
9492
9591
  //#region app/hooks/useReviewState.ts
9493
9592
  function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {}) {
9494
9593
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
9495
- const [expandedGenerated, setExpandedGenerated] = useState(() => /* @__PURE__ */ new Set());
9594
+ const [expandedReviewKeys, setExpandedReviewKeys] = useState(() => /* @__PURE__ */ new Set());
9496
9595
  const [itemVersionByKey, setItemVersionByKey] = useState({});
9497
9596
  const [selectedPath, setSelectedPath] = useState(initialSelectedPath);
9498
9597
  const [viewed, setViewed] = useState({});
@@ -9505,11 +9604,11 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
9505
9604
  return {
9506
9605
  bumpItemVersion,
9507
9606
  collapsed,
9508
- expandedGenerated,
9607
+ expandedReviewKeys,
9509
9608
  itemVersionByKey,
9510
9609
  selectedPath,
9511
9610
  setCollapsed,
9512
- setExpandedGenerated,
9611
+ setExpandedReviewKeys,
9513
9612
  setItemVersionByKey,
9514
9613
  setSelectedPath,
9515
9614
  setViewed,
@@ -9520,9 +9619,9 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
9520
9619
  else next.add(reviewKey);
9521
9620
  return next;
9522
9621
  });
9523
- setExpandedGenerated((current) => {
9622
+ setExpandedReviewKeys((current) => {
9524
9623
  const next = new Set(current);
9525
- if (isCollapsed && isGeneratedWalkthroughFile(file)) next.add(reviewKey);
9624
+ if (isCollapsed) next.add(reviewKey);
9526
9625
  else next.delete(reviewKey);
9527
9626
  return next;
9528
9627
  });
@@ -9534,12 +9633,20 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
9534
9633
  onViewedChange?.(next);
9535
9634
  return next;
9536
9635
  });
9537
- setCollapsed((current) => updateReviewIdentityCollapsed(current, reviewIdentity, isViewed));
9538
- if (!isViewed) setExpandedGenerated((current) => {
9539
- const next = new Set(current);
9540
- next.delete(reviewIdentity.key);
9541
- return next;
9542
- });
9636
+ const fileKey = reviewIdentity.coverage?.file.key ?? file.path;
9637
+ const prefix = getWalkthroughReviewKeyPrefix(fileKey);
9638
+ const clearRelatedKeys = (current) => new Set([...current].filter((key) => key !== fileKey && (reviewIdentity.coverage ? key !== reviewIdentity.key : !key.startsWith(prefix))));
9639
+ if (reviewIdentity.coverage || reviewIdentity.key === file.path) {
9640
+ setCollapsed(clearRelatedKeys);
9641
+ setExpandedReviewKeys(clearRelatedKeys);
9642
+ } else {
9643
+ setCollapsed((current) => updateReviewIdentityCollapsed(current, reviewIdentity, isViewed));
9644
+ setExpandedReviewKeys((current) => {
9645
+ const next = new Set(current);
9646
+ next.delete(reviewIdentity.key);
9647
+ return next;
9648
+ });
9649
+ }
9543
9650
  bumpItemVersion(reviewIdentity.key);
9544
9651
  }, [bumpItemVersion, onViewedChange]),
9545
9652
  viewed
@@ -9572,13 +9679,13 @@ const defaultConfigTemplate = {
9572
9679
  keymap: {
9573
9680
  "askAgent": "Mod+Alt+Enter",
9574
9681
  "closeSearch": "Escape",
9575
- "commandBar": "Mod+Shift+p",
9682
+ "commandBar": "Mod+k",
9576
9683
  "diffSearch": "Mod+f",
9577
9684
  "discardComment": "Escape",
9578
9685
  "fileFilter": "Mod+p",
9579
9686
  "nextHunk": ["Ctrl+ArrowDown", "j"],
9580
9687
  "nextSearchMatch": "Enter",
9581
- "openFile": "Mod+k",
9688
+ "openFile": "Mod+Shift+o",
9582
9689
  "prevHunk": ["Ctrl+ArrowUp", "k"],
9583
9690
  "prevSearchMatch": "Shift+Enter",
9584
9691
  "shortcutsHelp": "Shift+?",
@@ -9732,7 +9839,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
9732
9839
  }, [keymap, toggleSidebar]);
9733
9840
  const sidebarMode = Boolean(initialMode && onModeChange) && initialMode ? initialMode : uncontrolledSidebarMode;
9734
9841
  const [treeScrollTarget, setTreeScrollTarget] = useState(null);
9735
- const { bumpItemVersion, collapsed, expandedGenerated, itemVersionByKey, selectedPath, setSelectedPath, toggleCollapsed, toggleViewed, viewed } = useReviewFileState({ initialSelectedPath: snapshot.files[0]?.path ?? null });
9842
+ const { bumpItemVersion, collapsed, expandedReviewKeys, itemVersionByKey, selectedPath, setSelectedPath, toggleCollapsed, toggleViewed, viewed } = useReviewFileState({ initialSelectedPath: snapshot.files[0]?.path ?? null });
9736
9843
  const { resizeSidebar, sidebarWidth } = useResizableSidebar({
9737
9844
  collapseThreshold: 80,
9738
9845
  onCollapse: () => {
@@ -10107,7 +10214,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
10107
10214
  diffLineHeight,
10108
10215
  diffStyle: snapshot.preferences.diffStyle,
10109
10216
  disableWorkerPool: true,
10110
- expandedGenerated,
10217
+ expandedReviewKeys,
10111
10218
  focusCommentId,
10112
10219
  focusCommentRequest,
10113
10220
  gitIdentity,
package/dist/style.css CHANGED
@@ -2807,6 +2807,10 @@ form._multiFieldForm_sre1d_1628 {
2807
2807
  padding-left: 20px;
2808
2808
  }
2809
2809
 
2810
+ .mdx-editor .mdx-editor-content li > ul, .mdx-editor .mdx-editor-content li > ol {
2811
+ margin-block: 0;
2812
+ }
2813
+
2810
2814
  .mdx-editor-content li {
2811
2815
  margin: 0;
2812
2816
  padding-left: 2px;
@@ -5797,6 +5801,10 @@ html[data-codiff-platform="darwin"] .sidebar {
5797
5801
  background: var(--sidebar-vibrancy-tint);
5798
5802
  }
5799
5803
 
5804
+ .app-shell.command-bar-open > :not(.command-bar-overlay) {
5805
+ filter: blur(4px);
5806
+ }
5807
+
5800
5808
  .merge-request-nav-button {
5801
5809
  color: var(--muted);
5802
5810
  cursor: pointer;
@@ -8601,7 +8609,6 @@ diffs-container .review-comment-thread {
8601
8609
  }
8602
8610
 
8603
8611
  .command-bar-overlay, .open-review-source-overlay {
8604
- backdrop-filter: blur(4px);
8605
8612
  background: #ffffff47;
8606
8613
  justify-content: center;
8607
8614
  align-items: flex-start;
@@ -8611,6 +8618,10 @@ diffs-container .review-comment-thread {
8611
8618
  inset: 0;
8612
8619
  }
8613
8620
 
8621
+ .open-review-source-overlay {
8622
+ backdrop-filter: blur(4px);
8623
+ }
8624
+
8614
8625
  .command-bar-overlay {
8615
8626
  z-index: 100;
8616
8627
  }
@@ -8638,6 +8649,7 @@ diffs-container .review-comment-thread {
8638
8649
  flex-direction: column;
8639
8650
  width: min(520px, 90vw);
8640
8651
  max-height: 400px;
8652
+ padding-top: 6px;
8641
8653
  display: flex;
8642
8654
  overflow: hidden;
8643
8655
  }
@@ -8645,15 +8657,16 @@ diffs-container .review-comment-thread {
8645
8657
  .command-bar-input {
8646
8658
  color: var(--text);
8647
8659
  corner-shape: squircle;
8648
- font: 14px/1.35 var(--font-sans);
8660
+ font: 13px/1.35 var(--font-sans);
8649
8661
  background: #7f7f7f1a;
8650
8662
  border: 0;
8651
8663
  border-radius: 16px;
8652
8664
  outline: none;
8653
8665
  width: calc(100% - 20px);
8654
8666
  height: 34px;
8655
- margin: 10px;
8656
- padding: 0 12px;
8667
+ min-height: 34px;
8668
+ margin: 4px 10px 8px;
8669
+ padding: 0 10px;
8657
8670
  }
8658
8671
 
8659
8672
  .command-bar-input:focus {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nkzw/codiff-core",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "A fast diff viewer.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -51,16 +51,16 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
- "@nkzw/mdx-editor": "^1.0.1",
54
+ "@nkzw/mdx-editor": "^1.0.3",
55
55
  "@nkzw/use-relative-time": "^1.2.3",
56
56
  "@phosphor-icons/react": "^2.1.10",
57
- "@pierre/diffs": "1.3.6",
57
+ "@pierre/diffs": "1.4.2",
58
58
  "@pierre/trees": "1.0.0-beta.6",
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.39.0",
63
- "valibot": "^1.4.2"
62
+ "lucide-react": "^1.46.0",
63
+ "valibot": "^1.5.0"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "react": "^19.2.0",