[FEATURE]: slash command for reload #4119

Open
opened 2026-02-16 17:42:41 -05:00 by yindo · 10 comments
Owner

Originally created by @wojons on GitHub (Jan 2, 2026).

Originally assigned to: @rekram1-node on GitHub.

Feature hasn't been suggested before.

  • 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

Originally created by @wojons on GitHub (Jan 2, 2026). Originally assigned to: @rekram1-node on GitHub. ### Feature hasn't been suggested before. - [x] 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
yindo added the discussion label 2026-02-16 17:42:41 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 2, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #815: Hot reload or add keymap to reload the theme (relates to reloading theme configuration)

Feel free to ignore if this doesn't address your specific case about reloading all config files (opencode.jsonc, .opencode/, etc) in one command.

@github-actions[bot] commented on GitHub (Jan 2, 2026): This issue might be a duplicate of existing issues. Please check: - #815: Hot reload or add keymap to reload the theme (relates to reloading theme configuration) Feel free to ignore if this doesn't address your specific case about reloading all config files (opencode.jsonc, .opencode/, etc) in one command.
Author
Owner

@JosXa commented on GitHub (Jan 17, 2026):

Are there technical hurdles to this?

@JosXa commented on GitHub (Jan 17, 2026): Are there technical hurdles to this?
Author
Owner

@JosXa commented on GitHub (Jan 18, 2026):

This is what plan mode came back with:


Analysis Summary

The Issue

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:

  1. Worker-side reload (packages/opencode/src/cli/cmd/tui/worker.ts line 133-136):

    async reload() {
      Config.global.reset()
      await Instance.disposeAll()
    }
    
  2. SIGUSR2 signal handler (packages/opencode/src/cli/cmd/tui/thread.ts line 108-110):

    process.on("SIGUSR2", async () => {
      await client.call("reload", undefined)
    })
    
  3. Config lazy loading (Config.global uses lazy() which can be .reset() to force re-evaluation)

  4. Instance state disposal (Instance.disposeAll() clears all cached instance state, forcing Config, Commands, Agents, MCP, etc. to reload)

  5. 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:

  1. packages/opencode/src/cli/cmd/tui/app.tsx

    • Add a new command registration for /reload
    • The command would:
      1. Call worker's reload via RPC (through SDK or direct worker call)
      2. Wait for reload to complete
      3. Trigger a sync refresh to reload all data from the server
      4. Show a toast notification confirming reload
  2. 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:

  1. 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()
        await Instance.dispose()  // Just current instance, not all
        return c.json({ success: true })
      },
    )
    
  2. Regenerate SDK (run ./packages/sdk/js/script/build.ts)

  3. Add TUI Slash Command (packages/opencode/src/cli/cmd/tui/app.tsx)

    • Register a new command with slash: { name: "reload" }
    • Call sdk.client.config.reload()
    • Trigger sync.refresh() to re-fetch all data
    • Show toast on success
  4. Add Web App Slash Command (packages/app/src/pages/session.tsx)

    • Same pattern as TUI
  5. Handle MCP Reconnection (if needed)

    • MCP servers may need special handling during reload
    • Check if Instance.dispose() properly handles MCP cleanup

Considerations:

  • Event stream: After reload, the event stream may need to be restarted (already handled in worker.ts via startEventStream)
  • Active sessions: Should warn if a session is running, or gracefully handle in-progress operations
  • Provider reconnection: Provider state may need refresh after config reload

Questions

  1. Scope: Should /reload also restart MCP servers that may have changed config? Or just reload config values?

  2. Session behavior: If there's an active chat session, should reload:

    • Cancel/abort it first?
    • Queue reload for after completion?
    • Reload anyway (might cause issues if agent/model config changed)?
  3. Web app: Should this also be implemented in the web app (packages/app), or just TUI for now?

  4. Confirmation: Should there be a confirmation dialog, or just execute immediately with a toast notification?

