@sayknow-cli/tui 0.6.5 → 0.6.6

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/CHANGELOG.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [0.6.5] - 2026-09-26
5
+ ## [0.6.6] - 2026-09-28
6
+
7
+ ### Added
8
+
9
+ - `renderPetHalfBlocks(frame, skin, colorMode)` draws a Sayknow pet frame as half-block text (two pixel rows per terminal row, truecolor or 256 colors), for surfaces with no sixel/kitty image support.
6
10
 
7
11
  ## [0.5.12] - 2026-09-15
8
12
  ### Fixed
@@ -125,4 +125,11 @@ export declare function buildSayknowPixelFrames(options: {
125
125
  /** Color skin for the sprite palette (default "red"). */
126
126
  skin?: PetSkinId;
127
127
  }): SayknowPixelFrames;
128
+ /**
129
+ * Draw a pet frame as text with half blocks, one terminal row per two pixel rows,
130
+ * so the same octopus shows up where no pixel protocol is available (the launch
131
+ * card). Fully transparent pixel rows at the top and bottom are cropped; columns
132
+ * are kept so every frame of the animation keeps the same width.
133
+ */
134
+ export declare function renderPetHalfBlocks(frame: SayknowPixelFrameName, skin?: PetSkinId, colorMode?: "truecolor" | "256color"): string[];
128
135
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sayknow-cli/tui",
4
- "version": "0.6.5",
4
+ "version": "0.6.6",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://sayknow-cli.com",
7
7
  "author": "jaybeyond",
@@ -38,8 +38,8 @@
38
38
  "fmt": "biome format --write ."
39
39
  },
40
40
  "dependencies": {
41
- "@sayknow-cli/natives": "0.6.5",
42
- "@sayknow-cli/utils": "0.6.5",
41
+ "@sayknow-cli/natives": "0.6.6",
42
+ "@sayknow-cli/utils": "0.6.6",
43
43
  "lru-cache": "11.3.6",
44
44
  "marked": "^18.0.3"
45
45
  },
@@ -433,3 +433,42 @@ export function buildSayknowPixelFrames(options: {
433
433
 
434
434
  return { frames, protocol: options.protocol, widthPx, heightPx, columns, rows, rasterRows };
435
435
  }
436
+
437
+ /**
438
+ * Draw a pet frame as text with half blocks, one terminal row per two pixel rows,
439
+ * so the same octopus shows up where no pixel protocol is available (the launch
440
+ * card). Fully transparent pixel rows at the top and bottom are cropped; columns
441
+ * are kept so every frame of the animation keeps the same width.
442
+ */
443
+ export function renderPetHalfBlocks(
444
+ frame: SayknowPixelFrameName,
445
+ skin: PetSkinId = "red",
446
+ colorMode: "truecolor" | "256color" = "truecolor",
447
+ ): string[] {
448
+ const grid = PIXEL_GRIDS[frame];
449
+ const palette = PET_SKINS[skin].palette;
450
+ const opaque = (row: string): boolean => [...row].some(ch => palette[ch] != null);
451
+ let top = 0;
452
+ while (top < grid.length && !opaque(grid[top]!)) top++;
453
+ let bottom = grid.length - 1;
454
+ while (bottom > top && !opaque(grid[bottom]!)) bottom--;
455
+ const format = colorMode === "truecolor" ? "ansi-16m" : "ansi-256";
456
+ const fg = (rgb: Rgb): string => Bun.color(`rgb(${rgb[0]},${rgb[1]},${rgb[2]})`, format) ?? "";
457
+ const bg = (rgb: Rgb): string => fg(rgb).replace("\x1b[38;", "\x1b[48;");
458
+ const lines: string[] = [];
459
+ for (let row = top; row <= bottom; row += 2) {
460
+ const upper = grid[row]!;
461
+ const lower = row + 1 <= bottom ? grid[row + 1]! : "";
462
+ let line = "";
463
+ for (let col = 0; col < upper.length; col++) {
464
+ const up = palette[upper[col]!] ?? null;
465
+ const down = palette[lower[col] ?? "."] ?? null;
466
+ if (!up && !down) line += " ";
467
+ else if (up && down) line += `${fg(up)}${bg(down)}▀\x1b[0m`;
468
+ else if (up) line += `${fg(up)}▀\x1b[0m`;
469
+ else line += `${fg(down!)}▄\x1b[0m`;
470
+ }
471
+ lines.push(line);
472
+ }
473
+ return lines;
474
+ }