FAQ
I get GRANT_DENIED even though I declared the grant
Check:
- Form is exact:
@grant utools.*or@grant globalNativeApi.*. Subset forms like@grant utools.copyTextare not accepted. - The method isn't on the utools denylist —
utools.db*,setFeature, payment,on*, etc. - The metadata header isn't accidentally inside
/* */— the parser only reads// @key valuelines.
@require fails to load / SRI doesn't match
Is the host in the whitelist (
registry.npmmirror.com,cdn.jsdelivr.net,unpkg.com)?Recompute the hash:
bashcurl -sL "<url>" | openssl dgst -sha256 -binary | base64Append
#sha256-<base64>to the URL.npmmirrorpaths look likehttps://registry.npmmirror.com/<pkg>/<version>/files/<path>.
showPanel flickers and immediately closes
closeOnOutsidedefaultstrueand the very click that triggered your command may be detected as outside. CallshowPanelfirst, then do anything async.- The iframe body needs visible content; an empty body with
height: "auto"computes to 0. - Two
showPanelcalls overwrite each other — close the previous panel first.
getClipBody returns null or empty fields
nullmeans the host has cleaned up that clip (TTL / user delete).- Text clips may have
body.text === undefinedfor very large entries; fall back tobody.preview. - Image clips might give you only
body.preview(base64 thumb); guardif (body.bytes).
How do I access OS-level APIs?
You can't — scripts run inside an iframe sandbox and have no direct access to the host process. What scripts get is:
globalNativeApi.*(clipboard / file / notification / OCR write-back)utools.*(subset)- Standard web platform APIs the iframe exposes (
fetch,Worker,IndexedDB,crypto.subtle, …)
Need something new? Open an issue against the main repo to discuss adding it to globalNativeApi.
Can scripts share data across namespaces?
KV is strictly per-namespace. Workarounds:
globalNativeApi.setClipMetadatawrites into the clip'sscriptData[<namespace>]. Other scripts reading the same clip can see only their own namespace bucket — no cross-read.- The system clipboard as a signal channel (not recommended; pollutes history).
When does a @run-at background script run?
- As soon as the plugin loads and listeners are wired — no need for the main window to be visible.
- Disabled / uninstalled → destroyed.
- Throws / hangs past
@timeout→ bridge force-terminates the call.
Notifications don't show up
- macOS — System Settings → Notifications → uTools must be allowed.
- Windows — disabled when Notification Center is muted.
- Linux — relies on
notify-send; install if missing.
My script crashed — what do I do?
- Settings → Scripts keeps the last error per script.
- Toggle the script off — others keep working.
- Prefer
globalNativeApi.error()overthrow; it surfaces in the same UI.
Type IntelliSense isn't working
- Install
@super-clipboard/userscript-types. - Add either at the top of your script:
/// <reference types="@super-clipboard/userscript-types" />or intsconfig.jsonviacompilerOptions.types. - Use
.user.ts—.user.jsworks but IDE help is weaker.