* feat: add Slack channel skill (/add-slack) Slack Bot integration via @slack/bolt with Socket Mode. Can replace WhatsApp entirely (SLACK_ONLY=true) or run alongside it. - SlackChannel implementing Channel interface (46 unit tests) - Socket Mode connection (no public URL needed) - @mention translation (Slack <@UBOTID> → TRIGGER_PATTERN) - Message splitting at 4000-char Slack API limit - Thread flattening (threaded replies delivered as channel messages) - User name resolution with caching - Outgoing message queue with flush-on-reconnect - Channel metadata sync with pagination - Proper Bolt types (GenericMessageEvent | BotMessageEvent) - Multi-channel orchestrator changes (conditional channel creation) - Setup guide (SLACK_SETUP.md) and known limitations documented Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * local settings * adjusted when installing --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1.2 KiB
1.2 KiB
Intent: src/config.ts modifications
What changed
Added SLACK_ONLY configuration export for Slack channel support.
Key sections
- readEnvFile call: Must include
SLACK_ONLYin the keys array. NanoClaw does NOT load.envintoprocess.env— all.envvalues must be explicitly requested viareadEnvFile(). - SLACK_ONLY: Boolean flag from
process.envorenvConfig, whentruedisables WhatsApp channel creation - Note: SLACK_BOT_TOKEN and SLACK_APP_TOKEN are NOT read here. They are read directly by SlackChannel via
readEnvFile()inslack.tsto keep secrets off the config module entirely (same pattern as ANTHROPIC_API_KEY in container-runner.ts).
Invariants
- All existing config exports remain unchanged
- New Slack key is added to the
readEnvFilecall alongside existing keys - New export is appended at the end of the file
- No existing behavior is modified — Slack config is additive only
- Both
process.envandenvConfigare checked (same pattern asASSISTANT_NAME)
Must-keep
- All existing exports (
ASSISTANT_NAME,POLL_INTERVAL,TRIGGER_PATTERN, etc.) - The
readEnvFilepattern — ALL config read from.envmust go through this function - The
escapeRegexhelper andTRIGGER_PATTERNconstruction