@hheei/pi-ext-ui 0.8.3 → 0.8.4
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.
|
@@ -287,7 +287,8 @@ function attach(host, run, background, outputPad) {
|
|
|
287
287
|
weight += 0.5;
|
|
288
288
|
}
|
|
289
289
|
if (first !== undefined && weight >= 2) {
|
|
290
|
-
const group = groups.get(first) ??
|
|
290
|
+
const group = groups.get(first) ??
|
|
291
|
+
new ToolGroupView(host.ui, host.requestRender, background, outputPad);
|
|
291
292
|
const boundaryTime = ended && boundary !== undefined
|
|
292
293
|
? (run.observed.get(boundary)?.at ?? performance.now())
|
|
293
294
|
: undefined;
|
|
@@ -70,7 +70,7 @@ export declare class TailUnit implements Component {
|
|
|
70
70
|
*/
|
|
71
71
|
export declare class ToolGroupView extends Container {
|
|
72
72
|
#private;
|
|
73
|
-
constructor(ui: ExtensionUIContext, redraw: () => void, background: () => boolean);
|
|
73
|
+
constructor(ui: ExtensionUIContext, redraw: () => void, background: () => boolean, outputPad: () => number);
|
|
74
74
|
/**
|
|
75
75
|
* Release the block's own lifetime. The projection drops a block when it is evicted, when
|
|
76
76
|
* grouping is disabled, or when the patch unloads; an idempotent dispose keeps that path honest,
|
package/dist/tool-group-view.js
CHANGED
|
@@ -157,6 +157,8 @@ export class ToolGroupView extends Container {
|
|
|
157
157
|
#redraw;
|
|
158
158
|
/** Pi-native block backgrounds are opt-in; while they are on, the fill replaces the rails. */
|
|
159
159
|
#background;
|
|
160
|
+
/** Pi's own output padding, so the frame lines up with the tool rows it wraps. */
|
|
161
|
+
#outputPad;
|
|
160
162
|
/** The stable clock for this block; restored history stays unknown until live content joins. */
|
|
161
163
|
#clock;
|
|
162
164
|
/** The block's own members, drawn inside the group. */
|
|
@@ -179,11 +181,12 @@ export class ToolGroupView extends Container {
|
|
|
179
181
|
// One extra colored row above and below: the block needs breathing room inside its background.
|
|
180
182
|
#box = new Box(0, 1);
|
|
181
183
|
#spacer = new Spacer(1);
|
|
182
|
-
constructor(ui, redraw, background) {
|
|
184
|
+
constructor(ui, redraw, background, outputPad) {
|
|
183
185
|
super();
|
|
184
186
|
this.#ui = ui;
|
|
185
187
|
this.#redraw = redraw;
|
|
186
188
|
this.#background = background;
|
|
189
|
+
this.#outputPad = outputPad;
|
|
187
190
|
this.#heading = new MouseRegion(this.#header, (event) => {
|
|
188
191
|
if (event.type !== "click" || event.button !== "left")
|
|
189
192
|
return undefined;
|
|
@@ -387,8 +390,13 @@ export class ToolGroupView extends Container {
|
|
|
387
390
|
const theme = this.#ui.theme;
|
|
388
391
|
const lines = [];
|
|
389
392
|
const hits = [];
|
|
393
|
+
// The frame is the block's own row; a tool row inside it pads itself, so only these rows take
|
|
394
|
+
// Pi's output padding.
|
|
395
|
+
const pad = Math.max(0, this.#outputPad());
|
|
396
|
+
const lead = " ".repeat(pad);
|
|
397
|
+
const inner = Math.max(0, width - pad * 2);
|
|
390
398
|
const push = (row, action = { kind: "none" }) => {
|
|
391
|
-
lines.push(fitRow(row
|
|
399
|
+
lines.push(fitRow(`${lead}${row}`, Math.max(0, width), "…"));
|
|
392
400
|
hits.push({ height: 1, action });
|
|
393
401
|
};
|
|
394
402
|
/** Rows that belong to one component keep one hit so its own geometry stays correct. */
|
|
@@ -404,7 +412,7 @@ export class ToolGroupView extends Container {
|
|
|
404
412
|
if (member.kind === "tool")
|
|
405
413
|
tools.push(index);
|
|
406
414
|
}
|
|
407
|
-
push(theme.fg("borderMuted", "─".repeat(
|
|
415
|
+
push(theme.fg("borderMuted", "─".repeat(inner)));
|
|
408
416
|
const notices = this.#noticeItems();
|
|
409
417
|
if (notices.length > 0) {
|
|
410
418
|
const kinds = new Map();
|
|
@@ -418,7 +426,7 @@ export class ToolGroupView extends Container {
|
|
|
418
426
|
category: "notices",
|
|
419
427
|
});
|
|
420
428
|
if (this.#category === "notices")
|
|
421
|
-
this.#renderNotices(notices,
|
|
429
|
+
this.#renderNotices(notices, inner, push);
|
|
422
430
|
}
|
|
423
431
|
const thinking = this.#thinkingItems();
|
|
424
432
|
if (thinking.length > 0) {
|
|
@@ -428,7 +436,7 @@ export class ToolGroupView extends Container {
|
|
|
428
436
|
category: "thinking",
|
|
429
437
|
});
|
|
430
438
|
if (this.#category === "thinking")
|
|
431
|
-
this.#renderThinking(thinking,
|
|
439
|
+
this.#renderThinking(thinking, inner, push);
|
|
432
440
|
}
|
|
433
441
|
// Names and header calls share one eligibility: only completed calls are counted. A tool that
|
|
434
442
|
// is still streaming or running stays listed and expandable, but adds no number.
|
|
@@ -461,7 +469,7 @@ export class ToolGroupView extends Container {
|
|
|
461
469
|
this.#renderTools(tools, width, push, pushBlock);
|
|
462
470
|
}
|
|
463
471
|
// The rails bracket the header, categories, and any opened detail; the footer sits below them.
|
|
464
|
-
push(theme.fg("borderMuted", "─".repeat(
|
|
472
|
+
push(theme.fg("borderMuted", "─".repeat(inner)));
|
|
465
473
|
// The footer is always the block's request and token totals: one row, never a tool status.
|
|
466
474
|
push(this.#footerRow());
|
|
467
475
|
this.#hits = hits;
|
|
@@ -698,7 +706,8 @@ export class ToolGroupView extends Container {
|
|
|
698
706
|
theme.fg("dim", elapsed),
|
|
699
707
|
theme.fg("dim", `${calls} ${calls === 1 ? "call" : "calls"}`),
|
|
700
708
|
].join(theme.fg("dim", " · "));
|
|
701
|
-
|
|
709
|
+
const pad = Math.max(0, this.#outputPad());
|
|
710
|
+
this.#header.setText(fitRow(`${" ".repeat(pad)}${theme.fg("dim", this.#renderedExpanded ? "▾" : "▸")} ${details}`, Math.max(0, width - pad * 2), "…"));
|
|
702
711
|
return super.render(width);
|
|
703
712
|
}
|
|
704
713
|
/**
|