This file provides repository-wide guidance for any automated or AI-assisted contributor. Follow these conventions unless a human maintainer explicitly overrides them.
webdev-bot is a Discord bot for the Web Dev & Design server. It is a TypeScript Node.js application built with pnpm, bundled via tsup, and tested with the Node.js built-in test runner.
Branches use Conventional Commits type prefixes:
<type>/<short-description>
<type>/<issue-number>/<short-description>
Types: feat, fix, docs, refactor, test, chore, and other conventional commit types as appropriate.
Examples:
feat/add-baseline-command
feat/86/agent-file
fix/42/handle-timeout-error
docs/update-contributing-guide
Use lowercase, hyphen-separated descriptions. When work relates to an existing GitHub issue, include the issue number in the branch name.
When a change addresses an existing issue:
-
Branch — include the issue number (see above).
-
Title — include the issue number, e.g.
feat(#86): add baseline command. -
Body — include a closing keyword so GitHub links and auto-closes the issue:
Closes #86
Use Closes, Fixes, or Resolves as appropriate. One issue per PR when possible.
For changes with no related issue, omit the issue number from the branch and title.
- Do not add new npm packages unless a maintainer explicitly approves. Prefer built-in Node.js APIs and existing dependencies.
- Minimize scope — change only what is needed for the task. Avoid drive-by refactors or unrelated cleanup.
- Reuse existing patterns — read surrounding code and match its style, abstractions, and conventions before writing something new.
Code should be self-descriptive. Do not add comments that restate what the code already says.
Add a comment only when the business logic is not obvious from the code itself — for example, a non-standard algorithm, a Discord API quirk, or a constraint that would surprise a reader.
// ❌ BAD — narrates the obvious
// Get the user from the interaction
const user = interaction.user;
// ✅ GOOD — explains non-obvious business logic
// Discord allows bots to timeout members only if the bot's highest role
// is above the target member's highest role.
if (botRole.position <= targetMember.roles.highest.position) {
return;
}Always use full words for variables, parameters, and functions. Do not abbreviate.
// ❌ BAD
const msg = interaction.options.getString('query');
const cfg = getConfig();
// ✅ GOOD
const query = interaction.options.getString('query');
const configuration = getConfiguration();-
Do not use
interface. Usetypealiases instead.// ❌ BAD interface CommandOptions { name: string; description: string; } // ✅ GOOD type CommandOptions = { name: string; description: string; };
-
Do not use
enum. Use string literal unions oras constobjects instead.// ❌ BAD enum CommandStatus { Pending = 'pending', Ready = 'ready', } // ✅ GOOD type CommandStatus = 'pending' | 'ready'; // ✅ GOOD — when you need a runtime value map const CommandStatus = { Pending: 'pending', Ready: 'ready', } as const;
Root-level config files define how this project is built, linted, formatted, and run. Do not invent parallel config (no new ESLint/Prettier/Biome/Jest/Vitest configs, no duplicate tsconfig variants, no ad-hoc tooling files).
Treat these as authoritative:
| File | Purpose |
|---|---|
package.json |
Scripts, dependencies, lint-staged hooks |
pnpm-lock.yaml |
Locked dependency versions |
tsconfig.json |
TypeScript compiler options |
tsup.config.ts |
Build/bundle configuration |
oxlint.config.ts |
Linter rules |
oxfmt.config.ts |
Formatter rules |
docker-compose.yml |
Local Docker services |
Dockerfile |
Container image |
.nvmrc |
Node.js version |
.gitignore |
Ignored paths |
.dockerignore |
Docker build exclusions |
src/env.ts |
Environment variable schema and access (do not read .env* files directly) |
If something seems missing from config, ask a maintainer rather than adding a new config file.
- Do not open, read, or reference any files matching:
.env.env.*.env*
- Treat
src/env.tsas the only allowed source of environment configuration. Use it whenever environment info is required. - If a needed value appears only in a
.env*file, stop and ask to add it tosrc/env.tsinstead of reading the.env*file.
Before considering work complete, run lint and format checks on changed code:
pnpm lint # check for lint errors
pnpm lint:fix # auto-fix lint issues where possible
pnpm fmt:check # verify formatting
pnpm fmt # apply formatting
pnpm typecheck # TypeScript type checkingCI runs lint, format check, build, and tests on every pull request. Fix any failures before submitting.
Everything that can be tested should be tested. When adding or changing code, write unit tests for the new or modified behavior.
-
Test files live alongside source code as
*.test.ts. -
Use the Node.js built-in test runner (
node:test/node:assert). -
Run tests locally:
pnpm test # run tests via tsx (development) pnpm test:ci # run compiled tests (matches CI) pnpm build # required before test:ci
Match the style of existing tests (see src/**/*.test.ts).
pnpm install # install dependencies
pnpm dev # start with hot reload
pnpm build # compile for production
pnpm start # run compiled output
pnpm deploy # deploy Discord slash commandsPackage manager is pnpm (see packageManager field in package.json). Do not use npm or yarn.
Project skills live in .agents/skills/. Each skill is a SKILL.md file with step-by-step workflow instructions. These are tool-agnostic — any agent should read and follow them when relevant.
After cloning, prepare the repository for your agent:
pnpm agent-ready claude
pnpm agent-ready cursor
pnpm agent-ready copilot
pnpm agent-ready codexPass --skills to link skills only, skipping other setup steps:
pnpm agent-ready claude --skills # .claude/skills -> .agents/skillsAgent-specific skill directories are gitignored; .agents/skills/ is the canonical source committed to the repository. Cursor and Codex also read .agents/skills/ directly — linking for those agents is optional and the script will ask for confirmation.
| Skill | Use when |
|---|---|
| create-github-issue | Creating a GitHub issue or ticket (provide a short problem or goal) |
| plan-github-issue | Planning work from a GitHub issue (provide issue number or URL) |
- Read existing code in the area you are changing before writing new code.
- Prefer small, focused diffs over large rewrites.
- Do not commit secrets, credentials, or
.envfiles. - Do not create git commits or open pull requests unless explicitly asked by the human working with you.
- When unsure about a convention, check existing branches, pull requests, and config files before guessing.