@nkzw/codiff-core 1.9.1 → 1.11.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.
Files changed (31) hide show
  1. package/dist/SharedWalkthroughApp.d.ts +2 -1
  2. package/dist/app/components/DefinitionPopover.d.ts +12 -0
  3. package/dist/app/components/OpenReviewSourceDialog.d.ts +6 -0
  4. package/dist/app/components/OpenReviewSourceMenu.d.ts +5 -0
  5. package/dist/app/components/Panels.d.ts +8 -2
  6. package/dist/app/components/ReadOnlyMarkdownView.d.ts +1 -0
  7. package/dist/app/components/ResolvedThreadDisclosure.d.ts +9 -0
  8. package/dist/app/components/ReviewCodeView.d.ts +4 -2
  9. package/dist/app/components/ReviewModeControl.d.ts +14 -0
  10. package/dist/app/components/ReviewTopBar.d.ts +14 -13
  11. package/dist/app/components/merge-request/GeneralComments.d.ts +2 -1
  12. package/dist/app/components/walkthrough/NarrativeWalkthroughView.d.ts +6 -4
  13. package/dist/app/components/walkthrough/useNarrativeNavigation.d.ts +1 -1
  14. package/dist/app/hooks/useAppCommands.d.ts +3 -2
  15. package/dist/app/hooks/useAppReviewComments.d.ts +1 -0
  16. package/dist/app/hooks/useAppWalkthrough.d.ts +1 -1
  17. package/dist/app/hooks/useResizableSidebar.d.ts +2 -1
  18. package/dist/app/hooks/useReviewCommentDrafts.d.ts +1 -0
  19. package/dist/config/keyboard-layout.d.ts +13 -0
  20. package/dist/config/keymap.d.ts +3 -1
  21. package/dist/config/types.d.ts +3 -0
  22. package/dist/lib/app-types.d.ts +1 -0
  23. package/dist/lib/code-view-options.d.ts +1 -1
  24. package/dist/lib/files.d.ts +10 -1
  25. package/dist/lib/identifier-navigation.d.ts +10 -0
  26. package/dist/lib/keyboard.d.ts +1 -0
  27. package/dist/react.mjs +1163 -278
  28. package/dist/share.mjs +8 -7
  29. package/dist/style.css +392 -52
  30. package/dist/types.d.ts +37 -1
  31. package/package.json +6 -5
@@ -34,9 +34,10 @@ export type ReviewSurfaceProps = {
34
34
  providerLabel?: string;
35
35
  repositoryUrl?: string;
36
36
  settingsBar?: ReactNode;
37
+ sidebarPosition?: 'left' | 'right';
37
38
  signInLabel?: string;
38
39
  snapshot: SharedWalkthroughSnapshot;
39
40
  sourceDescriptionFooterAside?: ReactNode;
40
41
  title?: string;
41
42
  };
