Phase 7 of TEAMS.md. `api.registerSlashCommands` stops throwing: a module registers a command's DEFINITION and its HANDLER together, the bot pulls the definitions over the internal listener and runs none of our code, and the handler executes here — forced by the bot container having no `modules` volume, and the right boundary anyway. Registration validates what Discord would reject as a batch (names, description lengths, the four option types, required-before-optional), because the bot registers the whole set in one PUT and a single bad entry costs every command including the bot's own. Commands are not namespaced under their owner — there is no dot in Discord's name grammar — so collisions are first-come with the holder named. The dispatcher is the access boundary: `linked` has no Discord equivalent, so the platform-side permission default can only ever be advertising. It resolves the actor by `auth_providers.kind` rather than the id slug, treats a banned account as unlinked, bounds a handler under the bot's own timeout, and keeps `ok` outside the envelope so a handler cannot forge it. Liveness is asked at both the pull and the dispatch. The registries have no removal path, so a module an operator disables at runtime would otherwise keep a live handler behind a command Discord still advertises. Co-Authored-By: Claude <noreply@anthropic.com>
64 lines
3.9 KiB
JavaScript
64 lines
3.9 KiB
JavaScript
// The module API version — the single number a module's `coreApi` range is
|
|
// checked against (docs/website/MODULE_API.md §1.1).
|
|
//
|
|
// Bump minor when a member is ADDED to ctx or a new register* call appears;
|
|
// major when one is removed, its signature changes, or its behaviour changes
|
|
// without a signature change. A core-internal refactor behind an unchanged
|
|
// member is not a bump.
|
|
//
|
|
// Deliberately separate from PROTOCOL_VERSION (which versions the shard wire and
|
|
// has nothing to say about a website module) and from any module's own version.
|
|
|
|
// 1.6.0 — the Team surface (docs/website/TEAMS.md Part 11). Additions only, so
|
|
// minor: `api.registerTeamProvider({ getTeams, getTeamMembers, getTeamLeaders })`,
|
|
// `ctx.teams.publish(event)`, `ctx.teams.reconcile({ reason })`,
|
|
// `ctx.teams.activity.push(items)`, `api.registerSlashCommands([...])`, and the
|
|
// client slots `team.overview` / `team.member.row`. module-uo's `coreApi:
|
|
// "^1.3.0"` still resolves.
|
|
//
|
|
// **The number covers the whole surface; the members arrived by phase, and all of
|
|
// them have now arrived.** `activity.push` landed with the Team activity feed
|
|
// (§4, phase 3) and `registerSlashCommands` with the Discord commands (§7.1,
|
|
// phase 7); until each did, it was present and THREW rather than being absent or,
|
|
// worse, silently accepting data into a table that did not exist. Nothing in
|
|
// 1.6.0 throws any more.
|
|
//
|
|
// 1.5.0 — a CLIENT addition: `PublicLayout` takes an optional `shell` prop that
|
|
// renders the page body wrapper core's own pages write by hand (MODULE_API.md
|
|
// §3.4). Minor, not major: §3.4 makes *changing* a kit component's props a major
|
|
// bump because that breaks a call already written, and adding an optional one
|
|
// breaks nothing — omitting `shell` is 1.4.0's behaviour exactly. Nothing on the
|
|
// server changed; this file bumps for the reason below. Found by the Integration
|
|
// Kit's acceptance run (docs/modules/kit-acceptance.md), where a module built
|
|
// exactly as the kit teaches rendered outside the site's page column.
|
|
//
|
|
// 1.4.0 — no member changed. §2.7 gained one prohibition: a module does not open
|
|
// a connection to a game server from the website process; it talks to a sidecar,
|
|
// which owns the durable copy of the game's state. Minor rather than major
|
|
// because the SURFACE is identical to 1.3.0 — module-uo's `coreApi: "^1.3.0"`
|
|
// still resolves, and it already complies — but a module written against 1.3.0
|
|
// could satisfy every member and still be built the wrong way round, which is
|
|
// what this number now says. The one §2.7 rule with no CI behind it: an outbound
|
|
// socket is not statically detectable the way an internal require is.
|
|
//
|
|
// 1.3.0 — three CLIENT additions from Phase 3 slice 3: a nav item may carry an
|
|
// `icon`, core declares a `player.invite.accepted` slot, and `window.__rg.api`
|
|
// gained `BASE` (which §3.5 always specified and shared.js never published).
|
|
// Nothing on the server changed; this file bumps for the reason below.
|
|
//
|
|
// 1.2.0 — the CLIENT registry gained `registerExtension` and core gained client
|
|
// extension slots (MODULE_API.md §3.7): the twin of this half's declareSlot /
|
|
// registerExtension, for module content inside a core *page* rather than under a
|
|
// core route prefix. Nothing on the server changed, and this file bumps anyway —
|
|
// the two halves state ONE version, because a module declares a single `coreApi`
|
|
// range and is served one chunk (client/src/modules/version.js).
|
|
//
|
|
// 1.1.0 — `ctx` gained `activity.log`, `users.getById` and `site.baseUrl`, each
|
|
// because module-uo's extraction needed it and none of them could be vendored:
|
|
// an admin action a module performs belongs in core's one audit log, the
|
|
// extension slot needs the user its prefix names, and §2.7 forbids a module
|
|
// reading core's `APP_BASE_URL` for itself. Additions only, so minor.
|
|
const MODULE_API_VERSION = '1.6.0'
|
|
|
|
module.exports = { MODULE_API_VERSION }
|