dsh-diff-approval 0.23.2 → 0.24.1

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.
@@ -25,6 +25,19 @@ export interface DiscussionMessage {
25
25
  /** The message text as it is rendered. */
26
26
  text: string;
27
27
  }
28
+ /**
29
+ * The gutter pair of one quoted line: the numbers the file showed beside it.
30
+ *
31
+ * Kept per line with the quote so an outdated thread can put the code back on the file's own
32
+ * columns — the numbers are what the reader navigates by, and the two sides of a hunk do not
33
+ * simply count up from the range's first line, so they cannot be derived from the anchor.
34
+ */
35
+ export interface DiscussionQuoteLine {
36
+ /** Old-file number, `undefined` on a row the old side does not have (an added line). */
37
+ old: number | undefined;
38
+ /** New-file number — the second gutter — `undefined` on a removed line. */
39
+ new: number | undefined;
40
+ }
28
41
  /** One discussion bound to a row range. */
29
42
  export interface Discussion {
30
43
  /** Stable identity for keys and toggles. */
@@ -41,13 +54,39 @@ export interface Discussion {
41
54
  /** Folded to the one-row header. */
42
55
  collapsed: boolean;
43
56
  /**
44
- * No line of the anchor exists in the file any more (the code was changed or
45
- * removed under it). The block stays where it last matched, cannot be commented
46
- * on again, and is the user's to delete.
57
+ * The anchored lines as they read when the thread was created.
58
+ *
59
+ * The line numbers are what a rebuild moves; this is what says whether they still hold the
60
+ * code the comment was written about. When they do not, the thread is re-anchored on the
61
+ * quote (see `remapDiscussion`), and when even that finds nothing the block is marked
62
+ * outdated and the quote is what the reader is shown to know what it had been about.
63
+ */
64
+ quote?: string;
65
+ /**
66
+ * The gutter numbers of `quote`'s lines, in the same order, so an outdated block can lay the
67
+ * quote out exactly as the file lays code out. See `DiscussionQuoteLine`.
68
+ */
69
+ quoteLines?: readonly DiscussionQuoteLine[];
70
+ /**
71
+ * The anchor no longer holds the code the thread was written about — the lines were edited
72
+ * under it, or they are gone from the file. The block stays where it last matched, says so,
73
+ * keeps its quote and its turns, and owns no rows: it is read-only (nothing current to write
74
+ * about), it washes no lines, and a new annotation may take the rows under it. Removal is the
75
+ * user's call. The mark is derived from the current model, so the lines coming back with their
76
+ * quote clears it.
47
77
  */
48
78
  lost?: boolean;
49
79
  /** The answer being streamed for the question in flight. */
50
80
  reply?: string;
81
+ /**
82
+ * Where the session's transcript stood when the last question was sent — its node count.
83
+ *
84
+ * Kept with the block rather than only in the panel's refs, so a question still waiting
85
+ * for its answer can be picked up again after the panel is closed and reopened: the search
86
+ * for our own prompt starts here, which is what keeps an older, identical-looking prompt
87
+ * from being mistaken for it.
88
+ */
89
+ baseline?: number;
51
90
  /** The turn for the last question is running. */
52
91
  asking?: boolean;
53
92
  /**
@@ -154,6 +193,12 @@ export declare function discussionOnRange(discussions: readonly Discussion[], an
154
193
  * annotation at most, so a selection that touches an existing block offers no
155
194
  * second one - otherwise two blocks would describe the same line.
156
195
  *
196
+ * An outdated thread owns no rows: the code under its numbers is no longer what the
197
+ * comment was written about, so it cannot hold the range against a new annotation of the
198
+ * code that is there now. Nothing marks those rows for it either (see the panel's band),
199
+ * which is the same rule seen from the other side: a thread that no longer matches is
200
+ * kept for its quote and its turns, not for its position.
201
+ *
157
202
  * @param discussions - the blocks currently attached to this file.
158
203
  * @param anchor - the candidate range.
159
204
  * @returns the overlapping discussion, or `undefined`.
@@ -163,17 +208,26 @@ export declare function discussionOverlapping(discussions: readonly Discussion[]
163
208
  end: number;
164
209
  }): Discussion | undefined;
165
210
  /**
166
- * Re-anchor one discussion against the current rows: the rows whose new-file line
167
- * falls inside the annotation's line range. When no line matches any more, the
168
- * block keeps the rows it last matched and is marked lost, so it stays where the
169
- * user last saw it and can only be deleted.
211
+ * Re-anchor one discussion against the current rows.
212
+ *
213
+ * The anchor's new-file line numbers are what a rebuild moves; the quote the thread carries
214
+ * is what says whether they still hold the code the comment was written about. When they do
215
+ * not — the lines were edited under it, or the hunk moved — the quote is looked for elsewhere
216
+ * in the model and the thread follows it, nearest occurrence first when the same code shows up
217
+ * more than once. When nothing matches, the block keeps the rows it last matched and is marked
218
+ * outdated: it says so and keeps its quote for the reader, rather than being silently moved
219
+ * onto whatever took those lines. Only when the whole range is gone from the model does the
220
+ * block move, and then by line number, back to where the range used to be (see `gone`). The mark
221
+ * is derived, not sticky — the lines coming back with their quote clears it (GitHub recomputes
222
+ * `isOutdated` the same way).
170
223
  *
171
224
  * @param discussion - the block to re-anchor.
172
225
  * @param lineOf - the new-file line number of a row, or `undefined` for a row that has none.
226
+ * @param textOf - the text of a row, for the quote comparison.
173
227
  * @param rowCount - how many rows the current model has.
174
228
  * @returns the re-anchored discussion (the same object when nothing moved).
175
229
  */
176
- export declare function remapDiscussion(discussion: Discussion, lineOf: (row: number) => number | undefined, rowCount: number): Discussion;
230
+ export declare function remapDiscussion(discussion: Discussion, lineOf: (row: number) => number | undefined, textOf: (row: number) => string, rowCount: number): Discussion;
177
231
  /** What the selection frame shows for the current selection. */
178
232
  export interface SelectionFrameActions {
179
233
  /** Whether keep/revert apply (the selection fully covers change blocks). */
@@ -89,17 +89,20 @@ export declare const zh: {
89
89
  'action.discussionExpand': string;
90
90
  'action.discussionCollapse': string;
91
91
  'discussion.placeholder': string;
92
+ 'discussion.placeholderOutdated': string;
92
93
  'discussion.marker': string;
93
94
  'discussion.promptRule': string;
94
95
  'discussion.promptRuleSkill': string;
95
96
  'discussion.thinking': string;
96
97
  'discussion.queued': string;
97
- 'discussion.lost': string;
98
+ 'discussion.outdated': string;
99
+ 'discussion.quote': string;
98
100
  'discussion.hidden': string;
99
101
  'discussion.failed': string;
100
102
  'discussion.stopped': string;
101
103
  'action.revert': string;
102
104
  'action.delete': string;
105
+ 'action.discussionEnd': string;
103
106
  'action.keepAll': string;
104
107
  'action.revertAll': string;
105
108
  'action.openFile': string;
@@ -301,17 +304,20 @@ export declare const en: {
301
304
  'action.discussionExpand': string;
302
305
  'action.discussionCollapse': string;
303
306
  'discussion.placeholder': string;
307
+ 'discussion.placeholderOutdated': string;
304
308
  'discussion.marker': string;
305
309
  'discussion.promptRule': string;
306
310
  'discussion.promptRuleSkill': string;
307
311
  'discussion.thinking': string;
308
312
  'discussion.queued': string;
309
- 'discussion.lost': string;
313
+ 'discussion.outdated': string;
314
+ 'discussion.quote': string;
310
315
  'discussion.hidden': string;
311
316
  'discussion.failed': string;
312
317
  'discussion.stopped': string;
313
318
  'action.revert': string;
314
319
  'action.delete': string;
320
+ 'action.discussionEnd': string;
315
321
  'action.keepAll': string;
316
322
  'action.revertAll': string;
317
323
  'action.openFile': string;
@@ -13,6 +13,20 @@
13
13
  *
14
14
  * @module dsh-diff-approval/client/panel-memory
15
15
  */
16
+ import type { Discussion } from './discussion.ts';
17
+ /**
18
+ * The comment threads a session's panel is holding.
19
+ * @param sessionId - the session, if any.
20
+ * @returns the threads by pending entry id; empty when there are none.
21
+ */
22
+ export declare function rememberedDiscussions(sessionId: string | undefined): Readonly<Record<string, readonly Discussion[]>>;
23
+ /**
24
+ * Remember the comment threads a session's panel holds. Called on every change, so a mount
25
+ * that appears later (another presentation, or the panel reopened) starts from them.
26
+ * @param sessionId - the session the panel is reviewing; nothing is recorded without one.
27
+ * @param byFile - the threads, by pending entry id.
28
+ */
29
+ export declare function rememberDiscussions(sessionId: string | undefined, byFile: Readonly<Record<string, readonly Discussion[]>>): void;
16
30
  /**
17
31
  * Remember that a session's panel was left showing one file, and where in it.
18
32
  * @param sessionId - the session the panel was reviewing; nothing is recorded
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-diff-approval",
3
- "version": "0.23.2",
3
+ "version": "0.24.1",
4
4
  "description": "DeepSeek Harness plugin: pending-edit review with whole-file diff and Keep/Revert",
5
5
  "packageManager": "pnpm@11.21.0",
6
6
  "author": "Wu Zhiwei",