@xynogen/pix-edit 0.1.16 → 0.1.18

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-edit",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Pi tool — precise text replacement edit with diff rendering",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -34,8 +34,9 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "@xynogen/pix-pretty": "^1.7.20",
38
- "@xynogen/pix-data": "^0.3.0"
37
+ "@xynogen/pix-data": "^0.3.4",
38
+ "@xynogen/pix-pretty": "^1.7.22",
39
+ "@xynogen/pix-runtime": "^0.1.1"
39
40
  },
40
41
  "peerDependencies": {
41
42
  "@earendil-works/pi-coding-agent": "*",
package/src/edit.ts CHANGED
@@ -7,11 +7,13 @@ import type {
7
7
  } from "@earendil-works/pi-coding-agent";
8
8
 
9
9
  import { type CollapseState, tickCollapse } from "@xynogen/pix-data/collapse";
10
+ import { resolveBaseBackground } from "@xynogen/pix-pretty/ansi";
10
11
  import { MAX_RENDER_LINES } from "@xynogen/pix-pretty/config";
11
12
  import type { ToolContext } from "@xynogen/pix-pretty/context";
12
13
  import { parseDiff } from "@xynogen/pix-pretty/diff";
13
14
  import {
14
15
  diffThemeCacheKey,
16
+ renderDiffSummary,
15
17
  renderSplit,
16
18
  resolveDiffColors,
17
19
  summarize,
@@ -171,6 +173,7 @@ export function registerEditTool(
171
173
  },
172
174
 
173
175
  renderCall(args: EditParams, theme: ThemeLike, renderCtx: RenderContextLike<EditRenderState>) {
176
+ resolveBaseBackground(theme);
174
177
  const fp = args?.path ?? args?.file_path ?? "";
175
178
  const operations = getEditOperations(args);
176
179
  const text = renderCtx.lastComponent ?? new TextComponent("", 0, 0);
@@ -188,8 +191,12 @@ export function registerEditTool(
188
191
  }
189
192
 
190
193
  const { summary } = summarizeEditOperations(operations);
191
- const suffix = operations.length === 1 ? summary : `${operations.length} edits ${summary}`;
192
- text.setText(fillToolBackground(`${hdr} ${theme.fg("muted", suffix)}`));
194
+ const coloredSummary = renderDiffSummary(summary, theme);
195
+ const suffix =
196
+ operations.length === 1
197
+ ? coloredSummary
198
+ : `${theme.fg("muted", `${operations.length} edits`)} ${coloredSummary}`;
199
+ text.setText(fillToolBackground(`${hdr} ${suffix}`));
193
200
  return text;
194
201
  },
195
202
 
@@ -199,6 +206,7 @@ export function registerEditTool(
199
206
  theme: ThemeLike,
200
207
  renderCtx: RenderContextLike<EditRenderState>,
201
208
  ) {
209
+ resolveBaseBackground(theme);
202
210
  const text = renderCtx.lastComponent ?? new TextComponent("", 0, 0);
203
211
  const d = result.details as Record<string, unknown> | undefined;
204
212
  const isPartial = _opt?.isPartial === true;
@@ -249,7 +257,8 @@ export function registerEditTool(
249
257
  renderCtx.state._edk = key;
250
258
  const loc =
251
259
  (d.editLine as number) > 0 ? ` ${theme.fg("muted", `at line ${d.editLine}`)}` : "";
252
- renderCtx.state._edt = ` ${d.summary}${loc}\n${theme.fg("muted", " rendering diff…")}`;
260
+ const summary = renderDiffSummary(String(d.summary), theme);
261
+ renderCtx.state._edt = ` ${summary}${loc}\n${theme.fg("muted", " rendering diff…")}`;
253
262
  const dc = resolveDiffColors(theme);
254
263
  const diff = parseDiff(
255
264
  d.oldContent as string,
@@ -262,7 +271,8 @@ export function registerEditTool(
262
271
  if (renderCtx.state._edk !== key) return;
263
272
  const loc2 =
264
273
  (d.editLine as number) > 0 ? ` ${theme.fg("muted", `at line ${d.editLine}`)}` : "";
265
- renderCtx.state._edt = ` ${d.summary}${loc2}\n${rendered}`;
274
+ const summary = renderDiffSummary(String(d.summary), theme);
275
+ renderCtx.state._edt = ` ${summary}${loc2}\n${rendered}`;
266
276
  renderCtx.invalidate();
267
277
  })
268
278
  .catch(() => {
@@ -281,7 +291,8 @@ export function registerEditTool(
281
291
  if (renderCtx.toolCallId) trackInvalidator(renderCtx.toolCallId, renderCtx.invalidate);
282
292
  if (renderCtx.state._edk !== key) {
283
293
  renderCtx.state._edk = key;
284
- renderCtx.state._edt = ` ${d.editCount} edits ${d.summary}\n${theme.fg("muted", " rendering diff…")}`;
294
+ const summary = renderDiffSummary(String(d.summary), theme);
295
+ renderCtx.state._edt = ` ${theme.fg("muted", `${d.editCount} edits`)} ${summary}\n${theme.fg("muted", " rendering diff…")}`;
285
296
  const dc = resolveDiffColors(theme);
286
297
  Promise.all(
287
298
  (
@@ -299,7 +310,8 @@ export function registerEditTool(
299
310
  .then((rendered) => {
300
311
  if (renderCtx.state._edk !== key) return;
301
312
  const body = rendered.join(`\n${theme.fg("muted", " ···")}\n`);
302
- renderCtx.state._edt = ` ${d.editCount} edits ${d.summary}\n${body}`;
313
+ const summary = renderDiffSummary(String(d.summary), theme);
314
+ renderCtx.state._edt = ` ${theme.fg("muted", `${d.editCount} edits`)} ${summary}\n${body}`;
303
315
  renderCtx.invalidate();
304
316
  })
305
317
  .catch(() => {
package/src/extension.ts CHANGED
@@ -7,8 +7,8 @@ import { CursorStore, fffState } from "@xynogen/pix-pretty/fff";
7
7
  import { attachResizeListener, trackInvalidator } from "@xynogen/pix-pretty/resize";
8
8
  import type { PiPrettyApi, TextComponentCtor, ToolFactory } from "@xynogen/pix-pretty/types";
9
9
  import { shortPath } from "@xynogen/pix-pretty/utils";
10
+ import { once } from "@xynogen/pix-runtime/once";
10
11
  import { registerEditTool } from "./edit.js";
11
- import { once } from "./once.ts";
12
12
 
13
13
  export default function pixEditExtension(pi: PiPrettyApi): void {
14
14
  once(pi, "pix-edit", () => {
package/src/once.ts DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * Per-instance idempotency guard for extension activation.
3
- *
4
- * pix-core (the meta-package) invokes this package's factory, and a standalone
5
- * install makes Pi invoke it again — sometimes against the SAME `pi`. We must
6
- * dedupe that. But Pi rebuilds the extension runtime on /new, /resume, /fork,
7
- * and /reload, handing the factory a BRAND-NEW `pi`; that must re-register.
8
- *
9
- * Keying the registry on the `pi` instance satisfies both: same instance =>
10
- * skip, new instance => run. The registry lives on globalThis because jiti
11
- * (`moduleCache: false`) re-evaluates this module on every load pass, so a
12
- * module-scoped WeakMap would not be shared between the aggregator pass and the
13
- * standalone pass within a single session.
14
- */
15
- export function once(pi: object, key: string, fn: () => void): void {
16
- const g = globalThis as { __pixOnce?: WeakMap<object, Set<string>> };
17
- if (!g.__pixOnce) g.__pixOnce = new WeakMap<object, Set<string>>();
18
- const registry = g.__pixOnce;
19
- let loaded = registry.get(pi);
20
- if (!loaded) {
21
- loaded = new Set<string>();
22
- registry.set(pi, loaded);
23
- }
24
- if (loaded.has(key)) return;
25
- loaded.add(key);
26
- fn();
27
- }