@JosXa commented on GitHub (Jan 18, 2026): This is what plan mode came back with: --- ## Analysis Summary ### The Issue 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: 1. **Worker-side reload** (`packages/opencode/src/cli/cmd/tui/worker.ts` line 133-136): ```ts async reload() { Config.global.reset() await Instance.disposeAll() } ``` 2. **SIGUSR2 signal handler** (`packages/opencode/src/cli/cmd/tui/thread.ts` line 108-110): ```ts process.on("SIGUSR2", async () => { await client.call("reload", undefined) }) ``` 3. **Config lazy loading** (`Config.global` uses `lazy()` which can be `.reset()` to force re-evaluation) 4. **Instance state disposal** (`Instance.disposeAll()` clears all cached instance state, forcing Config, Commands, Agents, MCP, etc. to reload) 5. **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: 1. **`packages/opencode/src/cli/cmd/tui/app.tsx`** - Add a new command registration for `/reload` - The command would: 1. Call worker's reload via RPC (through SDK or direct worker call) 2. Wait for reload to complete 3. Trigger a sync refresh to reload all data from the server 4. Show a toast notification confirming reload 2. **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: 1. **Add Server Endpoint** (`packages/opencode/src/server/routes/config.ts`) ```ts .post( "/reload", describeRoute({ summary: "Reload configuration", description: "Reload all configuration files...", operationId: "config.reload", responses: { 200: ... }, }), async (c) => { Config.global.reset() await Instance.dispose() // Just current instance, not all return c.json({ success: true }) }, ) ``` 2. **Regenerate SDK** (run `./packages/sdk/js/script/build.ts`) 3. **Add TUI Slash Command** (`packages/opencode/src/cli/cmd/tui/app.tsx`) - Register a new command with `slash: { name: "reload" }` - Call `sdk.client.config.reload()` - Trigger `sync.refresh()` to re-fetch all data - Show toast on success 4. **Add Web App Slash Command** (`packages/app/src/pages/session.tsx`) - Same pattern as TUI 5. **Handle MCP Reconnection** (if needed) - MCP servers may need special handling during reload - Check if `Instance.dispose()` properly handles MCP cleanup #### Considerations: - **Event stream**: After reload, the event stream may need to be restarted (already handled in worker.ts via `startEventStream`) - **Active sessions**: Should warn if a session is running, or gracefully handle in-progress operations - **Provider reconnection**: Provider state may need refresh after config reload --- ## Questions 1. **Scope**: Should `/reload` also restart MCP servers that may have changed config? Or just reload config values? 2. **Session behavior**: If there's an active chat session, should reload: - Cancel/abort it first? - Queue reload for after completion? - Reload anyway (might cause issues if agent/model config changed)? 3. **Web app**: Should this also be implemented in the web app (`packages/app`), or just TUI for now? 4. **Confirmation**: Should there be a confirmation dialog, or just execute immediately with a toast notification?
Author
Owner

@JosXa commented on GitHub (Jan 18, 2026):

@opencode-agent

  1. 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.
  2. 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.
@JosXa commented on GitHub (Jan 18, 2026): @opencode-agent 1. 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. 2. 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.
Author
Owner

