Conventions
SkillCommunicationDescribes how to structure commands, scheduled jobs, interaction handlers, logging, and user-facing messages/embeds in nypsi. Use when creating or modifying a command, a cron job in src/scheduled/jobs, an interaction/autocomplete handler, a log message, or any message sent to a user.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Conventions skill
What this skill tells your AI
The instructions your AI receives, as published by mxz7/nypsi in .agents/skills/conventions/SKILL.md and read by ahel’s review.
File names
Use kebab-case for file names.
Variable grouping
Group variable declarations by context and separate different groups with a blank line:
- Keep related user, database, cache, or inventory fetches together. Destructure
Promise.alldirectly when fetching independent values concurrently. - Keep values derived from the fetched data together in the following block.
- Keep UI construction together, such as embeds, containers, selects, and buttons, with whitespace separating it from fetched and derived data.
- Start another block when declarations serve a different purpose or lifecycle. Do not interleave fetching, domain calculations, and component construction.
- Avoid adding whitespace between declarations that form one small, cohesive operation.
User Facing Messages
Use CustomEmbed for standard messages, and ErrorEmbed for error messages. Only use content string if a mention is specifically needed.
Logging
Never await logger calls.
Format every log message as <subject>: <message>, using a stable lowercase subject. Include useful
identifying context in the message when it improves readability, and also include those values in
metadata for structured filtering. Keep large or noisy values, including error objects, in metadata.
Commands
Do not import or query Prisma directly in command files. Put database access in domain utility
functions under src/utils/functions/ and call those functions from the command.
Create a Command instance and export it as default:
import { Command } from "../models/Command.js";
const cmd = new Command("name", "description", "category")
.setAliases(["alias"])
.setRun(async (message, send, args) => { … });
export default cmd;
Commands are auto-loaded from src/commands/ at startup. See src/models/Command.ts for full API, and the codebase-structure skill for slash option/subcommand patterns.
Scheduled Jobs
Export a Job object from src/scheduled/jobs/:
export default { name: "job-name", cron: "0 * * * *", run: async (log) => { … } } satisfies Job;
Interaction Handlers
Export an InteractionHandler or AutocompleteHandler from src/interactions/. See src/types/InteractionHandler.ts and the codebase-structure skill for routing/autocomplete/button examples.
When a component interaction replaces the message state, prefer acknowledging it directly with
interaction.update(...). Avoid deferUpdate() followed by message.edit(...) unless the updated
payload cannot be prepared within Discord's acknowledgement window. When processing time is
variable, schedule deferUpdate() after 2,500 ms and use
interaction.update(data).catch(() => interaction.message.edit(data)).
Signals
- GitHub stars
- 69
- Forks
- 31
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
conventions- Source
- github.com/mxz7/nypsi