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:
@@ -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,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
|
||||
Vendored
+5
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user