JavaScript Runtime & openclip.* API
Complete JavaScriptCore bridge reference, openclip.* global API, and async fetch polyfill.
OpenClip embeds Apple's native JavaScriptCore engine. Scripts run isolated in background tasks with a dedicated event loop and strict concurrency limits (maxConcurrentSyncScriptEvaluations = 4).
JavaScriptCore Architecture
Dedicated Background Thread
All JS execution runs off the main thread in a detached Swift task, pumping a private CFRunLoop.
30-Second Watchdog Timer
Guarantees that infinite loops or hanging network calls are terminated cleanly after 30 seconds.
openclip.input Context Properties
openclip.* Side-Effect Methods
Async Mode & Native Fetch Polyfill
Enable "async": true in your manifest action to use Promises and the native openclip.fetch(url, options) API:
// Action declared with "async": true in openclip.json
async function action(selection, options) {
const city = selection.trim();
const apiKey = options.apiKey;
const response = await openclip.fetch(
`https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${encodeURIComponent(city)}`
);
if (!response.ok) {
openclip.toast("City not found", "error");
return;
}
const data = await response.json();
return `${data.location.name}: ${data.current.temp_c}°C, ${data.current.condition.text}`;
}SSRF & Network Security Guard
Automated Localhost & Private Subnet Protection
openclip.fetch strictly enforces Server-Side Request Forgery (SSRF) protection. Requests to loopback (127.0.0.0/8, ::1), private subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), and link-local addresses are rejected automatically before connecting.Script Entry Points & Return Values
You can define function action(selection, options) or function main(selection, options). Returning a string pastes the result into the frontmost application.