# Repository Guidelines ## Project Structure NOVA is a TypeScript Telegram AI bot. Two source files hold everything: - `index.ts` — entry point, calls `startNova()` from `src/bot.ts` - `src/bot.ts` — ~7000 lines, single file containing all bot logic (Telegram polling, Gemini tool calling, session management, admin commands, image gen, voice, reminders, PDF, web apps, scheduler) - `src/kv.ts` — `SqliteKV` class implementing a Cloudflare-KV-style interface over `better-sqlite3` (`kv_store` table with optional TTL) - `nova.db` — runtime SQLite database (gitignored; `/data/nova.db` inside Docker) There is no build step. `tsx` runs TypeScript directly. ## Commands ```bash npm install # install deps npm run dev # tsx watch index.ts — auto-restart on change npm start # tsx index.ts — production long-polling npm run type-check # tsc --noEmit — required validation before submitting docker compose up -d # container with restart policy, healthcheck, persistent nova-data volume ``` There is no test framework. `npm run type-check` is the only automated check. ## Architecture Notes - **Update mode**: Telegram Bot API long polling via `getUpdates`. No webhooks. - **Express server** on `PORT` (default 3000): serves `/health` endpoint and hosted web apps at `/app/:name`. - **Scheduler**: `setInterval` calls `runScheduled()` every 5 minutes for reminders, broadcasts, and cleanup. - **Session model**: `ChatSession` stored in KV under `session:`. In-memory `CacheLayer` (200 entries, 3 min TTL) wraps hot reads. - **Tool calling**: Gemini function-calling drives bot features (image gen, web search, voice, PDF, reminders, admin actions). Tool results fed back as `functionResponse` parts. - **Key rotation**: Gemini keys (`GEMINI_KEY_1..5`), ElevenLabs keys (`ELEVENLABS_KEY_1..5`), Cloudflare pairs (`CF_ID_1..3`/`CF_TOKEN_1..3`). Disabled keys tracked in KV, auto-rotated on failure. - **Rate limiting**: `TokenBucket` per user, daily limits per session type, in-memory dedup via `activeProgressMessages`. - **Bot config**: persisted in KV under `bot_config` key with runtime defaults. Editable via owner Telegram commands. - **Bot version**: `BOT_VERSION` constant at top of `src/bot.ts`. ## Coding Conventions - TypeScript `strict` mode. Two-space indent, semicolons, single quotes. - `camelCase` for functions/variables, `PascalCase` for interfaces/classes. - Sections in `bot.ts` are separated by `// SECTION:` comment banners — keep new logic in labeled sections. - Prefer typed interfaces; avoid `any` unless local and unavoidable. - State goes through `SqliteKV` (async API matching Cloudflare KV). Never read/write `nova.db` directly. ## Configuration Loaded from `.env` via `dotenv/config` (imported as first line in `bot.ts`). Required: - `TOKEN` — Telegram bot token (app exits if missing) - `BOT_OWNER_ID` — primary owner user ID (number) - `ADDITIONAL_OWNER_IDS` — comma-separated extra owner IDs Optional provider keys: `GEMINI_KEY_*`, `ELEVENLABS_KEY_*`, `CF_ID_*`/`CF_TOKEN_*`, `GOOGLE_SEARCH_API_KEY`, `GOOGLE_SEARCH_ENGINE_ID`. `DB_PATH` defaults to `./nova.db`, overridden to `/data/nova.db` in Docker. ## Security Constraints - `/eval` is permanently disabled. Never reintroduce shell access, `child_process`, runtime JS eval, or AI-triggered command execution. - Owner access is strictly via `BOT_OWNER_ID` + `ADDITIONAL_OWNER_IDS` env vars. No username-based or hidden escalation. - `.env`, API keys, bot tokens, and Cloudflare tokens are sensitive. Never log or commit them.