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

@@ -565,7 +565,7 @@
"Admin · Rust"
],
"summary": "Create or update a Rust server",
"description": "Writes one server row. `sidecarToken` is write-only — send it to set or rotate the credential, and omit it or send an empty string to leave the stored one untouched. The id is the slug every URL under the module carries.",
"description": "Writes one server row. `sidecarToken` is write-only — send it to set or rotate the credential, and omit it or send an empty string to leave the stored one untouched. The id is the slug every URL under the module carries. The wipe schedule (`wipeRule`, `wipeDay`, `wipeTime`, `wipeTz`, `wipeAnchor`, `wipeOnceAt`) is written only when `wipeRule` is present, so a body without it leaves the stored schedule alone. `wipeRule` is `none`, `forced`, `weekly` or `biweekly`; a weekly or biweekly rule needs `wipeDay` (0 = Sunday), `wipeTime` (`HH:MM`) and an IANA `wipeTz`, and a biweekly rule a `wipeAnchor` date on that day. `wipeOnceAt` is a one-off wipe in the future. A 400 carries one sentence per problem in `errors`.",
"parameters": [
{
"name": "id",
@@ -588,30 +588,11 @@
}
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"example": "any"
},
"sidecarBaseUrl": {
"example": "any"
},
"sidecarToken": {
"example": "any"
},
"protocol": {
"example": "any"
},
"enabled": {
"example": "any"
},
"sortOrder": {
"example": "any"
}
}
"$ref": "#/components/schemas/RustServerSave"
}
}
}
@@ -1972,6 +1953,418 @@
"example": false
}
}
},
"nextWipe": {
"$ref": "#/components/schemas/RustNextWipe"
}
}
}
}
},
"RustNextWipe": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"nullable": {
"type": "boolean",
"example": true
},
"description": {
"type": "string",
"example": "When the server wipes next, computed from the operator’s schedule on every read, or null when no schedule is set. `source` is `forced` (Facepunch’s monthly forced wipe, first Thursday 19:00 UK time), `rule` (the server’s own weekly or biweekly day) or `once` (a one-off date the operator set, which replaces any computed wipe before it). Absent from a module older than phase 16."
},
"properties": {
"type": "object",
"properties": {
"at": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date-time"
},
"example": {
"type": "string",
"example": "2026-10-01T18:00:00.000Z"
}
}
},
"source": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"enum": {
"type": "array",
"example": [
"forced",
"rule",
"once"
],
"items": {
"type": "string"
}
},
"example": {
"type": "string",
"example": "forced"
}
}
}
}
}
}
},
"RustWipeSchedule": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"description": {
"type": "string",
"example": "A server’s wipe schedule as the operator stored it — what they typed, not what it computes to. A past `onceAt` is still returned so the form can show it as past."
},
"properties": {
"type": "object",
"properties": {
"rule": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"enum": {
"type": "array",
"example": [
"none",
"forced",
"weekly",
"biweekly"
],
"items": {
"type": "string"
}
},
"example": {
"type": "string",
"example": "weekly"
}
}
},
"day": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"nullable": {
"type": "boolean",
"example": true
},
"description": {
"type": "string",
"example": "0 = Sunday … 6 = Saturday"
},
"example": {
"type": "number",
"example": 4
}
}
},
"time": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {
"type": "string",
"example": "14:00"
}
}
},
"tz": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {
"type": "string",
"example": "America/Chicago"
}
}
},
"anchor": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {}
}
},
"onceAt": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date-time"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {}
}
}
}
}
}
},
"RustServerSave": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"description": {
"type": "string",
"example": "The body of PUT /admin/rust/servers/{id}. The wipe fields are written only when `wipeRule` is present."
},
"properties": {
"type": "object",
"properties": {
"name": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"example": {
"type": "string",
"example": "Main · Vanilla"
}
}
},
"sidecarBaseUrl": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"example": {
"type": "string",
"example": "http://10.0.0.5:8090"
}
}
},
"sidecarToken": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"description": {
"type": "string",
"example": "Write-only. Omit or send empty to keep the stored one."
},
"example": {
"type": "string",
"example": ""
}
}
},
"protocol": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"example": {
"type": "number",
"example": 11
}
}
},
"enabled": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "boolean"
},
"example": {
"type": "boolean",
"example": true
}
}
},
"sortOrder": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"example": {
"type": "number",
"example": 0
}
}
},
"wipeRule": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"enum": {
"type": "array",
"example": [
"none",
"forced",
"weekly",
"biweekly"
],
"items": {
"type": "string"
}
},
"example": {
"type": "string",
"example": "weekly"
}
}
},
"wipeDay": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {
"type": "number",
"example": 4
}
}
},
"wipeTime": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {
"type": "string",
"example": "14:00"
}
}
},
"wipeTz": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {
"type": "string",
"example": "America/Chicago"
}
}
},
"wipeAnchor": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {}
}
},
"wipeOnceAt": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date-time"
},
"nullable": {
"type": "boolean",
"example": true
},
"example": {}
}
}
}
}
@@ -2201,6 +2594,12 @@
"example": false
}
}
},
"nextWipe": {
"$ref": "#/components/schemas/RustNextWipe"
},
"schedule": {
"$ref": "#/components/schemas/RustWipeSchedule"
}
}
}