@vincemakes/kiso-tui-cells 0.47.3 → 0.49.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.
@@ -639,9 +639,10 @@ function settledMeta(c) {
639
639
  if (c.name === "write_file" && parsed !== null && typeof parsed.content === "string") {
640
640
  return `+${countLines(parsed.content)}`;
641
641
  }
642
- if (c.name === "edit_file" && parsed !== null && typeof parsed.search === "string" && typeof parsed.replace === "string") {
643
- const added = countLines(parsed.replace);
644
- const removed = countLines(parsed.search);
642
+ const hunks = c.name === "edit_file" && parsed !== null ? hunksOf(parsed) : null;
643
+ if (hunks !== null) {
644
+ const added = hunks.reduce((n, h) => n + countLines(h.replace), 0);
645
+ const removed = hunks.reduce((n, h) => n + countLines(h.search), 0);
645
646
  if (added + removed > 0)
646
647
  return `+${added} -${removed}`;
647
648
  }
package/dist/diff.d.ts CHANGED
@@ -85,9 +85,12 @@ export declare function editFileDiff(oldContent: string, search: string, replace
85
85
  /** write_file: a new file is all +; an existing file diffs row-level
86
86
  * against its old content. */
87
87
  export declare function writeFileDiff(oldContent: string | null, newContent: string): DiffResult;
88
- /** The hunks an edit_file call carries: its `edits`, or its one
89
- * `search`/`replace` pair. Null when the input has neither (the tool
90
- * refuses such a call, so there is nothing to draw). */
88
+ /** The hunks an edit_file call carries, in either vocabulary the tool
89
+ * takes (ADR-0061): `edits` of `{oldText, newText}` or of legacy
90
+ * `{search, replace}`, or the legacy top-level pair. A log written before
91
+ * the rename keeps the old names, so a reader must take both. Null when
92
+ * the tool would refuse the shape (nothing, or a hunk mixing the two) —
93
+ * there is nothing to draw. */
91
94
  export declare function hunksOf(input: Record<string, unknown>): Hunk[] | null;
92
95
  /** Graphite §6 (R2a) — what an edit CHANGED, drawn from the call's own
93
96
  * hunks: per hunk a line LCS of `search` against `replace`, the lines
package/dist/diff.js CHANGED
@@ -152,21 +152,30 @@ export function writeFileDiff(oldContent, newContent) {
152
152
  const lines = withContext(lcsDiff(oldContent.split("\n"), newContent.split("\n")));
153
153
  return { lines, ...stats(lines), outcome: "diff" };
154
154
  }
155
- /** The hunks an edit_file call carries: its `edits`, or its one
156
- * `search`/`replace` pair. Null when the input has neither (the tool
157
- * refuses such a call, so there is nothing to draw). */
155
+ /** The hunks an edit_file call carries, in either vocabulary the tool
156
+ * takes (ADR-0061): `edits` of `{oldText, newText}` or of legacy
157
+ * `{search, replace}`, or the legacy top-level pair. A log written before
158
+ * the rename keeps the old names, so a reader must take both. Null when
159
+ * the tool would refuse the shape (nothing, or a hunk mixing the two) —
160
+ * there is nothing to draw. */
158
161
  export function hunksOf(input) {
159
- const pair = (x) => {
162
+ const pair = (x, current) => {
160
163
  if (typeof x !== "object" || x === null)
161
164
  return null;
162
- const { search, replace } = x;
165
+ const { oldText, newText, search, replace } = x;
166
+ const hasCurrent = oldText !== undefined || newText !== undefined;
167
+ const hasLegacy = search !== undefined || replace !== undefined;
168
+ if (hasCurrent && (hasLegacy || !current))
169
+ return null;
170
+ if (hasCurrent)
171
+ return typeof oldText === "string" && typeof newText === "string" ? { search: oldText, replace: newText } : null;
163
172
  return typeof search === "string" && typeof replace === "string" ? { search, replace } : null;
164
173
  };
165
174
  if (Array.isArray(input.edits)) {
166
- const hunks = input.edits.map(pair);
175
+ const hunks = input.edits.map((h) => pair(h, true));
167
176
  return hunks.length > 0 && hunks.every((h) => h !== null) ? hunks : null;
168
177
  }
169
- const one = pair(input);
178
+ const one = pair(input, false);
170
179
  return one === null ? null : [one];
171
180
  }
172
181
  /** Graphite §6 (R2a) — what an edit CHANGED, drawn from the call's own
package/dist/render.js CHANGED
@@ -6,6 +6,7 @@
6
6
  * dependencies (the tui-cells package has none).
7
7
  */
8
8
  import { charWidth, displayWidth, visibleWidth, widthCut } from "./width.js";
9
+ import { hunksOf } from "./diff.js";
9
10
  import { bg, breathRamp, fg, graphiteColours, mix, terminalTier } from "./graphite.js";
10
11
  const BASE = { bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32m", warn: "\x1b[33m", italic: "\x1b[3m", italicEnd: "\x1b[23m", underline: "\x1b[4m", underlineEnd: "\x1b[24m", rv: "\x1b[7m", rvEnd: "\x1b[27m", reset: "\x1b[0m" };
11
12
  /**
@@ -364,8 +365,9 @@ function toolSummaryDetail(name, input, result) {
364
365
  }
365
366
  case "edit_file": {
366
367
  const path = String(input.path ?? "?");
367
- const removed = lines(String(input.search ?? ""));
368
- const added = lines(String(input.replace ?? ""));
368
+ const hunks = hunksOf(input) ?? [];
369
+ const removed = hunks.reduce((n, h) => n + lines(h.search), 0);
370
+ const added = hunks.reduce((n, h) => n + lines(h.replace), 0);
369
371
  return `${path} (+${added} -${removed})`;
370
372
  }
371
373
  case "shell": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui-cells",
3
- "version": "0.47.3",
3
+ "version": "0.49.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",