feat(rust): slash commands and the next wipe, server half (phase 16)

Five read-only commands registered with api.registerSlashCommands:
/status, /wipe, /top, /online and /clan (D126). Every refusal is private,
and any answer narrower than public (online names, a clan roster) goes
to the caller alone (D127). No command asks a sidecar.

The next wipe (D128, D130): six nullable columns on rust_servers, a pure
nextWipe(row, now) with the zone arithmetic through Intl, computed on
every read. The public server shape gains nextWipe; the admin shape
gains the stored schedule; PUT /admin/rust/servers/:id takes the six
fields and writes them only when wipeRule is present.

server/commands joins ci/bundle.json, which checkBundle caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-25 13:23:11 -05:00
parent cf4d183181
commit 0670341198
22 changed files with 1985 additions and 31 deletions

View File

@@ -172,4 +172,10 @@ module.exports = {
// core's and the module's location is the loader's business.
get moduleRoot() { return need().paths.moduleRoot },
get moduleId() { return need().moduleId },
// The site's public address, with no trailing slash (§2.3, 1.1.0). Phase 16's
// slash commands link an answer's title to its page; a chat message has no
// origin to be relative to. A getter over core's getter, so an operator who
// changes `APP_BASE_URL` is read at the call, never captured at load.
get baseUrl() { return need().site.baseUrl },
}