scmJS docs

Plugin typings

npm run build:plugin-types (scripts/build-plugin-types.mjs) rolls the contract into one plugin-api/index.d.ts with dts-bundle-generator over src/plugins/api.ts, plus a package.json. npm run publish:plugin-types (scripts/publish-plugin-api.mjs) publishes those two files as @scm-js/plugin-api on npm and commits and tags them at scm-js/plugin-api — the registry is what plugin repositories depend on (^1), the repository is the audit trail behind the tarball. Each of them used to carry a hand-refreshed copy of the 61-file, 480 KB emitted tree.

The version is the API's: major is PLUGIN_API_VERSION, the minor moves when the declarations do, and the editor's own version is deliberately not in it — editor 0.1.0 to 0.2.0 is an ordinary release that semver would read as a break, and an npm version cannot be republished once it is wrong. nextVersion asks the registry what is published and bumps from that; a build that did not move the contract publishes nothing, tags nothing and commits nothing. tsc emits one declaration per module the entry reaches, which is why the bundling step exists at all; the build refuses a bundle that still carries an import, since one that names jotai or react (or a file the bundler missed) is a plugin repository that cannot compile with the file alone.

build.yml's plugin-api job runs on every build, since a contract that moved on main is one plugin authors can have today. The git push uses the PLUGIN_API_PAT organisation secret and reports rather than fails when it is absent; the npm publish is behind the PUBLISH_PLUGIN_API repository variable, because a tarball needs the scope and npm's trusted publishing set up and cannot be taken back once it is out. It goes out with --provenance, so the package page names the workflow run and the commit. Authentication is OIDC alone — there is no npm token, which is why the job's setup-node has no registry-url (that writes an .npmrc holding an empty _authToken for npm to present instead of exchanging its OIDC one). The trusted publisher on npmjs.com names this repository and build.yml, leaves Environment blank, and must have Allowed actions permitting a direct publish — staging is always allowed and direct is opt-in, and without it a correct publisher still answers 403 OIDC permission denied for this action. The plain types the contract shares with the chrome — EditorLayer, TerrainMode, ViewFlags, Toast (editor/view.ts), Preferences (editor/preferences.ts), DialogId (components/dialogs/ids.ts) — live outside the atom modules for that reason. Two external names remain, mopaq and typescript, reached through type-only imports; a plugin repository compiles with skipLibCheck and needs neither installed.