Skip to content

Development Tasks

Quick navigation for common TomoriBot implementation tasks and coding conventions.

Each guide below is self-contained with steps, notes, and a quality gate.

TaskGuide
Add a slash commandadding-slash-command.md
Add an event handleradding-event-handler.md
Add a built-in tooladding-builtin-tool.md
Add a DB columnadding-db-column.md
Add a localeadding-locale.md
Add a new AI provideradding-new-provider.md
Add a feature flag-controlled tooladding-feature-flag-tool.md
Add a persona presetadding-persona-preset.md

Run these before merging any change:

Terminal window
bun run check # TypeScript strict mode
bun run lint # Biome lint/format
bun run check-locales # locale key parity (when locale keys or command metadata changed)
bun run db:lifecycle # schema lifecycle test (when schema.sql changed; needs local PostgreSQL)

bun run db:lifecycle requires a local disposable PostgreSQL target with CREATE/DROP database permission. It creates and drops its own temporary database, then tests fresh initialization plus backup/restore and DB maintenance scripts.


These rules apply to all TomoriBot source code regardless of task type.

  • Use 2 spaces for indentation (Biome project setting).
  • Use double quotes for strings.
  • Run bun run lint after edits.
  • Keep TypeScript strict; avoid any.
  • Prefer explicit shared types under src/types/.
  • Use Zod/runtime validation for untrusted external input.
  • Add concise JSDoc for exported/public functions when behavior is non-obvious.
  • Use camelCase file names.
  • Use @/* path aliases for src/* imports.
  • Use node: protocol for Node built-ins (node:path, node:fs, etc.).
  • Do not hardcode operational limits/timeouts/thresholds in feature logic.
  • Use env vars with fallback defaults:
const VALUE = Number.parseInt(process.env.CONFIG_VAR || "10", 10);
  • Add required setup vars to .env.example and optional/tuning vars to .env.optional.example, each with a clear comment.
  • Use Bun SQL template literals for queries.
  • Keep schema migrations idempotent (IF NOT EXISTS, helper functions, guarded blocks).
  • For DB model details, see docs/subsystems/database-schema.md.

When a write affects cached reads:

  1. Perform the DB write successfully.
  2. Then invalidate affected cache key(s).

Do not invalidate before failed writes, and do not manually mutate cached objects. See docs/subsystems/caching.md for the cache map and invalidation APIs.

  • Use log from src/utils/misc/logger.ts.
  • Include useful context metadata (errorType, IDs, action context).
  • Treat startup-critical failures differently from recoverable runtime failures.
  • Slash commands only (no legacy prefix command surface).
  • All user-facing text must be localized via localizer().
  • Follow interaction timing patterns in docs/subsystems/command-system.md.