@JosXa commented on GitHub (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 after Instance.dispose():

Module State Purpose
Config.state Project-level config (merges global + project opencode.json)
Agent.state Agent definitions (built-in + user-defined from config)
MCP.state MCP client connections and status
Command.state Slash commands (built-in + .opencode/ commands)
Skill.state Skill definitions
Provider.state Provider configuration and auth
Provider.auth.state Provider authentication tokens
Bus.state Event bus subscriptions
Permission.state Permission rules
PermissionNext.state New permission system state
LSP.state Language server connections
Format.state Code formatters
File.state File indexing/caching
FileWatcher.state File system watchers
FileTime.state File modification times
Pty.state PTY sessions
Vcs.state Git/VCS info
Tool.registry.state Tool registry
Question.state Question tool state
Plugin.state Plugin registry
Env.state Environment variables
Session.status.state Session status tracking
Session.prompt.state Prompt state

The MCP module has a proper dispose function that closes all client connections:

async (state) => {
  await Promise.all(
    Object.values(state.clients).map((client) =>
      client.close().catch(...)
    ),
  )
}

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:

export async function InstanceBootstrap() {
  await Plugin.init()
  Share.init()
  ShareNext.init()
  Format.init()
  await LSP.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:

async reload() {
  Config.global.reset()
  await Instance.disposeAll()
}

This should handle most cases. The main addition needed is:

  1. A way to trigger this from the TUI (the /reload slash command)
  2. Possibly restart the event stream after reload
  3. Show feedback to the user (toast notification)
  4. Optional: warn if a session is actively running

Would you like me to start implementing this?

@JosXa commented on GitHub (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 after `Instance.dispose()`: | Module | State Purpose | |--------|---------------| | `Config.state` | Project-level config (merges global + project `opencode.json`) | | `Agent.state` | Agent definitions (built-in + user-defined from config) | | `MCP.state` | MCP client connections and status | | `Command.state` | Slash commands (built-in + `.opencode/` commands) | | `Skill.state` | Skill definitions | | `Provider.state` | Provider configuration and auth | | `Provider.auth.state` | Provider authentication tokens | | `Bus.state` | Event bus subscriptions | | `Permission.state` | Permission rules | | `PermissionNext.state` | New permission system state | | `LSP.state` | Language server connections | | `Format.state` | Code formatters | | `File.state` | File indexing/caching | | `FileWatcher.state` | File system watchers | | `FileTime.state` | File modification times | | `Pty.state` | PTY sessions | | `Vcs.state` | Git/VCS info | | `Tool.registry.state` | Tool registry | | `Question.state` | Question tool state | | `Plugin.state` | Plugin registry | | `Env.state` | Environment variables | | `Session.status.state` | Session status tracking | | `Session.prompt.state` | Prompt state | The MCP module has a proper dispose function that closes all client connections: ```ts async (state) => { await Promise.all( Object.values(state.clients).map((client) => client.close().catch(...) ), ) } ``` ## 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: ```ts export async function InstanceBootstrap() { await Plugin.init() Share.init() ShareNext.init() Format.init() await LSP.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: ```ts async reload() { Config.global.reset() await Instance.disposeAll() } ``` This should handle most cases. The main addition needed is: 1. A way to trigger this from the TUI (the `/reload` slash command) 2. Possibly restart the event stream after reload 3. Show feedback to the user (toast notification) 4. Optional: warn if a session is actively running Would you like me to start implementing this? <!-- opencode-agent:{"v":1,"replyTo":3765611484,"timestamp":"2025-01-18T12:00:00Z","branch":"main"} -->
Author
Owner

@JosXa commented on GitHub (Jan 21, 2026):

Research Summary: Plugin Reload Strategy

Great question! I've done a deep dive into the plugin system architecture to understand how /reload should handle custom plugins. Here's what I found:

Current Plugin Architecture

Plugins in OpenCode are loaded through a stateful initialization pattern using Instance.state():

  1. Plugin Loading (packages/opencode/src/plugin/index.ts:15-96):

    • Plugins are async functions that return a Hooks object
    • Each plugin is initialized once during instance creation and stored in memory
    • The initialization creates event subscriptions, tool registrations, and hook implementations
  2. No Lifecycle Hooks:

    • Plugins do not have dispose/cleanup/shutdown hooks - I checked the plugin interface thoroughly
    • The Hooks interface only defines event handlers and lifecycle hooks for OpenCode events, not plugin lifecycle
    • Plugins can maintain internal state, subscribe to events, and register tools, but there's no standard way to tear them down
  3. Existing Reload Mechanism (packages/opencode/src/cli/cmd/tui/worker.ts:133-136):

    async reload() {
      Config.global.reset()
      await Instance.disposeAll()
    }
    

    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

  1. User runs /reload
  2. Config.global.reset() clears cached config
  3. Instance.disposeAll() tears down all instances and their plugin state
  4. 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.

@JosXa commented on GitHub (Jan 21, 2026): ## Research Summary: Plugin Reload Strategy Great question! I've done a deep dive into the plugin system architecture to understand how `/reload` should handle custom plugins. Here's what I found: ### Current Plugin Architecture Plugins in OpenCode are loaded through a **stateful initialization pattern** using `Instance.state()`: 1. **Plugin Loading** (`packages/opencode/src/plugin/index.ts:15-96`): - Plugins are async functions that return a `Hooks` object - Each plugin is initialized once during instance creation and stored in memory - The initialization creates event subscriptions, tool registrations, and hook implementations 2. **No Lifecycle Hooks**: - Plugins **do not have dispose/cleanup/shutdown hooks** - I checked the plugin interface thoroughly - The `Hooks` interface only defines event handlers and lifecycle hooks for *OpenCode events*, not plugin lifecycle - Plugins can maintain internal state, subscribe to events, and register tools, but there's no standard way to tear them down 3. **Existing Reload Mechanism** (`packages/opencode/src/cli/cmd/tui/worker.ts:133-136`): ```ts async reload() { Config.global.reset() await Instance.disposeAll() } ``` 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 1. User runs `/reload` 2. `Config.global.reset()` clears cached config 3. `Instance.disposeAll()` tears down all instances and their plugin state 4. 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. <!-- opencode-agent:{"v":1,"replyTo":3778370988,"timestamp":"2026-01-21T17:59:00.000Z"} -->
Author
Owner

@JosXa commented on GitHub (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 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.

@JosXa commented on GitHub (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 `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.
Author
Owner

@JosXa commented on GitHub (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. 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 }.

Pull Request

Created PR #9871: feat: add /reload slash command

@JosXa commented on GitHub (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. 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 }`. ## Pull Request Created PR #9871: [feat: add /reload slash command](https://github.com/anomalyco/opencode/pull/9871) <!-- opencode-agent:{"v":1,"replyTo":3780078298,"timestamp":"2026-01-21T18:31:44.710Z"} -->
Author
Owner

@macseem commented on GitHub (Feb 8, 2026):

any updates on this?

@macseem commented on GitHub (Feb 8, 2026): any updates on this?
Author
Owner

@JosXa commented on GitHub (Feb 8, 2026):

any updates on this?

Awaiting review https://github.com/anomalyco/opencode/pull/9871

@JosXa commented on GitHub (Feb 8, 2026): > any updates on this? Awaiting review https://github.com/anomalyco/opencode/pull/9871
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4119