Skip to content

feat(tui): expose api.keymap to TUI plugins for OpenCode compatibility - #2064

Open
YOMXXX wants to merge 2 commits into
XiaomiMiMo:mainfrom
YOMXXX:feat/tui-plugin-keymap
Open

feat(tui): expose api.keymap to TUI plugins for OpenCode compatibility#2064
YOMXXX wants to merge 2 commits into
XiaomiMiMo:mainfrom
YOMXXX:feat/tui-plugin-keymap

Conversation

@YOMXXX

@YOMXXX YOMXXX commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #2001. TUI plugins written against the upstream OpenCode plugin API (api.keymap.registerLayer({ commands, bindings })) failed to initialize on MiMoCode because @mimo-ai/plugin's TUI API was missing the keymap module — the error killed the whole TUI plugin (sidebar slots included).

Design: reimplement a narrow, type-compatible subset of api.keymap in the fork (no @opentui/keymap dependency — it targets opentui 0.2.x, incompatible with the fork's 0.1.x). It bridges to the existing command dialog + keybind system.

  • packages/plugin/src/tui.ts: keymap types (TuiKeymap, Binding, Layer, Command, CommandContext, RunCommandResult, …) + TuiPluginApi.keymap.
  • packages/opencode/src/cli/cmd/tui/plugin/keymap.ts (new): createPluginKeymapregisterLayer (bridges commands into the command palette, keybind via existing dialog loop; function-valued binding.cmd handled as hidden keybind options), dispatchCommand/runCommand (thread payload/event, command.palette.show special case, enabled gate), getCommands/getCommandEntries/getCommandBindings, setData/getData (surfaced in CommandContext.data), on/intercept no-ops, key helpers.
  • useCommandDialog.find(name), wiring in api.tsx/runtime.ts/app.tsx.
  • api.command (legacy) keeps working.

Test Plan

  • Focused createPluginKeymap test (8 cases): registerLayer bridging, dispatch, palette.show, not-found, data round-trip + ctx.data, enabled gate, payload/event, function binding.
  • bun typecheck clean (both packages/opencode and packages/plugin); existing plugin/TUI suites 423 pass no regression.

Known gaps (documented in code)

Sequence keys ("g c"), layer target/priority/targetMode semantics, reactive enabled/suggested (snapshot-evaluated), api.lifecycle.onDispose no-op, api.mode absent. These are the documented subset boundaries — the acceptance path (real plugin initializes + commands appear in palette + run(ctx) valid) holds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@mimo-ai/plugin TUI API missing 'keymap' module — TUI plugins using api.keymap.registerLayer fail to initialize

1 participant