diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 2b3b0aaea..d690d16ba 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -68,6 +68,7 @@ ### Fixed - Fixed `mergeTaskBranches` and `applyNestedPatches` leaving stage 1/2/3 unmerged entries in `.git/index` when the post-merge stash pop conflicted with the cherry-picked HEAD. The corrupted index survived indefinitely and every subsequent overlay-isolated task inherited it through the lower layer, causing `captureRepoDeltaPatch` to emit `diff --cc` output that `git apply` rejects with "No valid patches in input". The stash restore now runs behind a 3-way preflight check (`git apply --3way --check`) and a `reset --hard HEAD` cleanup fallback; the stash entry is preserved for manual recovery on conflict, and the merged commits still land on HEAD. ([#4175](https://github.com/can1357/oh-my-pi/issues/4175)) +- Fixed macOS `Command+V` image pastes in Ghostty by binding the Kitty `super+v` key event to the image-paste action alongside `Ctrl+V`. ([#4178](https://github.com/can1357/oh-my-pi/issues/4178)) ## [16.2.13] - 2026-07-01 diff --git a/packages/coding-agent/src/config/keybindings.ts b/packages/coding-agent/src/config/keybindings.ts index 5ad80c670..385fa2258 100644 --- a/packages/coding-agent/src/config/keybindings.ts +++ b/packages/coding-agent/src/config/keybindings.ts @@ -65,7 +65,9 @@ declare module "@oh-my-pi/pi-tui" { * Resolve default image-paste shortcuts for the current terminal platform. */ export function getDefaultPasteImageKeys(platform: NodeJS.Platform = process.platform): KeyId[] { - return platform === "win32" ? ["ctrl+v", "alt+v"] : ["ctrl+v"]; + if (platform === "win32") return ["ctrl+v", "alt+v"]; + if (platform === "darwin") return ["ctrl+v", "super+v"]; + return ["ctrl+v"]; } /** diff --git a/packages/coding-agent/src/modes/components/custom-editor.test.ts b/packages/coding-agent/src/modes/components/custom-editor.test.ts index 49ae52a4f..18a5fd681 100644 --- a/packages/coding-agent/src/modes/components/custom-editor.test.ts +++ b/packages/coding-agent/src/modes/components/custom-editor.test.ts @@ -1,5 +1,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "bun:test"; +import { setKittyProtocolActive } from "@oh-my-pi/pi-tui/keys"; import { $ } from "bun"; +import { getDefaultPasteImageKeys } from "../../config/keybindings"; import { getEditorTheme, initTheme } from "../theme/theme"; import { CustomEditor, @@ -124,6 +126,24 @@ describe("CustomEditor bracketed path paste", () => { expect(imagePathCalls).toBe(0); }); }); +describe("CustomEditor configured paste image keys", () => { + it("routes Ghostty Cmd+V kitty key events through the macOS image-paste default", () => { + const { editor } = makeEditor(); + const onPasteImage = vi.fn(); + editor.onPasteImage = onPasteImage; + editor.setActionKeys("app.clipboard.pasteImage", getDefaultPasteImageKeys("darwin")); + setKittyProtocolActive(true); + + try { + editor.handleInput("\x1b[118;9u"); + } finally { + setKittyProtocolActive(false); + } + + expect(onPasteImage).toHaveBeenCalledTimes(1); + expect(editor.getText()).toBe(""); + }); +}); describe("extractImagePathFromText (issue #3506)", () => { it("returns the path when the text is a single image file path", () => { diff --git a/packages/coding-agent/test/keybindings-display.test.ts b/packages/coding-agent/test/keybindings-display.test.ts index 65b0eefde..3fafef3ff 100644 --- a/packages/coding-agent/test/keybindings-display.test.ts +++ b/packages/coding-agent/test/keybindings-display.test.ts @@ -38,8 +38,8 @@ describe("getDefaultPasteImageKeys", () => { expect(getDefaultPasteImageKeys("win32")).toEqual(["ctrl+v", "alt+v"]); }); - it("uses Ctrl+V as the image-paste shortcut on non-Windows platforms", () => { + it("adds the macOS Command key event to Ctrl+V for image paste", () => { expect(getDefaultPasteImageKeys("linux")).toEqual(["ctrl+v"]); - expect(getDefaultPasteImageKeys("darwin")).toEqual(["ctrl+v"]); + expect(getDefaultPasteImageKeys("darwin")).toEqual(["ctrl+v", "super+v"]); }); });