All notable changes to this project will be documented in this file.
Format follows Keep a Changelog. Versioning follows SemVer.
Add your changes to
[Unreleased]. They get moved into a version heading at release time.
0.19.2 — 2026-10-14
- Added separate PR CI guards via
just test-intfor harness integration andjust test-e2efor cache-installed OpenCode v1/v2 E2E editing, with exact prompt checks and no-plugin controls; local runs remain on demand and outside the unit suite. - Added no-argument
just test-e2edefaults for both pinned hosts, optional single-host selection, fresh temp receipts, private pinned bootstrap, and ignored path-only.envbinary overrides; existing explicit CI paths remain supported. - Added v1/v2 Terminal Control regressions for answer append followed by native paste in one PTY write, with synthetic question setup fixtures and exact visible-answer checks.
- Custom question answers now support Vim editing on both OpenCode v1 and v2, starting in insert mode with isolated mode/undo state and preserving native answer submission, choice navigation and permissions (#78).
- Native paste in question answers now waits for queued Vim motions, preventing insertion at the previous cursor position.
- E2E startup failures retain the native exit status and current-scenario host error log instead of only reporting a closed readiness stream.
0.19.1 — 2026-10-04
- Added Vim-style subagent-navigation aliases to
just devandjust dev2alongside the arrow bindings for manual checks.
- Remapped navigation keys now reach OpenCode in read-only child-session views without changing the Vim mode (#79).
- Corrected v2 root-session metadata so root prompts continue receiving Vim commands.
- Declared the OpenTUI keymap dev dependency so navigation regression tests run from clean installs.
0.19.0 — 2026-10-02
- Experimental OpenCode v2 TUI support using a dual v1/v2 entrypoint and a renderer-key interception adapter, validated on OpenCode 2.0.15 on macOS.
- Optional installed-package compatibility harness with exact editor-state checks on pinned v1/v2 binaries; lightweight harness regressions run in CI without downloading hosts.
just dev2launches local source with a pinned OpenCode v2 release and separate.dev2/settings/history.
- Started a gradual transition toward v2-only maintenance. v1 compatibility remains in v0.19.0; existing v1 users can stay pinned to the recommended v0.18.1 release.
- Document Git installation, options, and custom leader settings separately for OpenCode v1 and experimental v2.
- Corrected contributor paths for the split Vim engine and documented CI's compatibility-harness checks.
- Visual
h/lnow selects through the cursor in both tested hosts, including backward motions, empty buffers and EOF/EOL boundaries, without resetting the native anchor for subsequent word or line motions. Visual mode re-anchors at the new prompt's cursor when the focused editor changes. - The v2 form leader guard and Vim controller now share a per-activation disabled setting; external TUI toggles take effect on reload, local
/vimtoggles take effect immediately. - Compatibility checks ignore user tmux configuration, reject JSONC project-config ancestors, and poll boundedly for asynchronous form/permission completion, retaining the last server response in receipts.
- Selection normalization no longer requires an installed
@opentui/coretype dependency; host-owned selection colors are forwarded unchanged.
0.18.1 — 2026-09-11
- Updated the documented cache-installed mode indicator limitation with the latest OpenCode and OpenTUI findings (#3).
- Fixed Vim keys remaining unresponsive after dismissing or rejecting a question prompt (#72).
0.18.0 — 2026-09-02
- Word text objects
iwandaw, for use with thed,c, andyoperators and in visual mode:diw,ciw,daw,viw, and so on (#57). - Quote and bracket text objects
i"i'i`i(i{i[i<(withavariants) ford/c/yand visual mode:di",ci(,vi[, and so on.iq/ibmatch the nearest quote/bracket of any type;ibmeans any bracket, not vim's parens-onlyib.
- After an operator,
i/anow start a text object instead of switching to insert mode, sodiandciwait for the object key (#57).
0.17.1 — 2026-09-02
- Arrow keys no longer get swallowed in normal and visual mode. They pass through to OpenCode, so you can exit the subagent view (and use other native navigation) without first switching to insert mode (#63).
0.17.0 — 2026-09-02
- Redesigned the vim engine into a modular architecture for easier maintenance and future keybindings. No change to existing keybindings or behavior.
dgganddrxno longer leave a stray operator that affected the next keypress.
0.16.0 — 2026-08-31
:wand:writenow send the prompt instead of autocompleting to:wqand quitting OpenCode. Sessions auto-persist, so the natural mapping for vim users' reflexive "save" is to submit the current prompt.:wqstill quits.
0.15.3 — 2026-07-01
- Repeated
ein visual mode now extends the selection progressively instead of getting stuck after the first press.
ein visual mode now moves to end of word instead of behaving likew(#52).
0.15.1 — 2026-06-23
- Enter/Escape now work on subagent permission dialogs instead of being consumed by vim (#47).
0.15.0 — 2026-06-16
- Non-printable leader keys (e.g.
ctrl+x) now work in insert mode instead of being swallowed (#42). - Escape from insert mode now moves cursor left, matching vim.
- Clipboard now uses
wl-copyon Wayland instead ofxclip, which doesn't work there.
0.14.0 — 2026-06-13
/vimtoggle command to disable/enable vim mode. Persisted across restarts.- Startup toast when vim is disabled so users know why keybindings aren't active.
Vselects the current line and enters visual mode.
- Counted delete/change commands such as
3dwnow undo in oneupress instead of one undo per repeated host command. - Leader key now works with modifier-based configurations like the default
ctrl+x. Previously,parseLeaderKeyexpected vim-styleC-xnotation but OpenCode's keybinds API returnsctrl+xformat, so the leader key was silently broken for any config with modifiers. - Leader detection supports all OpenCode modifier aliases (
control,alt,option,super) and multiple leader bindings. - Optional chaining on
api.kv.setto avoid crashes on older OpenCode versions. - Escape/Enter no longer intercepted when vim is disabled.
- Toggling vim off resets mode and clears pending state.
:vimpalette title uses:prefix, consistent with:q/:quit/:wq.
0.13.0 — 2026-06-09
- Leader key is now auto-detected from OpenCode's
keybinds.leaderconfig. Theleaderplugin option has been removed.
- Leader key (e.g. space) no longer enters pending-sequence state when typing in question or permission prompt overlays.
0.12.2 — 2026-06-08
- Persistent mode indicator removed. The SolidJS slot approach doesn't work from git-installed plugins — the host's JSX runtime can't be resolved from the package cache. Back to toast-only for now (#3).
modeIndicatoroption now accepts"toast"(default) or"none". The"status"value from v0.12.0 is gone until the host resolves JSX for external plugins.Ctrl+Oone-shot normal now emits a propermodeaction instead of a toast side-channel. The toast shows(insert)in lowercase, matching Vim convention.
0.12.0 — 2026-06-08
- Persistent mode indicator next to the prompt (#3). Shows NORMAL, INSERT, VISUAL, or (insert) for one-shot normal. Replaces the old toast, which disappeared after a second.
modeIndicatoroption:"status"(default, persistent label),"toast"(old behavior), or"none"(disabled). The oldmodeToastoption still works as a fallback.
- Plugin entry point is now
.tsx(was.ts) to support SolidJS slot rendering.
0.11.0 — 2026-06-08
:q,:quit, and:wqquit OpenCode from the command palette (#19). Since:already opens the palette, typing:qand pressing Enter exits the app.Ctrl+Oin insert mode — run one normal-mode command, then return to insert. Motions, operators, counts, andr{char}all work.leaderplugin option — lets you use space (or any key) as leader without breaking insert mode. Spaces type normally while editing, and leader sequences likespace lstill work in normal mode (#21).
0.10.0 — 2026-05-31
dGandcG— delete/change from cursor to end of buffer.yGalready worked, now all three operators work withG.
- Cursor shape is set via the editor widget's
cursorStyleproperty instead of writing DECSCUSR escape sequences to stdout. Fixes terminals that don't support DECSCUSR (e.g. macOS Terminal.app).
dG,cG,de,ceundo in a singleupress. The host editor's undo system splits multi-line deletions into per-line entries, so these operations now go througheditBuffer.deleteRange()with a pre-operation snapshot thaturestores from directly.yyreads the cursor position from the editor widget instead of a line counter. The counter drifted on clicks, arrow keys, and word motions, causingyyto yank the wrong line.emoves to end of word instead of behaving likew.de,ce, andyeoperate on the correct range too.gwaits for a second keypress instead of jumping to buffer start on its own.ggnow works as a proper two-key command.
0.9.0 — 2026-05-29
r{char}replaces the character under the cursor. Supports counts:3rareplaces 3 characters witha.
0.8.0 — 2026-05-26
- Yank with motions:
yw,yb,ye,y$,y0,y^,yh,yl,yj,yk,yG. Previously onlyyyworked. - Plugin init sanity test that catches crashes from hostile API shapes before release.
- Biome for linting and formatting, enforced in CI.
just test,just lint,just lint-fix,just checkrecipes.
- Plugin failed to load when
api.kvdidn't match the expected interface (e.g. object with no.getmethod). Broke installs on some OpenCode versions.
- README operators section rewritten to show
d,c, andyside by side for each motion. - Noted that
eandwbehave identically (the host has no separate end-of-word command).
0.7.0 — 2026-05-26
- Cross-platform clipboard. Yank/paste now works on macOS (
pbcopy), Windows (clip.exe), and Linux (xclip). Previously macOS-only. - Plugin configuration via
tui.jsontuple syntax. Three options available:updateCheck— disable the daily GitHub version check.modeToast— disable the mode-switch toast, relying on cursor shape alone.startMode— start in normal mode instead of insert.
- Daily caching for the update checker via
api.kv. Previously checked GitHub on every launch. - GitHub Actions CI — runs
bun teston push and PR to main. - Issue templates for bug reports and missing keybinding requests.
- Version sync test — catches drift between
VERSIONandpackage.jsonat test time. typecheckscript (tsc --noEmit) inpackage.json.- MIT LICENSE file.
- Removed unused devDependencies (
@opentui/core,@opentui/keymap,@opentui/solid,solid-js). Pinned@opencode-ai/pluginto^1.15.4. - Removed
private: truefrompackage.json. - Dropped lockfiles from git. Plugin consumers resolve their own deps.
- Replaced local paths in AGENTS.md with public GitHub URLs.
- Fixed
g/ggcontradiction in README —gremoved from keybinding tables. - Added platform notes and configuration sections to README.
0.6.1 — 2026-05-25
- Updated AGENTS.md with current line counts and visual mode status in known limitations.
- Dead
readClipboard()export from clipboard module. - Stale implementation plan (
docs/plan.md) from initial prototype.
0.6.0 — 2026-05-24
- Character-wise visual mode (
v). Select text with motions, thend/xto delete,cto change,yto yank. All normal-mode motions work for extending the selection, with counts. - Tab inserts a tab character in insert mode. Previously fell through to OpenCode's default handler because the plugin had no way to insert text at the cursor. Now uses
insertTexton the focused editor directly.
j/know move the cursor up/down in multi-line text. Previously they always dispatched prompt history commands because the plugin read prompt text fromapi.promptwhich doesn't exist. Now reads fromapi.renderer.currentFocusedEditor.plainText.din visual mode deletes the full selection instead of just the last character. TheclearSelectionaction was racing the deferredinput.backspacecommand.- Block cursor now shows in visual mode (not just normal mode).
0.5.0 — 2026-05-24
- Tab insertion in insert mode. The clipboard-based workaround (write tab to clipboard, paste, restore) clobbered the user's clipboard and raced with async I/O. Tab now falls through to OpenCode's default handler.
0.4.0 — 2026-05-24
/in normal mode opens the session timeline (jump-to-message picker).[/]scroll the conversation view half a page up/down.{/}jump to the previous/next message in the conversation.translateKeynow maps shift+[→{and shift+]→}.
0.3.3 — 2026-05-21
- Update check now uses GitHub API instead of raw.githubusercontent.com, which caches content for up to 5 minutes.
0.3.2 — 2026-05-21
No user-facing changes. Version bump to test the update notification.
0.3.1 — 2026-05-21
- Update check on launch. Shows a toast when a newer version is available on GitHub.
- Install instructions now pin a version tag (
#v0.3.1). Changing the tag intui.jsoninvalidates the cache and pulls the new version on next launch.
- Cursor shape now works for git-installed plugins, not just
just dev. Switched fromaddPostProcessFn(unavailable in the cache context) to a direct DECSCUSR interval.
0.3.0 — 2026-05-20
- Cursor shape changes with mode: block in normal mode, bar in insert mode. Uses DECSCUSR escape sequences via a post-render hook, bypassing the Textarea's hardcoded block cursor.
0.2.2 — 2026-05-20
- Vimcode now passes through all keys when any overlay is active (command palette, session list, question prompts, permission prompts). Previously vim consumed j/k/Enter/Escape before these UIs could handle them.
0.2.1 — 2026-05-20
- Vim keybindings no longer interfere with the question tool. When the AI asks a question with selectable options, vimcode passes through all keys.
0.2.0 — 2026-05-20
Ctrl+Entersubmits the prompt from insert mode. Previously there was no way to submit without switching to normal first.j/kin normal mode cycle through prompt history when the input is empty, matching up/down arrow behavior.
- File picker and autocomplete work in insert mode. Enter picks the selected item and Escape closes the picker without leaving insert. Previously the vim intercept consumed both keys before the autocomplete layer saw them.
0.1.4 — 2026-05-20
- Colored mode indicator in the prompt bar when running from source (
just dev). Falls back to toast for git/npm installs where the host runtime modules can't be imported.
0.1.3 — 2026-05-20
- Git URL installation works. Removed all external runtime imports (
solid-js,@opentui/solid) since OpenCode's runtime module plugin doesn't resolve host packages for cache-installed plugins.
- Mode indicator replaced with toast notifications. Toast shows "NORMAL" or "INSERT" briefly on each switch.
indicator.ts(no longer needed without the slot-based indicator).
0.1.2 — 2026-05-19
- Git URL installation works. Replaced JSX with programmatic rendering to avoid
jsx-dev-runtimeresolution failure from the package cache path.
0.1.1 — 2026-05-19
- Git URL installation (
vimcode@git+https://...intui.json) no longer fails withjsxDEV not found. Peer deps moved to devDependencies so type stubs don't shadow the host runtime.
- Removed unnecessary
"."export from package.json. Only"./tui"is needed by the plugin loader.
0.1.0 — 2026-05-18
First release. Modal editing for the OpenCode prompt.
- Normal and insert modes, toggled by
Escapeand insert-entry keys. - Mode indicator in the prompt bar (NORMAL/INSERT).
- Normal mode motions:
h,j,k,l,w,b,e,0,^,$,g,G. - Numeric counts for all motions (
3j,5w, etc.). - Operators
d(delete),c(change),y(yank) with motion combinations (dw,c$,yb). - Doubled operators for line-wise action:
dd,cc,yy. - Counts on both operator and motion (
2d3w). DandCshortcuts for delete/change to end of line.- Insert entries:
i,a,A,o,O. x,X,u,Ctrl+r,p,J,:,Enter.- Insert mode
Enterinserts a newline. - Yank copies to system clipboard via
pbcopy.
gfires immediately as buffer-home instead of waiting forgg. Theyyline tracker drifts on clicks and arrow keys. Visual mode and text objects aren't feasible without cursor position access.