@quandev104/pi-style 0.2.3 → 0.2.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.
|
@@ -343,6 +343,7 @@ function rewriteTokens(text, rewritten, tmpRoot) {
|
|
|
343
343
|
// extension-src/pi-style/features/messages/image-preview.ts
|
|
344
344
|
import {
|
|
345
345
|
getCapabilities,
|
|
346
|
+
getCellDimensions,
|
|
346
347
|
getImageDimensions,
|
|
347
348
|
Image
|
|
348
349
|
} from "@earendil-works/pi-tui";
|
|
@@ -569,6 +570,8 @@ var IMAGE_PREVIEW_EXPANDED_MAX_WIDTH_CELLS = 60;
|
|
|
569
570
|
var IMAGE_PREVIEW_MAX_WIDTH_CELLS = 60;
|
|
570
571
|
var GRID_GAP = 2;
|
|
571
572
|
var GRID_MIN_COLUMN = 14;
|
|
573
|
+
var GRID_MAX_HEIGHT_RATIO = 1.5;
|
|
574
|
+
var FALLBACK_IMAGE_DIMENSIONS = { widthPx: 800, heightPx: 600 };
|
|
572
575
|
function isPreviewableImage(value) {
|
|
573
576
|
if (!value || typeof value !== "object") return false;
|
|
574
577
|
const data = value.data;
|
|
@@ -624,10 +627,10 @@ function renderImagePreviewEntry(entry, options, theme) {
|
|
|
624
627
|
)
|
|
625
628
|
);
|
|
626
629
|
const labels2 = images.map((_image, index) => imageLabel(themed, index + 1, dims[index]));
|
|
627
|
-
cached = { images, components: components2, labels: labels2 };
|
|
630
|
+
cached = { images, dimensions: dims, components: components2, labels: labels2 };
|
|
628
631
|
previewCache.set(entry, cached);
|
|
629
632
|
}
|
|
630
|
-
const { components, labels } = cached;
|
|
633
|
+
const { components, dimensions, labels } = cached;
|
|
631
634
|
let memo;
|
|
632
635
|
return {
|
|
633
636
|
invalidate() {
|
|
@@ -643,7 +646,7 @@ function renderImagePreviewEntry(entry, options, theme) {
|
|
|
643
646
|
let lines;
|
|
644
647
|
if (width <= 0) lines = [];
|
|
645
648
|
else if (images.length === 1 || !kitty) lines = renderStacked(width, maxWidth, labels, components);
|
|
646
|
-
else lines = renderGrid(width, maxWidth, labels, components);
|
|
649
|
+
else lines = renderGrid(width, maxWidth, labels, components, dimensions);
|
|
647
650
|
memo = { key, lines };
|
|
648
651
|
return lines;
|
|
649
652
|
}
|
|
@@ -667,7 +670,7 @@ function stripTrailingSpaces(line) {
|
|
|
667
670
|
while (end > 0 && line.charCodeAt(end - 1) === 32) end--;
|
|
668
671
|
return line.slice(0, end);
|
|
669
672
|
}
|
|
670
|
-
function renderGrid(width, maxWidth, labels, components) {
|
|
673
|
+
function renderGrid(width, maxWidth, labels, components, dimensions) {
|
|
671
674
|
const usable = Math.max(1, width - 2);
|
|
672
675
|
const maxColumns = Math.floor((usable + GRID_GAP) / (GRID_MIN_COLUMN + GRID_GAP));
|
|
673
676
|
const columns = Math.max(1, Math.min(components.length, maxColumns, 3));
|
|
@@ -675,31 +678,56 @@ function renderGrid(width, maxWidth, labels, components) {
|
|
|
675
678
|
const columnWidth = Math.min(maxWidth, Math.floor((usable - (columns - 1) * GRID_GAP) / columns));
|
|
676
679
|
if (columnWidth < GRID_MIN_COLUMN) return renderStacked(width, maxWidth, labels, components);
|
|
677
680
|
const lines = [];
|
|
681
|
+
const cellDimensions = getCellDimensions();
|
|
678
682
|
for (let start = 0; start < components.length; start += columns) {
|
|
679
683
|
const group = components.slice(start, start + columns);
|
|
680
684
|
const groupLabels = labels.slice(start, start + columns);
|
|
685
|
+
const groupDimensions = dimensions.slice(start, start + columns);
|
|
681
686
|
if (start > 0) lines.push("");
|
|
682
687
|
const rendered = group.map((component) => component.render(columnWidth));
|
|
683
|
-
const
|
|
684
|
-
|
|
688
|
+
const sizes = groupDimensions.map((imageDimensions) => imageCellSize(imageDimensions, columnWidth, cellDimensions));
|
|
689
|
+
const rowCounts = rendered.map((column) => column.length).filter((count) => count > 0);
|
|
690
|
+
const minRows = Math.min(...rowCounts);
|
|
691
|
+
const maxRows = Math.max(...rowCounts);
|
|
692
|
+
if (rowCounts.length > 1 && minRows > 0 && maxRows >= minRows * GRID_MAX_HEIGHT_RATIO) {
|
|
693
|
+
return renderStacked(width, maxWidth, labels, components);
|
|
694
|
+
}
|
|
695
|
+
const slotWidths = groupLabels.map(
|
|
696
|
+
(label, index) => Math.max(sizes[index]?.columns ?? 1, visibleWidth(stripAnsi(label)))
|
|
697
|
+
);
|
|
698
|
+
const labelRow = groupLabels.map((label, index) => {
|
|
699
|
+
const pad = Math.max(0, (slotWidths[index] ?? 0) - visibleWidth(stripAnsi(label)));
|
|
685
700
|
return label + " ".repeat(pad);
|
|
686
701
|
}).join(" ".repeat(GRID_GAP)).trimEnd();
|
|
687
702
|
lines.push(labelRow);
|
|
688
703
|
const rows = Math.max(...rendered.map((column) => column.length));
|
|
689
704
|
for (let row = 0; row < rows; row++) {
|
|
690
705
|
let line = "";
|
|
706
|
+
let startCol = 0;
|
|
691
707
|
for (let column = 0; column < rendered.length; column++) {
|
|
692
|
-
if (column > 0) {
|
|
693
|
-
const startCol = column * (columnWidth + GRID_GAP);
|
|
694
|
-
line += `\x1B[${startCol + 1}G`;
|
|
695
|
-
}
|
|
708
|
+
if (column > 0) line += `\x1B[${startCol + 1}G`;
|
|
696
709
|
line += rendered[column]?.[row] ?? "";
|
|
710
|
+
startCol += (slotWidths[column] ?? 0) + GRID_GAP;
|
|
697
711
|
}
|
|
698
712
|
lines.push(stripTrailingSpaces(line));
|
|
699
713
|
}
|
|
700
714
|
}
|
|
701
715
|
return lines;
|
|
702
716
|
}
|
|
717
|
+
function imageCellSize(dimensions, requestedWidth, cellDimensions) {
|
|
718
|
+
const imageDimensions = dimensions ?? FALLBACK_IMAGE_DIMENSIONS;
|
|
719
|
+
const maxWidth = Math.max(1, Math.min(requestedWidth - 2, 60));
|
|
720
|
+
const maxHeight = Math.max(1, Math.ceil(maxWidth * cellDimensions.widthPx / cellDimensions.heightPx));
|
|
721
|
+
const imageWidth = Math.max(1, imageDimensions.widthPx);
|
|
722
|
+
const imageHeight = Math.max(1, imageDimensions.heightPx);
|
|
723
|
+
const widthScale = maxWidth * cellDimensions.widthPx / imageWidth;
|
|
724
|
+
const heightScale = maxHeight * cellDimensions.heightPx / imageHeight;
|
|
725
|
+
const scale = Math.min(widthScale, heightScale);
|
|
726
|
+
return {
|
|
727
|
+
columns: Math.max(1, Math.min(maxWidth, Math.ceil(imageWidth * scale / cellDimensions.widthPx))),
|
|
728
|
+
rows: Math.max(1, Math.min(maxHeight, Math.ceil(imageHeight * scale / cellDimensions.heightPx)))
|
|
729
|
+
};
|
|
730
|
+
}
|
|
703
731
|
function registerImagePreviewSurface(pi) {
|
|
704
732
|
pi.registerEntryRenderer(IMAGE_PREVIEW_ENTRY_TYPE, renderImagePreviewEntry);
|
|
705
733
|
}
|
|
@@ -13285,9 +13313,9 @@ function piStyleExtension(pi) {
|
|
|
13285
13313
|
registerPiStyleCommand(pi, coordinator.app);
|
|
13286
13314
|
registerImagePreviewSurface(pi);
|
|
13287
13315
|
let stagedImagePreview;
|
|
13316
|
+
let previewFlushTimer;
|
|
13288
13317
|
pi.on("before_agent_start", (event) => {
|
|
13289
|
-
|
|
13290
|
-
if (staged) stagedImagePreview = staged;
|
|
13318
|
+
stagedImagePreview = stageImagePreviewData(event.images ?? []);
|
|
13291
13319
|
});
|
|
13292
13320
|
pi.on("session_start", async (event, ctx) => {
|
|
13293
13321
|
resetUsageFromSessionCache(ctx.sessionManager);
|
|
@@ -13339,7 +13367,20 @@ function piStyleExtension(pi) {
|
|
|
13339
13367
|
);
|
|
13340
13368
|
pi.on("message_start", (event) => {
|
|
13341
13369
|
closeActiveBatch();
|
|
13370
|
+
if (event.message?.role === "user" && stagedImagePreview && !previewFlushTimer) {
|
|
13371
|
+
const pending = stagedImagePreview;
|
|
13372
|
+
previewFlushTimer = setTimeout(() => {
|
|
13373
|
+
previewFlushTimer = void 0;
|
|
13374
|
+
if (stagedImagePreview !== pending) return;
|
|
13375
|
+
flushImagePreviewEntry(pi, pending);
|
|
13376
|
+
stagedImagePreview = void 0;
|
|
13377
|
+
}, 0);
|
|
13378
|
+
}
|
|
13342
13379
|
if (stagedImagePreview && event.message?.role === "assistant") {
|
|
13380
|
+
if (previewFlushTimer) {
|
|
13381
|
+
clearTimeout(previewFlushTimer);
|
|
13382
|
+
previewFlushTimer = void 0;
|
|
13383
|
+
}
|
|
13343
13384
|
flushImagePreviewEntry(pi, stagedImagePreview);
|
|
13344
13385
|
stagedImagePreview = void 0;
|
|
13345
13386
|
}
|