Skip to content

Commit 0f3b34c

Browse files
committed
fix: auto-set cwd in API queries
- Remove server restart logic on directory change - Set default directory to current working directory in API client queries - Change DirChangedPre to DirChanged autocmd for proper timing
1 parent 9fdb565 commit 0f3b34c

5 files changed

Lines changed: 18 additions & 93 deletions

File tree

lua/opencode/api_client.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ function OpencodeApiClient:_call(endpoint, method, body, query)
6262
local url = self.base_url .. endpoint
6363

6464
if query then
65+
if not query.directory then
66+
query.directory = vim.fn.getcwd()
67+
end
68+
6569
local params = {}
6670

6771
for k, v in pairs(query) do

lua/opencode/core.lua

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -548,31 +548,25 @@ end
548548
--- @return Promise<void>
549549
M.handle_directory_change = Promise.async(function()
550550
local log = require('opencode.log')
551+
if not state.active_session then
552+
is_new = true
553+
state.active_session = M.create_new_session():await()
554+
end
551555

552556
if state.opencode_server then
553-
vim.notify('Directory changed, restarting Opencode server...', vim.log.levels.INFO)
554-
log.info('Shutting down Opencode server due to directory change...')
555-
556-
state.opencode_server:shutdown():await()
557+
vim.notify('Working directory changed.', vim.log.levels.INFO)
558+
log.debug('Working directory change %s', vim.inspect({ cwd = vim.fn.getcwd() }))
557559

558560
vim.defer_fn(
559561
Promise.async(function()
560-
state.opencode_server = nil
561-
server_job.ensure_server():await()
562-
563562
vim.notify('Loading last session for new working dir [' .. vim.fn.getcwd() .. ']', vim.log.levels.INFO)
564563

565564
state.active_session = nil
566565
state.last_sent_context = nil
567566
context.unload_attachments()
568567

569568
local is_new = false
570-
state.active_session = session.get_last_workspace_session():await()
571-
572-
if not state.active_session then
573-
is_new = true
574-
state.active_session = M.create_new_session():await()
575-
end
569+
state.active_session = session.get_last_workspace_session():await() or M.create_new_session():await()
576570

577571
log.debug(
578572
'Loaded session for new working dir' .. vim.inspect({ session = state.active_session, is_new = is_new })

lua/opencode/ui/autocmds.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function M.setup_autocmds(windows)
4949
end,
5050
})
5151

52-
vim.api.nvim_create_autocmd('DirChangedPre', {
52+
vim.api.nvim_create_autocmd('DirChanged', {
5353
group = group,
5454
callback = function(event)
5555
local core = require('opencode.core')

tests/unit/api_client_spec.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ describe('api_client', function()
6262
local server_job = require('opencode.server_job')
6363
local original_call_api = server_job.call_api
6464
local captured_calls = {}
65+
local original_cwd = vim.fn.getcwd
66+
vim.fn.getcwd = function()
67+
return '/current/directory'
68+
end
6569

6670
server_job.call_api = function(url, method, body)
6771
table.insert(captured_calls, { url = url, method = method, body = body })
@@ -74,7 +78,7 @@ describe('api_client', function()
7478

7579
-- Test without query params
7680
client:list_projects()
77-
assert.are.equal('http://localhost:8080/project', captured_calls[1].url)
81+
assert.are.equal('http://localhost:8080/project?directory=/current/directory', captured_calls[1].url)
7882
assert.are.equal('GET', captured_calls[1].method)
7983

8084
-- Test with query params
@@ -95,5 +99,6 @@ describe('api_client', function()
9599

96100
-- Restore original function
97101
server_job.call_api = original_call_api
102+
vim.fn.getcwd = original_cwd
98103
end)
99104
end)

tests/unit/core_spec.lua

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -484,72 +484,14 @@ describe('opencode.core', function()
484484
fn()
485485
end
486486

487-
stub(server_job, 'ensure_server').invokes(function()
488-
local p = Promise.new()
489-
p:resolve({
490-
is_running = function()
491-
return true
492-
end,
493-
shutdown = function()
494-
return Promise.new():resolve()
495-
end,
496-
url = 'http://127.0.0.1:4000',
497-
})
498-
return p
499-
end)
500487
stub(context, 'unload_attachments')
501488
end)
502489

503490
after_each(function()
504491
vim.defer_fn = original_defer_fn
505-
if server_job.ensure_server.revert then
506-
server_job.ensure_server:revert()
507-
end
508-
if context.unload_attachments.revert then
509-
context.unload_attachments:revert()
510-
end
511-
end)
512-
513-
it('does nothing when no server is running', function()
514-
state.opencode_server = nil
515-
state.active_session = { id = 'sess1' }
516-
517-
core.handle_directory_change():wait()
518-
519-
assert.is_nil(state.opencode_server)
520-
assert.equal('sess1', state.active_session.id)
521-
assert.stub(server_job.ensure_server).was_not_called()
522-
end)
523-
524-
it('shuts down existing server and starts new one', function()
525-
local shutdown_called = false
526-
state.opencode_server = {
527-
is_running = function()
528-
return true
529-
end,
530-
shutdown = function()
531-
shutdown_called = true
532-
return Promise.new():resolve()
533-
end,
534-
url = 'http://127.0.0.1:4000',
535-
}
536-
537-
core.handle_directory_change():wait()
538-
539-
assert.is_true(shutdown_called)
540-
assert.stub(server_job.ensure_server).was_called()
541492
end)
542493

543494
it('clears active session and context', function()
544-
state.opencode_server = {
545-
is_running = function()
546-
return true
547-
end,
548-
shutdown = function()
549-
return Promise.new():resolve()
550-
end,
551-
url = 'http://127.0.0.1:4000',
552-
}
553495
state.active_session = { id = 'old-session' }
554496
state.last_sent_context = { some = 'context' }
555497

@@ -563,16 +505,6 @@ describe('opencode.core', function()
563505
end)
564506

565507
it('loads last workspace session for new directory', function()
566-
state.opencode_server = {
567-
is_running = function()
568-
return true
569-
end,
570-
shutdown = function()
571-
return Promise.new():resolve()
572-
end,
573-
url = 'http://127.0.0.1:4000',
574-
}
575-
576508
core.handle_directory_change():wait()
577509

578510
assert.truthy(state.active_session)
@@ -581,16 +513,6 @@ describe('opencode.core', function()
581513
end)
582514

583515
it('creates new session when no last session exists', function()
584-
state.opencode_server = {
585-
is_running = function()
586-
return true
587-
end,
588-
shutdown = function()
589-
return Promise.new():resolve()
590-
end,
591-
url = 'http://127.0.0.1:4000',
592-
}
593-
594516
-- Override stub to return nil (no last session)
595517
session.get_last_workspace_session:revert()
596518
stub(session, 'get_last_workspace_session').invokes(function()

0 commit comments

Comments
 (0)