just install # install deps
just dev # launch OpenCode v1 with the plugin loaded
just dev2 # launch pinned v2 with local source and separate .dev2/ state
just check # run lint + existing fast tests
just test # existing fast suite
just test-int # on-demand harness integration checks (including launcher)
just test-e2e # both pinned hosts; inferred private binaries/temp outputsRunning opencode directly in this directory won't load the plugin. just dev sets OPENCODE_TUI_CONFIG=dev-tui.json. just dev2 uses npm's package runner (npx) for OpenCode 2.0.15 and keeps its on-disk settings/history separate under .dev2/. To use an existing v2 binary, run just dev2 /absolute/path/to/opencode-v2 or set OPENCODE_V2_BIN. See the v2 POC notes.
just test-e2e runs v1@1.18.34 and v2@2.0.15; add v1 or v2 to select one. It prints fresh canonical temp receipt paths and may download/install the pinned hosts privately. Optional ignored .env path keys VIMCODE_E2E_V1_BIN / VIMCODE_E2E_V2_BIN use existing binaries; process settings win, CI ignores the file, and unknown keys are not forwarded. The advanced HOST BINARY VERSION OUTPUT form remains available. See the runner settings and validation limits before using overrides (Linux runtime remains pending).
- Add the key check in the matching mode handler under
src/vim/(src/vim/normal.tsfor normal mode keys). - Return appropriate actions:
{ consume: true, actions: [{ type: "cmd", cmd: "input.some.command" }] } - Add a test in the matching file under
test/vim/(test/vim/normal.test.tsfor normal mode keys). - Run
just check, thenjust devto verify.
See AGENTS.md for operator+motion combos and other patterns.
All changes go through pull requests — direct pushes to main are blocked.
Use type/description with lowercase, hyphen-separated words:
feat/replace-charfix/escape-handlingchore/update-deps
Types match commit prefixes: feat, fix, refactor, chore, test, docs.
- Create a branch:
git checkout -b feat/your-feature - Make changes, run
just checklocally. It must pass with zero errors and zero warnings. - Push and open a PR against
main. - CI runs
just checkandjust compat-unit, plusjust test-intfor harness integration andjust test-e2efor product E2E on pinned OpenCode v1/v2. Warnings and guard failures fail the build. Locally these guards run only on demand; the existing Python/tmux live-host compatibility harness remains manual. See the guard commands and limits. An owner must configure the new check names as required after their first successful Actions run. - PRs are squash-merged. The PR title becomes the commit message on
main.
Conventional-ish prefixes: feat:, fix:, refactor:, chore:, test:, docs:.
Follow Keep a Changelog. Add your change to [Unreleased] in CHANGELOG.md in the same PR. Past tense, reader's perspective, one bullet per change.
SemVer. 0.x.y until the plugin API stabilizes:
- PATCH: Bug fixes, docs
- MINOR: New keybindings, new features (backward compatible)
- MAJOR: Breaking changes, removed keybindings
OpenCode v2 support is rolling out gradually and remains experimental in vimcode v0.19.2. Future maintenance will move to v2 only; v1 compatibility remains in this release. The recommended v1 pin stays at v0.18.1. Do not automatically advance that legacy recommendation when preparing a v2-focused release.
Releases are manual.
- Check that
[Unreleased]in CHANGELOG.md is complete. - Decide the version bump (SemVer rules above).
- Move
[Unreleased]entries into a new## [X.Y.Z] — YYYY-MM-DDsection. - Update link references at the bottom of CHANGELOG.md.
- Bump version in
package.json(npm version X.Y.Z --no-git-tag-version). - Bump
VERSIONinsrc/version.tsto match. - Update the current v2 package refs and release wording in
README.mdand this guide, including options and leader examples. Keep the recommended v1 pin unchanged unless a v1 upgrade is deliberately recommended and verified. - Run
just check. - Open a PR with the release changes. Title:
Release vX.Y.Z: <one-line summary>. - After CI passes, squash-merge the PR.
- Tag and push:
git tag vX.Y.Z && git push origin vX.Y.Z - Create a GitHub release:
gh release create vX.Y.Z --title "vX.Y.Z" --latest --notes "<changelog section for this version>"
Both host versions load the same ./tui package entry via a Git URL. Pin a tag or commit so upgrades use a new cache entry.
On OpenCode v1, use tui.json. The recommended legacy pin is v0.18.1; v0.19.2 includes v1 compatibility plus the subagent-navigation and question-answer fixes for users who opt in:
{ "plugin": ["vimcode@git+https://github.com/oribarilan/vimcode.git#v0.18.1"] }On OpenCode v2, use cli.json and pin v0.19.2. v2 support is experimental; the v1-only v0.18.1 release does not work on v2:
{
"plugins": [
{
"package": "vimcode@git+https://github.com/oribarilan/vimcode.git#v0.19.2"
}
]
}Bare names (like "vimcode") trigger npm resolution, which won't work since the package isn't published. The @git+ prefix tells OpenCode to clone from GitHub. See the README for options and v2 compatibility limits; the POC notes also cover tarball installs.
src/vim/ owns pure key handling. src/index.ts applies actions and registers the shared controller; src/v2.ts adapts the v2 host API. See AGENTS.md for the full architecture guide.