Conversation
* feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12
There was a problem hiding this comment.
Pull request overview
This PR bumps the package to v0.2.0 and introduces a command “requirements” system (scope + authorization) along with prefix-command support, including centralized registries/loaders and user-facing permission error replies.
Changes:
- Added command requirement types + validation helpers, and permission-denied reply builders (including ephemeral support for interaction responses).
- Added prefix command loading/registry plus a
messageCreateevent to execute prefix commands (e.g.,!ping). - Updated deployment logic to split “main guild only” slash commands vs global commands, and improved module loading robustness.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/command.ts | Adds command requirement/permission types and extends Slash/Prefix command interfaces. |
| src/registries/prefix-registry.ts | Introduces shared Map registry for prefix commands (names + aliases). |
| src/lib/errors.ts | Adds helper to build a standardized “missing permissions” container reply. |
| src/lib/components/container.ts | Adds ephemeral option to build flags; keeps V2 components rendering helpers. |
| src/lib/command-requirements.ts | Adds scope/authorization checking and a combined requirements validator. |
| src/lang/ping.ts | Adds localized “calculating” string and exports a shared ping description. |
| src/lang/index.ts | Re-exports pingDescription. |
| src/lang/errors.ts | Adds localized “missing permissions” error reply text builder. |
| src/handlers/slash-handler.ts | Cleans unused path/url utilities; continues loading slash commands via base loader. |
| src/handlers/prefix-handler.ts | Adds prefix command loader and runtime type guard. |
| src/handlers/event-handler.ts | Cleans unused fs/path/url utilities; continues loading events via base loader. |
| src/handlers/base-loader.ts | Adds try/catch around dynamic imports to skip broken modules safely. |
| src/events/message-create.ts | Adds prefix command dispatch + requirements enforcement and error replies. |
| src/events/interaction-create.ts | Adds requirements enforcement + ephemeral permission error replies for slash commands. |
| src/deploy-commands.ts | Updates slash command loading import and deploy logic (main guild vs global). |
| src/commands/slash/ping.ts | Uses shared pingDescription export for slash command description. |
| src/commands/prefix/ping.ts | Adds prefix ping command with “calculating” message then edits to final result. |
| src/client/crownutils-client.ts | Adds prefix command loading, message intents, and wraps event execution in void blocks. |
| package.json | Bumps version to 0.2.0. |
| .env.example | Updates env variables (TEST_GUILD_ID, MAIN_GUILD_ID, OWNER_ID, PRIVILEGED_IDS). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+16
to
18
| if (!isProduction && !testGuildId) { | ||
| throw new Error('Missing DISCORD_GUILD_ID for development deployment'); | ||
| } |
Comment on lines
+10
to
+19
| const candidate = obj as Record<string, unknown>; | ||
| if (typeof candidate.name !== 'string') { | ||
| return false; | ||
| } | ||
|
|
||
| if (typeof candidate.execute !== 'function') { | ||
| return false; | ||
| } | ||
|
|
||
| return true; |
Comment on lines
+28
to
+34
| for (const command of commands) { | ||
| prefixCommands.set(command.name, command); | ||
| if (command.aliases) { | ||
| for (const alias of command.aliases) { | ||
| prefixCommands.set(alias, command); | ||
| } | ||
| } |
Comment on lines
+44
to
+46
| : process.env.PRIVILEGED_IDS?.split(',').filter(Boolean).includes(userId) | ||
| ? 'privileged' | ||
| : 'public'; |
Comment on lines
49
to
53
| if (event.once) { | ||
| this.discord.once(event.name, (...args) => event.execute(...args)); | ||
| this.discord.once(event.name, (...args) => { | ||
| void event.execute(...args); | ||
| }); | ||
| } else { |
Comment on lines
+69
to
+71
| await loadPrefixCommands(); | ||
| logger.info(`Loaded ${prefixCommands.size} prefix command(s).`); | ||
| } |
Comment on lines
+24
to
+27
| export interface CommandRequirements { | ||
| scope?: CommandScope; | ||
| authorizations?: CommandAuthorization; | ||
| } |
Comment on lines
+29
to
+32
| export interface CommandValidation { | ||
| canBeExecuted: boolean; | ||
| missing_permissions: CommandPermission[]; | ||
| } |
Ntalcme
added a commit
that referenced
this pull request
Jun 9, 2026
* V0.2.0 (#14) * feat(prefix): add prefix command support with !ping (#9) * Wrap dynamic import in try/catch to skip broken files (#10) * fix(handlers): wrap dynamic import in try/catch to skip broken files #5 * Fix cacth error #5 * feat(commands): add description field to prefix commands #11 (#13) * Command authorizations and scopes (#15) * feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12 * Add scope deployment for slash commands #16 (#18) * Update package.json version to v0.2.0 * build: resolve path aliases with tsc-alias for production build * feat(lib): add parseDuration function #3 * feat(db): set up Prisma with SQLite and Reminder model * Add sqlite support #3 * feat(lib): add branded time types and msToUnixSeconds #3 * feat(lib): add prisma client with better-sqlite3 adapter #3 * chore(config): ignore prisma.config.ts in eslint #3 * feat(reminders): add reminder service and messages #3 * refactor(lib): centralize environment access with fail-fast requireEnv * refactor(components): add barrel and remove unused Footer, RawComponent and render * refactor(lib): replace branded time types with plain millisecond helpers * refactor(lang): unify user-facing text under a single lang namespace * refactor(permissions): separate execution context from required scope * refactor(commands): consume lang and component barrels in ping * feat(events): report unexpected command errors to the user * chore: remove redundant file comments * feat(reminders): create, schedule, present and rehydrate reminders #3 * feat(reminders): add /remind and !remind commands #3 * refactor(permissions): modularize command types and permission engine * refactor: adopt satisfies and command type-module import paths * feat(components): add Section, Button, ActionRow and Title sizes * feat(reminders): limit to 5 per user and add list and cancel buttons #3 * feat(reminder): Reminder limit for priviliged user #3
Ntalcme
added a commit
that referenced
this pull request
Jun 9, 2026
* feat(prefix): add prefix command support with !ping (#9) * Wrap dynamic import in try/catch to skip broken files (#10) * fix(handlers): wrap dynamic import in try/catch to skip broken files #5 * Fix cacth error #5 * feat(commands): add description field to prefix commands #11 (#13) * Command authorizations and scopes (#15) * feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12 * Add scope deployment for slash commands #16 (#18) * Update package.json version to v0.2.0 * Reminders System (#20) * V0.2.0 (#14) * feat(prefix): add prefix command support with !ping (#9) * Wrap dynamic import in try/catch to skip broken files (#10) * fix(handlers): wrap dynamic import in try/catch to skip broken files #5 * Fix cacth error #5 * feat(commands): add description field to prefix commands #11 (#13) * Command authorizations and scopes (#15) * feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12 * Add scope deployment for slash commands #16 (#18) * Update package.json version to v0.2.0 * build: resolve path aliases with tsc-alias for production build * feat(lib): add parseDuration function #3 * feat(db): set up Prisma with SQLite and Reminder model * Add sqlite support #3 * feat(lib): add branded time types and msToUnixSeconds #3 * feat(lib): add prisma client with better-sqlite3 adapter #3 * chore(config): ignore prisma.config.ts in eslint #3 * feat(reminders): add reminder service and messages #3 * refactor(lib): centralize environment access with fail-fast requireEnv * refactor(components): add barrel and remove unused Footer, RawComponent and render * refactor(lib): replace branded time types with plain millisecond helpers * refactor(lang): unify user-facing text under a single lang namespace * refactor(permissions): separate execution context from required scope * refactor(commands): consume lang and component barrels in ping * feat(events): report unexpected command errors to the user * chore: remove redundant file comments * feat(reminders): create, schedule, present and rehydrate reminders #3 * feat(reminders): add /remind and !remind commands #3 * refactor(permissions): modularize command types and permission engine * refactor: adopt satisfies and command type-module import paths * feat(components): add Section, Button, ActionRow and Title sizes * feat(reminders): limit to 5 per user and add list and cancel buttons #3 * feat(reminder): Reminder limit for priviliged user #3 * Update package.json
Ntalcme
added a commit
that referenced
this pull request
Jun 13, 2026
* feat(prefix): add prefix command support with !ping (#9) * Wrap dynamic import in try/catch to skip broken files (#10) * fix(handlers): wrap dynamic import in try/catch to skip broken files #5 * Fix cacth error #5 * feat(commands): add description field to prefix commands #11 (#13) * Command authorizations and scopes (#15) * feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12 * Add scope deployment for slash commands #16 (#18) * Update package.json version to v0.2.0 * Reminders System (#20) * V0.2.0 (#14) * feat(prefix): add prefix command support with !ping (#9) * Wrap dynamic import in try/catch to skip broken files (#10) * fix(handlers): wrap dynamic import in try/catch to skip broken files #5 * Fix cacth error #5 * feat(commands): add description field to prefix commands #11 (#13) * Command authorizations and scopes (#15) * feat(types): Add CommandAuthorization & CommandScope #12 * feat(types): add CommandRequirements, CommandValidation and permission types #12 * feat(lib): add command requirements checker #12 * feat(lib): add error container builder and permission error messages #12 * feat(components): add ephemeral option to Container.build() #12 * fix(client): wrap event listeners to handle async execute #12 * fix(handlers): remove unused imports #12 * feat(events): check command requirements before execution #12 * chore(config): add MAIN_GUILD_ID, OWNER_ID and PRIVILEGED_IDS to env.example #12 * Fix name #12 * Add scope deployment for slash commands #16 (#18) * Update package.json version to v0.2.0 * build: resolve path aliases with tsc-alias for production build * feat(lib): add parseDuration function #3 * feat(db): set up Prisma with SQLite and Reminder model * Add sqlite support #3 * feat(lib): add branded time types and msToUnixSeconds #3 * feat(lib): add prisma client with better-sqlite3 adapter #3 * chore(config): ignore prisma.config.ts in eslint #3 * feat(reminders): add reminder service and messages #3 * refactor(lib): centralize environment access with fail-fast requireEnv * refactor(components): add barrel and remove unused Footer, RawComponent and render * refactor(lib): replace branded time types with plain millisecond helpers * refactor(lang): unify user-facing text under a single lang namespace * refactor(permissions): separate execution context from required scope * refactor(commands): consume lang and component barrels in ping * feat(events): report unexpected command errors to the user * chore: remove redundant file comments * feat(reminders): create, schedule, present and rehydrate reminders #3 * feat(reminders): add /remind and !remind commands #3 * refactor(permissions): modularize command types and permission engine * refactor: adopt satisfies and command type-module import paths * feat(components): add Section, Button, ActionRow and Title sizes * feat(reminders): limit to 5 per user and add list and cancel buttons #3 * feat(reminder): Reminder limit for priviliged user #3 * Update package.json * Botinfo command (#25) * Add NOTICE #24 * feat(about): expose bot version, license and source URL via env #23 * feat(about): add /about command #23 * feat(components): update component lib to support more md syntax * feat(commands): Update label description for a more descriptive name * feat(lang): add command about texts and update texts using md syntax to delete hardcoded md syntax * feat(lib): add md support for texts * feat(presentations): move reminder-presentation to the new src/services/presentation which builds the reply to user + add about-presentation * feat(reminder): (not relative to this branch but was done) change reminder limit * chore(pnpm-lock.yaml): apply format * feat(about): add /about and finish about-presentation service #23 * Grade command (#30) * refacto(lang): refacto commands texts to be englobed into lang.commands * Add grade prefix command #28 * feat(commands): end of grade command #28 * feat(commands): grade slash command #28 * refacto: apply format and refacto lang const * refactp: lang + format * apply prettier * Collector and interaction upgrade (#31) * refactor: migrate reminder collectors to InteractiveMessage and extract core/ Replace the manual collector boilerplate in reminder-cancel/reminder-list with the generic Collector/InteractiveMessage primitives, simplify the delete/cancel button ids now that authorization is handled by allowedIds, and extract a discord.js-free core/ layer (config, time, permissions, persistence) per the architecture refactor plan. * refactor: split reminder-service into core/reminders and discord bridge Extract pure reminder logic (repository, validation, scheduler) into core/reminders/, which has no discord.js dependency. The scheduler now triggers via a generic onTrigger callback instead of holding a Client. Add discord/reminders/reminder-bridge.ts as the Client-aware layer that wires the scheduler to message delivery and exposes the same API previously provided by services/reminder-service.ts. * refactor: move Discord-facing code under discord/ Relocate components, lang, presentations, commands, events, client, handlers, registries, interactions, and Discord-only types (SlashCommand, PrefixCommand, Event) under src/discord/, completing the core/discord split apart from the shared logger (next step). * refactor: move logger to shared/ Complete the core/discord split by relocating the cross-layer logger to src/shared/, the only module used by both core/ and discord/. * Collector must always precise their alloweds users * feat: add Select component and CustomId helper Add Select to the Components V2 DSL, wrapping itself in its own ActionRow as required by Discord (a select occupies a full row). Add CustomId<C>, a small build/parse helper that encodes a context and an id into a single customId string, and migrate the reminder delete/cancel button ids onto it to remove duplicated prefix logic. * Help command & refactor lang + add selectMenu component (#32) * refactor(lang): rename reminder lang module to remind/reminders Splits the reminder lang content into separate remind and reminders modules, following the one-module-per-command convention, and aligns about/grade lang modules to use the messages namespace consistently. Also centralizes the command prefix into a shared discord/constants.ts constant and switches it from `!` to `c!`, and makes interaction collectors reply ephemerally with an error when a non-allowed user interacts instead of silently failing. * feat(help): add /help command (#27) Adds a /help and !help command that shows a select menu listing every registered command and, once one is picked, its description, usage and aliases. Introduces a mandatory CommandHelp field (usageSlash/usagePrefix) on every command and a CommandLang type to enforce the lang module shape required to power the help display. * feat(help): add main menu #27 * Fix error display + up the limit for classic user # 29 (#33) * Add JSdoc (thanks to A.I for this one) #22 (#34) * Maintenance command (#36) * feat(maintenance): add maintenance mode & maintenance command #35 * Command help display only authorized commands for the user * Update version
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.
No description provided.