### Start Workflow from Command with TypeScript Source: https://context7_llms Demonstrates how to start a workflow from a CommandKit command using the 'start' function. It imports the necessary types and functions, defines a command, and then calls 'start' with the workflow function and its arguments. ```typescript import type { CommandData, ChatInputCommand } from 'commandkit'; import { start } from 'workflow/api'; import { greetUserWorkflow } from '@/workflows/greet/greet.workflow'; export const command: CommandData = { name: 'greet', description: 'Greet a user with a workflow', }; export const chatInput: ChatInputCommand = async (ctx) => { await ctx.interaction.reply("I'm going to greet you! :wink:"); await start(greetUserWorkflow, [ctx.interaction.user.id]); }; ``` -------------------------------- ### Basic Translation File Example Source: https://context7_llms Provides an example of a basic translation JSON file for a command. It includes keys for 'response', 'error', and 'database_response', with placeholders for dynamic values like 'dbLatency'. ```json { "response": "🏓 Pong! Latency: **{{latency}}ms**", "error": "❌ Failed to ping the server", "database_response": "📊 Database latency: **{{dbLatency}}ms**" } ``` -------------------------------- ### Custom Build Script Example using CommandKit API Source: https://context7_llms An example demonstrating how to use the CommandKit CLI API to create a custom build script. It includes type checking and creating a production build. ```typescript import { production, compiler, typeChecker } from 'commandkit/cli'; async function customBuild() { const configPath = './commandkit.config.ts'; try { // Perform type checking first await typeChecker.performTypeCheck('./src'); // Create production build await production.createProductionBuild(configPath); // Additional custom build steps console.log('Custom build completed successfully!'); } catch (error) { console.error('Build failed:', error); process.exit(1); } } customBuild(); ``` -------------------------------- ### Install @commandkit/ai Plugin Source: https://context7_llms Installs the core @commandkit/ai plugin and the AI SDK for Google Gemini. Ensure you have Node.js and npm/yarn installed. This is the first step to enabling AI features in your CommandKit project. ```bash npm install @commandkit/ai@next npm install @ai-sdk/google ``` -------------------------------- ### Good Workflow vs. Bad Workflow Example Source: https://context7_llms Illustrates best practices for organizing CommandKit workflows and steps. The 'good' example shows a workflow orchestrating calls to steps, while the 'bad' example demonstrates an anti-pattern of performing complex logic directly within the workflow instead of delegating to steps. ```typescript // Good - workflow orchestrates, steps do work export async function memberVerificationWorkflow( userId: string, guildId: string, ) { 'use workflow'; const member = await fetchMember(userId, guildId); const verified = await verifyMember(member); return { userId, verified, status: 'completed' }; } // Avoid - doing too much in the workflow export async function badWorkflow(userId: string) { 'use workflow'; // Don't do actual work here - use steps instead const user = await fetch('...'); // ❌ } ``` -------------------------------- ### Complete Runtime Plugin Example (TypeScript) Source: https://context7_llms This comprehensive example demonstrates creating a 'LoggingPlugin' that extends CommandKit's RuntimePlugin. It implements several hooks: onAfterClientLogin for login confirmation, onBeforeInteraction for logging command usage, executeCommand for timing and tracking command execution, and prepareCommand for adding a 'dev_' prefix to command names in development environments. ```typescript import { type PreparedAppCommandExecution, type CommandKitEnvironment, type CommandKitPluginRuntime, type CommandBuilderLike, RuntimePlugin, } from 'commandkit'; import type { Interaction, Message } from 'discord.js'; export class LoggingPlugin extends RuntimePlugin { private commandUsage = new Map(); async onAfterClientLogin(ctx: CommandKitPluginRuntime): Promise { console.log(`Bot logged in as ${ctx.client.user?.tag}!`); console.log(`Serving ${ctx.client.guilds.cache.size} guilds`); } async onBeforeInteraction( ctx: CommandKitPluginRuntime, interaction: Interaction, ): Promise { if (interaction.isCommand()) { console.log( `Command "${interaction.commandName}" used by ${interaction.user.tag}`, ); } } async executeCommand( ctx: CommandKitPluginRuntime, env: CommandKitEnvironment, source: Interaction | Message, command: PreparedAppCommandExecution, execute: () => Promise, ): Promise { const startTime = Date.now(); // Let CommandKit handle normal execution await execute(); // Log execution time const execTime = Date.now() - startTime; console.log(`Command "${command.name}" executed in ${execTime}ms`); // Track usage this.commandUsage.set( command.name, (this.commandUsage.get(command.name) || 0) + 1, ); return true; // We've handled it } async prepareCommand( ctx: CommandKitPluginRuntime, command: CommandBuilderLike, ): Promise { // Add dev tag to command names in development environment if (process.env.NODE_ENV === 'development') { command.name = `dev_${command.name}`; } return command; } } ``` -------------------------------- ### Localization Example for Command Names (JSON) Source: https://context7_llms An example JSON file demonstrating how to localize command names and descriptions for different contexts using the i18n plugin. It shows specific keys for general commands, user context commands (`$command:user-ctx`), and message context commands (`$command:message-ctx`). ```json { "$command": { "name": "Report", // this will add `name_localizations` to the regular command name "description": "Report a message or user to moderators." // this will add `description_localizations` to the regular command description }, "$command:user-ctx": { "name": "Report User" // this will add `name_localizations` to the `nameAliases.user` option }, "$command:message-ctx": { "name": "Report Message" // this will add `name_localizations` to the `nameAliases.message` option } } ``` -------------------------------- ### Manually start CommandKit application in production Source: https://context7_llms Manually starts the CommandKit application in production mode by executing the compiled 'index.js' file from the 'dist' folder using Node.js. This is an alternative to 'commandkit start' and assumes a production build has been created. ```bash node dist/index.js ``` -------------------------------- ### Install BullMQ for Production Tasks Source: https://context7_llms Installs the BullMQ package, which is required for using the BullMQ driver for distributed task scheduling in production environments with Redis. ```bash npm install bullmq ``` -------------------------------- ### Install CommandKit using npm Source: https://context7_llms This command installs the CommandKit package and its latest version using npm. It is the first step in manually setting up CommandKit in an existing application. ```sh npm install commandkit@next ``` -------------------------------- ### Basic Message Command Setup in TypeScript and JavaScript Source: https://context7_llms Demonstrates the basic structure for creating a message command in CommandKit. It shows how to export the 'message' function and define command data. This setup is essential for CommandKit to recognize and process message-based commands. ```typescript import type { CommandData, MessageCommand } from 'commandkit'; export const command: CommandData = { name: 'ping', }; export const message: MessageCommand = async (ctx) => { await ctx.message.reply('Pong!'); }; ``` ```javascript /** * @typedef {import('commandkit').CommandData} CommandData * @typedef {import('commandkit').MessageCommand} MessageCommand */ /** @type {CommandData} */ export const command = { name: 'ping', }; /** @type {MessageCommand} */ export const message = async (ctx) => { await ctx.message.reply('Pong!'); }; ``` -------------------------------- ### Install @commandkit/workflow Plugin Source: https://context7_llms Shows the npm command to install the necessary packages for the @commandkit/workflow plugin. ```bash npm install @commandkit/workflow workflow ``` -------------------------------- ### Step Function Example with TypeScript Source: https://context7_llms Shows an example of a step function in TypeScript, 'greetUser'. It uses the 'use step' directive and the 'useClient' hook to fetch a user and send them a message. ```typescript import { useClient } from 'commandkit/hooks'; export async function greetUser(userId: string, again = false) { 'use step'; const client = useClient(); const user = await client.users.fetch(userId); const message = again ? 'Hello again!' : 'Hello!'; await user.send(message); } ``` -------------------------------- ### Install @commandkit/legacy Plugin (npm/yarn) Source: https://context7_llms Installs the `@commandkit/legacy` plugin, which provides backward compatibility for older CommandKit versions. This is useful for migrating existing projects incrementally. ```sh npm install @commandkit/legacy@next ``` -------------------------------- ### Start CommandKit Development Server Source: https://context7_llms Starts the CommandKit application in development mode using the command-line interface. This command is necessary for the devtools plugin to become active and accessible. ```bash npx commandkit dev ``` -------------------------------- ### Install CommandKit Cache Package (Bash) Source: https://context7_llms Command to install the `@commandkit/cache` package using npm. This is the first step to enabling the caching system in CommandKit. ```bash npm install @commandkit/cache@next ``` -------------------------------- ### Bootstrap Development Server with CommandKit Source: https://context7_llms Starts the CommandKit development server with hot module reloading. It takes an optional configuration file path and returns a development server instance with access to its watcher and process. ```typescript import { development } from 'commandkit/cli'; // Bootstrap development server const devServer = await development.bootstrapDevelopmentServer( './commandkit.config.ts', ); // Access the development server instance const watcher = devServer.watcher; const process = devServer.getProcess(); ``` -------------------------------- ### CommandKit Help Command (npm/yarn) Source: https://context7_llms This command displays all available options and usage examples for the CommandKit CLI. It's useful for understanding the different functionalities and configurations available when working with CommandKit. ```sh npm create commandkit@latest --help ``` -------------------------------- ### Run CommandKit application in production mode Source: https://context7_llms Starts the CommandKit application in production mode using the 'commandkit start' command. This command loads environment variables from a .env file and runs the compiled production build. It requires the CommandKit CLI. ```bash npx commandkit start ``` -------------------------------- ### Install @commandkit/tasks Plugin (npm) Source: https://context7_llms Installs the `@commandkit/tasks` plugin, which allows for scheduling and managing background tasks within a Discord application. This is useful for periodic maintenance, scheduled messages, or data cleanup. ```bash npm install @commandkit/tasks@next ``` -------------------------------- ### Caching Database Queries Example Source: https://context7_llms An example demonstrating how to cache database query results. This function retrieves user profiles, tags the cache with 'user:', and sets a cache life of 1 hour, suitable for data that does not change frequently. ```typescript async function getUserProfile(userId: string) { 'use cache'; cacheTag(`user:${userId}`); cacheLife('1h'); // User profiles don't change often return await db.users.findOne({ where: { id: userId }, include: ['profile', 'settings'], }); } ``` -------------------------------- ### Configure Redis Connection for @commandkit/queue Source: https://context7_llms Provides examples of how to configure a Redis connection for use with @commandkit/queue. It shows a basic local connection and more detailed configurations including host, port, password, and TLS for cloud-based Redis instances. ```typescript import Redis from 'ioredis'; // Local Redis const redis = new Redis(); // Or with configuration const redis = new Redis({ host: 'localhost', port: 6379, password: 'your-password', db: 0, }); // Cloud Redis (example with Redis Cloud) const redis = new Redis({ host: 'your-redis-host.redis.cloud.com', port: 6379, password: 'your-redis-password', tls: {}, }); ``` -------------------------------- ### Implement String Select Menu with CommandKit Source: https://context7_llms Provides an example of creating and handling a string select menu in CommandKit. Users can select from predefined string options, and the selection is processed by a handler function. ```tsx import { type ChatInputCommand, type OnStringSelectMenuKitSubmit, ActionRow, StringSelectMenu, StringSelectMenuOption, } from 'commandkit'; import { MessageFlags } from 'discord.js'; const handleSelect: OnStringSelectMenuKitSubmit = async ( interaction, context, ) => { const selection = interaction.values[0]; await interaction.reply({ content: `You selected: ${selection}`, flags: MessageFlags.Ephemeral, }); // Clean up the select menu context context.dispose(); }; export const chatInput: ChatInputCommand = async ({ interaction }) => { const selectMenu = ( ); await interaction.reply({ content: 'Please make a selection:', components: [selectMenu], }); }; ``` -------------------------------- ### Setup CommandKit Cache Plugin (TypeScript) Source: https://context7_llms Configures CommandKit to use the cache plugin. This involves importing the `cache` function from `@commandkit/cache` and adding it to the `plugins` array in the `defineConfig` function. ```typescript import { defineConfig } from 'commandkit'; import { cache } from '@commandkit/cache'; export default defineConfig({ plugins: [cache()], }); ``` -------------------------------- ### Handle Button Clicks with CommandKit Source: https://context7_llms Shows how to handle button interactions in CommandKit using the `onClick` prop. This example defines a click handler function and attaches it to a button. ```tsx import { type ChatInputCommand, type OnButtonKitClick, ActionRow, Button, } from 'commandkit'; import { MessageFlags } from 'discord.js'; const handleClick: OnButtonKitClick = async (interaction, context) => { await interaction.reply({ content: 'Button clicked!', flags: MessageFlags.Ephemeral, }); // Clean up the button context context.dispose(); }; export const chatInput: ChatInputCommand = async ({ interaction }) => { const interactiveButton = ( ); await interaction.reply({ content: 'Click the button to see it work:', components: [interactiveButton], }); }; ``` -------------------------------- ### Basic CommandKit i18n Plugin Setup Source: https://context7_llms Configures CommandKit to use the i18n plugin. This involves importing defineConfig and i18n, and then including the i18n() function within the plugins array of the defineConfig. ```typescript import { defineConfig } from 'commandkit'; import { i18n } from '@commandkit/i18n'; export default defineConfig({ plugins: [i18n()], }); ``` -------------------------------- ### Create Custom Analytics Provider in CommandKit Source: https://context7_llms This example provides a template for creating a custom analytics provider in CommandKit by implementing the `AnalyticsProvider` interface. It includes methods for tracking and identifying events with custom logic. ```typescript import { AnalyticsProvider, AnalyticsEvent, IdentifyEvent, } from 'commandkit/analytics'; class CustomAnalyticsProvider implements AnalyticsProvider { readonly name = 'custom-analytics'; constructor(private readonly analytics: YourAnalyticsService) {} async track(engine: AnalyticsEngine, event: AnalyticsEvent): Promise { // Implement your tracking logic here const { name, data } = event; // Example: Send anonymous data to your analytics service await this.analytics.track({ name, // Only include anonymous data data: { ...data, // Add anonymous session info sessionId: this.generateSessionId(), timestamp: Date.now(), }, }); } async identify(engine: AnalyticsEngine, event: IdentifyEvent): Promise { // Implement anonymous session identification await this.analytics.identify({ // Use anonymous session identifiers sessionId: this.generateSessionId(), timestamp: Date.now(), // Include anonymous session properties properties: { environment: process.env.NODE_ENV, version: '1.0.0', }, }); } private generateSessionId(): string { return 'session_' + Math.random().toString(36).substring(7); } } ``` -------------------------------- ### Send Messages Using @commandkit/queue Source: https://context7_llms Demonstrates how to send messages to different topics using the `send` function from the @commandkit/queue package. Examples include sending simple JSON objects with varying data structures and timestamps. ```typescript import { send } from '@commandkit/queue'; // Send a simple message await send('user-events', { userId: '123', action: 'login' }); // Send different types of data await send('notifications', { type: 'welcome', userId: '123', message: 'Welcome to our platform!', }); await send('analytics', { event: 'page_view', page: '/dashboard', timestamp: Date.now(), }); ``` -------------------------------- ### Label with Description in CommandKit Source: https://context7_llms Illustrates how to use the Label component with a description to provide additional context for form fields. This example includes both a ShortInput for username and a ParagraphInput for a user bio. It requires the 'commandkit' library. ```tsx import { CommandData, Modal, ShortInput, ParagraphInput, Label, OnModalKitSubmit, ChatInputCommandContext, } from 'commandkit'; import { MessageFlags } from 'discord.js'; export const command: CommandData = { name: 'profile', description: 'Create your profile', }; const handleSubmit: OnModalKitSubmit = async (interaction, context) => { const username = interaction.fields.getTextInputValue('username'); const bio = interaction.fields.getTextInputValue('bio'); await interaction.reply({ content: `**Username:** ${username}\n**Bio:** ${bio}`, flags: MessageFlags.Ephemeral, }); context.dispose(); }; export const chatInput: ChatInputCommandContext = async (ctx) => { const modal = ( ); await ctx.interaction.showModal(modal); }; ``` -------------------------------- ### Configure 'Once' Event Handler in CommandKit Source: https://context7_llms This snippet shows how to configure an event handler to run only once. By exporting a `once` variable set to `true`, the event will only be triggered the first time it occurs. This is useful for setup tasks that should only happen at the start. ```typescript import type { EventHandler } from 'commandkit'; export const once = true; const handler: EventHandler<'clientReady'> = (client) => { console.log(`🤖 ${client.user.displayName} is online!`); }; export default handler; ``` ```javascript /** * @typedef {import('commandkit').EventHandler<'clientReady'>} ClientReadyHandler */ export const once = true; /** @type {ClientReadyHandler} */ const handler = (client) => { console.log(`🤖 ${client.user.displayName} is online!`); }; export default handler; ``` -------------------------------- ### Create Production Build and Bootstrap Server with CommandKit Source: https://context7_llms Handles production builds and server startup. It includes functions to create an optimized production build and then bootstrap the production server, both taking a configuration file path. ```typescript import { production } from 'commandkit/cli'; // Create a production build await production.createProductionBuild('./commandkit.config.ts'); // Start production server const server = await production.bootstrapProductionServer( './commandkit.config.ts', ); ``` -------------------------------- ### Nested Property Access in CommandKit KV using Dot Notation Source: https://context7_llms Demonstrates how to access and modify nested properties within stored objects in the CommandKit KV store using dot notation. It shows examples of getting and setting values deep within a JSON structure. ```typescript // Store an object kv.set('user:123', { name: 'John Doe', settings: { theme: 'dark', notifications: { email: true, push: false }, }, }); // Access nested properties const theme = kv.get('user:123.settings.theme'); // 'dark' const emailNotifications = kv.get('user:123.settings.notifications.email'); // true // Set nested properties kv.set('user:123.settings.theme', 'light'); kv.set('user:123.settings.notifications.push', true); ``` -------------------------------- ### CommandKit v1 vs v0 Configuration File Source: https://context7_llms Illustrates the simplified configuration file in CommandKit v1 compared to the manual setup in v0. V1 automatically detects project structure, making configuration optional for many use cases. ```typescript import { defineConfig } from 'commandkit'; export default defineConfig({ // Configuration is now optional for most use cases // CommandKit automatically detects your app structure }); ``` ```typescript import { defineConfig } from 'commandkit'; export default defineConfig({ src: 'src', main: 'index.mjs', // Manual configuration was required }); ``` -------------------------------- ### CommandKit v1 vs v0 Entry Point Source: https://context7_llms Demonstrates the streamlined entry point for CommandKit v1, where only a configured Discord.js client is exported. V0 required manual setup of the CommandKit instance, client login, and path configurations. ```typescript import { Client } from 'discord.js'; const client = new Client({ intents: [ 'Guilds', 'GuildMessages', 'MessageContent', ], }); // Optional: Override the default DISCORD_TOKEN env variable client.token = 'CUSTOM_BOT_TOKEN'; export default client; // CommandKit handles the rest automatically ``` ```typescript import { Client, GatewayIntentBits } from 'discord.js'; import { CommandKit } from 'commandkit'; import path from 'path'; const client = new Client({ intents: [ 'Guilds', 'GuildMessages', 'MessageContent', ], }); new CommandKit({ client, commandsPath: path.join(__dirname, 'commands'), eventsPath: path.join(__dirname, 'events'), validationsPath: path.join(__dirname, 'validations'), skipBuiltInValidations: true, bulkRegister: true, }); client.login('YOUR_TOKEN_HERE'); ``` -------------------------------- ### Define User Onboarding Workflow Source: https://context7_llms Defines a multi-step user onboarding process using CommandKit. It orchestrates several steps including sending a welcome message, assigning a role, waiting for a specified duration, and sending a follow-up message. Dependencies include 'workflow' and custom step modules. ```typescript import { sleep } from 'workflow'; import { sendWelcomeMessage } from './steps/send-welcome-message'; import { assignRole } from './steps/assign-role'; import { sendFollowUpMessage } from './steps/send-follow-up-message'; export async function userOnboardingWorkflow(userId: string, guildId: string) { 'use workflow'; await sendWelcomeMessage(userId, guildId); await assignRole(userId, guildId); await sleep('7 days'); await sendFollowUpMessage(userId, guildId); return { userId, status: 'completed' }; } ``` -------------------------------- ### Install @commandkit/devtools Plugin Source: https://context7_llms Installs the next version of the @commandkit/devtools plugin using npm or yarn. This command is essential for adding the development tools to your project. ```sh npm install @commandkit/devtools@next ``` ```sh yarn add @commandkit/devtools@next ``` -------------------------------- ### Install @commandkit/i18n Plugin Source: https://context7_llms Installs the next version of the @commandkit/i18n plugin using npm or yarn. This plugin is essential for enabling internationalization features in your CommandKit bot. ```sh npm install @commandkit/i18n@next # or yarn add @commandkit/i18n@next ``` -------------------------------- ### Basic Key-Value Store Usage with CommandKit KV Source: https://context7_llms Demonstrates the basic usage of CommandKit's key-value (KV) store, which uses SQLite for persistent storage. It shows how to create a KV instance and set/get various data types. ```typescript import { KV } from 'commandkit/kv'; // Create a new KV store const kv = new KV('data.db'); // Store data directly kv.set('user:123', { name: 'John', age: 30 }); kv.set('counter', 42); kv.set('active', true); // Retrieve data const user = kv.get('user:123'); // { name: 'John', age: 30 } const counter = kv.get('counter'); // 42 ``` -------------------------------- ### Set Up Redis Pub/Sub Driver for @commandkit/queue Source: https://context7_llms Configures the @commandkit/queue package to use a Redis Pub/Sub driver. This involves creating a Redis connection, initializing a PubSubRedisBroker, and then creating and setting the RedisPubSubDriver. ```typescript import { setDriver } from '@commandkit/queue'; import { RedisPubSubDriver } from '@commandkit/queue/discordjs'; import { PubSubRedisBroker } from '@discordjs/brokers'; import Redis from 'ioredis'; // Create a Redis connection const redis = new Redis(); // Create a broker const broker = new PubSubRedisBroker(redis); // Create a driver const driver = new RedisPubSubDriver(broker); // Set the driver setDriver(driver); ``` -------------------------------- ### Create Discord.js Client Entrypoint Source: https://context7_llms Sets up the main application file, typically `src/app.ts` or `src/app.js`, which must export your discord.js client instance. CommandKit handles the client login process. ```typescript import { Client } from 'discord.js'; const client = new Client({ intents: ['Guilds'], }); client.token = '...'; // Optional: Manually set a bot token export default client; ``` ```javascript import { Client } from 'discord.js'; const client = new Client({ intents: ['Guilds'], }); client.token = '...'; // Optional: Manually set a bot token export default client; ``` -------------------------------- ### Install @commandkit/analytics Package Source: https://context7_llms Installs the `@commandkit/analytics` package using npm or yarn. This package enables tracking of events and metrics in your Discord bot while prioritizing user privacy. ```bash npm install @commandkit/analytics@next ``` -------------------------------- ### Create Custom Development Server with CommandKit Source: https://context7_llms This snippet demonstrates how to create a custom development server using CommandKit's internal CLI API. It allows setting custom environment variables, bootstrapping the server with a configuration file, and adding custom file watchers to trigger logic on file changes. The running process can also be accessed. ```typescript import { development, env } from 'commandkit/cli'; async function customDevServer() { // Set custom environment variables process.env.CUSTOM_DEV_FLAG = 'true'; // Bootstrap development server const devServer = await development.bootstrapDevelopmentServer( './commandkit.config.ts', ); // Add custom file watchers devServer.watcher.on('change', (path) => { console.log(`File changed: ${path}`); // Custom logic here }); // Access the running process const process = devServer.getProcess(); return devServer; } customDevServer(); ``` -------------------------------- ### Execute Member Setup Steps in Parallel Source: https://context7_llms Demonstrates parallel execution of multiple steps within a workflow using `Promise.all`. This workflow assigns roles, creates a private channel, and logs member join activity concurrently before sending a welcome message. It relies on imported step functions. ```typescript import { assignRoles, sendWelcomeMessage, createPrivateChannel, logMemberJoin, } from './steps'; export async function memberSetupWorkflow(userId: string, guildId: string) { 'use workflow'; const [roles, channel, log] = await Promise.all([ assignRoles(userId, guildId), createPrivateChannel(userId, guildId), logMemberJoin(userId, guildId), ]); await sendWelcomeMessage(userId, guildId, channel.id); return { userId, roles, channelId: channel.id, logged: log }; } ``` -------------------------------- ### Implement Channel Select Menu with CommandKit Source: https://context7_llms Demonstrates how to create a channel select menu in CommandKit, allowing users to select a channel from the server. The selected channel is then processed by a handler function. ```tsx import { type ChatInputCommand, type OnChannelSelectMenuKitSubmit, ActionRow, ChannelSelectMenu, } from 'commandkit'; import { MessageFlags } from 'discord.js'; const handleSelect: OnChannelSelectMenuKitSubmit = async ( interaction, context, ) => { const channel = interaction.values[0]; await interaction.reply({ content: `Selected channel: <#${channel}>`, flags: MessageFlags.Ephemeral, }); // Clean up the select menu context context.dispose(); }; export const chatInput: ChatInputCommand = async ({ interaction }) => { const selectMenu = ( ); await interaction.reply({ content: 'Select a channel:', components: [selectMenu], }); }; ``` -------------------------------- ### Descriptive Naming for Workflow Functions in TypeScript Source: https://context7_llms Illustrates the importance of using descriptive names for workflow functions to improve code readability and maintainability. It shows a 'Good' example with `userOnboardingWorkflow` versus a 'Bad' example with `workflow1`. ```typescript // Good export async function userOnboardingWorkflow(userId: string) { 'use workflow'; // ... } // Avoid export async function workflow1(userId: string) { 'use workflow'; // ... } ``` -------------------------------- ### Use Appropriate Message Sizes with TypeScript Source: https://context7_llms Illustrates the importance of using appropriate message sizes for efficient communication. It shows an example of a good, reasonable message size and contrasts it with an example of a very large message that should be avoided. ```typescript // Good - reasonable message size await send('user-profile-updates', { userId: '123', changes: { displayName: 'New Name', avatar: 'https://example.com/avatar.jpg', }, }); // Avoid - very large messages await send('user-profile-updates', { userId: '123', fullProfile: { /* massive object */ }, }); ``` -------------------------------- ### Implement Welcome Message Step with Error Handling Source: https://context7_llms Implements a step to send a welcome message to a user in a Discord guild using CommandKit. It fetches guild and member information, finds a welcome channel, and sends an embed message. Includes error handling for common Discord API errors like disabled DMs or member not found. ```typescript import { FatalError } from 'workflow'; import { useClient } from 'commandkit/hooks'; export async function sendWelcomeMessage(userId: string, guildId: string) { 'use step'; const client = useClient(); try { const guild = await client.guilds.fetch(guildId); const member = await guild.members.fetch(userId); const welcomeChannel = guild.channels.cache.find( (channel) => channel.name === 'welcome', ); if (welcomeChannel?.isTextBased()) { await welcomeChannel.send({ content: `Welcome to ${guild.name}, <@${userId}>! 🎉`, embeds: [ { title: 'Welcome!', description: 'Thanks for joining our server!', color: 0x00ff00, }, ], }); } else { const user = await client.users.fetch(userId); await user.send({ embeds: [ { title: 'Welcome!', description: `Thanks for joining ${guild.name}`, color: 0x00ff00, }, ], }); } } catch (error: any) { if (error.code === 50007) { throw new FatalError('User has DMs disabled'); } if (error.code === 10007) { throw new FatalError('Member not found in guild'); } throw error; } } ``` -------------------------------- ### Configuring CommandKit KV Store Options Source: https://context7_llms Explains how to configure the CommandKit KV store using the `openKV` function. It covers specifying a custom database file path, using an in-memory store for testing, and setting a namespace. ```typescript import { openKV } from 'commandkit/kv'; // Create with custom database file const kv = openKV('my-bot-data.db'); // In-memory store for testing const testKv = openKV(':memory:'); // Create with specific namespace const userKv = openKV('data.db', { namespace: 'users', }); ``` -------------------------------- ### Use Descriptive Task Names in CommandKit (TypeScript) Source: https://context7_llms This example highlights the best practice of using descriptive names for tasks created with CommandKit. It contrasts a good example with a poor one, emphasizing that clear naming improves code readability and maintainability. ```typescript // Good await createTask({ name: 'user-reminder', data: { userId, message }, schedule: reminderTime, }); // Avoid await createTask({ name: 'task', data: { userId, message }, schedule: reminderTime, }); ``` -------------------------------- ### Caching API Responses Example Source: https://context7_llms A practical example of caching API responses. This function fetches game statistics, tags the cache entry with 'game:', and sets the cache life to 30 minutes, reflecting that API data updates every 30 minutes. ```typescript async function fetchGameStats(gameId: string) { 'use cache'; cacheTag(`game:${gameId}`); cacheLife('30m'); // API updates every 30 minutes const response = await fetch(`https://api.game.com/stats/${gameId}`); return response.json(); } ``` -------------------------------- ### Configure CommandKit Source: https://context7_llms Creates a configuration file at the root of your project to set up CommandKit and its plugins. This file is essential for initializing the framework. ```typescript import { defineConfig } from 'commandkit'; export default defineConfig({}); ``` ```javascript import { defineConfig } from 'commandkit'; export default defineConfig({}); ``` -------------------------------- ### Caching Computed Results Example Source: https://context7_llms An example showcasing the caching of computed results. This function calculates user statistics, tags the cache with 'user:' and 'stats', and sets a cache life of 5 minutes, as the calculations might need to be redone frequently. Requires helper functions like calculateLevel, calculateRank, and getAchievements. ```typescript async function calculateUserStats(userId: string) { 'use cache'; cacheTag(`user:${userId}`); cacheTag('stats'); cacheLife('5m'); // Recalculate every 5 minutes const user = await db.users.findOne(userId); return { level: calculateLevel(user.xp), rank: await calculateRank(userId), achievements: await getAchievements(userId), }; } ``` -------------------------------- ### Manage Task State with CommandKit Context Store (TypeScript) Source: https://context7_llms This example shows how to use the CommandKit context store to manage state between task executions. It implements a 'prepare' function to check a cooldown period based on the last run time stored in the context, and the 'execute' function updates a counter and performs work. This is ideal for rate-limiting or tracking task history. ```typescript import { task } from '@commandkit/tasks'; export default task({ name: 'stateful-task', schedule: '0 */2 * * *', // Every 2 hours async prepare(ctx) { // Check if we're in a cooldown period const lastRun = ctx.commandkit.store.get('last-run'); const cooldown = 30 * 60 * 1000; // 30 minutes if (lastRun && Date.now() - lastRun < cooldown) { return false; // Skip execution } return true; }, async execute(ctx) { // Update last run time ctx.commandkit.store.set('last-run', Date.now()); // Get or initialize counter const counter = ctx.commandkit.store.get('execution-counter') || 0; ctx.commandkit.store.set('execution-counter', counter + 1); console.log(`Task executed ${counter + 1} times`); // Perform the actual work await performWork(); }, }); ``` -------------------------------- ### Add Ping/Pong Command Source: https://context7_llms Implements a basic ping/pong command that responds to both slash commands and message commands. This example demonstrates registering a command with CommandKit. ```typescript import type { ChatInputCommand, CommandData, MessageCommand } from 'commandkit'; export const command: CommandData = { name: 'ping', description: 'Pong!', }; export const chatInput: ChatInputCommand = async ({ interaction }) => { await interaction.reply('Pong!'); }; export const message: MessageCommand = async ({ message }) => { await message.reply('Pong!'); }; ``` ```javascript /** * @typedef {import('commandkit').ChatInputCommand} ChatInputCommand * @typedef {import('commandkit').CommandData} CommandData * @typedef {import('commandkit').MessageCommand} MessageCommand */ /** @type {CommandData} */ export const command = { name: 'ping', description: 'Pong!', }; /** @type {ChatInputCommand} */ export const chatInput = async ({ interaction }) => { await interaction.reply('Pong!'); }; /** @type {MessageCommand} */ export const message = async ({ message }) => { await message.reply('Pong!'); }; ``` -------------------------------- ### Implement onBeforeClientLogin Hook in TypeScript Source: https://context7_llms Illustrates the `onBeforeClientLogin` hook, which is triggered just before the Discord client attempts to log in. This is suitable for last-minute setup before the bot connects. ```typescript async onBeforeClientLogin(ctx: CommandKitPluginRuntime): Promise { console.log('Bot is about to connect to Discord...'); // Last minute preparations before login } ``` -------------------------------- ### Create CommandKit Project (npm/yarn) Source: https://context7_llms This command is used to create a new CommandKit project using the latest development build. It utilizes npm or yarn to fetch and set up the project scaffolding. Be aware that development versions may contain bugs. ```sh npm create commandkit@dev ``` -------------------------------- ### Update CommandKit to v1 Source: https://context7_llms Installs the latest v1 version of CommandKit using npm. This command updates the 'commandkit@next' package and modifies your 'package.json' file. ```bash npm install commandkit@next ``` ```bash yarn add commandkit@next ``` -------------------------------- ### Configure Umami Analytics in CommandKit Source: https://context7_llms This snippet demonstrates how to set up the Umami analytics provider in CommandKit. You need to provide your Umami host URL and website ID, with optional parameters for session and user agent. ```typescript import { defineConfig } from 'commandkit'; import { umami } from '@commandkit/analytics/umami'; export default defineConfig({ plugins: [ umami({ umamiOptions: { hostUrl: 'YOUR_UMAMI_HOST_URL', websiteId: 'YOUR_UMAMI_WEBSITE_ID', // Optional: Additional configuration sessionId: 'YOUR_UMAMI_SESSION_ID', userAgent: 'YOUR_UMAMI_USER_AGENT', }, }), ], }); ``` -------------------------------- ### Disable Buttons with CommandKit Source: https://context7_llms Demonstrates how to disable buttons in CommandKit to prevent user interaction. This example shows creating both disabled and enabled buttons within an ActionRow. ```tsx import { type ChatInputCommand, ActionRow, Button } from 'commandkit'; export const chatInput: ChatInputCommand = async ({ interaction }) => { const disabledButton = ( ); await interaction.reply({ content: 'Disabled vs enabled buttons:', components: [disabledButton], }); }; ``` -------------------------------- ### Add Generated Files to .gitignore Source: https://context7_llms Example .gitignore content to exclude the .commandkit directory, which is generated by the CommandKit development server. This prevents committing temporary development files. ```gitignore .commandkit/ ``` -------------------------------- ### Build Application with CommandKit Compiler Source: https://context7_llms Handles application building and compilation. The `buildApplication` function allows you to build your application with custom options, including configuration path, development mode, and plugins. ```typescript import { compiler } from 'commandkit/cli'; // Build application with custom options await compiler.buildApplication({ configPath: './commandkit.config.ts', isDev: false, plugins: [], rolldownPlugins: [], }); ``` -------------------------------- ### Schedule Task with Cron Expression (TypeScript) Source: https://context7_llms Defines a task that runs on a recurring schedule using a cron expression. This example sets the task to execute every hour. ```typescript export default task({ name: 'hourly-task', schedule: '0 * * * *', // Every hour async execute(ctx) { // Task logic }, }); ```