- Dashboard/login links now target the production domain `app.slinker.cc` across help/footer and test helper defaults.
- Discord and TikTok OAuth callbacks now prefer the active request host so login flows stay on the domain users opened.
- TikTok URL-prefix verification file serving was validated via the `public/` static path for production verification checks.
- YouTube feed tracking now supports per-entry owner routing (`/yts add` owner option and `!yts add ... --owner ...`).
- Added a dashboard social page for TikTok linking, posting mode selection, and draft-only test uploads.
- YouTube Shorts crosspost now enforces owner+video dedupe, channel allowlist checks, and DM status notifications.
- Enemy clan follow-ups in auto-ticket/testauto are now guarded by deterministic JS matching and only reference matched clans.
- Auto-ticket/testauto logs now fall back to applicant user IDs/tags when member resolution fails, avoiding "Unknown applicant" in known cases.
- Role Sentinel auto prompts now include authoritative enemy clan assessment context from server-side parsing.
- Removed noisy Twitch watch poll debug logs while keeping warning/error output.
- Settings repo push now debounces with configurable `SETTINGS_REPO_PUSH_DEBOUNCE_MS` (default 5000ms).
- Settings repo push queue now serializes per file and retries once on GitHub 409 conflicts with a refreshed SHA.
- Added periodic cleanup for Twitch watcher runtime maps, verify ping state, setup preset selections, and Roblox join cooldown state.
- Twitch watch runtime now clears immediately when members leave, servers are removed, or users are unwatched.
- Raid Guard now prunes stale join/message buckets so per-user anti-spam state does not grow indefinitely over time.
- Package tracking now uses Shippo instead of AfterShip.
- Carrier slug is now required when adding new package tracks (`--carrier <slug>`).
- Dashboard package add form now marks carrier as required to match Shippo API requirements.
- Added `!changelog`/`!clog` to enable, disable, check status, and manually post pending changelog updates per server.
- Changelog broadcasts now post to configured staff channel first, then mod-log fallback, with one message per version.
- Per-guild changelog stamps prevent duplicate reposts and optional auto-check runs at startup when enabled.
- Released Voice Master join-role resolution updates using mapped Verified/Member roles with explicit overwrite fallback.
- Channels pre-locked by join-role denies now unlock correctly on first toggle when no snapshot exists.
- New Voice Master channels now seed missing Verified/Member overwrites with inherited Connect state.
- Voice Master lock now resolves join roles from mapped Verified/Member roles, with explicit Allow Connect overwrite fallback.
- Lock state now detects channels pre-locked by denied join roles, and first toggle unlock opens join roles when no snapshot exists.
- New VM channels seed missing Verified/Member role overwrites with inherited Connect so lock/unlock can manage them consistently.
- Voice Master lock now denies Connect for join roles (Member/Verified) so locking actually blocks new joins.
- Staff bypass: Owner/Manager/Moderator roles remain able to Connect while a channel is locked.
- Unlock restores prior Connect overwrites for every role the lock modified.
- Fixed `/vm` slash commands to reliably respond by deferring before saving settings.
- Added optional env `SLASH_GUILD_ID`/`SLASH_COMMAND_GUILD_ID` for fast guild-only slash command registration during development.
- Added the Voice Master (VM) plugin: join a configured hub voice channel to receive a personal voice channel.
- Channel owners can lock/unlock joins and permit specific users via an in-channel control menu.
- New `/vm` slash command for setup, status, and clearing the hub configuration.
- Raid Guard dashboard now supports per-channel overrides for spam, mention, links, caps, and timeout settings.
- Join spike size and join window remain global per server while message moderation controls can be tuned by channel.
- Fixed `!sticker` capacity checks to use the current guild sticker list, so deleted stickers immediately free a slot.
- Auto-ticket enemy clan prompts now only trigger when the applicant explicitly lists a configured enemy clan.
- Applicants with no clans (or no matches) are no longer asked to leave enemy clans.
- Added a dev-only `!blacklist` command to block abusive users from running commands.
- Blacklisted users receive a generic notice without reason details.
- Color role add commands now accept multi-line batches in a single message.
- Docs updated with batch add examples for `!cr add`.
- Color role prompts now post as embeds with 5 roles per message (auto-paged).
- Added `!cr add` and `!cr remove` to create or delete color roles using hex/rgb/rgba inputs.
- New public documentation page for color role commands and embed behavior.
- Added a Done button to Role Sentinel auto-ticket prompts for applicants who prefer clicking instead of typing.
- Auto-ticket button presses now run the same checklist flow as the done/finished trigger with safety checks.
- Auto-ticket clan checks now use applicant clan lists and skip enemy-clan questions when none are configured/found.
- Added a start-game button for `!tictactoe`/`!ttt` so players can launch a new game from the channel.
- Start buttons are one-per-channel and disable after being used.
- Added `!sentinel pingmessage` to customize unlock reminder pings with {user}/{role} placeholders.
- Role Sentinel help and status responses now use paged embeds to avoid message length limits.
- Added paging buttons so long Role Sentinel output can be navigated without spam.
- Chunked Role Sentinel bonus role confirmations to avoid Discord 2000 character limits.
- Added bonus roles that are excluded from unlock pings and ticket auto-analysis role context.
- Instructed the ticket auto-approval prompt to only grant trainee roles when req level is not met.
- Prevent Twitch watch live/offline notices from double-firing when presence and Helix polling overlap.
- Skip announcement channel type conversion when the server does not support it and suppress 50086 spam.
- Added CORS headers for the stream-audio relay endpoint to allow browser uploads.
- Added @snazzah/davey so voice connections can use the DAVE protocol when required.
- Stream audio test failures now report to the mod log with error details.
- Added process-level error handlers so stream-audio test joins do not crash the bot on unhandled errors.
- Added `!streamaudio join|stop|status` to force voice follow for stream-audio tests.
- Packaged codexSearch as `@gaston1799/codexsearch` with CLI bins and npm metadata.
- Added `!streamaudio join|stop|status` to test stream-audio voice follow without a live stream.
- codexSearch now falls back to DuckDuckGo when Google search hits a bot-check.
- Added `!rps` (Rock-Paper-Scissors) with hidden button choices and public reveal.
- Added `!tictactoe channel <#channel|off>` to lock the game to a specific channel.
- Added `!tictactoe` (or `!ttt`) to play a button-based tic-tac-toe game in embeds.
- Admins can set custom X/O emojis with `!tictactoe emojis <x> <o>`.
- Auto-ticket now asks applicants to confirm leaving enemy clans before denying.
- Added `!sentinel tag` to set a clan tag for auto-ticket responses.
- Improved trainee-level approvals and action reply handling in auto-ticket flows.
- Active Checker now posts its weekly report only on Saturdays (no catch-up posts on other days).
- Added the Active Checker plugin to track weekly activity for members with selected roles.
- New `!checker add|list|clear` command to configure and manage weekly activity reports.
- Reports post to the staff channel if set, otherwise the mod log channel.
- Added `!sentinel testauto` to generate a checklist + action script for ticket automation.
- Added configurable trainee/member roles to Role Sentinel (`!sentinel trainee` / `!sentinel member`).
- Added optional ranker role support via `!sentinel ranker`.
- Auto test prompts now include applicant roles, role config, and linked main server info.
- Auto test actions now include `command` + `kick`, and `--run` executes the plan.
- Role Sentinel status output now shows trainee/member/ranker role links.
- Help text updated to include the new Role Sentinel commands.
- Role Sentinel now supports `!sentinel schema` to generate a test checklist schema for tickets using the server rules.
- `!track list` now uses paged embeds (10 users per page) with buttons, so it never hits Discord message limits.
- Roblox presence polling now chunks large userId lists (default 50 per request) to avoid upstream “Too many User Ids” 400 errors.
- Roblox presence polling now surfaces upstream status codes, backs off on failures (e.g. 429), and throttles repeated error logs.
- Animated sticker inputs (GIF/APNG) are now recompressed into a smaller APNG instead of being flattened to a static PNG during processing.
- Twitch watch polling now tracks `prev` in-memory per watched user, so live transitions are detected reliably without relying on persisted settings.
- Fixed Twitch Helix watch polling so `lastLiveState` / `lastStartedAt` persist correctly (prevents repeated “prev=false” and repeated updates).
- The `!sticker` command now checks server sticker slots before downloading/processing, and shows a clear message when the server is full.
- GIF inputs for `!sticker` are now converted into animated PNG (APNG) stickers (or fall back to static if they cannot fit under 512 KB).
- Added Tenor link resolving for `!emoji` / `!sticker`, including reply-to-message URL/emoji sources.
- Sticker processing now converts media to PNG and avoids Sharp multi-page resize errors.
- Context AI output is chunked to stay under Discord message limits.
- Ticket analyzer now uses OPENAI_API_KEY/OPENAI_KEY and the official OpenAI API base URL.
- Twitch watch alerts can now poll the Twitch API using a saved channel URL instead of relying on Discord streaming presence.
- Role Sentinel no longer explicitly grants ViewChannel to the dummy role in ticket channels; it now inherits view permissions instead.
- Added `!tt` / `!tickettest` to run DNS + OpenAI API connectivity checks and attach a full report.
- OpenAI key detection now respects OPENAI_API_KEY directly (in addition to OPENAI_KEY).
- Ticket analyzer now ignores OPENAI_API_KEY and always uses the embedded inline key.
- Ticket analyzer now always attaches transcript and image URL files (with fallback inline transcript if attachments fail).
- Added `!sentinel enemies` and `!sentinel levels <trainee> <member> [ranker]` to configure analyzer enemy clans and level thresholds.
- Ticket analyzer response now attaches the transcript and image URL list as files for easier review.
- Ticket analyzer JSON error logs now include stack/trace details for easier debugging.
- Fixed a stray variable reference that could crash the `!done` ticket analyzer.
- Settings sync now uses the GitHub contents API with fetch (no execSync) and includes guildSettings.json.
- guildSettings.json loads through BOM/UTF-16 normalization and backs up corrupt JSON without crashing.
- Settings sync now pulls guildSettings.json too and normalizes UTF-16/BOM content to UTF-8.
- Guild settings load backs up corrupt/invalid JSON instead of crashing the bot.
- Settings sync now uses GitHub contents API with auth headers (works for private repo paths like /main/devSettingsStore.js).
- Settings sync test script logs failing URLs and respects private repo access.
- On boot, syncs config/devSettings.json, devSettingsStore.js, and guildConfigStore.js from the SlinkerSettings repo using the GHPAGES_TOKEN.
- When guild/dev settings change, writes locally and pushes updates back to the SlinkerSettings repo.
- Added a dev-only dashboard form to upload and apply guildSettings.json locally (writes to disk and memory).
- Added a dev-only endpoint to upload and apply guildSettings.json via the dashboard.
- Guild settings override writes even when GUILD_SETTINGS_READONLY is enabled (dev upload only).
- Added GUILD_SETTINGS_READONLY=1 to skip writing guildSettings.json so deployments can rely on the committed file.
- Ticket analyzer now attaches a JSON error file in-channel when OpenAI calls fail.
- Version bump to capture persistence tweaks.
- Updated ticket analyzer to use the json_schema format object compatible with the Responses API.
- Ticket checklist analyzer now uses the embedded key fallback automatically when environment variables are missing.
- Removed the hard stop on missing OPENAI_API_KEY and set env to the inline value if provided.
- Ticket checklist analyzer now accepts the in-file key fallback to work around hosting env issues.
- Version bump to surface the deployment.
- Added `!done` ticket analyzer that sends transcripts + images to OpenAI and returns a checklist embed.
- Role Sentinel now includes configurable checklist defaults for titles, enemy clans, and level thresholds.
- OpenAI API key fallback from OPENAI_KEY now populates OPENAI_API_KEY automatically.
- Fixed GitHub Pages join links to respect custom base URLs, including direct index.html paths.
- Dashboard-generated Roblox presence links now point to the correct page for your configured repo and subdirectory.
- Dashboard now includes a scheduled-tasks panel: create tasks, view the next run, and cancel them without leaving the UI.
- Developer settings page caches permanent server join links and lets you regenerate them on demand so the bot owner can invite it anywhere.
- The new changelog page (this page!) surfaces the latest entry and is linked from the header for quick awareness.