Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions lua/opencode/api_client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,20 @@ function OpencodeApiClient:_call(endpoint, method, body, query)
end
local url = self.base_url .. endpoint

if query then
local params = {}
query = query or {}
if query.directory == nil then
query.directory = vim.fn.getcwd()
end

for k, v in pairs(query) do
if v ~= nil then
table.insert(params, k .. '=' .. tostring(v))
end
local params = {}
for k, v in pairs(query) do
if v ~= nil then
table.insert(params, k .. '=' .. vim.uri_encode(tostring(v)))
end
end

if #params > 0 then
url = url .. '?' .. table.concat(params, '&')
end
if #params > 0 then
url = url .. '?' .. table.concat(params, '&')
end

return server_job.call_api(url, method, body)
Expand Down Expand Up @@ -394,13 +396,11 @@ end
--- Subscribe to events (streaming)
--- @param directory string|nil Directory path
--- @param on_event fun(event: table) Event callback
--- @return table The streaming job handle
--- @return table streaming job handle
function OpencodeApiClient:subscribe_to_events(directory, on_event)
self:_ensure_base_url()
local url = self.base_url .. '/event'
if directory then
url = url .. '?directory=' .. directory
end
directory = directory or vim.fn.getcwd()
local url = self.base_url .. '/event?directory=' .. vim.uri_encode(directory)

return server_job.stream_api(url, 'GET', nil, function(chunk)
-- strip data: prefix if present
Expand Down Expand Up @@ -434,6 +434,37 @@ function OpencodeApiClient:list_tools(provider, model, directory)
})
end

--- Check if a server at the given URL is healthy
--- This is a static method that doesn't require an established connection
--- @param base_url string The server URL to check
--- @param timeout_ms? number Timeout in milliseconds (default: 2000)
--- @return Promise<boolean> promise that resolves to true if healthy, rejects otherwise
function OpencodeApiClient.check_health(base_url, timeout_ms)
local Promise = require('opencode.promise')
local curl = require('opencode.curl')

local health_promise = Promise.new()
local url = base_url:gsub('/$', '') .. '/global/health'

curl.request({
url = url,
method = 'GET',
timeout = timeout_ms or 2000,
callback = function(response)
if response and response.status >= 200 and response.status < 300 then
health_promise:resolve(true)
else
health_promise:reject('unhealthy')
end
end,
on_error = function(err)
health_promise:reject(err or 'health check failed')
end,
})

return health_promise
end

--- Create a factory function for the module
--- @param base_url? string The base URL of the opencode server
--- @return OpencodeApiClient
Expand Down Expand Up @@ -464,4 +495,5 @@ end
return {
new = OpencodeApiClient.new,
create = create_client,
check_health = OpencodeApiClient.check_health,
}
3 changes: 3 additions & 0 deletions lua/opencode/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ M.defaults = {
capture_streamed_events = false,
show_ids = true,
},
server = {
port = 41096, -- Default high port for opencode server
},
prompt_guard = nil,
hooks = {
on_file_edited = nil,
Expand Down
Loading