How openmonkey works
Everything is public
Creating a script and publishing it are the same action. There are no private scripts. Every version is immutable once published, and every fork records its lineage. The registry is a plain JSON API — see /llms.txt.
Publishing a script
Sign in with your passkey, then paste your script at /publish.
The metadata block supplies the name and description, and a @match or
@include line is required. The script is public the moment you submit,
served at its own .user.js URL, and gets a slug derived from its name.
To edit an existing script, hit Edit on its page (or open
/publish?slug=<slug>): the latest code loads into the form, and
submitting publishes a new immutable version. Authors only — for anyone else the
form offers a fork with your changes, lineage recorded.
Everything the publish page does goes through the public JSON API, so scripts,
CLIs, and agents can publish the same way: POST /api/scripts with
{"code": "..."} and your proc.io session cookie. The full API is
described in /llms.txt.
The shortest path of all: install openmonkey anywhere (TPX), go to the page you want to change, and open its panel (your manager's menu command, or the floating 🐵 button). Describe the change; the model sees the page you're on — URL, title, real DOM — generates a script with working selectors, publishes it here, and opens it for install. It matches every site by necessity, which by our own norm earns it a warn: scan it, and see that it talks only to TPX and this registry, only when you ask.
Prefer starting from the registry? Install
openmonkey composer (TPX): it adds a
"Generate with my model" box to the publish page and an "Edit with my model"
box to every script page. Describe the script you want, or the change you want
made to the one you're looking at; a metered TPX grant you approve writes the
result into the publish form, you review it, you publish it. Scripts that need inference do the full OAuth flow themselves
(dynamic client registration, PKCE, popup approval) using
/oauth/tpx on this site as the redirect relay — a pattern any
script here is welcome to copy.
Installing
Every script is served at /scripts/<slug>.user.js, the URL shape
every userscript manager understands. Click Install on a script page and
Userscripts for Safari,
Tampermonkey, or Violentmonkey takes over. See /install.
At serve time the registry fills in @downloadURL,
@updateURL, and @homepageURL (when the author omitted
them), so your manager registers the canonical URL and picks up new versions on
its normal update checks.
The scan norm
Your own scripts you can trust, you wrote them. Before running anyone else's,
have it security-scanned on your behalf, by your model: feed the exact
source to your own endpoint (tokenpony or any
OpenAI-compatible API) and publish the verdict back to the registry with
POST /api/versions/:id/scans:
- pass — no meaningful risk found.
- warn — read the summary before deciding.
- fail — don't run it. Fork it, fix it, republish it.
The easiest way to follow the norm is with a userscript, naturally: openmonkey scanner (TPX) is hosted on this registry, adds a "Scan with my model" button to every script page, runs the audit through a metered TPX budget you approve in an OAuth popup (no API keys to copy), and publishes the verdict. It is a script you didn't write, so scan it first — by hand, or with a model, before the button exists.
A new version of a script is new code: verdicts never carry over, each version is
scanned on its own. Verdicts are published to the script's page (which model, which
verdict, whose scan) so trust accumulates in the open. Since installs happen in
third-party managers, the registry can't block a bad install; it makes the
verdicts impossible to miss instead. The registry lifecycle is model-checked with
TLA+; the spec lives in the repo under specs/.
Script format
Standard Greasemonkey-style metadata blocks. @match/@include
are required — a script that runs everywhere is a script that gets a
warn.
// ==UserScript==
// @name Wider GitHub
// @description Make GitHub use the full window width
// @version 1.0.0
// @match https://github.com/*
// ==/UserScript==
(function () {
const s = document.createElement("style");
s.textContent = ".container-xl { max-width: 100% !important; }";
document.head.appendChild(s);
})();