跳到內容

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 Full Install setup moduleadding-setup-module.md
Add a localeadding-locale/
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
Add an environment variableadding-env-variable.md
Add or move docs pagesdocs-authoring.md
Localize the docs site or READMEsdocs-site-localization.md
Write or review code commentscomment-policy.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 lint applies fixes in place, so it can leave your working tree changed after it reports success. Commit whatever it rewrites: CI runs bun run lint:ci, which is the same Biome check without --fix, and that one fails on formatting instead of silently correcting it.

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.

To run selected regression files through the same disposable-database harness, pass their paths to the test script:

Terminal window
bun run test tests/regression/db/llm.regression.test.ts

bun run vl runs the whole check suite and prints one verdict per gate, so it is the fastest way to answer “is this branch green” without remembering each script name:

Terminal window
bun run vl

Its last line is machine readable, which matters when a wrapper or an agent reads the result rather than a person:

vl-status: PASS exit=0 pass=<n> warn=<n> fail=<n> skip=<n>

Output is quiet by default. No flag means quiet; --verbose is opt-in. A gate that passes prints nothing, and its row in the results block carries the verdict. A gate that fails always prints its full detail, so quiet mode can never hide a finding; it only removes the passing noise around one. Advisory detail, such as locale parity or the lockfile-wide bun audit listing, collapses to a count or to the entries that changed the verdict.

Pass --verbose to restore every line each gate would otherwise print:

Terminal window
bun run vl --verbose

--no-verbose is the explicit spelling of the default rather than a mode of its own: it produces the same output as passing nothing. It exists so vl can force quiet onto the checks it invokes, and it wins over --verbose regardless of the order the two appear in. It is never required.

Individual gates accept both flags, and vl forwards one to them. Redirect the output to a file if you want to keep the exit code while reading selectively, and never pipe a gate through grep or tail: the pipeline reports the filter’s exit status instead of the gate’s.

Terminal window
bun run vl > /tmp/vl.log 2>&1; echo "VL_EXIT=$?" >> /tmp/vl.log

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.
  • Write comments that explain rationale, constraints, or non-obvious behavior. See the comment policy.
  • 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. See adding-env-variable.md for the tier system and placement conventions.

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/en/architecture/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.