anomalyco / anomalyco/opencode

Slash command defined in opencode.json (command key) never appears in TUI autocomplete despite being loaded by config

Open
#43,873 0 comments 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Aug 21, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

A slash command defined in opencode.json under the top-level command key is loaded correctly by the config layer, but never appears in the TUI slash-command autocomplete list.

Environment

  • OpenCode: 1.18.20
  • OS: Windows 11 (10.0.26200 x64)
  • Global config dir contains both opencode.json and opencode.jsonc

Reproduction

  1. Add a command to the global config:
// ~/.config/opencode/opencode.json
{
  "command": {
    "dcp-compress": {
      "template": "",
      "description": "Trigger DCP manual compression with: /dcp-compress [focus]"
    }
  }
}
  1. Restart OpenCode completely.
  2. Type / in the prompt and check the autocomplete list.

Expected: /dcp-compress appears in the list.

Actual: it does not appear. Typing /dcp-compress manually just sends it as a plain user message.

Evidence that the config layer sees the command

opencode debug config | jq '.command | keys' on the same machine does include "dcp-compress" (alongside skill-derived entries), so the v1 config pipeline loads and merges the entry correctly. The break is somewhere between the resolved config and what the TUI displays.

Source-level analysis (v1.18.20 tag)

The intended chain looks complete on paper, which is why this is confusing:

  1. packages/core/src/v1/config/migrate.tsisV1() recognizes the command key, and migrate() maps commands: info.command.
  2. packages/core/src/config/plugin/command.ts ("config-command" internal plugin) reads entry.info.commands from each document entry and writes them into the CommandV2 store via draft.update(...).
  3. packages/tui/src/component/prompt/autocomplete.tsx renders slash suggestions from sync.data.command, which is populated by sdk.client.command.list(...) (GET /command) in packages/tui/src/context/sync.tsx.

Somewhere along 1 → 2 → 3 the JSON-defined command is dropped. Markdown-defined commands (command/*.md) go through the loadDirectory branch of step 2 and appear to be unaffected; the loss seems specific to commands declared inside JSON config documents.

One additional observation: querying GET /command?directory=... directly against the ports my running instances listen on returned 404 for all of them, but I had multiple OpenCode processes running and cannot rule out having probed the wrong instance, so treat that as anecdotal.

Impact

Any plugin or user relying on JSON-declared commands loses them silently — notably @tarquinen/opencode-dcp, which registers /dcp-compress via its plugin config hook (a related but distinct failure mode, filed as Opencode-DCP/opencode-dynamic-context-pruning#609). The manual opencode.json declaration was supposed to be the workaround for that case, and it does not reach the TUI either.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.