33--- - [implementation](https://github.com/sst/opencode/blob/dev/packages/opencode/src/server/server.ts)
44local M = {}
55
6- local sse_state = {
7- -- Track the port - `opencode` may have restarted, usually on a new port
8- port = nil ,
9- --- @type number | nil
10- job_id = nil ,
11- }
12-
136--- Generate a UUID v4 (cross-platform, no external dependencies)
147--- @return string UUID in format xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
158local function generate_uuid ()
5043
5144--- @param url string
5245--- @param method string
53- --- @param body table | nil
54- --- @param callback fun ( response : table )| nil
46+ --- @param body table ?
47+ --- @param on_success fun ( response : table )?
48+ --- @param on_error fun ( code : number , msg : string ?)?
5549--- @return number job_id
56- local function curl (url , method , body , callback )
50+ local function curl (url , method , body , on_success , on_error )
5751 local command = {
5852 " curl" ,
5953 " -s" ,
@@ -86,8 +80,8 @@ local function curl(url, method, body, callback)
8680 vim .schedule (function ()
8781 local ok , response = pcall (vim .fn .json_decode , full_event )
8882 if ok then
89- if callback then
90- callback (response )
83+ if on_success then
84+ on_success (response )
9185 end
9286 else
9387 vim .notify (
@@ -132,12 +126,17 @@ local function curl(url, method, body, callback)
132126 -- Process any remaining buffered data.
133127 process_response_buffer ()
134128 elseif code ~= 18 and code ~= 143 then
135- -- 18 = connection closed, 143 = SIGTERM (manual disconnect)
136- local error_message = " curl command failed with exit code: "
137- .. code
138- .. " \n stderr:\n "
139- .. (# stderr_lines > 0 and table.concat (stderr_lines , " \n " ) or " <none>" )
140- vim .notify (error_message , vim .log .levels .ERROR , { title = " opencode" })
129+ local stderr_message = # stderr_lines > 0 and table.concat (stderr_lines , " \n " ) or nil
130+ if on_error then
131+ on_error (code , stderr_message )
132+ else
133+ -- 18 = connection closed, 143 = SIGTERM (manual disconnect)
134+ local error_message = " curl command failed with exit code: "
135+ .. code
136+ .. " \n stderr:\n "
137+ .. (stderr_message or " <none>" )
138+ vim .notify (error_message , vim .log .levels .ERROR , { title = " opencode" })
139+ end
141140 end
142141 end ,
143142 })
@@ -147,11 +146,12 @@ end
147146--- @param port number
148147--- @param path string
149148--- @param method " GET" | " POST"
150- --- @param body table | nil
151- --- @param callback fun ( response : table )| nil
149+ --- @param body table ?
150+ --- @param on_success fun ( response : table )?
151+ --- @param on_error fun ( code : number , msg : string ?)?
152152--- @return number job_id
153- function M .call (port , path , method , body , callback )
154- return curl (" http://localhost:" .. port .. path , method , body , callback )
153+ function M .call (port , path , method , body , on_success , on_error )
154+ return curl (" http://localhost:" .. port .. path , method , body , on_success , on_error )
155155end
156156
157157--- @param text string
@@ -243,6 +243,16 @@ function M.get_sessions(port, callback)
243243 M .call (port , " /session" , " GET" , nil , callback )
244244end
245245
246+ --- @class opencode.cli.client.SessionStatus
247+
248+ --- Get sessions' status from `opencode`.
249+ ---
250+ --- @param port number
251+ --- @param callback fun ( statuses : opencode.cli.client.SessionStatus[] )
252+ function M .get_sessions_status (port , callback )
253+ M .call (port , " /session/status" , " GET" , nil , callback )
254+ end
255+
246256--- Select session in `opencode`.
247257---
248258--- @param port number
@@ -256,27 +266,10 @@ end
256266--- @field worktree string
257267
258268--- @param port number
259- --- @return opencode.cli.client.PathResponse
260- function M .get_path (port )
261- -- Query each port synchronously for working directory
262- -- TODO: Migrate to align with async paradigm used elsewhere
263- local curl_result = vim
264- .system ({
265- " curl" ,
266- " -s" ,
267- " --connect-timeout" ,
268- " 1" ,
269- " http://localhost:" .. port .. " /path" ,
270- })
271- :wait ()
272- require (" opencode.util" ).check_system_call (curl_result , " curl" )
273-
274- local path_ok , path_data = pcall (vim .fn .json_decode , curl_result .stdout )
275- if path_ok and (path_data .directory or path_data .worktree ) then
276- return path_data
277- else
278- error (" Failed to parse `opencode` CWD data: " .. curl_result .stdout , 0 )
279- end
269+ --- @param on_success fun ( response : opencode.cli.client.PathResponse )
270+ --- @param on_error fun ()
271+ function M .get_path (port , on_success , on_error )
272+ M .call (port , " /path" , " GET" , nil , on_success , on_error )
280273end
281274
282275--- @class opencode.cli.client.Event
288281---
289282--- @param port number
290283--- @param callback fun ( response : opencode.cli.client.Event )| nil
284+ --- @return number job_id
291285function M .sse_subscribe (port , callback )
292- if sse_state .port ~= port then
293- if sse_state .job_id then
294- vim .fn .jobstop (sse_state .job_id )
295- end
296-
297- sse_state = {
298- port = port ,
299- job_id = M .call (port , " /event" , " GET" , nil , callback ),
300- }
301- end
302- end
303-
304- function M .sse_unsubscribe ()
305- if sse_state .job_id then
306- vim .fn .jobstop (sse_state .job_id )
307- end
308-
309- sse_state = {
310- port = nil ,
311- job_id = nil ,
312- }
286+ return M .call (port , " /event" , " GET" , nil , callback )
313287end
314288
315289return M
0 commit comments