MasterBot is the host repo. It discovers bots under bots/<botName>/, loads each bot config and .env, and can start them either in shared host mode or as one PM2-managed worker per bot.
It also generates PM2 config for a separate optional Rust watchdog process that reads PM2 status and reports guardrail allocation.
- Loads bot configs from
bots/<botName>/index.js - Loads bot env files from
bots/<botName>/.env - Builds one Discord client per bot
- Loads shared tools from
src/functions/tools - Loads shared functions from
src/functions/handlers - Loads shared events from
src/events - Lets bots override paths, tools, functions, and events through their own config
- Generates
ecosystem.config.jsfrom thebots/folder and includes the PM2 health monitor process - Adds
masterbot-watchdogto PM2 only when the release binary exists
index.js- entrypointsrc/core/- bot discovery, client setup, loaders, and database bootstrappingsrc/worker/- single-bot worker entry used by PM2src/pm2/- PM2 client helpers, health monitor, alert sink, and allocation logicsrc/functions/- shared tools and handlerssrc/events/- shared eventsbots/<botName>/- bot-specific config, env, commands, events, and toolsecosystem.config.js- generated PM2 app listrust/masterbot-watchdog/- optional Rust watchdog binary and workspace files
botConfig.enabled === falseprevents that bot from startingbot.env.TOKENorbotConfig.tokensupplies the login tokenbot.env.CLIENT_IDorbotConfig.clientIdsupplies the slash command application idbotPaths.commandspoints at the bot command rootclient.handleCommands()is owned by the host and registers slash commands for the bot- Slash command registration is hash-gated and skips REST refreshes when the command definitions have not changed
client.lazyFunctions.<name>()loads configured lazy functions on first use and keeps the module cached after that- PM2 status readers use an in-memory cache that refreshes every few seconds instead of calling
pm2 jliston each request - Startup profiling logs timing marks for the main boot phases when a bot finishes starting
BOT_NAMEis set per PM2 worker sosrc/worker/botWorker.jscan start exactly one bot- The Rust watchdog is optional and only added to PM2 when
rust/masterbot-watchdog/target/release/masterbot-watchdogexists
npm start- rebuildsecosystem.config.jsand runspm2-runtimenpm run build:ecosystem- rebuilds the generated PM2 config without starting botsnpm run watchdog:build- builds the Rust watchdog release binarynpm run watchdog- runs the built watchdog in watch modenpm run pm2:start- rebuilds the generated PM2 config and starts PM2 in the backgroundnpm run pm2:list,npm run pm2:logs,npm run pm2:monitnode index.js- shared host mode, starts all bots in one Node process./masterbot-linux.sh- installs npm deps, builds the watchdog, regenerates PM2, and starts PM2
If you want one command to bring the stack up on Linux, use:
./masterbot-linux.shIt does this in order:
npm install --no-audit --no-fundcargo build --release --manifest-path rust/masterbot-watchdog/Cargo.tomlnpm run build:ecosystemnpm run pm2:start
The watchdog stays optional. If the release binary is not present, ecosystem generation skips the watchdog app and the rest of PM2 still works.
Run these in order when you want to verify the hybrid setup:
cargo check --manifest-path rust/masterbot-watchdog/Cargo.toml
cargo build --release --manifest-path rust/masterbot-watchdog/Cargo.toml
./rust/masterbot-watchdog/target/release/masterbot-watchdog --json
npm run build:ecosystemIf you want to exercise the watchdog against a live PM2 daemon, run:
npm run watchdogIf the release binary does not exist, npm run build:ecosystem will skip the watchdog app and keep the rest of PM2 generation working.
- PM2 here is process control and restart/memory guardrails, not a hard CPU or cgroup limiter.
- Each worker uses
instances: 1,autorestart: true, per-botNODE_OPTIONS, and per-botmax_memory_restart. - The Rust watchdog uses PM2 status as input and reports guardrail allocation for bots only. It is not a hard resource cap.
- The generated ecosystem file is only rewritten when the content changes.
- The host currently supports shared command loading, shared query helpers, startup caches, and per-bot overrides.
- Bot-specific code should stay inside the bot folder unless it is meant to be shared across every bot.