diff --git a/internal/adapter/renderer/kitty_renderer.go b/internal/adapter/renderer/kitty_renderer.go index 389c924..54529c0 100644 --- a/internal/adapter/renderer/kitty_renderer.go +++ b/internal/adapter/renderer/kitty_renderer.go @@ -96,7 +96,7 @@ func (r *KittyRenderer) Display(vp *domain.Viewport) (string, error) { // Clear previous display and show new frame // Move cursor to top-left, clear screen area, then display output := "\x1b[H" // move cursor to top-left - output += fmt.Sprintf("\x1b_Ga=p,i=%d,x=%d,y=%d,w=%d,h=%d,c=%d,r=%d,q=2\x1b\\", + output += fmt.Sprintf("\x1b_Ga=p,i=%d,p=1,x=%d,y=%d,w=%d,h=%d,c=%d,r=%d,q=2\x1b\\", r.imageID, srcX, srcY, srcW, srcH, displayCols, displayRows) return output, nil @@ -217,7 +217,7 @@ func (r *KittyRenderer) DisplayMinimap(vp *domain.Viewport, cols, rows int, bord } // Build placement command (always needed since main image re-render may overwrite) - placeCmd := fmt.Sprintf("\x1b[%d;%dH\x1b_Ga=p,i=%d,c=%d,r=%d,z=1,q=2\x1b\\", + placeCmd := fmt.Sprintf("\x1b[%d;%dH\x1b_Ga=p,i=%d,p=1,c=%d,r=%d,z=1,q=2\x1b\\", startRow, startCol, r.minimapID, cols, rows) // Skip re-upload if indicator rectangle and border color haven't changed. diff --git a/internal/adapter/renderer/kitty_renderer_test.go b/internal/adapter/renderer/kitty_renderer_test.go index ebb41e8..24bf2c4 100644 --- a/internal/adapter/renderer/kitty_renderer_test.go +++ b/internal/adapter/renderer/kitty_renderer_test.go @@ -35,6 +35,9 @@ func TestKittyRenderer_Display(t *testing.T) { if !strings.Contains(output, "a=p") { t.Error("output should contain action=place") } + if !strings.Contains(output, "p=1") { + t.Error("output should contain placement ID for consistent cross-terminal behavior") + } if !strings.Contains(output, "w=800") { t.Error("output should contain source width") } @@ -152,6 +155,19 @@ func TestKittyRenderer_DisplayMinimap(t *testing.T) { if !strings.Contains(output, "a=p") { t.Error("output should contain action=place") } + // Verify p=1 within the placement command only (not in base64 payload) + aPos := strings.Index(output, "a=p") + if aPos == -1 { + t.Fatal("output should contain action=place (a=p) command") + } + termPosRel := strings.Index(output[aPos:], "\x1b\\") + if termPosRel == -1 { + t.Fatalf("output should contain kitty graphics terminator after placement command: %q", output) + } + placementCmd := output[aPos : aPos+termPosRel] + if !strings.Contains(placementCmd, "p=1") { + t.Errorf("placement command should contain placement ID p=1 for consistent cross-terminal behavior, got: %q", placementCmd) + } // Uses raw RGBA format if !strings.Contains(output, "f=32") { t.Error("output should use raw RGBA format (f=32)")