@xynogen/pix-edit 0.2.1 → 0.2.3
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/package.json +2 -2
- package/src/edit.test.ts +23 -10
- package/src/edit.ts +12 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-edit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Pi tool — precise text replacement edit with diff rendering",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@xynogen/pix-pretty": "^1.
|
|
41
|
+
"@xynogen/pix-pretty": "^1.19.0",
|
|
42
42
|
"@xynogen/pix-runtime": "^0.8.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
package/src/edit.test.ts
CHANGED
|
@@ -16,6 +16,10 @@ class MockTextComponent {
|
|
|
16
16
|
getText() {
|
|
17
17
|
return this.text;
|
|
18
18
|
}
|
|
19
|
+
render(_width: number) {
|
|
20
|
+
return this.text.split("\n");
|
|
21
|
+
}
|
|
22
|
+
invalidate() {}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
describe("registerEditTool", () => {
|
|
@@ -76,7 +80,7 @@ describe("registerEditTool", () => {
|
|
|
76
80
|
() => {},
|
|
77
81
|
);
|
|
78
82
|
const theme: ThemeLike = {
|
|
79
|
-
fg: (
|
|
83
|
+
fg: (key: string, value: string) => `[${key}]${value}[/${key}]`,
|
|
80
84
|
bold: (value: string) => value,
|
|
81
85
|
};
|
|
82
86
|
const result = registered.renderResult?.(
|
|
@@ -102,8 +106,10 @@ describe("registerEditTool", () => {
|
|
|
102
106
|
} as unknown as RenderContextLike,
|
|
103
107
|
);
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
expect(
|
|
109
|
+
const lines = result?.render(80) ?? [];
|
|
110
|
+
expect(lines[0]).toBe(`[success]${"─".repeat(80)}[/success]`);
|
|
111
|
+
expect(lines.join("\n")).toContain("rendering diff");
|
|
112
|
+
expect(lines.join("\n")).not.toContain("✓ edit");
|
|
107
113
|
});
|
|
108
114
|
|
|
109
115
|
it("renders single-step output inline as one compact line, framed when expanded", () => {
|
|
@@ -183,7 +189,7 @@ describe("registerEditTool", () => {
|
|
|
183
189
|
() => {},
|
|
184
190
|
);
|
|
185
191
|
const theme: ThemeLike = {
|
|
186
|
-
fg: (
|
|
192
|
+
fg: (key: string, value: string) => `[${key}]${value}[/${key}]`,
|
|
187
193
|
bold: (value: string) => value,
|
|
188
194
|
};
|
|
189
195
|
const diagnostic = "oldText was not found in sample.ts";
|
|
@@ -199,19 +205,26 @@ describe("registerEditTool", () => {
|
|
|
199
205
|
editLine: 0,
|
|
200
206
|
},
|
|
201
207
|
};
|
|
202
|
-
const render = (state: Record<string, unknown>, expanded = false) =>
|
|
208
|
+
const render = (state: Record<string, unknown>, expanded = false, isPartial = false) =>
|
|
203
209
|
registered
|
|
204
|
-
.renderResult?.(result, { isPartial
|
|
210
|
+
.renderResult?.(result, { isPartial }, theme, {
|
|
205
211
|
expanded,
|
|
206
212
|
isError: true,
|
|
207
213
|
invalidate: () => {},
|
|
208
214
|
state,
|
|
209
215
|
} as unknown as RenderContextLike)
|
|
210
|
-
?.
|
|
216
|
+
?.render(80) ?? [];
|
|
211
217
|
|
|
212
|
-
expect(render({ timer: 1 })).
|
|
213
|
-
expect(render({
|
|
214
|
-
|
|
218
|
+
expect(render({ timer: 1 })[0]).toBe(`[error]${"─".repeat(80)}[/error]`);
|
|
219
|
+
expect(render({ timer: 1 }).join("\n")).toContain(diagnostic);
|
|
220
|
+
const collapsed = render({ collapsed: true }).join("\n");
|
|
221
|
+
expect(collapsed).toContain("edit");
|
|
222
|
+
expect(collapsed).toContain("sample.ts");
|
|
223
|
+
expect(collapsed).toContain("failed");
|
|
224
|
+
expect(render({ collapsed: true })[0]).not.toContain("────");
|
|
225
|
+
expect(render({ collapsed: true }, true).join("\n")).toContain(diagnostic);
|
|
226
|
+
expect(render({ collapsed: true }, true)[0]).toContain("[error]────");
|
|
227
|
+
expect(render({}, false, true)[0]).not.toContain("[error]────");
|
|
215
228
|
});
|
|
216
229
|
});
|
|
217
230
|
|
package/src/edit.ts
CHANGED
|
@@ -30,6 +30,7 @@ import type {
|
|
|
30
30
|
import {
|
|
31
31
|
dotJoin,
|
|
32
32
|
fillToolBackground,
|
|
33
|
+
frameToolResult,
|
|
33
34
|
getTextContent,
|
|
34
35
|
hideCollapsedToolCall,
|
|
35
36
|
isTextContent,
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
renderToolError,
|
|
38
39
|
setResultDetails,
|
|
39
40
|
termW,
|
|
41
|
+
unframeToolResult,
|
|
40
42
|
} from "@xynogen/pix-pretty/utils";
|
|
41
43
|
import { type CollapseState, tickCollapse } from "@xynogen/pix-runtime/collapse";
|
|
42
44
|
|
|
@@ -133,6 +135,7 @@ export function registerEditTool(
|
|
|
133
135
|
try {
|
|
134
136
|
result = (await origEdit.execute(
|
|
135
137
|
tid,
|
|
138
|
+
// SAFETY: EditParams preserves the built-in edit schema and only adds legacy aliases.
|
|
136
139
|
params as unknown as Parameters<typeof origEdit.execute>[1],
|
|
137
140
|
sig,
|
|
138
141
|
upd,
|
|
@@ -202,7 +205,7 @@ export function registerEditTool(
|
|
|
202
205
|
)
|
|
203
206
|
)
|
|
204
207
|
return text;
|
|
205
|
-
const hdr = `${theme.fg("toolTitle", theme.bold("edit"))} ${theme.fg("
|
|
208
|
+
const hdr = `${theme.fg("toolTitle", theme.bold("edit"))} ${theme.fg("dim", sp(fp))}`;
|
|
206
209
|
|
|
207
210
|
if (operations.length === 0) {
|
|
208
211
|
text.setText(fillToolBackground(hdr));
|
|
@@ -211,7 +214,7 @@ export function registerEditTool(
|
|
|
211
214
|
|
|
212
215
|
const { summary } = summarizeEditOperations(operations);
|
|
213
216
|
const coloredSummary = renderDiffSummary(summary, theme);
|
|
214
|
-
const paint = (s: string) => theme.fg("
|
|
217
|
+
const paint = (s: string) => theme.fg("muted", s);
|
|
215
218
|
const suffix = dotJoin(
|
|
216
219
|
[
|
|
217
220
|
hdr,
|
|
@@ -231,14 +234,15 @@ export function registerEditTool(
|
|
|
231
234
|
renderCtx: RenderContextLike<EditRenderState>,
|
|
232
235
|
) {
|
|
233
236
|
resolveBaseBackground(theme);
|
|
234
|
-
const text = renderCtx.lastComponent ?? new TextComponent("", 0, 0);
|
|
237
|
+
const text = unframeToolResult(renderCtx.lastComponent ?? new TextComponent("", 0, 0));
|
|
235
238
|
const d = result.details as Record<string, unknown> | undefined;
|
|
236
239
|
const isPartial = _opt?.isPartial === true;
|
|
240
|
+
const completed = () => frameToolResult(text, theme, renderCtx.isError);
|
|
237
241
|
const structuredError =
|
|
238
242
|
renderCtx.isError && (d?._type === "editInfo" || d?._type === "multiEditInfo");
|
|
239
243
|
if (renderCtx.isError && (!structuredError || isPartial)) {
|
|
240
244
|
text.setText(renderToolError(getTextContent(result) || "Error", theme));
|
|
241
|
-
return text;
|
|
245
|
+
return isPartial ? text : completed();
|
|
242
246
|
}
|
|
243
247
|
|
|
244
248
|
// Auto-collapse: show summary line after delay
|
|
@@ -270,7 +274,7 @@ export function registerEditTool(
|
|
|
270
274
|
|
|
271
275
|
if (renderCtx.isError) {
|
|
272
276
|
text.setText(renderToolError(getTextContent(result) || "Error", theme));
|
|
273
|
-
return
|
|
277
|
+
return completed();
|
|
274
278
|
}
|
|
275
279
|
|
|
276
280
|
// Single edit — full split diff
|
|
@@ -301,7 +305,7 @@ export function registerEditTool(
|
|
|
301
305
|
});
|
|
302
306
|
}
|
|
303
307
|
text.setText(renderCtx.state._edt ?? ` ${d.summary}`);
|
|
304
|
-
return text;
|
|
308
|
+
return isPartial ? text : completed();
|
|
305
309
|
}
|
|
306
310
|
|
|
307
311
|
// Multi-edit — stacked diffs
|
|
@@ -339,13 +343,13 @@ export function registerEditTool(
|
|
|
339
343
|
});
|
|
340
344
|
}
|
|
341
345
|
text.setText(renderCtx.state._edt ?? ` ${d.editCount} edits ${d.summary}`);
|
|
342
|
-
return text;
|
|
346
|
+
return isPartial ? text : completed();
|
|
343
347
|
}
|
|
344
348
|
|
|
345
349
|
const fallback = result.content?.[0];
|
|
346
350
|
const fallbackText = fallback && isTextContent(fallback) ? fallback.text : "edited";
|
|
347
351
|
text.setText(fillToolBackground(` ${theme.fg("dim", String(fallbackText).slice(0, 120))}`));
|
|
348
|
-
return text;
|
|
352
|
+
return isPartial ? text : completed();
|
|
349
353
|
},
|
|
350
354
|
});
|
|
351
355
|
}
|