Skip to content

Add prefix command support with !ping#9

Merged
Ntalcme merged 1 commit into
developfrom
add-prefix-support
Jun 6, 2026
Merged

Add prefix command support with !ping#9
Ntalcme merged 1 commit into
developfrom
add-prefix-support

Conversation

@Ntalcme

@Ntalcme Ntalcme commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Ntalcme Ntalcme added this to the v0.2.0 milestone Jun 6, 2026
@Ntalcme Ntalcme self-assigned this Jun 6, 2026
@Ntalcme Ntalcme added feature New feature or request priority: medium Should do soon labels Jun 6, 2026
@Ntalcme Ntalcme linked an issue Jun 6, 2026 that may be closed by this pull request
6 tasks
@Ntalcme Ntalcme marked this pull request as ready for review June 6, 2026 00:54
Copilot AI review requested due to automatic review settings June 6, 2026 00:54
@Ntalcme Ntalcme merged commit 09eaaea into develop Jun 6, 2026
1 check passed
@Ntalcme Ntalcme deleted the add-prefix-support branch June 6, 2026 00:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial support for prefix-based commands (e.g. !ping) alongside the existing slash-command system by introducing a prefix command registry/loader, a messageCreate router, and a first prefix ping command.

Changes:

  • Introduces a prefix command registry + loader and wires it into the client startup.
  • Adds a messageCreate event handler that dispatches !-prefixed commands from messages.
  • Implements a prefix ping command and extends ping i18n strings to support a “calculating…” response.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/registries/prefix-registry.ts Adds a shared Map registry for prefix commands (name + aliases).
src/lang/ping.ts Adds a new calculating message used by prefix ping replies.
src/handlers/slash-handler.ts Introduces a dedicated slash-command loader using the shared module loader.
src/handlers/prefix-handler.ts Adds a prefix-command loader + type guard and populates the prefix registry (including aliases).
src/events/message-create.ts Adds MessageCreate routing for ! prefix commands.
src/deploy-commands.ts Updates deploy script to import the new slash-command loader.
src/commands/prefix/ping.ts Adds a !ping prefix command implementation using existing component rendering.
src/client/crownutils-client.ts Enables message intents required for prefix commands and loads prefix commands at startup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import { Separator } from '@/lib/components/separator.js';
import { Text } from '@/lib/components/text.js';
import { Title } from '@/lib/components/title.js';
import { PrefixCommand } from '@/types/command.js';
Comment on lines +13 to +18
const before = Date.now();
const sent = await message.reply(
render(new Text(pingMessages.calculating)),
);
const totalLatency = sent.createdTimestamp - before;
const discordLatency = Math.round(message.client.ws.ping);
@@ -0,0 +1,36 @@
import { loadModules } from '@/handlers/base-loader.js';
Comment on lines +15 to +19
if (typeof candidate.execute !== 'function') {
return false;
}

return true;
Comment on lines +29 to +34
prefixCommands.set(command.name, command);
if (command.aliases) {
for (const alias of command.aliases) {
prefixCommands.set(alias, command);
}
}
Comment on lines +64 to +67
private async loadPrefixCommands(): Promise<void> {
await loadPrefixCommands();
logger.info(`Loaded ${prefixCommands.size} prefix command(s).`);
}
Comment on lines +16 to +20
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
Ntalcme added a commit that referenced this pull request Jun 6, 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
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request priority: medium Should do soon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add prefix command support

2 participants