.env is the single source of truth. It is loaded automatically at startup
(process.loadEnvFile), is gitignored, and is validated at boot. A missing or
invalid required value fails fast with an actionable error.
Start from .env.example and set the required values. Everything else has a
working default:
Variables
DEFAULT_MODEL, DEFAULT_AGENT, and APPROVAL_MODE are seeded into the
settings table on the first boot only. Once a value exists there, it is
authoritative and re-reading .env will not overwrite it.Multiple guilds
Celly deploys its command set to every guild inDISCORD_GUILD_IDS and runs
boot subscribe and thread reconcile across all of them. At startup each
configured guild is fetched; a guild the bot cannot see (for example, it was
never invited) is skipped with a warning. Startup fails only when no
configured guild is reachable, or when the bot token itself is invalid. A
single guild failing command deployment does not abort startup.
Config.guildId remains available as guildIds[0] for code paths that still
expect one guild.
Access control is global:
ACCESS_ROLE_ID, BLOCK_ROLE_ID, and
OWNER_ROLE_ID apply to every configured guild. Role IDs only match in the
guild that owns them, and each guild’s owner (or a member with Manage Guild /
Administrator) is always allowed in that guild. Per-guild role configuration
is not supported in this version.SESSION_BUDGET_USD is the global seed. /budget set <usd> stores
budget_usd:<channelId> in the settings table; that value wins for the
channel, and /budget set 0 disables the budget for it.
PROJECTS_ROOT and path containment
PROJECTS_ROOT is the only directory Celly will mount. A project’s host
directory must resolve (realpath, case-insensitive) to a path inside
PROJECTS_ROOT. Anything outside is rejected before a sandbox is created.
On top of containment, a sensitive-path denylist rejects any project directory
that overlaps:
- The bot repository itself (
process.cwd()). DATA_DIR.- Under the user profile:
.ssh,.aws,.gnupg,.config,.docker,.kube,.azure,.npmrc,.netrc,.celly, andAppData. - System directories (
C:\Windows,System32,Program Files,ProgramData, or/etc,/usr,/bin,/sbin,/var,/opt,/System,/Libraryon POSIX).
PROJECTS_ROOT or of any denied path. PROJECTS_ROOT is intentionally not
runtime-editable; changing it means editing .env and restarting.
DATA_DIR
DATA_DIR holds the SQLite database (bot.db), the rotating log
(bot.log), per-project server logs (logs/<sandbox>.log), and the
single-instance lock. It is gitignored and created on boot.
Idle auto-stop
WithIDLE_STOP_MINUTES greater than 0 (default 30), Celly stops a
project’s sandbox after that many minutes without message, prompt, or !shell
activity. Projects with a run in flight and projects still provisioning are
skipped. Celly posts a plain notice in the project channel; the next message
wakes the project again. Set IDLE_STOP_MINUTES=0 to keep every started
project running.
Admin page, backups, and log rotation
ADMIN_PORT starts a loopback-only HTTP status page and JSON API on
127.0.0.1. It has no authentication; reach it locally or through an SSH
tunnel, never through a public interface.
Backups run every BACKUP_INTERVAL_HOURS hours into DATA_DIR/backups and keep
BACKUP_KEEP files. Logs rotate at LOG_MAX_BYTES and keep LOG_MAX_FILES
numbered copies.