42
- export declare function ReviewSurface({ commenting, externalUrl, gitIdentity, initialMode, interactive, onDeleteShare, onModeChange, providerLabel, repositoryUrl, settingsBar, signInLabel, snapshot, sourceDescriptionFooterAside, title, }: ReviewSurfaceProps): import("react").JSX.Element;
43
+ export declare function ReviewSurface({ commenting, externalUrl, gitIdentity, initialMode, interactive, onDeleteShare, onModeChange, providerLabel, repositoryUrl, settingsBar, sidebarPosition, signInLabel, snapshot, sourceDescriptionFooterAside, title, }: ReviewSurfaceProps): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import type { DefinitionCandidate, DefinitionSearchResult } from '../../types.ts';
2
+ export declare function DefinitionPopover({ anchor, getDestination, identifier, onClose, onOpen, result, }: {
3
+ anchor: {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ getDestination: (candidate: DefinitionCandidate) => 'diff' | 'editor' | 'unavailable';
8
+ identifier: string;
9
+ onClose: () => void;
10
+ onOpen: (candidate: DefinitionCandidate) => void;
11
+ result: DefinitionSearchResult | null;
12
+ }): import("react").ReactPortal;
@@ -0,0 +1,6 @@
1
+ import type { OpenReviewSourceKind } from '../../types.ts';
2
+ export declare function OpenReviewSourceDialog({ kind, onClose, onOpen, }: {
3
+ kind: OpenReviewSourceKind;
4
+ onClose: () => void;
5
+ onOpen: (value: string) => Promise<void>;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { OpenReviewSourceKind } from '../../types.ts';
2
+ export declare function OpenReviewSourceMenu({ onOpen, onOpenFolder, }: {
3
+ onOpen: (kind: OpenReviewSourceKind) => void;
4
+ onOpenFolder: () => void;
5
+ }): import("react").JSX.Element;
@@ -1,12 +1,18 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import type { CodiffKeymap } from '../../config/types.ts';
3
3
  import type { RepositoryLoadError, ReviewComment } from '../../lib/app-types.ts';
4
- import type { ChangedFile, PullRequestMergeOptions, PullRequestMergeState, PullRequestReviewEvent, PullRequestReviewStatus } from '../../types.ts';
4
+ import type { ChangedFile, CodiffUpdateStatus, PullRequestMergeOptions, PullRequestMergeState, PullRequestReviewEvent, PullRequestReviewStatus } from '../../types.ts';
5
5
  export declare function ReviewSourceLoading(): import("react").JSX.Element;
6
6
  export declare function RepositoryChangeBanner({ onRefresh, visible, }: {
7
7
  onRefresh: () => void;
8
8
  visible: boolean;
9
9
  }): import("react").JSX.Element;
10
+ export type { CodiffUpdateStatus as UpdateStatus } from '../../types.ts';
11
+ export declare function UpdatePill({ onApply, onDismiss, status, }: {
12
+ onApply: () => void;
13
+ onDismiss?: () => void;
14
+ status: CodiffUpdateStatus;
15
+ }): import("react").JSX.Element | null;
10
16
  export declare function WalkthroughOutdatedBanner({ onDismiss, reason, }: {
11
17
  onDismiss: () => void;
12
18
  reason: string | null;
@@ -45,7 +51,7 @@ export declare function CopyCommentsButton({ comments, files, reviewCommentsPref
45
51
  files: ReadonlyArray<ChangedFile>;
46
52
  reviewCommentsPrefix: string;
47
53
  showWhitespace: boolean;
48
- }): import("react").JSX.Element | null;
54
+ }): import("react").JSX.Element;
49
55
  export declare const isPullRequestReviewActionDisabled: (reviewStatus: PullRequestReviewStatus | undefined, event: PullRequestReviewEvent) => boolean;
50
56
  export declare function PullRequestReviewButtons({ children, disabled, hasPendingComments, onClosePullRequest, onSubmitReview, reviewStatus, showCommentReview, }: {
51
57
  children?: ReactNode;
@@ -2,6 +2,7 @@ import { MarkdownEditor } from '@nkzw/mdx-editor';
2
2
  import type { ComponentProps, ReactNode } from 'react';
3
3
  type MarkdownEditorProps = ComponentProps<typeof MarkdownEditor>;
4
4
  export declare const normalizeReadOnlyMarkdownValue: (value: string) => string;
5
+ export declare const extractFencedCodeBlocks: (value: string) => Array<string>;
5
6
  export declare function ReadOnlyMarkdownView({ additionalPlugins, ariaLabel, className, contentClassName, density, fallback, onHeightChange, value, variant, }: {
6
7
  additionalPlugins?: MarkdownEditorProps['additionalPlugins'];
7
8
  ariaLabel: string;
@@ -0,0 +1,9 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function ResolvedThreadDisclosure({ children, commentCount, focused, focusRequest, initialExpanded, saving, }: {
3
+ children: ReactNode;
4
+ commentCount: number;
5
+ focused?: boolean;
6
+ focusRequest?: number;
7
+ initialExpanded?: boolean;
8
+ saving?: boolean;
9
+ }): import("react").JSX.Element;
@@ -2,7 +2,7 @@ import { type FileDiffLoadedFiles } from '@pierre/diffs';
2
2
  import { type ReactNode } from 'react';
3
3
  import type { CodiffDiffStyle, CodiffKeymap } from '../../config/types.ts';
4
4
  import type { CodeViewInstance, DiffSearchMatch, ReviewComment, ReviewIdentity, ReviewScrollTarget, WalkthroughNote } from '../../lib/app-types.ts';
5
- import type { ChangedFile, CodiffPreferences, CommitMetadata, DiffImageContentRequest, DiffImageContentResult, DiffSection, GitIdentity, PullRequestCodeQualityFinding, ReviewSource } from '../../types.ts';
5
+ import type { ChangedFile, CodiffPreferences, CommitMetadata, DefinitionCandidate, DefinitionSearchRequest, DefinitionSearchResult, DiffImageContentRequest, DiffImageContentResult, DiffSection, GitIdentity, PullRequestCodeQualityFinding, ReviewSource } from '../../types.ts';
6
6
  type PullRequestSource = Extract<ReviewSource, {
7
7
  type: 'pull-request';
8
8
  }>;
@@ -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, onLoadImageContent, onLoadSection, onLoadSectionContents, 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, 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, }: {
43
43
  activeSearchMatch: DiffSearchMatch | null;
44
44
  agentId: 'codex' | 'claude' | 'opencode' | 'pi';
45
45
  agentLabel: string;
@@ -70,9 +70,11 @@ export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel,
70
70
  onCommentDraftChange?: (comment: Pick<ReviewComment, 'body' | 'id'> | null) => void;
71
71
  onCreateComment: (comment: Omit<ReviewComment, 'body' | 'id'>) => void;
72
72
  onDeleteComment: (commentId: string) => void;
73
+ onFindDefinitions?: (request: DefinitionSearchRequest) => Promise<DefinitionSearchResult>;
73
74
  onLoadImageContent?: (request: DiffImageContentRequest) => Promise<DiffImageContentResult>;
74
75
  onLoadSection: (file: ChangedFile, section: DiffSection) => void;
75
76
  onLoadSectionContents?: (file: ChangedFile, section: DiffSection) => Promise<FileDiffLoadedFiles>;
77
+ onOpenDefinition?: (candidate: DefinitionCandidate) => void;
76
78
  onOpenFile?: (file: ChangedFile) => void;
77
79
  onRefreshMarkdown?: (file: ChangedFile, section: DiffSection) => Promise<boolean>;
78
80
  onResolveThread?: (threadId: string, resolved: boolean) => Promise<void> | void;
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ export type ReviewModeItem<Mode extends string> = {
3
+ ariaLabel?: string;
4
+ icon: ReactNode;
5
+ indicator?: ReactNode;
6
+ label: string;
7
+ title?: string;
8
+ value: Mode;
9
+ };
10
+ export declare function ReviewModeControl<Mode extends string>({ mode, modes, onModeChange, }: {
11
+ mode: Mode;
12
+ modes: ReadonlyArray<ReviewModeItem<Mode>>;
13
+ onModeChange: (mode: Mode) => void;
14
+ }): import("react").JSX.Element;
@@ -1,22 +1,23 @@
1
1
  import type { ReactNode } from 'react';
2
- export type ReviewModeItem<Mode extends string> = {
3
- ariaLabel?: string;
4
- icon: ReactNode;
5
- indicator?: ReactNode;
6
- label: string;
7
- title?: string;
8
- value: Mode;
9
- };
10
- export declare function ReviewTopBar<Mode extends string>({ actions, context, leading, mode, modes, onModeChange, onToggleSidebar, repository, repositoryTooltip, sidebarCollapsed, toggleTitle, }: {
2
+ import { type ReviewModeItem } from './ReviewModeControl.tsx';
3
+ export declare function ReviewTopBar<Mode extends string>({ actions, center, context, leading, mode, modes, onModeChange, onToggleSidebar, repository, repositoryTooltip, sidebarCollapsed, sidebarPosition, sourceMenu, toggleTitle, }: {
11
4
  actions?: ReactNode;
5
+ center?: ReactNode;
12
6
  context?: ReactNode;
13
7
  leading?: ReactNode;
14
- mode: Mode;
15
- modes: ReadonlyArray<ReviewModeItem<Mode>>;
16
- onModeChange: (mode: Mode) => void;
17
8
  onToggleSidebar: () => void;
18
9
  repository: ReactNode;
19
10
  repositoryTooltip?: string;
20
11
  sidebarCollapsed: boolean;
12
+ sidebarPosition?: 'left' | 'right';
13
+ sourceMenu?: ReactNode;
21
14
  toggleTitle: string;
22
- }): import("react").JSX.Element;
15
+ } & ({
16
+ mode: Mode;
17
+ modes: ReadonlyArray<ReviewModeItem<Mode>>;
18
+ onModeChange: (mode: Mode) => void;
19
+ } | {
20
+ mode?: undefined;
21
+ modes?: undefined;
22
+ onModeChange?: undefined;
23
+ })): import("react").JSX.Element;
@@ -23,7 +23,7 @@ export declare function SidebarGeneralCommentList({ comments, focusedCommentId,
23
23
  focusedCommentId: string | null;
24
24
  onActivateComment: (commentId: string) => void;
25
25
  }): import("react").JSX.Element;
26
- export declare function MergeRequestCommentsView({ canComment, commenting, draft, editDraft, editError, editingCommentId, editSubmitting, error, focusedCommentId, focusedCommentRequest, gitIdentity, keymap, onCancelEdit, onChangeDraft, onChangeEditDraft, onSaveEdit, onStartEdit, onSubmit, signInLabel, sourceDescription, submitting, threads, }: {
26
+ export declare function MergeRequestCommentsView({ canComment, commenting, draft, editDraft, editError, editingCommentId, editSubmitting, error, focusedCommentId, focusedCommentRequest, gitIdentity, keymap, onCancelEdit, onChangeDraft, onChangeEditDraft, onResolveDiscussion, onSaveEdit, onStartEdit, onSubmit, signInLabel, sourceDescription, submitting, threads, }: {
27
27
  canComment: boolean;
28
28
  commenting?: ReviewCommenting;
29
29
  draft: string;
@@ -39,6 +39,7 @@ export declare function MergeRequestCommentsView({ canComment, commenting, draft
39
39
  onCancelEdit: () => void;
40
40
  onChangeDraft: (draft: string) => void;
41
41
  onChangeEditDraft: (draft: string) => void;
42
+ onResolveDiscussion?: (discussionId: string, resolved: boolean) => Promise<void>;
42
43
  onSaveEdit: () => void;
43
44
  onStartEdit: (comment: PullRequestGeneralComment) => void;
44
45
  onSubmit: () => void;
@@ -14,16 +14,18 @@ export type WalkthroughBlockScrollTarget = {
14
14
  blockId: string;
15
15
  request: number;
16
16
  };
17
- export declare const getWalkthroughBlockScrollTarget: ({ activeBlockId, firstSupportBlockId, mode, stopScrollRequest, supportScrollRequest, }: {
17
+ export declare const getWalkthroughBlockScrollTarget: ({ activeBlockId, firstSupportBlockId, scrollTarget, }: {
18
18
  activeBlockId: string | null | undefined;
19
19
  firstSupportBlockId: string | null;
20
- mode: NarrativeNavigation['mode'];
21
- stopScrollRequest: number;
22
- supportScrollRequest: number;
20
+ scrollTarget: NarrativeNavigation['scrollTarget'];
23
21
  }) => WalkthroughBlockScrollTarget | null;
24
22
  export type RenderWalkthroughDiffBlocks = (blocks: ReadonlyArray<ReviewDiffBlock>, scrollTarget: WalkthroughBlockScrollTarget | null, onActiveBlockChange: (blockId: string) => void) => ReactNode;
25
23
  type WalkthroughNavigationKeyEvent = Pick<KeyboardEvent, 'altKey' | 'ctrlKey' | 'key' | 'metaKey' | 'shiftKey'>;
26
24
  export declare const getWalkthroughNavigationKeyDirection: (event: WalkthroughNavigationKeyEvent) => -1 | 0 | 1;
25
+ export declare const getWalkthroughKeyboardForwardIndex: ({ index, scrollRequest, }: {
26
+ index: number;
27
+ scrollRequest: number;
28
+ }) => number;
27
29
  export declare function NarrativeWalkthroughView({ allowCommit, files, navigation, onActiveReviewTargetChange, onCommit, onCommitOutput, onShareWalkthrough, onUpdateCommitMessage, renderDiffBlocks, shareWalkthroughDisabled, showWhitespace, walkthrough, }: {
28
30
  allowCommit?: boolean;
29
31
  files: ReadonlyArray<ChangedFile>;
@@ -19,11 +19,11 @@ export declare const useNarrativeNavigation: (walkthrough: NarrativeWalkthrough
19
19
  releaseStopScrollLock: () => void;
20
20
  scrollTarget: {
21
21
  index: number;
22
+ kind: 'stop' | 'support';
22
23
  nonce: number;
23
24
  };
24
25
  setCommitBody: (value: string) => void;
25
26
  setCommitSubject: (value: string) => void;
26
- supportScrollRequest: number;
27
27
  supportVisited: boolean;
28
28
  syncIndexFromScroll: (target: number) => void;
29
29
  syncSupportFromScroll: () => void;
@@ -2,12 +2,13 @@ import { type RefObject } from 'react';
2
2
  import type { ReviewComment, ReviewIdentity, SidebarMode } from '../../lib/app-types.ts';
3
3
  import { type Command } from '../../lib/command-registry.ts';
4
4
  import type { ReviewCommandTarget } from '../../lib/review-command-target.ts';
5
- import type { ChangedFile, CodiffPreferences, RepositoryState } from '../../types.ts';
5
+ import type { ChangedFile, CodiffPreferences, OpenReviewSourceKind, RepositoryState } from '../../types.ts';
6
6
  type UseAppCommandsOptions = {
7
7
  changeSidebarMode: (mode: SidebarMode) => void;
8
8
  focusFileFilter: () => void;
9
9
  getReviewCommandTarget: () => ReviewCommandTarget | null;
10
10
  onOpenDiffSearch: () => void;
11
+ onOpenReviewSource: (kind: OpenReviewSourceKind) => void;
11
12
  onOpenSelectedFile: () => void;
12
13
  onRefreshRepository: () => void;
13
14
  onToggleSidebar: () => void;
@@ -18,5 +19,5 @@ type UseAppCommandsOptions = {
18
19
  stateRef: RefObject<RepositoryState | null>;
19
20
  viewedRef: RefObject<Record<string, string>>;
20
21
  };
21
- export declare function useAppCommands({ changeSidebarMode, focusFileFilter, getReviewCommandTarget, onOpenDiffSearch, onOpenSelectedFile, onRefreshRepository, onToggleSidebar, onToggleViewed, onToggleWordWrap, preferencesRef, reviewCommentsRef, stateRef, viewedRef, }: UseAppCommandsOptions): readonly Command[];
22
+ export declare function useAppCommands({ changeSidebarMode, focusFileFilter, getReviewCommandTarget, onOpenDiffSearch, onOpenReviewSource, onOpenSelectedFile, onRefreshRepository, onToggleSidebar, onToggleViewed, onToggleWordWrap, preferencesRef, reviewCommentsRef, stateRef, viewedRef, }: UseAppCommandsOptions): readonly Command[];
22
23
  export {};
@@ -18,6 +18,7 @@ export declare function useAppReviewComments({ isReviewActionDisabled, onComment
18
18
  clearCommentFocus: (commentId: string) => void;
19
19
  createComment: (comment: Omit<ReviewComment, 'body' | 'id'>) => void;
20
20
  deleteComment: (commentId: string) => void;
21
+ focusComment: (commentId: string) => void;
21
22
  focusCommentId: string | null;
22
23
  focusCommentRequest: number;
23
24
  resetCommentFocus: () => void;
@@ -32,11 +32,11 @@ export declare function useAppWalkthrough({ preferencesRef, state, stateGenerati
32
32
  releaseStopScrollLock: () => void;
33
33
  scrollTarget: {
34
34
  index: number;
35
+ kind: 'stop' | 'support';
35
36
  nonce: number;
36
37
  };
37
38
  setCommitBody: (value: string) => void;
38
39
  setCommitSubject: (value: string) => void;
39
- supportScrollRequest: number;
40
40
  supportVisited: boolean;
41
41
  syncIndexFromScroll: (target: number) => void;
42
42
  syncSupportFromScroll: () => void;
@@ -3,9 +3,10 @@ type UseResizableSidebarOptions = {
3
3
  collapseThreshold?: number;
4
4
  onCollapse?: () => void;
5
5
  onWidthCommit: (width: number) => void;
6
+ position: 'left' | 'right';
6
7
  readWidth: () => number;
7
8
  };
8
- export declare function useResizableSidebar({ collapseThreshold, onCollapse, onWidthCommit, readWidth, }: UseResizableSidebarOptions): {
9
+ export declare function useResizableSidebar({ collapseThreshold, onCollapse, onWidthCommit, position, readWidth, }: UseResizableSidebarOptions): {
9
10
  resizeSidebar: (event: ReactPointerEvent<HTMLDivElement>) => void;
10
11
  sidebarWidth: number;
11
12
  };
@@ -13,6 +13,7 @@ export declare function useReviewCommentDrafts({ canCreateComment, comments, onC
13
13
  clearCommentFocus: (commentId: string) => void;
14
14
  createComment: (comment: Omit<ReviewComment, 'body' | 'id'>) => void;
15
15
  deleteComment: (commentId: string) => void;
16
+ focusComment: (commentId: string) => void;
16
17
  focusCommentId: string | null;
17
18
  focusCommentRequest: number;
18
19
  resetCommentFocus: () => void;
@@ -0,0 +1,13 @@
1
+ export type NativeKeyboardKeyMapping = {
2
+ value: string;
3
+ valueIsDeadKey?: boolean;
4
+ withShift: string;
5
+ withShiftIsDeadKey?: boolean;
6
+ };
7
+ export type NativeKeyboardLayout = Readonly<Record<string, NativeKeyboardKeyMapping>>;
8
+ export declare const codeForCharacter: (character: string, shiftKey: boolean) => string | null;
9
+ export declare const shiftedCharacterForCode: (code: string) => string | null;
10
+ export declare const hasKeyboardLayout: () => boolean;
11
+ export declare const trackKeyboardLayout: () => void;
12
+ export declare const applyKeyboardLayout: (layout: NativeKeyboardLayout) => void;
13
+ export declare const resetKeyboardLayout: () => void;
@@ -1,3 +1,5 @@
1
1
  import type { CodiffKeymap } from './types.ts';
2
- export declare const matchesShortcut: (event: Pick<KeyboardEvent, 'altKey' | 'ctrlKey' | 'key' | 'metaKey' | 'shiftKey'>, keymap: CodiffKeymap, action: keyof CodiffKeymap) => boolean;
2
+ type ShortcutEvent = Pick<KeyboardEvent, 'altKey' | 'code' | 'ctrlKey' | 'key' | 'metaKey' | 'shiftKey'>;
3
+ export declare const matchesShortcut: (event: ShortcutEvent, keymap: CodiffKeymap, action: keyof CodiffKeymap) => boolean;
3
4
  export declare const getShortcutLabel: (keymap: CodiffKeymap, action: keyof CodiffKeymap) => string;
5
+ export {};
@@ -3,6 +3,7 @@ export type CodiffTheme = 'system' | 'light' | 'dark';
3
3
  export type CodiffAgentBackend = 'codex' | 'claude' | 'opencode' | 'pi';
4
4
  export type CodiffSettings = {
5
5
  agentBackend: CodiffAgentBackend;
6
+ checkForUpdates: boolean;
6
7
  claudeModel: string;
7
8
  codeFontFamily: string;
8
9
  codeFontSize: number;
@@ -16,6 +17,7 @@ export type CodiffSettings = {
16
17
  reviewCommentsPrefix: string;
17
18
  showOutdated: boolean;
18
19
  showWhitespace: boolean;
20
+ sidebarPosition: 'left' | 'right';
19
21
  theme: CodiffTheme;
20
22
  walkthroughPrompt: string;
21
23
  wordWrap: boolean;
@@ -23,6 +25,7 @@ export type CodiffSettings = {
23
25
  export type KeyCombo = string;
24
26
  export type KeyComboBinding = KeyCombo | ReadonlyArray<KeyCombo>;
25
27
  export type CodiffKeymap = {
28
+ askAgent: KeyCombo;
26
29
  closeSearch: KeyCombo;
27
30
  commandBar: KeyCombo;
28
31
  diffSearch: KeyCombo;
@@ -47,6 +47,7 @@ export type ReviewScrollBehavior = 'instant' | 'smooth';
47
47
  export type ReviewScrollTarget = {
48
48
  behavior?: ReviewScrollBehavior;
49
49
  blockId?: string;
50
+ commentId?: string;
50
51
  path?: string;
51
52
  request: number;
52
53
  };
@@ -23,4 +23,4 @@ export declare const workerHighlighterOptions: {
23
23
  useTokenTransformer: boolean;
24
24
  };
25
25
  export declare const maxWorkerThreads = 3;
26
- export declare const codeViewUnsafeCSS = "\n :host {\n border-radius: var(--codiff-diff-radius, 28px);\n corner-shape: squircle;\n --diffs-font-family: var(--font-diff-mono, var(--font-mono));\n --diffs-header-font-family: var(--font-sans);\n --diffs-font-size: var(--font-diff-size, 13px);\n --diffs-line-height: var(--font-diff-line-height, 20px);\n --diffs-light-bg: var(--code-bg);\n --diffs-dark-bg: var(--code-bg);\n --diffs-bg-selection-override: rgb(61 135 245 / 0.34);\n --diffs-bg-selection-number-override: rgb(61 135 245 / 0.46);\n }\n\n [data-diff-type=\"split\"][data-overflow=\"scroll\"] {\n grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);\n }\n\n [data-diffs-header=\"custom\"][data-sticky] {\n background-color: transparent;\n border-radius: 0;\n }\n\n :host(.codiff-walkthrough-header-item) {\n background: var(--app-bg);\n border-radius: 0;\n box-shadow: none;\n corner-shape: initial;\n overflow: visible;\n }\n\n :host(.codiff-walkthrough-header-item) [data-file],\n :host(.codiff-walkthrough-header-item) pre,\n :host(.codiff-walkthrough-header-item) code,\n :host(.codiff-walkthrough-header-item) [data-code],\n :host(.codiff-walkthrough-header-item) [data-line-annotation] {\n background: var(--app-bg);\n border-radius: 0;\n box-shadow: none;\n overflow: visible;\n }\n\n :host(.codiff-walkthrough-header-item) [data-column-number],\n :host(.codiff-walkthrough-header-item) [data-line-number],\n :host(.codiff-walkthrough-header-item) [data-gutter],\n :host(.codiff-walkthrough-header-item) [data-gutter-buffer],\n :host(.codiff-walkthrough-header-item) [data-content] > [data-line] {\n display: none;\n }\n\n .review-comment-thread {\n padding: 8px 0 8px 16px;\n }\n\n /* Align scrollbar with number column */\n [data-code]::-webkit-scrollbar-track {\n margin-left: var(--diffs-column-number-width);\n }\n\n /* Ensure right edge of scrollbar never gets cropped by rounded corners */\n [data-file] [data-code]::-webkit-scrollbar-track,\n [data-diff-type=\"single\"] [data-code]::-webkit-scrollbar-track,\n [data-diff-type=\"split\"] [data-code][data-additions]::-webkit-scrollbar-track {\n margin-right: 14px;\n }\n\n :host(.codiff-markdown-preview-item) [data-file] [data-code] {\n grid-column: 1 / -1;\n }\n\n :host(.codiff-markdown-preview-item) [data-file] [data-line=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"],\n :host(.codiff-markdown-preview-item) [data-file] [data-column-number=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"],\n :host(.codiff-markdown-preview-item) [data-gutter] > [data-gutter-utility-slot] {\n display: none;\n pointer-events: none;\n }\n\n :host(.codiff-image-preview-item) [data-file] {\n --diffs-code-grid: 1fr;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-code] {\n grid-column: 1 / -1;\n padding-block: 0;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-content] {\n grid-column: 1;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-gutter],\n :host(.codiff-image-preview-item) [data-file] [data-line=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"] {\n display: none;\n pointer-events: none;\n }\n\n :host(.codiff-loadable-summary-item) [data-file] [data-line],\n :host(.codiff-loadable-summary-item) [data-file] [data-column-number] {\n cursor: pointer;\n }\n\n :host(.codiff-loading-summary-item) [data-file] [data-line],\n :host(.codiff-loading-summary-item) [data-file] [data-column-number] {\n cursor: progress;\n }\n\n .codiff-search-mark {\n background: var(--diffs-find-highlight-bg, rgb(255 216 92 / 0.65));\n border-radius: 3px;\n color: inherit;\n padding: 0 1px;\n }\n\n .codiff-search-mark.active {\n background: var(--diffs-find-active-bg, rgb(255 176 46 / 0.96));\n box-shadow: 0 0 0 1px rgb(255 142 36 / 0.4);\n }\n\n [data-utility-button] {\n background: color-mix(in srgb, var(--diffs-bg) 88%, var(--diffs-modified-base));\n border: 1px solid color-mix(in srgb, var(--diffs-modified-base) 34%, transparent);\n border-radius: 3px;\n box-shadow: 0 7px 18px -14px rgb(0 0 0 / 0.72);\n color: var(--diffs-modified-base);\n height: calc(1lh - 4px);\n transform: translate(-4px, 2px);\n width: calc(1lh - 4px);\n }\n\n [data-selected-line] [data-gutter-utility-slot] {\n display: none;\n }\n";
26
+ export declare const codeViewUnsafeCSS = "\n :host {\n border-radius: var(--codiff-diff-radius, 28px);\n corner-shape: squircle;\n --diffs-font-family: var(--font-diff-mono, var(--font-mono));\n --diffs-header-font-family: var(--font-sans);\n --diffs-font-size: var(--font-diff-size, 13px);\n --diffs-line-height: var(--font-diff-line-height, 20px);\n --diffs-light-bg: var(--code-bg);\n --diffs-dark-bg: var(--code-bg);\n --diffs-bg-selection-override: rgb(61 135 245 / 0.34);\n --diffs-bg-selection-number-override: rgb(61 135 245 / 0.46);\n }\n\n [data-diff-type=\"split\"][data-overflow=\"scroll\"] {\n grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);\n }\n\n [data-diffs-header=\"custom\"][data-sticky] {\n background-color: transparent;\n border-radius: 0;\n }\n\n :host(.codiff-walkthrough-header-item) {\n background: var(--app-bg);\n border-radius: 0;\n box-shadow: none;\n corner-shape: initial;\n overflow: visible;\n }\n\n :host(.codiff-walkthrough-header-item) [data-file],\n :host(.codiff-walkthrough-header-item) pre,\n :host(.codiff-walkthrough-header-item) code,\n :host(.codiff-walkthrough-header-item) [data-code],\n :host(.codiff-walkthrough-header-item) [data-line-annotation] {\n background: var(--app-bg);\n border-radius: 0;\n box-shadow: none;\n overflow: visible;\n }\n\n :host(.codiff-walkthrough-header-item) [data-column-number],\n :host(.codiff-walkthrough-header-item) [data-line-number],\n :host(.codiff-walkthrough-header-item) [data-gutter],\n :host(.codiff-walkthrough-header-item) [data-gutter-buffer],\n :host(.codiff-walkthrough-header-item) [data-content] > [data-line] {\n display: none;\n }\n\n .review-comment-thread {\n padding: 8px 0 8px 16px;\n }\n\n /* Align scrollbar with number column */\n [data-code]::-webkit-scrollbar-track {\n margin-left: var(--diffs-column-number-width);\n }\n\n /* Ensure right edge of scrollbar never gets cropped by rounded corners */\n [data-file] [data-code]::-webkit-scrollbar-track,\n [data-diff-type=\"single\"] [data-code]::-webkit-scrollbar-track,\n [data-diff-type=\"split\"] [data-code][data-additions]::-webkit-scrollbar-track {\n margin-right: 14px;\n }\n\n :host(.codiff-markdown-preview-item) [data-file] [data-code] {\n grid-column: 1 / -1;\n }\n\n :host(.codiff-markdown-preview-item) [data-file] [data-line=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"],\n :host(.codiff-markdown-preview-item) [data-file] [data-column-number=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"],\n :host(.codiff-markdown-preview-item) [data-gutter] > [data-gutter-utility-slot] {\n display: none;\n pointer-events: none;\n }\n\n :host(.codiff-image-preview-item) [data-file] {\n --diffs-code-grid: 1fr;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-code] {\n grid-column: 1 / -1;\n padding-block: 0;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-content] {\n grid-column: 1;\n }\n\n :host(.codiff-image-preview-item) [data-file] [data-gutter],\n :host(.codiff-image-preview-item) [data-file] [data-line=\"1\"][data-line-index=\"0\"][data-line-type=\"context\"] {\n display: none;\n pointer-events: none;\n }\n\n :host(.codiff-loadable-summary-item) [data-file] [data-line],\n :host(.codiff-loadable-summary-item) [data-file] [data-column-number] {\n cursor: pointer;\n }\n\n :host(.codiff-loading-summary-item) [data-file] [data-line],\n :host(.codiff-loading-summary-item) [data-file] [data-column-number] {\n cursor: progress;\n }\n\n :host([data-codiff-definition-mode]) [data-codiff-identifier] {\n cursor: pointer;\n text-decoration-color: color-mix(in srgb, currentColor 38%, transparent);\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: 1px;\n text-underline-offset: 3px;\n }\n\n :host([data-codiff-definition-mode]) [data-codiff-identifier]:hover {\n text-decoration-color: currentColor;\n text-decoration-style: solid;\n }\n\n .codiff-search-mark {\n background: var(--diffs-find-highlight-bg, rgb(255 216 92 / 0.65));\n border-radius: 3px;\n color: inherit;\n padding: 0 1px;\n }\n\n .codiff-search-mark.active {\n background: var(--diffs-find-active-bg, rgb(255 176 46 / 0.96));\n box-shadow: 0 0 0 1px rgb(255 142 36 / 0.4);\n }\n\n [data-utility-button] {\n background: color-mix(in srgb, var(--diffs-bg) 88%, var(--diffs-modified-base));\n border: 1px solid color-mix(in srgb, var(--diffs-modified-base) 34%, transparent);\n border-radius: 3px;\n box-shadow: 0 7px 18px -14px rgb(0 0 0 / 0.72);\n color: var(--diffs-modified-base);\n height: calc(1lh - 4px);\n transform: translate(-4px, 2px);\n width: calc(1lh - 4px);\n }\n\n [data-selected-line] [data-gutter-utility-slot] {\n display: none;\n }\n\n /* The imperative API wraps annotations in a node that resets white-space, but\n the React API slots them in bare, so they inherit \"pre\" from the shadow\n <pre> and prose never wraps. */\n [data-annotation-content] slot::slotted(*) {\n white-space: normal;\n }\n";
@@ -9,6 +9,15 @@ export declare const fileTreeSort: (left: {
9
9
  path: string;
10
10
  segments?: ReadonlyArray<string>;
11
11
  }) => number;
12
- export declare const compactPath: (path: string) => string;
12
+ export declare const abbreviateHomePath: (path: string) => string;
13
+ /**
14
+ * Splits a repository path into a shrinkable head and the repository's own
15
+ * directory, so the top bar can keep the repository name visible and put the
16
+ * ellipsis in the middle when the full path overflows.
17
+ */
18
+ export declare const splitRepositoryPath: (path: string) => {
19
+ head: string;
20
+ tail: string;
21
+ };
13
22
  export declare const sortFiles: (files: ReadonlyArray<ChangedFile>) => ChangedFile[];
14
23
  export declare const fuzzyMatches: (path: string, query: string) => boolean;
@@ -0,0 +1,10 @@
1
+ export type IdentifierAtOffset = {
2
+ identifier: string;
3
+ start: number;
4
+ };
5
+ export declare const isNavigableIdentifierToken: (text: string) => boolean;
6
+ export declare const applyIdentifierNavigationState: (renderedItems: ReadonlyArray<{
7
+ element: HTMLElement;
8
+ }>, active: boolean) => void;
9
+ export declare const getIdentifierAtOffset: (text: string, offset: number) => IdentifierAtOffset | null;
10
+ export declare const getIdentifierFromPointerEvent: (event: PointerEvent, lineElement: HTMLElement) => string | null;
@@ -1,2 +1,3 @@
1
1
  export declare const isNativeInputTarget: (target: EventTarget | null) => boolean;
2
+ export declare const isPrimaryModifier: (event: Pick<KeyboardEvent, 'ctrlKey' | 'metaKey'>, platform?: string) => boolean;
2
3
  export declare const isDiffSearchShortcut: (event: Pick<KeyboardEvent, 'altKey' | 'ctrlKey' | 'key' | 'metaKey' | 'shiftKey'>, platform?: string) => boolean;