dsh-diff-approval 0.12.0 → 0.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/README.md +9 -3
- package/README.zh.md +9 -3
- package/lib/client.js +822 -260
- package/lib/index.js +24 -30
- package/lib/types/client/PendingPanel.d.ts +5 -1
- package/lib/types/client/conversation-access.d.ts +67 -0
- package/lib/types/client/index.d.ts +2 -1
- package/lib/types/client/locales.d.ts +12 -0
- package/lib/types/client/reference.d.ts +32 -2
- package/lib/types/client/remap-sync.d.ts +44 -0
- package/lib/types/client/settings.d.ts +20 -0
- package/lib/types/client/slots.d.ts +8 -0
- package/lib/types/client/store.d.ts +2 -0
- package/lib/types/types.d.ts +3 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1343,18 +1343,12 @@ function apply(ctx, config) {
|
|
|
1343
1343
|
};
|
|
1344
1344
|
const accepted = contentRangeOf(entry.newText, blockTarget.block.newStart, blockTarget.block.newEnd);
|
|
1345
1345
|
const updatedOld = replaceContentLines(entry.oldText, blockTarget.block.oldStart, blockTarget.block.oldEnd, accepted);
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
afterEntry = {
|
|
1353
|
-
...entry,
|
|
1354
|
-
oldText: updatedOld,
|
|
1355
|
-
updatedAt: Date.now()
|
|
1356
|
-
};
|
|
1357
|
-
}
|
|
1346
|
+
store.update(blockTarget.sessionId, blockTarget.id, { oldText: updatedOld });
|
|
1347
|
+
const afterEntry = {
|
|
1348
|
+
...entry,
|
|
1349
|
+
oldText: updatedOld,
|
|
1350
|
+
updatedAt: Date.now()
|
|
1351
|
+
};
|
|
1358
1352
|
pushUndo(blockTarget.sessionId, {
|
|
1359
1353
|
id: entry.id,
|
|
1360
1354
|
path: entry.path,
|
|
@@ -1369,7 +1363,10 @@ function apply(ctx, config) {
|
|
|
1369
1363
|
await persistSession(blockTarget.sessionId);
|
|
1370
1364
|
return {
|
|
1371
1365
|
ok: true,
|
|
1372
|
-
value:
|
|
1366
|
+
value: updatedOld === entry.newText ? {
|
|
1367
|
+
outcome: "kept",
|
|
1368
|
+
resolved: true
|
|
1369
|
+
} : { outcome: "kept" }
|
|
1373
1370
|
};
|
|
1374
1371
|
}
|
|
1375
1372
|
case "block-revert": {
|
|
@@ -1384,25 +1381,19 @@ function apply(ctx, config) {
|
|
|
1384
1381
|
const restored = contentRangeOf(entry.oldText, blockTarget.block.oldStart, blockTarget.block.oldEnd);
|
|
1385
1382
|
const updatedNew = replaceContentLines(entry.newText, blockTarget.block.newStart, blockTarget.block.newEnd, restored);
|
|
1386
1383
|
const content = reencodeEol(updatedNew, detectEol(entry.newText));
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
afterEntry = {
|
|
1394
|
-
...entry,
|
|
1395
|
-
newText: content,
|
|
1396
|
-
updatedAt: Date.now()
|
|
1397
|
-
};
|
|
1398
|
-
}
|
|
1384
|
+
store.update(blockTarget.sessionId, blockTarget.id, { newText: content });
|
|
1385
|
+
const afterEntry = {
|
|
1386
|
+
...entry,
|
|
1387
|
+
newText: content,
|
|
1388
|
+
updatedAt: Date.now()
|
|
1389
|
+
};
|
|
1399
1390
|
let undo;
|
|
1400
1391
|
try {
|
|
1401
|
-
const
|
|
1402
|
-
if (entry.kind === "create" && content === "") await rm(ctx.fs.processPath(
|
|
1392
|
+
const target = await ctx.fs.resolve(entry.path, { signal });
|
|
1393
|
+
if (entry.kind === "create" && content === "") await rm(ctx.fs.processPath(target), { force: true });
|
|
1403
1394
|
else {
|
|
1404
|
-
const preWrite = await ctx.fs.readText(
|
|
1405
|
-
await writeRevert(
|
|
1395
|
+
const preWrite = await ctx.fs.readText(target, void 0) ?? entry.newText;
|
|
1396
|
+
await writeRevert(target, content, blockTarget.sessionId, signal);
|
|
1406
1397
|
undo = {
|
|
1407
1398
|
before: {
|
|
1408
1399
|
id: entry.id,
|
|
@@ -1425,7 +1416,10 @@ function apply(ctx, config) {
|
|
|
1425
1416
|
await persistSession(blockTarget.sessionId);
|
|
1426
1417
|
return {
|
|
1427
1418
|
ok: true,
|
|
1428
|
-
value:
|
|
1419
|
+
value: normalizeEol(updatedNew) === normalizeEol(entry.oldText) ? {
|
|
1420
|
+
outcome: "reverted",
|
|
1421
|
+
resolved: true
|
|
1422
|
+
} : { outcome: "reverted" }
|
|
1429
1423
|
};
|
|
1430
1424
|
}
|
|
1431
1425
|
case "undo": {
|
|
@@ -6,6 +6,10 @@ import type { PendingPanelFace } from './slots.ts';
|
|
|
6
6
|
import type { DiffApprovalKey } from './locales.ts';
|
|
7
7
|
import { computeWholeFileDiff } from './whole-file-diff.ts';
|
|
8
8
|
import { highlightLines } from './highlight.ts';
|
|
9
|
+
/** The dsh shell's sidebar auto-collapse breakpoint (ui-layout columns.ts):
|
|
10
|
+
* below it the sidebar auto-collapses, and the file list floats on the same
|
|
11
|
+
* breakpoint so the two stay consistent. */
|
|
12
|
+
export declare const SIDEBAR_AUTO_COLLAPSE_PX = 1024;
|
|
9
13
|
export declare function wrapInto(text: string, widthPx: number, measure: (t: string) => number, tabPx: number): string[];
|
|
10
14
|
/** Full panel props composed by the sidebar footer-action slot. */
|
|
11
15
|
export type PendingPanelProps = PropsRuntime<'sidebar.footer.action'> & InjectFace<PendingPanelFace> & PropsLocale<'diff-approval'>;
|
|
@@ -56,5 +60,5 @@ export declare const SplitDiff: import("react").ForwardRefExoticComponent<{
|
|
|
56
60
|
onBlockRevert: (sessionId: SessionId, id: string, block: DiffApprovalBlockRange) => Promise<void>;
|
|
57
61
|
} & import("react").RefAttributes<SplitDiffHandle>>;
|
|
58
62
|
/** Render the pending-edit review panel and its unified footer action. */
|
|
59
|
-
export declare function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, t, }: PendingPanelProps): import("react").JSX.Element;
|
|
63
|
+
export declare function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, onAckJustResolved, collapseSidebar, t, }: PendingPanelProps): import("react").JSX.Element;
|
|
60
64
|
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-addressed access to the session's composer draft and pending queue.
|
|
3
|
+
* Extracted from the plugin entry so the wiring (not just the remap math) is
|
|
4
|
+
* unit-testable against a faithful fake of the DSH conversation service.
|
|
5
|
+
* @module dsh-diff-approval/client/conversation-access
|
|
6
|
+
*/
|
|
7
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
8
|
+
import type { SessionId } from '@deepseek-ai/dsh-client-connection/client';
|
|
9
|
+
/** One queued message's minimal shape read from the session input state. */
|
|
10
|
+
export interface QueueMessageView {
|
|
11
|
+
id: string;
|
|
12
|
+
placement: 'queued' | 'steering' | 'context';
|
|
13
|
+
content: readonly {
|
|
14
|
+
type: string;
|
|
15
|
+
text?: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
/** The conversation service slice the reference remap addresses through a session scope. */
|
|
19
|
+
export interface ConversationFace {
|
|
20
|
+
input: {
|
|
21
|
+
for(actx: ClientContext): {
|
|
22
|
+
setDraft(text: string): void;
|
|
23
|
+
state: {
|
|
24
|
+
getSnapshot(): {
|
|
25
|
+
queue: readonly QueueMessageView[];
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
updateQueue(itemId: string, action: {
|
|
31
|
+
kind: 'edit';
|
|
32
|
+
content: readonly {
|
|
33
|
+
type: string;
|
|
34
|
+
text?: string;
|
|
35
|
+
}[];
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the current session's scoped conversation face. The scoped context
|
|
40
|
+
* (`sessions.scope(id)`) carries no `conversation` inject of its own, so reading
|
|
41
|
+
* it as a property (`actx.conversation`) trips Cordis's inject check and throws
|
|
42
|
+
* `cannot get property "conversation" without inject`. `actx.get('conversation')`
|
|
43
|
+
* bypasses that check yet still returns the traceable bound to `actx`, so its
|
|
44
|
+
* verbs (e.g. `updateQueue`) resolve the right session scope.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveConversation(ctx: ClientContext, sessionId: SessionId | undefined): {
|
|
47
|
+
actx: ClientContext;
|
|
48
|
+
conversation: ConversationFace;
|
|
49
|
+
} | undefined;
|
|
50
|
+
/** Draft/queue verbs bound to the current session, resolved lazily per call. */
|
|
51
|
+
export interface ConversationAccess {
|
|
52
|
+
/** Write the current session's composer draft. */
|
|
53
|
+
writeDraft: (text: string) => void;
|
|
54
|
+
/** Read the current session's still-queued messages (queued placement only). */
|
|
55
|
+
readQueue: () => readonly QueueMessageView[];
|
|
56
|
+
/** Apply an edit mutation to one queued message's full content. */
|
|
57
|
+
writeQueue: (itemId: string, content: readonly {
|
|
58
|
+
type: string;
|
|
59
|
+
text?: string;
|
|
60
|
+
}[]) => void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build the per-call-resolved draft/queue accessor. `sessionId` is a function
|
|
64
|
+
* so the accessor always addresses the *current* session, even though it is
|
|
65
|
+
* handed to the remap sync once.
|
|
66
|
+
*/
|
|
67
|
+
export declare function conversationAccess(ctx: ClientContext, sessionId: () => SessionId | undefined): ConversationAccess;
|
|
@@ -4,7 +4,8 @@ export type { PendingPanelProps } from './PendingPanel.tsx';
|
|
|
4
4
|
export type { PendingDiffSnapshot, PendingPanelFace } from './slots.ts';
|
|
5
5
|
export type { DiffApprovalKey } from './locales.ts';
|
|
6
6
|
export { DIFF_APPROVAL_CHANNEL } from './port.ts';
|
|
7
|
-
/** Required services: locale, slots, the wire channel,
|
|
7
|
+
/** Required services: locale, slots, the wire channel, the current session, and
|
|
8
|
+
* the layout controller (this plugin collapses the sidebar before its modal opens). */
|
|
8
9
|
export declare const inject: string[];
|
|
9
10
|
/**
|
|
10
11
|
* Mount the pending-edit review panel.
|
|
@@ -26,9 +26,13 @@ export declare const zh: {
|
|
|
26
26
|
'panel.tabWidthDesc': string;
|
|
27
27
|
'panel.splitMode': string;
|
|
28
28
|
'panel.splitModeDesc': string;
|
|
29
|
+
'panel.quickSummon': string;
|
|
30
|
+
'panel.quickSummonDesc': string;
|
|
31
|
+
'panel.recordShortcut': string;
|
|
29
32
|
'settings.tabLabel': string;
|
|
30
33
|
'row.create': string;
|
|
31
34
|
'row.failed': string;
|
|
35
|
+
'row.dismiss': string;
|
|
32
36
|
'row.added': string;
|
|
33
37
|
'row.removed': string;
|
|
34
38
|
'action.keep': string;
|
|
@@ -64,6 +68,8 @@ export declare const zh: {
|
|
|
64
68
|
'status.kept': string;
|
|
65
69
|
'status.reverted': string;
|
|
66
70
|
'status.missing': string;
|
|
71
|
+
'panel.resolvedAsk': string;
|
|
72
|
+
'panel.keepInList': string;
|
|
67
73
|
};
|
|
68
74
|
/** Translation keys owned by the pending-edit review namespace. */
|
|
69
75
|
export type DiffApprovalKey = keyof typeof zh;
|
|
@@ -99,9 +105,13 @@ export declare const en: {
|
|
|
99
105
|
'panel.tabWidthDesc': string;
|
|
100
106
|
'panel.splitMode': string;
|
|
101
107
|
'panel.splitModeDesc': string;
|
|
108
|
+
'panel.quickSummon': string;
|
|
109
|
+
'panel.quickSummonDesc': string;
|
|
110
|
+
'panel.recordShortcut': string;
|
|
102
111
|
'settings.tabLabel': string;
|
|
103
112
|
'row.create': string;
|
|
104
113
|
'row.failed': string;
|
|
114
|
+
'row.dismiss': string;
|
|
105
115
|
'row.added': string;
|
|
106
116
|
'row.removed': string;
|
|
107
117
|
'action.keep': string;
|
|
@@ -137,4 +147,6 @@ export declare const en: {
|
|
|
137
147
|
'status.kept': string;
|
|
138
148
|
'status.reverted': string;
|
|
139
149
|
'status.missing': string;
|
|
150
|
+
'panel.resolvedAsk': string;
|
|
151
|
+
'panel.keepInList': string;
|
|
140
152
|
};
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* the panel.
|
|
6
6
|
* @module dsh-diff-approval/client/reference
|
|
7
7
|
*/
|
|
8
|
+
/** The marker that replaces a reference's line number when its lines are gone. */
|
|
9
|
+
export declare const LINE_MISSING_LABEL = "LINE_MISSING";
|
|
8
10
|
/**
|
|
9
11
|
* Last path segment of a file path, any separator style.
|
|
10
12
|
* @param path - the path to shorten.
|
|
@@ -30,11 +32,39 @@ export declare function referencePathOf(path: string, workspacePath: string | un
|
|
|
30
32
|
*/
|
|
31
33
|
export declare function lineRangeLabel(start: number, end: number): string;
|
|
32
34
|
/**
|
|
33
|
-
* Build the clipboard text for a selected line range
|
|
35
|
+
* Build the clipboard text for a selected line range, wrapped in parentheses so
|
|
36
|
+
* the reference reads as one unambiguous token (and can be matched precisely).
|
|
34
37
|
* @param path - the selected file's path.
|
|
35
38
|
* @param workspacePath - the current workspace root, or `undefined`.
|
|
36
39
|
* @param start - first selected line number.
|
|
37
40
|
* @param end - last selected line number.
|
|
38
|
-
* @returns the `path:range` reference text.
|
|
41
|
+
* @returns the `(path:range)` reference text.
|
|
39
42
|
*/
|
|
40
43
|
export declare function referenceOf(path: string, workspacePath: string | undefined, start: number, end: number): string;
|
|
44
|
+
/**
|
|
45
|
+
* Map one referenced line range from `oldContent` coordinates to `newContent`
|
|
46
|
+
* coordinates. Lines that survive (unchanged context) map to their new line
|
|
47
|
+
* numbers, and the surviving lines' min/max span is returned. When every line
|
|
48
|
+
* in the range was removed, returns `undefined` (the reference is expired).
|
|
49
|
+
* @param oldContent - the file content the reference was made against.
|
|
50
|
+
* @param newContent - the file content now.
|
|
51
|
+
* @param start - first referenced line (1-based, inclusive).
|
|
52
|
+
* @param end - last referenced line (1-based, inclusive).
|
|
53
|
+
* @returns the surviving range, or `undefined` when nothing survives.
|
|
54
|
+
*/
|
|
55
|
+
export declare function remapReferenceRange(oldContent: string, newContent: string, start: number, end: number): {
|
|
56
|
+
start: number;
|
|
57
|
+
end: number;
|
|
58
|
+
} | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Rewrite every `(referencePath:line)` / `(referencePath:start-end)` occurrence
|
|
61
|
+
* in `text`, remapping each range from `oldContent` to `newContent`. A range
|
|
62
|
+
* whose lines all survived becomes the new range; one whose lines were all
|
|
63
|
+
* removed becomes `(referencePath:LINE_MISSING)`.
|
|
64
|
+
* @param text - the free text (composer draft, queued message) to rewrite.
|
|
65
|
+
* @param referencePath - the file's reference path (workspace-relative or absolute).
|
|
66
|
+
* @param oldContent - the file content the references were made against.
|
|
67
|
+
* @param newContent - the file content now.
|
|
68
|
+
* @returns the rewritten text.
|
|
69
|
+
*/
|
|
70
|
+
export declare function remapReferences(text: string, referencePath: string, oldContent: string, newContent: string): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference remapping sync: track each pending file's last-seen content and,
|
|
3
|
+
* when it changes (an agent edit, a block revert, or an external adoption),
|
|
4
|
+
* rewrite stale references in the current composer draft and the pending queue.
|
|
5
|
+
* Pure orchestration over the pending store; the actual line remapping lives in
|
|
6
|
+
* `reference.ts`.
|
|
7
|
+
* @module dsh-diff-approval/client/remap-sync
|
|
8
|
+
*/
|
|
9
|
+
import type { PendingDiffStore } from './store.ts';
|
|
10
|
+
/** One queued message's minimal content block; text blocks carry `text`, and every other kind passes through verbatim. */
|
|
11
|
+
interface QueueBlock {
|
|
12
|
+
type: string;
|
|
13
|
+
text?: string;
|
|
14
|
+
}
|
|
15
|
+
/** A queued message's minimal shape for reference remapping. */
|
|
16
|
+
interface QueueMessage {
|
|
17
|
+
id: string;
|
|
18
|
+
content: readonly QueueBlock[];
|
|
19
|
+
}
|
|
20
|
+
/** One remapping sync's inputs; `readDraft`/`writeDraft` address the current composer. */
|
|
21
|
+
export interface ReferenceRemapOpts {
|
|
22
|
+
store: PendingDiffStore;
|
|
23
|
+
/** Read the current composer draft text (undefined when there is none). */
|
|
24
|
+
readDraft: () => string | undefined;
|
|
25
|
+
/** Write the current composer draft text. */
|
|
26
|
+
writeDraft: (text: string) => void;
|
|
27
|
+
/** Read the current session's still-queued messages (full content blocks). */
|
|
28
|
+
readQueue: () => readonly QueueMessage[];
|
|
29
|
+
/** Apply an edit mutation to one queued message's full content. */
|
|
30
|
+
writeQueue: (itemId: string, content: readonly QueueBlock[]) => void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Subscribe to the pending store and remap references as each file's content
|
|
34
|
+
* changes. The first observation of a file only seeds the baseline; a later
|
|
35
|
+
* `newText` change remaps (draft + queue) and advances the baseline. Files that
|
|
36
|
+
* leave the list drop their baseline so a future re-appearance re-baselines.
|
|
37
|
+
* @param opts - the sync inputs.
|
|
38
|
+
* @returns an unsubscribe function plus a direct remap verb for whole-file reverts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function attachReferenceRemap(opts: ReferenceRemapOpts): {
|
|
41
|
+
unsubscribe: () => void;
|
|
42
|
+
remapFile: (path: string, oldText: string, newText: string) => void;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
@@ -45,3 +45,23 @@ export declare function setTabWidth(value: number): void;
|
|
|
45
45
|
export declare function splitMode(): boolean;
|
|
46
46
|
/** Persist the split-view preference. */
|
|
47
47
|
export declare function setSplitMode(value: boolean): void;
|
|
48
|
+
/** Default quick-summon chord (toggle the review panel open/closed). */
|
|
49
|
+
export declare const DEFAULT_QUICK_SUMMON = "Ctrl+D";
|
|
50
|
+
/**
|
|
51
|
+
* The quick-summon chord. Stored as `Modifier+...+Key`; falls back to
|
|
52
|
+
* {@link DEFAULT_QUICK_SUMMON}.
|
|
53
|
+
* @returns the chord string.
|
|
54
|
+
*/
|
|
55
|
+
export declare function quickSummonKey(): string;
|
|
56
|
+
/** Persist the quick-summon chord. */
|
|
57
|
+
export declare function setQuickSummonKey(value: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Whether a keyboard event matches a chord string like `Ctrl+D`. Modifier
|
|
60
|
+
* names are matched case-insensitively (`Ctrl`/`Control`, `Alt`/`Option`,
|
|
61
|
+
* `Shift`, `Meta`/`Cmd`/`Command`/`Win`); the final part is the key. Exact
|
|
62
|
+
* modifier set is required (extra modifiers do not match).
|
|
63
|
+
* @param event - the keydown event.
|
|
64
|
+
* @param shortcut - the chord string.
|
|
65
|
+
* @returns whether the event matches.
|
|
66
|
+
*/
|
|
67
|
+
export declare function matchesShortcut(event: KeyboardEvent, shortcut: string): boolean;
|
|
@@ -20,6 +20,9 @@ export interface PendingDiffSnapshot {
|
|
|
20
20
|
* superseded the redo history; the panel surfaces it once (deferred if the
|
|
21
21
|
* panel is closed) via a bottom-right notice. */
|
|
22
22
|
redoCleared?: boolean;
|
|
23
|
+
/** Latched file id whose last block just resolved; the panel prompts once to
|
|
24
|
+
* remove-or-keep it, then acknowledges to clear the latch. */
|
|
25
|
+
justResolved?: string | undefined;
|
|
23
26
|
}
|
|
24
27
|
/** The injected face the panel component receives from the plugin body. */
|
|
25
28
|
export interface PendingPanelFace {
|
|
@@ -49,4 +52,9 @@ export interface PendingPanelFace {
|
|
|
49
52
|
onImportVcs: (sessionId: SessionId, includeUntracked: boolean) => Promise<VcsImportValue>;
|
|
50
53
|
/** Acknowledge the redo-cleared notice so it is only surfaced once. */
|
|
51
54
|
onAckRedoCleared: () => void;
|
|
55
|
+
/** Acknowledge the just-resolved prompt so it is only surfaced once. */
|
|
56
|
+
onAckJustResolved: () => void;
|
|
57
|
+
/** Collapse the DSH sidebar (no-op when already collapsed) before the modal
|
|
58
|
+
* opens or fullscreens, so an expanded sidebar can't overlap the modal. */
|
|
59
|
+
collapseSidebar: () => void;
|
|
52
60
|
}
|
|
@@ -34,6 +34,8 @@ export interface PendingDiffStore extends HostObservable<PendingDiffSnapshot> {
|
|
|
34
34
|
reset: () => void;
|
|
35
35
|
/** Acknowledge a redo-cleared notice so the panel surfaces it only once. */
|
|
36
36
|
clearRedoCleared: () => void;
|
|
37
|
+
/** Acknowledge the just-resolved prompt so it is only surfaced once. */
|
|
38
|
+
clearJustResolved: () => void;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Create the store over the review-channel port.
|
package/lib/types/types.d.ts
CHANGED
|
@@ -103,4 +103,7 @@ export interface DiffApprovalActionValue {
|
|
|
103
103
|
outcome: DiffApprovalActionOutcome;
|
|
104
104
|
/** Entry id the undo/redo affected; absent for a no-op or a non-undo action. */
|
|
105
105
|
id?: string | undefined;
|
|
106
|
+
/** Set when a block keep/revert just cleared the entry's last remaining
|
|
107
|
+
* block (the entry stays listed with no pending diff). */
|
|
108
|
+
resolved?: boolean | undefined;
|
|
106
109
|
}
|
package/package.json
CHANGED