fix(coding-agent/utils): guarded AppleScript file-url coercion to prevent URL text mangling

- Fixed a macOS clipboard bug where copied URL text like `https://i.can.ac/x.png` was coerced into a bogus HFS path (`/https/::i.can.ac:x.png`) and dead-ended with "Image not found" instead of falling through to text paste.
- The AppleScript now checks `clipboard info for "class furl"` before coercing so plain text/URL clipboards paste as text rather than file paths.
- Extracted the script to its own `.applescript` file and added TypeScript declarations for `.applescript` imports.
This commit is contained in:
can1357
2026-07-24 06:49:03 +02:00
parent 11eb003fc8
commit 1343dea49d
4 changed files with 47 additions and 30 deletions
+4
View File
@@ -9,6 +9,10 @@
- Exposed `computer` to models without native OpenAI computer-use support as a regular function tool with a typed GA action schema; the same native desktop backend and approval policy apply on both paths.
- Hardened computer action ingress: action-specific fields, modifier/key arrays, coordinates, drag points, and scroll deltas fail closed before native input; numeric fields must be signed 32-bit integers and coordinates must be non-negative.
### Fixed
- Fixed the clipboard image-paste keybind mangling copied URL text into a bogus path error on macOS (e.g. `Image not found at /https/::i.can.ac:CE4Ek3.png` for a copied `https://i.can.ac/CE4Ek3.png`). AppleScript's `the clipboard as «class furl»` coerces plain *text* into a file URL by treating the string as an HFS path (`:`↔`/` swap), so `readMacFileUrlsFromClipboard` returned a garbage path that dead-ended in `handleImagePathPaste` instead of falling through to the text paste. The script now bails early via `clipboard info for «class furl»` unless the pasteboard actually carries a `public.file-url` representation, so URL/text clipboards paste as text.
## [17.1.0] - 2026-07-24
### Breaking Changes
+1 -30
View File
@@ -1,6 +1,7 @@
import type { ClipboardImage } from "@oh-my-pi/pi-natives";
import * as native from "@oh-my-pi/pi-natives";
import { logger } from "@oh-my-pi/pi-utils";
import MAC_FILE_URL_SCRIPT from "./mac-file-urls.applescript" with { type: "text" };
/**
* Run a subprocess and capture its stdout without blocking the event loop.
@@ -52,36 +53,6 @@ function isWsl(): boolean {
return process.platform === "linux" && Boolean(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP);
}
// AppleScript that returns the POSIX paths of every file URL currently on the
// macOS pasteboard, one path per line. `pbpaste(1)` only surfaces plain text,
// EPS, or RTF, so a Finder `Cmd+C` (which puts only a `public.file-url`
// representation on the pasteboard) makes `pbpaste` empty. AppleScript's
// `«class furl»` coercion reaches the file-URL representation directly and
// works for both single-file and multi-file selections. The `try` blocks
// suppress the `-1700` "can't make … into type" error AppleScript raises when
// the clipboard holds no file URLs, so the script's exit status only reflects
// `osascript` itself.
const MAC_FILE_URL_SCRIPT = [
"on run",
'\tset output to ""',
"\ttry",
"\t\tset theClip to the clipboard as «class furl»",
"\t\tif class of theClip is list then",
"\t\t\trepeat with anItem in theClip",
"\t\t\t\ttry",
"\t\t\t\t\tset output to output & POSIX path of anItem & linefeed",
"\t\t\t\tend try",
"\t\t\tend repeat",
"\t\telse",
"\t\t\ttry",
"\t\t\t\tset output to POSIX path of theClip & linefeed",
"\t\t\tend try",
"\t\tend if",
"\tend try",
"\treturn output",
"end run",
].join("\n");
/**
* Read file paths from the macOS pasteboard's `public.file-url` representation.
*
@@ -0,0 +1,37 @@
-- Returns the POSIX paths of every file URL currently on the macOS
-- pasteboard, one path per line. `pbpaste(1)` only surfaces plain text,
-- EPS, or RTF, so a Finder Cmd+C (which puts only a `public.file-url`
-- representation on the pasteboard) makes `pbpaste` empty. The
-- `«class furl»` coercion reaches the file-URL representation directly and
-- works for both single-file and multi-file selections.
--
-- The coercion is guarded by `clipboard info for «class furl»`: AppleScript
-- happily coerces plain *text* into a file URL by treating it as an HFS
-- path, so an unguarded cast turns a copied `https://i.can.ac/x.png` string
-- into the mangled `/https/::i.can.ac:x.png` (HFS `:`↔`/` swap) and the
-- paste dead-ends with "Image not found" instead of falling back to pasting
-- the text. `clipboard info for` inspects the actual pasteboard types, so
-- it is `{}` unless a real `public.file-url` representation is present.
--
-- The `try` blocks suppress the `-1700` "can't make … into type" error
-- AppleScript raises when the clipboard holds no file URLs, so the script's
-- exit status only reflects `osascript` itself.
on run
set output to ""
try
if (clipboard info for «class furl») is {} then return output
set theClip to the clipboard as «class furl»
if class of theClip is list then
repeat with anItem in theClip
try
set output to output & POSIX path of anItem & linefeed
end try
end repeat
else
try
set output to POSIX path of theClip & linefeed
end try
end if
end try
return output
end run
+5
View File
@@ -33,6 +33,11 @@ declare module "*.sh" {
export default content;
}
declare module "*.applescript" {
const content: string;
export default content;
}
declare module "*.bdf" {
const content: string;
export default content;