@vincemakes/kiso-tui-cells 0.37.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/diff.d.ts CHANGED
@@ -20,9 +20,25 @@ export interface DiffResult {
20
20
  lines: DiffLine[];
21
21
  added: number;
22
22
  removed: number;
23
+ /** Which of the three this result is. Set on EVERY result.
24
+ *
25
+ * - `"diff"` — `lines` is a real diff and the counts are real
26
+ * - `"not-found"` — the search is not in the file
27
+ * - `"ambiguous"` — the search resolves in more than one place (ACI-2)
28
+ *
29
+ * The last two carry an honest note in `lines` and zero counts: the
30
+ * tool will refuse, so there is no edit to draw. */
31
+ outcome?: "diff" | "not-found" | "ambiguous";
23
32
  /** TUI2-R1.5 ② (VD-2): the search is not in the file — the tool will
24
33
  * ERROR, so the panel shows the honest note carried in `lines` and
25
- * never a diff. Absent on every real diff. */
34
+ * never a diff.
35
+ *
36
+ * @deprecated Read `outcome`. This flag means *the search was not
37
+ * found*; it has never meant *there is no diff*, and since ACI-2 those
38
+ * are different things — an ambiguous search also produces a note with
39
+ * no diff and does NOT set this flag. Its value is unchanged and will
40
+ * stay `outcome === "not-found"`, so nothing that reads it today
41
+ * changes meaning. */
26
42
  notFound?: true;
27
43
  }
28
44
  /** The RENDERER's truncation: head + "… N lines (/last for full)" + tail. */
@@ -45,7 +61,10 @@ export declare function truncateDiff(diff: DiffLine[]): DiffLine[];
45
61
  * A genuine miss is now reported as a miss: the tool will return
46
62
  * `pattern not found in <path>` and change nothing, so the panel says
47
63
  * exactly that instead of inventing a diff for an edit that will not
48
- * happen. `path` names the file in that note. */
64
+ * happen. `path` names the file in that note.
65
+ *
66
+ * Since ACI-2 an AMBIGUOUS search is the second case of the same rule:
67
+ * the tool refuses it, so there is no edit to draw. */
49
68
  export declare function editFileDiff(oldContent: string, search: string, replace: string, path?: string): DiffResult;
50
69
  /** write_file: a new file is all +; an existing file diffs row-level
51
70
  * against its old content. */
package/dist/diff.js CHANGED
@@ -109,7 +109,10 @@ function stats(diff) {
109
109
  * A genuine miss is now reported as a miss: the tool will return
110
110
  * `pattern not found in <path>` and change nothing, so the panel says
111
111
  * exactly that instead of inventing a diff for an edit that will not
112
- * happen. `path` names the file in that note. */
112
+ * happen. `path` names the file in that note.
113
+ *
114
+ * Since ACI-2 an AMBIGUOUS search is the second case of the same rule:
115
+ * the tool refuses it, so there is no edit to draw. */
113
116
  export function editFileDiff(oldContent, search, replace, path) {
114
117
  const at = oldContent.indexOf(search);
115
118
  if (at < 0) {
@@ -117,20 +120,34 @@ export function editFileDiff(oldContent, search, replace, path) {
117
120
  lines: [{ kind: " ", text: `pattern not found in ${path ?? "the file"}` }],
118
121
  added: 0,
119
122
  removed: 0,
123
+ outcome: "not-found",
120
124
  notFound: true,
121
125
  };
122
126
  }
127
+ // ACI-2: an ambiguous search is REFUSED by the tool, and this diff is
128
+ // drawn for the APPROVAL PANEL — before the tool runs. Previewing the
129
+ // first of N places showed a human the very edit ACI-2 exists to
130
+ // prevent, then asked them to approve one that would not happen. The
131
+ // same rule as the miss above, for the same reason.
132
+ if (search.length > 0 && oldContent.indexOf(search, at + 1) > at) {
133
+ return {
134
+ lines: [{ kind: " ", text: `pattern matches more than one place in ${path ?? "the file"}` }],
135
+ added: 0,
136
+ removed: 0,
137
+ outcome: "ambiguous",
138
+ };
139
+ }
123
140
  const result = oldContent.slice(0, at) + replace + oldContent.slice(at + search.length);
124
141
  const lines = withContext(lcsDiff(oldContent.split("\n"), result.split("\n")));
125
- return { lines, ...stats(lines) };
142
+ return { lines, ...stats(lines), outcome: "diff" };
126
143
  }
127
144
  /** write_file: a new file is all +; an existing file diffs row-level
128
145
  * against its old content. */
129
146
  export function writeFileDiff(oldContent, newContent) {
130
147
  if (oldContent === null) {
131
148
  const lines = newContent.split("\n").map((text) => ({ kind: "+", text }));
132
- return { lines, added: lines.length, removed: 0 };
149
+ return { lines, added: lines.length, removed: 0, outcome: "diff" };
133
150
  }
134
151
  const lines = withContext(lcsDiff(oldContent.split("\n"), newContent.split("\n")));
135
- return { lines, ...stats(lines) };
152
+ return { lines, ...stats(lines), outcome: "diff" };
136
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui-cells",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "kiso tui-cells \u2014 the components cell renderer (components, diff, width, the render slice). Zero runtime dependencies: input is data, output is bytes.",
5
5
  "type": "module",
6
6
  "license": "MIT",