Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ To add a command:
3. Add schema key `mycmd.enabled` (default) in `config-schema.ts`.
4. Document in `COMMANDS.md` if user-facing.

## Setup Wizard

The `/setup wizard` command provides interactive onboarding for configuring features. When adding new features:

**User-Facing Features:** Consider adding wizard support for user-facing features that require configuration.
- Add feature configuration to `src/commands/setup-wizard.ts` in the `FEATURES` constant
- Implement feature-specific configuration function (e.g., `configureMyFeature`)
- Add interaction handlers in `src/handlers/wizard-*-handler.ts` if needed
- Update auto-detection logic in `src/utils/channel-detector.ts` for resource discovery

**Wizard Architecture:**
- Ephemeral interactions in server (not DMs)
- Session-based state management via `WizardService` (15-min timeout)
- Button/select menu/modal interactions for multi-step configuration
- Auto-detects existing channels/categories to avoid duplicates
- Bulk configuration with single `ConfigService.triggerReload()` on completion

**When to Use Wizard vs Manual Config:**
- Wizard: Multi-setting features requiring guided setup (voice channels, tracking, quotes)
- Manual `/config set`: Single-setting features or advanced configuration

## Configuration Conventions

Keys use dot notation grouped by feature: `voicechannels.*`, `voicetracking.*`, `core.*`, `quotes.*`.
Expand Down
72 changes: 72 additions & 0 deletions src/commands/setup-wizard-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Guild, ChatInputCommandInteraction, EmbedBuilder } from "discord.js";
import { WizardService } from "../services/wizard-service.js";
import logger from "../utils/logger.js";

const wizardService = WizardService.getInstance();

// Features configuration
const FEATURES = {
voicechannels: {
name: "Voice Channels",
emoji: "🎤",
},
voicetracking: {
name: "Voice Tracking",
emoji: "📊",
},
quotes: {
name: "Quote System",
emoji: "💬",
},
gamification: {
name: "Gamification",
emoji: "🏆",
},
logging: {
name: "Core Logging",
emoji: "📝",
},
} as const;

type FeatureKey = keyof typeof FEATURES;

/**
* Start configuration for a specific feature
*/
export async function startFeatureConfiguration(
interaction: ChatInputCommandInteraction | any,
guild: Guild,
userId: string,
feature: FeatureKey,
): Promise<void> {
const guildId = guild.id;
const state = wizardService.getSession(userId, guildId);
if (!state) {
await interaction.followUp({
content: "❌ Wizard session expired. Please start again.",
ephemeral: true
});
return;
}

// Ensure feature is in selected features
if (!state.selectedFeatures.includes(feature)) {
state.selectedFeatures.push(feature);
wizardService.updateSession(userId, guildId, state);
}

const featureInfo = FEATURES[feature];
const embed = new EmbedBuilder()
.setTitle(`${featureInfo.emoji} ${featureInfo.name} Configuration`)
.setColor(0x5865f2);

// Call appropriate configuration function based on feature
// Note: These functions are not exported from setup-wizard.ts
// We need to refactor or handle this differently
logger.info(`Configuring feature: ${feature}`);
await interaction.followUp({
embeds: [embed],
content: `⚠️ Feature configuration for ${feature} is being set up...`,
ephemeral: true,
});
}
Loading