@sayknow-cli/coding-agent 0.4.6 → 0.4.7

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
@@ -5,6 +5,21 @@ This file tracks the **fork's own releases**; upstream's full feature history li
5
5
  in that project. Each release notes the upstream version it is built on.
6
6
 
7
7
 
8
+ ## [0.4.7] — 2026-07-24
9
+
10
+ ### Fixed (Sayknow Pet scroll under tmux)
11
+
12
+ - **Wrap the pet's sixel draw (save-cursor + position + sixel + restore-cursor)
13
+ in a single tmux DCS passthrough unit.** The pet uses `DECSC`/`DECRC`
14
+ (`\x1b7`/`\x1b8`) to stay cursor-neutral, but those bytes were emitted outside
15
+ the passthrough envelope, so only tmux saw them — the outer terminal received
16
+ just the cursor-advancing sixel via passthrough, never restored its cursor,
17
+ and scrolled the whole viewport up on every animation frame (leaving the pet
18
+ pinned in place). The save/restore now travels with the sixel through
19
+ passthrough, so the outer cursor returns and nothing scrolls. The footprint
20
+ clears stay tmux-level so tmux still repaints the vacated cells. Only affected
21
+ tmux + a sixel terminal.
22
+
8
23
  ## [0.4.6] — 2026-07-23
9
24
 
10
25
  ### Fixed (Sayknow Pet sizing/animation under tmux)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sayknow-cli/coding-agent",
4
- "version": "0.4.6",
4
+ "version": "0.4.7",
5
5
  "description": "Sayknow-CLI CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://sayknow-cli.com",
7
7
  "author": "jaybeyond",
@@ -52,12 +52,12 @@
52
52
  "@agentclientprotocol/sdk": "1.2.1",
53
53
  "@babel/parser": "^7.29.3",
54
54
  "@mozilla/readability": "^0.6.0",
55
- "@sayknow-cli/stats": "0.4.6",
56
- "@sayknow-cli/agent-core": "0.4.6",
57
- "@sayknow-cli/ai": "0.4.6",
58
- "@sayknow-cli/natives": "0.4.6",
59
- "@sayknow-cli/tui": "0.4.6",
60
- "@sayknow-cli/utils": "0.4.6",
55
+ "@sayknow-cli/stats": "0.4.7",
56
+ "@sayknow-cli/agent-core": "0.4.7",
57
+ "@sayknow-cli/ai": "0.4.7",
58
+ "@sayknow-cli/natives": "0.4.7",
59
+ "@sayknow-cli/tui": "0.4.7",
60
+ "@sayknow-cli/utils": "0.4.7",
61
61
  "@puppeteer/browsers": "^2.13.0",
62
62
  "@types/turndown": "5.0.6",
63
63
  "@xterm/headless": "^6.0.0",
@@ -4,6 +4,7 @@ import {
4
4
  type Component,
5
5
  type Container,
6
6
  getCellDimensions,
7
+ isUnderTmux,
7
8
  PARA_PARA_STEPS,
8
9
  PET_SKINS,
9
10
  type PetMode,
@@ -281,9 +282,6 @@ export class SayknowPetWidget {
281
282
  sixelTopPaddingPx: protocol === "sixel" ? PET_SIXEL_DROP_PX : 0,
282
283
  kittyCellYOffsetPx: protocol === "kitty" ? petKittyDropPx(cell.heightPx) : 0,
283
284
  kittyImageId: protocol === "kitty" ? this.#kittyImageId : undefined,
284
- // Forward the pet's sixel raster through tmux's DCS passthrough envelope
285
- // when under tmux (no-op otherwise), so the outer terminal renders it.
286
- wrapSixel: wrapTmuxPassthrough,
287
285
  });
288
286
  this.#framedEditor.setReserve(this.#pixel.columns + PET_SIDE_MARGIN);
289
287
  }
@@ -493,6 +491,7 @@ export class SayknowPetWidget {
493
491
  this.#frameCleanupAwaitingAck = false;
494
492
  const { x, y } = pos;
495
493
  let out = "";
494
+ const positioned = `\x1b[${y + 1};${x + 1}H${pixel.frames[this.#frame]}`;
496
495
 
497
496
  if (pixel.protocol === "sixel") {
498
497
  const footprint = { x, y, columns: pixel.columns, rows: pixel.rasterRows };
@@ -501,13 +500,21 @@ export class SayknowPetWidget {
501
500
  }
502
501
  if (clearPet) out += this.#clearSixelFootprint(footprint);
503
502
  this.#lastSixelFootprint = footprint;
504
- } else {
505
- // A kitty frame emitted below (re)places the image, so cleanup is
506
- // pending again even if a narrow-terminal pass consumed it earlier.
507
- this.#kittyCleanupPending = true;
503
+ // Under tmux the sixel is forwarded to the OUTER terminal via passthrough
504
+ // and advances its cursor; the frame's surrounding \x1b7/\x1b8 only reach
505
+ // tmux, so the outer terminal never restores and scrolls the viewport on
506
+ // every animation frame. Wrap save-cursor + position + sixel + restore-
507
+ // cursor as one passthrough unit so the outer cursor returns and nothing
508
+ // scrolls. The footprint clears above stay tmux-level so tmux repaints the
509
+ // vacated cells.
510
+ out += isUnderTmux() ? wrapTmuxPassthrough(`\x1b7${positioned}\x1b8`) : positioned;
511
+ return out;
508
512
  }
509
513
 
510
- out += `\x1b[${y + 1};${x + 1}H${pixel.frames[this.#frame]}`;
514
+ // A kitty frame (re)places the image cursor-neutrally, so cleanup is pending
515
+ // again even if a narrow-terminal pass consumed it earlier.
516
+ this.#kittyCleanupPending = true;
517
+ out += positioned;
511
518
  return out;
512
519
  }
513
520
  }