Subsystem 3c: command Discord surfaces (/help, /uptime, /leader, #info team summary) - #11
Merged
Conversation
… #info team summary) Subsystem 3c — third slice of subsystem 3. Surfaces the in-game command framework into Discord: /help (in-game + slash command listing), /uptime (bot process), /leader (member-select promote), and a team summary field on the per-server #info embed. Slash modules + help catalog live in the existing Features.Commands project (Approach A); the #info edit is local to Workspace's ServerInfoMessageRenderer. The #commands channel relay is deferred to 3c-ii. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7-task subagent-driven TDD plan: PromoteToLeaderAsync seam, CommandHelpCatalog + drift guard, HelpEmbedRenderer, LeaderService, the /help+/uptime+/leader modules, and the #info team summary field. Verified signatures against the codebase (IRustServerQuery, ServerInfoMessageRenderer, FakeRustSocketSource, RustPlusApi PromoteToLeaderAsync) and the Discord project/package ref gap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…keys Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dependency Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cosmetic only — multi-line parameter/call-chain wrapping in the 3c files that Roslynator does not flag (the repo's format gate). Build 0/0, full suite 249 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs/superpowers/ is gitignored; these spec/plan files were force-added past the ignore. Untrack them (3c here + the 3b-ii docs carried from PR #10) so they stay local working docs and never ship in a PR. Files remain on disk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR surfaces the existing in-game command framework into Discord by adding new slash-command interaction modules (/help, /uptime, /leader), extending the live server query seam to support team leader promotion, and augmenting the existing #info server embed with a live team summary field (EN/FR).
Changes:
- Add Discord slash-command surfaces and supporting help catalog/renderer + leader promotion service.
- Extend
IRustServerQuery/IRustServerConnectionwithPromoteToLeaderAsyncand implement it through the supervisor + RustPlus socket shim. - Add a connected-only team summary field to the
#infoembed and update related tests/localization.
Reviewed changes
Copilot reviewed 26 out of 29 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/RustPlusBot.Features.Workspace.Tests/WorkspaceRegistrationTests.cs | Registers IRustServerQuery for workspace DI tests. |
| tests/RustPlusBot.Features.Workspace.Tests/Messages/RendererTests.cs | Updates renderer ctor usage; adds team-summary tests. |
| tests/RustPlusBot.Features.Connections.Tests/ServerQueryTests.cs | Adds tests for PromoteToLeaderAsync behavior. |
| tests/RustPlusBot.Features.Connections.Tests/Fakes/FakeRustSocketSource.cs | Adds fake promote API + last-steamId tracking. |
| tests/RustPlusBot.Features.Commands.Tests/Leader/LeaderServiceTests.cs | Adds unit tests for leader selection/promotion logic. |
| tests/RustPlusBot.Features.Commands.Tests/Help/HelpEmbedRendererTests.cs | Adds unit tests for /help embed rendering. |
| tests/RustPlusBot.Features.Commands.Tests/Help/CommandHelpCatalogTests.cs | Adds drift/i18n guard tests for help catalog. |
| tests/RustPlusBot.Features.Commands.Tests/CommandRegistrationTests.cs | Asserts Commands contributes interaction-module assembly. |
| src/RustPlusBot.Features.Workspace/WorkspaceServiceCollectionExtensions.cs | Notes workspace requires connections composition for server info. |
| src/RustPlusBot.Features.Workspace/Messages/ServerInfoMessageRenderer.cs | Adds connected-only team summary field via IRustServerQuery. |
| src/RustPlusBot.Features.Workspace/Localization/LocalizationCatalog.cs | Adds EN/FR keys for team summary field. |
| src/RustPlusBot.Features.Connections/Supervisor/ConnectionSupervisor.cs | Implements query-level PromoteToLeaderAsync. |
| src/RustPlusBot.Features.Connections/Listening/RustPlusSocketSource.cs | Implements promote call mapping to RustPlus API response. |
| src/RustPlusBot.Features.Connections/Listening/IRustServerConnection.cs | Adds PromoteToLeaderAsync to internal socket interface. |
| src/RustPlusBot.Features.Commands/RustPlusBot.Features.Commands.csproj | Adds Discord project reference + Discord.Net package. |
| src/RustPlusBot.Features.Commands/Modules/LeaderComponentModule.cs | Handles /leader component callbacks (server/member selects). |
| src/RustPlusBot.Features.Commands/Modules/CommandSurfaceModule.cs | Adds /help, /uptime, /leader slash commands. |
| src/RustPlusBot.Features.Commands/Localization/CommandLocalizationCatalog.cs | Adds EN/FR strings for new command surfaces. |
| src/RustPlusBot.Features.Commands/Leader/LeaderService.cs | Adds testable leader selection/promotion service. |
| src/RustPlusBot.Features.Commands/Help/HelpEmbedRenderer.cs | Adds pure help embed renderer. |
| src/RustPlusBot.Features.Commands/Help/CommandHelpCatalog.cs | Adds curated help manifest for in-game + slash commands. |
| src/RustPlusBot.Features.Commands/Help/CommandGroup.cs | Adds help grouping enum. |
| src/RustPlusBot.Features.Commands/CommandServiceCollectionExtensions.cs | Registers help/leader services + interaction-module assembly. |
| src/RustPlusBot.Abstractions/Connections/TeamInfoSnapshot.cs | Adds team snapshot DTOs in Abstractions (kept namespace). |
| src/RustPlusBot.Abstractions/Connections/ServerTimeSnapshot.cs | Adds time snapshot DTO in Abstractions (kept namespace). |
| src/RustPlusBot.Abstractions/Connections/ServerInfoSnapshot.cs | Adds server info snapshot DTO in Abstractions (kept namespace). |
| src/RustPlusBot.Abstractions/Connections/IRustServerQuery.cs | Extends query seam with PromoteToLeaderAsync. |
| docs/superpowers/specs/2026-06-17-rustplusbot-3c-command-surfaces-design.md | Adds design spec for subsystem 3c surfaces. |
| docs/superpowers/plans/2026-06-17-rustplusbot-3c-command-surfaces.md | Adds detailed implementation plan for subsystem 3c. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- LeaderComponentModule.OnMemberSelectedAsync now surfaces the GetMembersAsync error (e.g. not-connected if the socket dropped between select and click) instead of falling through to a generic promote failure. - LeaderComponentModule guards Context.Guild == null on both component handlers (forged/DM payloads), matching the repo pattern (SettingsComponentModule etc.). - ServerInfoMessageRenderer #info team summary treats an empty/whitespace leader display name as missing and falls back to the SteamId (the API can report a member with no name); +1 renderer test. Build 0/0, full suite 250 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third slice of subsystem 3. Surfaces the in-game command framework into Discord.
What's in this slice
/help— ephemeral; lists the in-game!commands(grouped, with the server's prefix) and the slash commands; EN/FR; rendered from a drift-guardedCommandHelpCatalogvia a pureHelpEmbedRenderer./uptime— ephemeral bot-process uptime./leader— ManageGuild-gated; picks a teammate from a live select (server-pick first when the guild has >1 registered server) and promotes via a newPromoteToLeaderAsync.#infoteam summary — a "{online}/{total} online · leader {name}" field, shown only while Connected, refreshed on the existing#infotriggers (no new timer).Seam
New
PromoteToLeaderAsynconIRustServerQuery/IRustServerConnection, implemented onConnectionSupervisorand the untestedRustPlusSocketSourceshim (wraps RustPlusApi 2.0.0-beta.1RustPlus.PromoteToLeaderAsync, mapsResponse.IsSuccess). No new entity / migration / event / option / background service.Architecture note
The original plan assumed
Workspace → Connections, but the real graph isConnections → Workspace, so a direct reference would be circular. Resolved by movingIRustServerQuery+ theServerInfo/ServerTime/TeamInfosnapshot DTOs fromFeatures.Connections/Listeninginto the dependency-freeAbstractions/Connections, keeping the original namespace so all ~31 consumers compile unchanged. Abstractions stays dependency-free (no project refs, no Discord). The folder/namespace mismatch is a known, deferred cleanup.Deferred
The
#commandschannel (Discord → in-game command relay) is deferred to a future 3c-ii.Verification
jb ReformatAndReorderapplied.🤖 Generated with Claude Code