JavaScript Runtime & openclip.* API
Runtimes & APIsJavaScript Runtime & openclip.* API

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

Non-Blocking

All JS execution runs off the main thread in a detached Swift task, pumping a private CFRunLoop.

30-Second Watchdog Timer

Watchdog

Guarantees that infinite loops or hanging network calls are terminated cleanly after 30 seconds.

openclip.input Context Properties

PropertyTypeDescription
openclip.input.textstringFull selected text from active application.
openclip.input.matchedTextstringRegex-matched substring (or full text if no regex).
openclip.input.capturesstring[]Array of regex capture group matches.
openclip.input.app.bundleIDstringFrontmost app bundle identifier (e.g. "com.apple.Safari").
openclip.input.app.namestringFrontmost app display name (e.g. "Safari").
openclip.optionsobjectDictionary of resolved extension option values.
openclip.option(id)functionConvenience getter: openclip.option("apiKey").

openclip.* Side-Effect Methods

MethodSignatureDescription
openclip.paste(text)(text: string) => voidPastes text into the frontmost application.
openclip.copy(text)(text: string) => voidCopies text to the system pasteboard.
openclip.cut(text)(text: string) => voidCopies text and sends a synthetic delete key.
openclip.openURL(url)(url: string) => voidOpens URL in default browser or custom URI scheme.
openclip.keyPress(key, modifiers?)(key: string, mods?: string[]) => voidSends synthetic keystroke (e.g. keyPress("v", ["command", "shift"])).
openclip.runShortcut(name, input?)(name: string, input?: string) => voidExecutes a macOS Shortcuts workflow.
openclip.notify(title, message)(title: string, message: string) => voidDisplays a macOS system notification banner.
openclip.shareService(id, text?)(id: string, text?: string) => voidTriggers a macOS sharing service.
openclip.toast(msg, style?, opts?)(msg: string, style?: "success"|"error"|"info", opts?: { keepVisible?: boolean }) => voidShows a transient toast (dismisses the popup by default; keepVisible keeps it open).
openclip.requireConfiguration(spec)(spec: { reason?: string, missing?: string[] }) => voidShort-circuits execution to open extension settings.

Async Mode & Native Fetch Polyfill

Enable "async": true in your manifest action to use Promises and the native openclip.fetch(url, options) API:

weather.js
// 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.