All notable changes to this project will be documented in this file.
- Upstream
OPENCODE_SERVER_PASSWORDsupport (PR #50, closes #39): WhenOPENCODE_SERVER_PASSWORD(and optionallyOPENCODE_SERVER_USERNAME) is set in the bot's environment, the credentials are automatically forwarded as HTTP Basic auth on every internal request to the localopencode serveprocess: session HTTP calls, the SSE/eventstream, and readiness probes. Behavior is unchanged when the env vars are not set. Misconfigured credentials surface a clear actionable error instead of a vague connection failure. This is optional hardening / compatibility with upstream opencode auth, not a replacement for the Discord allowlist. /autocodecommand (PR #54): Added a per-project toggle that automatically enables passthrough mode for new/workand/opencodethreads, so plain messages are sent to OpenCode without needing/codefirst.
- Optional
/workdescription (PR #56):/workcan now be run without a description. When omitted or blank, the branch name is used as the default thread description. - Thread channel access docs (PR #52): Clarified Discord channel access requirements for threads in the README.
remote-opencode undeployCLI Command (PR #48): Added a new CLI command to remove the bot's slash commands from the configured Discord guild. This makes it easier to cleanly unregister commands during teardown, testing, or bot reconfiguration.
- Proxy Support: HTTP proxy environments are now supported for Discord and other external API requests via
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY, andNO_PROXYenvironment variables. Localopencode servetraffic onlocalhost,127.0.0.1, and::1is automatically excluded from proxying.
- Shell Spawn Removed (PR #42): OpenCode is now launched directly instead of through a shell, fixing service-environment failures. Session recovery consolidated so stale runtime sessions are recreated without resetting stored thread metadata.
- Silent Error Swallowing (PR #36, closes #32): Errors in
updateStreamMessage(Discord message edits) were silently caught, causing AI responses to appear lost while "Done" still displayed. All edit failures now fall back to sending new messages, ensuring users always see output or error details. - Model Provider Prefix (PR #35):
/model setno longer strips the provider prefix (e.g.,opencode/minimax-m2.5-free), which previously caused "Model not found" errors. Carriage returns (\r) in model names are now sanitized consistently across storage and prompt submission. - Duplicate README Content (PR #41): Removed duplicate lines in the README.
- Mermaid Diagram: Replaced the ASCII "How It Works" diagram with a Mermaid flowchart for better rendering on GitHub.
/sessionCommand: Browse and manage OpenCode CLI sessions directly from Discord.list: View all sessions for the current project — merges active server sessions with persisted thread mappings, showing title, session ID, mapped thread, and last-used time.attach: Attach an existing CLI session to the current thread via an interactive dropdown menu. Automatically setsfreshContext: falseto preserve conversation continuity.detach: Disconnect the current session from the thread, cleaning up SSE connections.info: Display detailed session status in a rich embed — session ID, project path, port, alive/dead status, creation time, last used time, and SSE connection state.
- Model Autocomplete:
/model setnow provides real-time autocomplete suggestions as you type, powered by a background-cached model list (30s TTL with async refresh). - Model Cache Pre-warming: The bot pre-loads the model list on startup so the first
/model setautocomplete is instant — no cold-start timeout. - Autocomplete Handler: Added generic autocomplete infrastructure to
interactionHandler.ts— commands can now export anautocompletemethod.
/model listFull Display: Removed the 10-model-per-provider cap. All models are now shown, with automatic message splitting when output exceeds Discord's 2000-character limit.- Model Validation:
/model setnow validates against a fast in-memory cache instead of a blockingexecSynccall, eliminating interaction timeouts on slow systems.
- Autocomplete Timeout: Prevented Discord autocomplete interaction crashes on cold cache by falling back to an empty response when models haven't loaded yet.
- Async Cache Refresh: Model cache now refreshes asynchronously in the background, preventing the 3-second autocomplete deadline from being exceeded on stale cache.
- Session Continuity: Changed
freshContextdefault fromtruetofalseso that conversations within the same Discord thread preserve context by default. Previously, each new message started a fresh session, losing conversation history. Users can still opt into fresh context per thread via/queue settings fresh_context:True. (Closes #27)
- Voice Message Transcription (STT): Automatically transcribe Discord voice messages to text using OpenAI Whisper API.
- Send voice messages in
/codepassthrough threads — they are transcribed and processed identically to typed text. - 🎙️ reaction indicates transcription in progress; removed on completion.
- Voice messages sent while the bot is busy are queued with attachment metadata — STT is deferred until the queue processes them.
- CLI commands:
remote-opencode voice set <apiKey>,voice remove,voice statusfor managing the OpenAI API key. - Discord
/voicecommand:removeandstatussubcommands (API key setting is CLI-only for security). - Setup wizard integration: Optional step to configure OpenAI API key during
remote-opencode setup. - API key resolution:
OPENAI_API_KEYenvironment variable takes priority overconfig.json. - Graceful degradation — voice messages are silently ignored when no API key is configured.
- Timeout protection: 30s for Discord CDN download, 60s for Whisper API transcription.
- File size validation: rejects files exceeding Whisper's 25MB limit before download.
- Send voice messages in
- Queue system:
QueuedMessageinterface extended withvoiceAttachmentUrlandvoiceAttachmentSizefields to support deferred voice transcription. - Message handler: Refactored to check busy state before STT, with error-tolerant reaction helpers (
safeReact,safeRemoveReaction).
/diffCommand: View git diffs directly from Discord — ideal for reviewing AI-made changes on mobile.targetoption:unstaged(default),staged, orbranchstatoption: show--statsummary only instead of full diffbaseoption: specify base branch fortarget:branchdiffs (default:main)- Inside a worktree thread → diffs the worktree path for that branch
- In a regular channel → diffs the channel-bound project path
- Output formatted in a
diffcode block; automatically truncated at Discord's 2000-char limit
- Access Control (Allowlist): Restrict bot usage to specific Discord users via a user ID allowlist.
- Setup wizard (Step 5): Optionally set a bot owner during initial setup.
- CLI commands:
remote-opencode allow add <userId>,remove <userId>,list, andresetfor managing the allowlist from the terminal. - Discord
/allowcommand: Authorized users can manage the allowlist directly from Discord (/allow add,/allow remove,/allow list) — only available when at least one user is already on the allowlist. - Auth guards: All Discord interactions (slash commands, buttons, passthrough messages) are checked against the allowlist.
- Unauthorized users receive an ephemeral "not authorized" message; passthrough messages are silently ignored.
- Empty allowlist = unrestricted mode (backward compatible — all server members can use the bot).
- Cannot remove the last allowed user via Discord (prevents lockout).
- Initial allowlist setup must be done via the CLI (
remote-opencode allow add) or the setup wizard (remote-opencode setup). The Discord/allowcommand is intentionally disabled when the allowlist is empty to prevent unauthorized users from bootstrapping access. - Config directory (
~/.remote-opencode/) is created with0700permissions (owner-only access). - Config file (
config.json) is written with0600permissions (owner read/write only). - CLI
allow addvalidates Discord snowflake format (17-20 digits).
- Context Header: All execution messages now display the current branch name and AI model at the top (e.g.
🌿 feature/dark-mode · 🤖 claude-sonnet-4-20250514). getCurrentBranch()utility inworktreeManagerto resolve the active git branch viagit rev-parse --abbrev-ref HEAD.buildContextHeader()formatter inmessageFormatterfor consistent header rendering.
- Replaced inline
(Model: ...)suffix with a dedicated context header line across all 7 message states (Starting, Waiting, Sending, Running, Done, Error-SSE, Error-catch).
- Automated Message Queuing: Added a new system to queue multiple prompts in a thread. If the bot is busy, new messages are automatically queued and processed sequentially.
- Fresh Context Mode: Each queued job can optionally start with a fresh AI conversation context (new session) while maintaining the same code state.
- Queue Management: New
/queueslash command suite to list, clear, pause, resume, and configure queue settings. - Queue Settings:
continue_on_failure: Toggle whether the queue stops or continues when a job encounters an error.fresh_context: Toggle between persistent conversation memory and fresh starts per job.
- Visual Feedback: The bot now reacts with
📥when a message is successfully queued via chat.
- Refactored Execution Logic: Moved core prompt execution to a dedicated
executionServicefor better reliability and code reuse. - Hardened Server Binding: Reverted
opencode serveto use default127.0.0.1binding (previously0.0.0.0) and updated port availability checks to match, preventing local network exposure.
- Model confirmation in Discord messages: The bot now displays which model is being used when starting a session.
- Real-time logging: Added always-on logging for
opencode servestartup commands, working directories, and process output (stdout/stderr) for easier debugging.
- Fixed
opencode servestartup failures: The bot now correctly detects when the server fails to start immediately and reports the actual error message to Discord instead of timing out after 30 seconds. - Resolved
--modelflag error: Moved model selection from theopencode servecommand (where it was unsupported) to the prompt API. - Fixed Model API format: Correctly formatted model identifiers as objects (
{ providerID, modelID }) as required by the OpenCode API. - Improved Port Management: Fixed port availability checks to bind to
0.0.0.0(matching the server) and added checks for orphaned servers to prevent "Address already in use" errors. - Fixed button handlers (Interrupt, Create PR) to correctly respect channel model preferences.
- Fixed instance key logic to include the model, allowing multiple models to be used for the same project in different channels.
- New
/setportsslash command to configure the port range for OpenCode server instances.
- Fixed Windows-specific spawning issue where the bot failed to find the
opencodecommand (now targetingopencode.cmd). - Resolved
spawn EINVALerrors on Windows by correctly configuring shell execution. - Fixed a crash where the bot would attempt to pass an unsupported
--modelflag toopencode serve. - Improved server reliability by extending the ready-check timeout to 30 seconds.
- Suppressed
DEP0190security warnings in the terminal caused by Windows-specific shell execution requirements. - Standardized internal communication to use
127.0.0.1and added real-time process logging (available viaDEBUGenv var).
- New
/modelslash command to list and set AI models per channel. - Support for
--modelflag in OpenCode server instances. - Persistent storage for channel-specific model preferences.
- Fixed a connection timeout issue where the bot failed to connect to the internal
opencode serveprocess. - Added
--hostname 0.0.0.0to theopencode servecommand to ensure the service is reachable. - Standardized internal communication to use
127.0.0.1instead oflocalhostto avoid IPv6 resolution conflicts on some systems. - Improved process exit handling in
serveManagerto ensure cleaner state management. - Fixed
DiscordAPIError[40060](Interaction already acknowledged) by adding safety checks and better error handling ininteractionHandler.ts. - Resolved a
TypeErrorinopencode.tsby adding safety checks for stream message updates. - Updated all interaction responses to use
MessageFlags.Ephemeralinstead of the deprecatedephemeralproperty to resolve terminal warnings.