Skip to content

Commit aac4c42

Browse files
committed
feat(runtime): replace use_wsl with runtime command config
1 parent 61efa1a commit aac4c42

22 files changed

Lines changed: 1220 additions & 203 deletions

README.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,16 @@ require('opencode').setup({
119119
default_mode = 'build', -- 'build' or 'plan' or any custom configured. @see [OpenCode Agents](https://opencode.ai/docs/modes/)
120120
default_system_prompt = nil, -- Custom system prompt to use for all sessions. If nil, uses the default built-in system prompt
121121
keymap_prefix = '<leader>o', -- Default keymap prefix for global keymaps change to your preferred prefix and it will be applied to all keymaps starting with <leader>o
122-
opencode_executable = 'opencode', -- Name of your opencode binary
122+
runtime = {
123+
command = { 'opencode' }, -- Base runtime command, array-only
124+
serve_args = { 'serve' }, -- Optional, defaults to {'serve'}
125+
version_args = { '--version' }, -- Optional, defaults to {'--version'}
126+
startup_timeout_ms = 15000, -- Optional startup timeout before failing with an error
127+
path = {
128+
to_server = nil, -- Optional fun(path) -> server path
129+
to_local = nil, -- Optional fun(path) -> local path
130+
},
131+
},
123132
keymap = {
124133
editor = {
125134
['<leader>og'] = { 'toggle' }, -- Open opencode. Close if opened
@@ -333,6 +342,83 @@ require('opencode').setup({
333342
})
334343
```
335344

345+
### Runtime Examples
346+
347+
`runtime.command` is array-only and is passed directly to `vim.system(...)`.
348+
349+
#### WSL (Windows host)
350+
351+
```lua
352+
require('opencode').setup({
353+
runtime = {
354+
command = { 'wsl.exe', '-e', 'opencode' },
355+
serve_args = { 'serve', '--hostname', '127.0.0.1', '--port', '0' },
356+
version_args = { '--version' },
357+
startup_timeout_ms = 8000,
358+
path = {
359+
to_server = function(path)
360+
local normalized = path:gsub('\\', '/')
361+
local drive, rest = normalized:match('^(%a):(/.*)$')
362+
if drive then
363+
return string.format('/mnt/%s%s', drive:lower(), rest)
364+
end
365+
return normalized
366+
end,
367+
to_local = function(path)
368+
local drive, rest = path:match('^/mnt/([a-zA-Z])/?(.*)$')
369+
if not drive then
370+
return path
371+
end
372+
local win_rest = rest:gsub('/', '\\')
373+
if win_rest ~= '' then
374+
return string.format('%s:\\%s', drive:upper(), win_rest)
375+
end
376+
return string.format('%s:\\', drive:upper())
377+
end,
378+
},
379+
},
380+
})
381+
```
382+
383+
If `wsl.exe -e opencode --version` fails but `wsl.exe -e bash -ilc "opencode --version"` works,
384+
your PATH is only configured in interactive shell startup files (commonly `.bashrc` with nvm).
385+
Use this command wrapper so runtime args are forwarded correctly:
386+
387+
```lua
388+
runtime = {
389+
command = { 'wsl.exe', '-e', 'bash', '-ilc', 'opencode "$@"', 'opencode' },
390+
serve_args = { 'serve', '--hostname', '127.0.0.1', '--port', '0' },
391+
version_args = { '--version' },
392+
}
393+
```
394+
395+
Hint: `-l` loads login startup files, `-i` loads interactive startup files (`.bashrc`).
396+
If your opencode PATH comes from `.bashrc`, use `-ilc`.
397+
398+
#### Docker
399+
400+
```lua
401+
require('opencode').setup({
402+
runtime = {
403+
command = {
404+
'docker',
405+
'run',
406+
'--rm',
407+
'-i',
408+
'--network=host',
409+
'-v',
410+
vim.fn.getcwd() .. ':' .. vim.fn.getcwd(),
411+
'-w',
412+
vim.fn.getcwd(),
413+
'ghcr.io/sst/opencode:latest',
414+
'opencode',
415+
},
416+
serve_args = { 'serve' },
417+
version_args = { '--version' },
418+
},
419+
})
420+
```
421+
336422
### Keymap Configuration
337423

338424
The keymap configuration has been restructured for better organization and clarity:

0 commit comments

Comments
 (0)