Publishing to the registry
Community plugins ship through the s2script registry on this site: one identity, one version, dual artifacts (.s2sp for operators + types tarball for authors). Publish is open; review is additive — new versions start unreviewed with a public disclaimer.
The CLI is s2s, shipped in @s2script/sdk. Use s2s … when the package is installed, or npx @s2script/sdk … otherwise.
Prerequisites#
- Create an account at /signup
- Claim a scope under Organizations (e.g.
@acme) — one scope per org - Authorize the CLI (CLI login) or mint a deploy token
Unscoped names (rtv) are owned by the first user who deploys them — no org required.
Authenticate#
Local (device login)#
s2s login
# or: npx @s2script/sdk loginThe CLI calls POST /api/v1/auth/device/start, prints a short code, and opens /cli/authorize. Approve in the browser; the CLI’s next POST /api/v1/auth/device/poll returns a s2s_… deploy token, which it stores in ~/.s2script/credentials.json.
Paste path (headless boxes):
s2s login --token s2s_…CI#
env:
S2SCRIPT_TOKEN: ${{ secrets.S2SCRIPT_TOKEN }}
run: npx @s2script/sdk deploy --ci--ci never prompts; missing S2SCRIPT_TOKEN exits non-zero.
package.json#
{
"name": "@edge/heal-zones",
"version": "1.0.0",
"types": "api.d.ts",
"s2script": {
"apiVersion": "1.x",
"publishes": { "@edge/heal-zones": "1.0.0" },
"pluginDependencies": { "@s2script/cs2": "^1.0.0" }
}
}If s2script.publishes is set, "types" must point at an existing .d.ts. The CLI packs that file into a types-only tarball; the registry rejects uploads that omit it (400 publishes_requires_types). Runtime-only plugins omit publishes and skip types.
Deploy#
s2s deploy- Runs the publishes ⇒ types gate
- Builds the
.s2sp - Packs types when needed
- Reads
README.mdbeside package.json, if there is one (SDK 0.28.0 and later) POST /api/v1/deploywithAuthorization: Bearer s2s_…: oneapplication/octet-streamzip holdingmanifest.json,plugin.s2sp, and optionallytypes.tgzandREADME.md. The manifest also carries package.json’srepositoryfield.
Success returns { name, version, reviewState: "unreviewed" }. Manage versions, yank, descriptions and the README from the publisher dashboard.
Package page#
Each package has a public page at /plugins/<name>. Below the description, a plugin’s page has two tabs: README and Config. Link straight to the Config tab with /plugins/<name>?tab=config.
README. Markdown that explains what the plugin does, its commands, permissions and setup. Keep it as README.md next to package.json: since SDK 0.28.0, s2s deploy sends it, and each deploy that carries one replaces the page’s README. You can also write or edit it on the package’s page in the publisher dashboard, which has a preview. A deploy without a README keeps the current one, so an edit made on the site stays until your next deploy that has one.
The README renders like these docs, with tables, highlighted code fences and blockquotes. Raw HTML shows as text, and links must be https:, http:, mailto: or on this site. Images must be https:. The limit is 100,000 characters.
Config. Built from the s2script.config block in your package.json, as published in the newest non-yanked version. You don’t write it separately. Each option gets a row with its key, type, default, range or allowed values, and description. Below the table are the block as declared in package.json and the config file the runtime writes on first load. Options with a group are listed under that heading. A label shows under the key.
Source. A link under the package name to where its code can be browsed. It comes from package.json’s standard repository field, which s2s deploy sends since SDK 0.28.0. Any npm form works, including { "url": …, "directory": … }, which links into a monorepo directory on GitHub, GitLab and Codeberg. You can also set it on the package’s page in the publisher dashboard: an https URL, or owner/repo for GitHub. A deploy without repository keeps the current link.
Operator & author consumers#
| Who | Command | Artifact |
|---|---|---|
| Dependent author | s2s add @edge/heal-zones@^1 | types only |
| Server operator | s2s install @edge/heal-zones | .s2sp closure |
Types are also available via the npm-compatible surface at /npm/* (never serves .s2sp). s2s add for a plugin dependency downloads types only (registry metadata + types artifact), not the producer binary — operators still s2s install the .s2sp closure. Protocol 2 producers stamp host API 3.x; see inter-plugin interfaces.
Yank#
From the dashboard, or:
curl -X POST https://s2script.com/api/v1/yank
-H "Authorization: Bearer $S2SCRIPT_TOKEN"
-H "Content-Type: application/json"
-d '{"name":"@edge/heal-zones","version":"1.0.0"}'Yanked versions are hidden from default resolve; lockfile pins can still warn.
Reserved#
@s2script/* is first-party only. Community tokens cannot deploy into that scope.
Next#
- Authoring plugins — scaffold, build, plugin shape
- Inter-plugin interfaces —
publishes/ producer-as-import - Plugin catalog — public package pages + disclaimer