You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
A /reload that reloads config files like opencode.jsonc of global and project level and also .opencode/ this way without having to close and open the tui just able to reload easily could be even better done when a /compact is runnning
GitHub Issue #6719 requests a /reload slash command that reloads the entire config (both global and project-level opencode.jsonc files and the .opencode/ directory) without having to restart the TUI.
Current Architecture
The codebase already has the core reload mechanism in place:
Worker-side reload (packages/opencode/src/cli/cmd/tui/worker.ts line 133-136):
Config lazy loading (Config.global uses lazy() which can be .reset() to force re-evaluation)
Instance state disposal (Instance.disposeAll() clears all cached instance state, forcing Config, Commands, Agents, MCP, etc. to reload)
Slash commands are registered via command.register() in the TUI with a slash: { name, aliases } property
What's Missing
Currently, there's no way for users to trigger a reload from within the TUI - the only way is to send a SIGUSR2 signal from outside. The feature request asks for a /reload slash command exposed to users.
Implementation Plan
Approach A: TUI-Only Implementation (Simpler)
Since the worker already has an RPC reload() method, and the TUI already uses RPC for other operations, we can add a /reload slash command that calls the worker's reload method directly.
Files to Modify:
packages/opencode/src/cli/cmd/tui/app.tsx
Add a new command registration for /reload
The command would:
Call worker's reload via RPC (through SDK or direct worker call)
Wait for reload to complete
Trigger a sync refresh to reload all data from the server
Show a toast notification confirming reload
Potentially expose RPC reload to TUI context
The thread.ts sets up the RPC client, but it's not directly accessible in the TUI components
May need to pass a reload function through context or add an SDK endpoint
Key Decision Point:
The current architecture uses SDK (HTTP) for most TUI<->Server communication, but reload is only exposed via direct RPC. We have two sub-options:
A1. Add reload to SDK/Server API (Recommended)
Add a POST /config/reload endpoint to ConfigRoutes
Update SDK generation
Call via SDK in TUI
A2. Pass RPC reload through context
Modify the TUI provider chain to pass a reload callback
More invasive changes to the component tree
Recommended Approach: A1 (Add Server Endpoint)
This follows the existing patterns and is cleaner.
Implementation Steps:
Add Server Endpoint (packages/opencode/src/server/routes/config.ts)
.post("/reload",describeRoute({summary: "Reload configuration",description: "Reload all configuration files...",operationId: "config.reload",responses: {200: ... },}),async(c)=>{Config.global.reset()awaitInstance.dispose()// Just current instance, not allreturnc.json({success: true})},)
Are there any potential unintended side-effects or configuration files that get loaded on startup but we're missing in this approach? Please thoroughly check the codebase for all file read operations again.
Are there any code paths that rely on configuration being available at startup, or modules that run only once after configuration loading has concluded? We must ensure that all configurations are properly reloaded.
2. Global lazy values (reset via Config.global.reset())
These use lazy() directly (not Instance.state) and are reset by Config.global.reset():
Module
Purpose
Config.global
Global config file (~/.config/opencode/opencode.json)
Shell.preferred
Preferred shell detection
Shell.acceptable
Acceptable shells list
Server.App
Hono app instance (routes)
Various route modules
Lazy route definitions
3. Bootstrap functions (one-time init)
The InstanceBootstrap() function in packages/opencode/src/project/bootstrap.ts runs once per instance creation:
exportasyncfunctionInstanceBootstrap(){awaitPlugin.init()Share.init()ShareNext.init()Format.init()awaitLSP.init()FileWatcher.init()File.init()Vcs.init()// Also sets up Bus subscription for Command.Event.Executed}
These init() functions typically just call the state accessor to trigger lazy initialization, so they'll work correctly on reload since the state is disposed first.
4. Potential gotchas for reload
Things that should work:
Config changes (global + project level)
MCP server changes (has proper dispose/reconnect)
Agent definitions
Command/skill changes in .opencode/
Provider configuration
Things to verify:
Event stream: The worker's event stream (startEventStream) uses a fixed directory parameter set at startup. After Instance.dispose(), the same event stream continues - may need to restart it with the new instance context.
LSP connections: LSP servers get closed on dispose but may need manual restart notification
Active sessions: If a session is running when reload happens, it could cause issues since the agent/model config may change mid-conversation
Recommendation
The existing rpc.reload() implementation looks solid:
This completely disposes all instances, which triggers the State.dispose() mechanism that clears all cached state, including plugins.
Answer: Complete Shutdown & Reload (Preferred)
Plugins will be completely shut down and force-reloaded - no extra effort needed from maintainers!
Here's why this is the preferred approach:
✅ Already Implemented: The existing reload() mechanism in worker.ts calls Instance.disposeAll(), which:
Clears all state caches via State.dispose()
Deletes the instance cache in Instance.ts
Triggers cleanup of all plugin state
✅ Clean Slate: When the next request comes in after reload:
Instance.provide() creates a fresh instance
Plugins are re-imported and re-initialized from scratch
All hooks and event subscriptions are recreated
Config files (global & project) are re-read
✅ No Plugin Developer Burden:
Plugin authors don't need to implement special reload hooks
The plugin interface stays simple - just return hooks from an async function
State management is handled by OpenCode's instance lifecycle
How It Works
User runs /reload
Config.global.reset() clears cached config
Instance.disposeAll() tears down all instances and their plugin state
Next operation triggers Instance.provide() which:
Reads fresh config files
Re-installs/re-imports plugins
Re-initializes all plugin hooks
Rebuilds event subscriptions
Potential Gotcha: Plugin Dependencies
One thing to watch: if plugins have external resources (database connections, file watchers, network connections), they might leak since there's no explicit disposal hook. However:
Most plugins use the SDK client or Bun shell APIs which are scoped to the instance
Event subscriptions are cleared when instances dispose
Well-behaved plugins should use instance-scoped resources
Recommendation
The current approach is solid. Plugins get completely shut down and reloaded - no custom hooks needed. This keeps the plugin API simple and guarantees a clean reload without requiring plugin maintainers to implement special lifecycle methods.
If we find specific plugins that need cleanup (rare), we could add an optional dispose hook to the plugin interface later, but it's not necessary for the /reload command to work correctly.
yo opencode, sounds good. I think we have all the infos we need. Adding a /reload plugin seems really straightforward from what we gathered, no particularly concerning edge cases. In particular, you told me that also users' custom plugins can get completely restarted automatically. Please implement it as a pull request against the dev branch. Please check the existing unit tests and see if the existing reload mechanism is already covered. If it is not, I think we best just build an integration/system test for the new /reload command using one of the existing pseudo-terminal tests as boilerplate.
yo opencode, sounds good. I think we have all the infos we need. Adding a /reload plugin seems really straightforward from what we gathered, no particularly concerning edge cases. Please implement it as a pull request against the dev branch. Please check the existing unit tests and see if the existing reload mechanism is already covered. If it is not, I think we best just build an integration/system test for the new /reload command using one of the existing pseudo-terminal tests as boilerplate.
Summary
I've implemented the /reload slash command that allows reloading configuration files without restarting the TUI.
Changes
packages/opencode/src/server/routes/config.ts - Added POST /config/reload endpoint that calls Config.global.reset() and Instance.disposeAll() to reload all configurations
packages/opencode/src/command/index.ts - Added RELOAD: "reload" to builtin commands
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx - Added special handling for /reload to call the config reload endpoint with toast notifications
packages/sdk/js/src/v2/gen/sdk.gen.ts - Added reload() method to the SDK Config class
packages/opencode/test/server/config-reload.test.ts - Added integration tests for the reload endpoint
Testing
Checked existing tests - no prior tests for the reload mechanism existed. Added integration tests for the new /config/reload endpoint that verify the endpoint exists and returns { success: true }.
I added a local profile switcher that rewrites agent model assignments in ~/.config/opencode/opencode.json (for example switching thinker/implementer/light agent groups between different models). The config file updates correctly, but the running OpenCode server keeps using the old cached models until restart.
I also tried the undocumented signal-based workaround and, in my setup, sending SIGUSR2 to the running app/server just killed it instead of giving me a usable reload flow.
A supported /reload that re-reads global/project config and invalidates cached agent/config state would make model/profile switching usable without restarting the app.
I added a local profile switcher that rewrites agent model assignments in ~/.config/opencode/opencode.json (for example switching thinker/implementer/light agent groups between different models). The config file updates correctly, but the running OpenCode server keeps using the old cached models until restart.
I also tried the undocumented signal-based workaround and, in my setup, sending SIGUSR2 to the running app/server just killed it instead of giving me a usable reload flow.
A supported /reload that re-reads global/project config and invalidates cached agent/config state would make model/profile switching usable without restarting the app.
Yeah, exactly - there are countless use cases where you wanna continue in the same instance while playing with the config
The subagent from /agents/tester.md has reached its token limit, so I'm changing the model name to continue working in the current session. How do I apply the changes? - /reload
Activity
github-actions commentedon Jan 3, 2026
This issue might be a duplicate of existing issues. Please check:
Feel free to ignore if this doesn't address your specific case about reloading all config files (opencode.jsonc, .opencode/, etc) in one command.
JosXa commentedon Jan 17, 2026
Are there technical hurdles to this?
JosXa commentedon Jan 18, 2026
This is what plan mode came back with:
Analysis Summary
The Issue
GitHub Issue #6719 requests a
/reloadslash command that reloads the entire config (both global and project-levelopencode.jsoncfiles and the.opencode/directory) without having to restart the TUI.Current Architecture
The codebase already has the core reload mechanism in place:
Worker-side reload (
packages/opencode/src/cli/cmd/tui/worker.tsline 133-136):SIGUSR2 signal handler (
packages/opencode/src/cli/cmd/tui/thread.tsline 108-110):Config lazy loading (
Config.globaluseslazy()which can be.reset()to force re-evaluation)Instance state disposal (
Instance.disposeAll()clears all cached instance state, forcing Config, Commands, Agents, MCP, etc. to reload)Slash commands are registered via
command.register()in the TUI with aslash: { name, aliases }propertyWhat's Missing
Currently, there's no way for users to trigger a reload from within the TUI - the only way is to send a SIGUSR2 signal from outside. The feature request asks for a
/reloadslash command exposed to users.Implementation Plan
Approach A: TUI-Only Implementation (Simpler)
Since the worker already has an RPC
reload()method, and the TUI already uses RPC for other operations, we can add a/reloadslash command that calls the worker's reload method directly.Files to Modify:
packages/opencode/src/cli/cmd/tui/app.tsx/reloadPotentially expose RPC reload to TUI context
Key Decision Point:
The current architecture uses SDK (HTTP) for most TUI<->Server communication, but reload is only exposed via direct RPC. We have two sub-options:
A1. Add reload to SDK/Server API (Recommended)
POST /config/reloadendpoint toConfigRoutesA2. Pass RPC reload through context
Recommended Approach: A1 (Add Server Endpoint)
This follows the existing patterns and is cleaner.
Implementation Steps:
Add Server Endpoint (
packages/opencode/src/server/routes/config.ts)Regenerate SDK (run
./packages/sdk/js/script/build.ts)Add TUI Slash Command (
packages/opencode/src/cli/cmd/tui/app.tsx)slash: { name: "reload" }sdk.client.config.reload()sync.refresh()to re-fetch all dataAdd Web App Slash Command (
packages/app/src/pages/session.tsx)Handle MCP Reconnection (if needed)
Instance.dispose()properly handles MCP cleanupConsiderations:
startEventStream)Questions
Scope: Should
/reloadalso restart MCP servers that may have changed config? Or just reload config values?Session behavior: If there's an active chat session, should reload:
Web app: Should this also be implemented in the web app (
packages/app), or just TUI for now?Confirmation: Should there be a confirmation dialog, or just execute immediately with a toast notification?
JosXa commentedon Jan 18, 2026
@opencode-agent
JosXa commentedon Jan 18, 2026
Great questions! I dug deeper into the codebase to answer them:
1. What components use
Instance.state()and will reload on dispose?Here's the complete list of modules that use
Instance.state()and will be re-initialized afterInstance.dispose():Config.stateopencode.json)Agent.stateMCP.stateCommand.state.opencode/commands)Skill.stateProvider.stateProvider.auth.stateBus.statePermission.statePermissionNext.stateLSP.stateFormat.stateFile.stateFileWatcher.stateFileTime.statePty.stateVcs.stateTool.registry.stateQuestion.statePlugin.stateEnv.stateSession.status.stateSession.prompt.stateThe MCP module has a proper dispose function that closes all client connections:
2. Global lazy values (reset via
Config.global.reset())These use
lazy()directly (notInstance.state) and are reset byConfig.global.reset():Config.global~/.config/opencode/opencode.json)Shell.preferredShell.acceptableServer.App3. Bootstrap functions (one-time init)
The
InstanceBootstrap()function inpackages/opencode/src/project/bootstrap.tsruns once per instance creation:These
init()functions typically just call the state accessor to trigger lazy initialization, so they'll work correctly on reload since the state is disposed first.4. Potential gotchas for reload
Things that should work:
.opencode/Things to verify:
startEventStream) uses a fixeddirectoryparameter set at startup. AfterInstance.dispose(), the same event stream continues - may need to restart it with the new instance context.Recommendation
The existing
rpc.reload()implementation looks solid:This should handle most cases. The main addition needed is:
/reloadslash command)Would you like me to start implementing this?
JosXa commentedon Jan 21, 2026
Research Summary: Plugin Reload Strategy
Great question! I've done a deep dive into the plugin system architecture to understand how
/reloadshould handle custom plugins. Here's what I found:Current Plugin Architecture
Plugins in OpenCode are loaded through a stateful initialization pattern using
Instance.state():Plugin Loading (
packages/opencode/src/plugin/index.ts:15-96):HooksobjectNo Lifecycle Hooks:
Hooksinterface only defines event handlers and lifecycle hooks for OpenCode events, not plugin lifecycleExisting Reload Mechanism (
packages/opencode/src/cli/cmd/tui/worker.ts:133-136):This completely disposes all instances, which triggers the
State.dispose()mechanism that clears all cached state, including plugins.Answer: Complete Shutdown & Reload (Preferred)
Plugins will be completely shut down and force-reloaded - no extra effort needed from maintainers!
Here's why this is the preferred approach:
✅ Already Implemented: The existing
reload()mechanism inworker.tscallsInstance.disposeAll(), which:State.dispose()Instance.ts✅ Clean Slate: When the next request comes in after reload:
Instance.provide()creates a fresh instance✅ No Plugin Developer Burden:
How It Works
/reloadConfig.global.reset()clears cached configInstance.disposeAll()tears down all instances and their plugin stateInstance.provide()which:Potential Gotcha: Plugin Dependencies
One thing to watch: if plugins have external resources (database connections, file watchers, network connections), they might leak since there's no explicit disposal hook. However:
Recommendation
The current approach is solid. Plugins get completely shut down and reloaded - no custom hooks needed. This keeps the plugin API simple and guarantees a clean reload without requiring plugin maintainers to implement special lifecycle methods.
If we find specific plugins that need cleanup (rare), we could add an optional
disposehook to the plugin interface later, but it's not necessary for the/reloadcommand to work correctly.JosXa commentedon Jan 21, 2026
yo opencode, sounds good. I think we have all the infos we need. Adding a /reload plugin seems really straightforward from what we gathered, no particularly concerning edge cases. In particular, you told me that also users' custom plugins can get completely restarted automatically. Please implement it as a pull request against the
devbranch. Please check the existing unit tests and see if the existing reload mechanism is already covered. If it is not, I think we best just build an integration/system test for the new /reload command using one of the existing pseudo-terminal tests as boilerplate.JosXa commentedon Jan 21, 2026
Summary
I've implemented the
/reloadslash command that allows reloading configuration files without restarting the TUI.Changes
packages/opencode/src/server/routes/config.ts- Added POST/config/reloadendpoint that callsConfig.global.reset()andInstance.disposeAll()to reload all configurationspackages/opencode/src/command/index.ts- AddedRELOAD: "reload"to builtin commandspackages/opencode/src/cli/cmd/tui/component/prompt/index.tsx- Added special handling for/reloadto call the config reload endpoint with toast notificationspackages/sdk/js/src/v2/gen/sdk.gen.ts- Addedreload()method to the SDK Config classpackages/opencode/test/server/config-reload.test.ts- Added integration tests for the reload endpointTesting
Checked existing tests - no prior tests for the reload mechanism existed. Added integration tests for the new
/config/reloadendpoint that verify the endpoint exists and returns{ success: true }.Pull Request
Created PR #9871: feat: add /reload slash command
2 remaining items
JosXa commentedon Feb 8, 2026
Awaiting review #9871
Femumme commentedon Apr 6, 2026
This would solve a real workflow gap for me.
I added a local profile switcher that rewrites agent model assignments in
~/.config/opencode/opencode.json(for example switching thinker/implementer/light agent groups between different models). The config file updates correctly, but the running OpenCode server keeps using the old cached models until restart.I also tried the undocumented signal-based workaround and, in my setup, sending
SIGUSR2to the running app/server just killed it instead of giving me a usable reload flow.A supported
/reloadthat re-reads global/project config and invalidates cached agent/config state would make model/profile switching usable without restarting the app.JosXa commentedon Apr 6, 2026
Yeah, exactly - there are countless use cases where you wanna continue in the same instance while playing with the config
AceCodePt commentedon May 5, 2026
Big plus! Please merge it!
maxylev commentedon May 7, 2026
The subagent from
/agents/tester.mdhas reached its token limit, so I'm changing the model name to continue working in the current session. How do I apply the changes? -/reloadfeat(opencode): add reload_skills tool and live Command.Service
feat(opencode): add reload_skills tool and live skill management (#16)
repomaa commentedon Jun 15, 2026
+1! Would be great for having opencode develop tools. I'd actually love to have this available as a tool for an agent to use.
docs(research): OpenCode does not reload; correct the table
docs(settings): Say why OpenCode registration needs a restart
rekram1-node commentedon Oct 1, 2026
https://opencode.ai/v2/docs
Opencode v2 has hot reloading and u can manually reload it w/ reload