Skip to content

Commit aa51f47

Browse files
committed
feat: listen to DirChanged
1 parent 98b4d22 commit aa51f47

4 files changed

Lines changed: 90 additions & 6 deletions

File tree

lua/mcphub/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
local M = {}
22

3-
local SHUTDOWN_DELAY = 10 * 60 * 1000 -- 10 minutes
3+
local SHUTDOWN_DELAY = 60 * 1000 -- 1 minute
44

55
---@class MCPHub.WorkspaceConfig
66
---@field enabled boolean Master switch for workspace-specific hubs

lua/mcphub/hub.lua

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,52 @@ function MCPHub:start()
329329
end)
330330
end
331331

332+
--- Handle directory changes - reconnect to appropriate workspace hub
333+
function MCPHub:handle_directory_change()
334+
if not State.config.workspace.enabled then
335+
return
336+
end
337+
338+
log.debug("Directory changed, checking if workspace hub should change")
339+
340+
-- Resolve new context for current directory
341+
local new_context = self:resolve_context()
342+
if not new_context then
343+
log.warn("Failed to resolve context after directory change")
344+
return
345+
end
346+
347+
-- Compare with current context
348+
local current_context = State.current_hub
349+
if not current_context then
350+
log.debug("No current hub context, starting new hub")
351+
self:start()
352+
return
353+
end
354+
355+
vim.notify("Dir changed")
356+
357+
-- Check if we need to switch hubs
358+
local needs_switch = false
359+
local reason = ""
360+
361+
if new_context.port ~= current_context.port then
362+
needs_switch = true
363+
reason = string.format("port change (%d -> %d)", current_context.port, new_context.port)
364+
end
365+
366+
if needs_switch then
367+
log.debug("Switching hub due to: " .. reason)
368+
-- self:restart(nil, reason)
369+
self:stop_sse()
370+
vim.schedule(function()
371+
self:start()
372+
end)
373+
else
374+
log.debug("No hub switch needed - context unchanged")
375+
end
376+
end
377+
332378
function MCPHub:handle_hub_ready()
333379
self.ready = true
334380
self.is_restarting = false
@@ -1150,8 +1196,6 @@ function MCPHub:hard_refresh(callback)
11501196
if not self:ensure_ready() then
11511197
return
11521198
end
1153-
-- Make sure to update the cache as well
1154-
config_manager.refresh_config()
11551199
self:api_request("GET", "refresh", {
11561200
callback = function(response, err)
11571201
if err then
@@ -1189,7 +1233,10 @@ function MCPHub:handle_hub_stopping()
11891233
end
11901234
end
11911235

1192-
function MCPHub:restart(callback)
1236+
--- Restart the MCP Hub server
1237+
--- @param callback function|nil Optional callback to execute after restart
1238+
--- @param reason string|nil Optional reason for the restart
1239+
function MCPHub:restart(callback, reason)
11931240
if not self:ensure_ready() then
11941241
return self:start()
11951242
end

lua/mcphub/init.lua

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function M.setup(opts)
151151
end
152152
end
153153

154-
-- Setup cleanup
154+
-- Setup cleanup and directory change handling
155155
local group = vim.api.nvim_create_augroup("mcphub_cleanup", {
156156
clear = true,
157157
})
@@ -165,6 +165,21 @@ function M.setup(opts)
165165
end,
166166
})
167167

168+
-- Handle directory changes for workspace-aware mode
169+
if config.workspace.enabled then
170+
vim.api.nvim_create_autocmd("DirChanged", {
171+
group = group,
172+
callback = vim.schedule_wrap(function()
173+
if State.hub_instance then
174+
-- Small delay to ensure directory change is complete
175+
vim.defer_fn(function()
176+
State.hub_instance:handle_directory_change()
177+
end, 100)
178+
end
179+
end),
180+
})
181+
end
182+
168183
-- Start version check
169184
local ok, job = pcall(function()
170185
---@diagnostic disable-next-line: missing-fields

lua/mcphub/utils/renderer.lua

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ function M.render_servers_grouped(servers, lines, current_line, view)
3939
current_line = current_line + 1
4040
end
4141
end
42+
-- Show empty project group if no marker files are found
43+
if #config_files == 1 and State.config.workspace.enabled then
44+
table.insert(lines, Text.empty_line())
45+
current_line = current_line + 1
46+
local is_global = false
47+
local icon = is_global and Text.icons.globe or Text.icons.folder
48+
local prefix = icon .. " " .. (is_global and "Global" or "Project") .. " "
49+
local header_line = NuiLine():append(prefix, Text.highlights.title)
50+
table.insert(lines, Text.pad_line(header_line))
51+
current_line = current_line + 1
52+
local line = NuiLine()
53+
local look_for = table.concat(State.config.workspace.look_for or {}, ", ")
54+
line:append(
55+
string.format("Could not find any local config files [%s] in the path", look_for),
56+
Text.highlights.muted
57+
)
58+
table.insert(lines, Text.pad_line(line, nil, 4))
59+
current_line = current_line + 1
60+
end
4261

4362
return current_line
4463
end
@@ -85,7 +104,10 @@ function M.render_server_group(config_source, servers, lines, current_line, view
85104
table.insert(
86105
lines,
87106
Text.pad_line(
88-
NuiLine():append("No servers found (Install from Marketplace)", Text.highlights.muted),
107+
NuiLine():append(
108+
string.format("No servers found in `%s` (Install from Marketplace)", config_source),
109+
Text.highlights.muted
110+
),
89111
nil,
90112
4
91113
)

0 commit comments

Comments
 (0)