You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kickstart.nvim/lua/nvim-claude/registry.lua

199 lines
4.4 KiB
Lua

-- Agent registry module for nvim-claude
local M = {}
local utils = require('nvim-claude.utils')
-- Registry data
M.agents = {}
M.registry_path = nil
-- Initialize registry
function M.setup(config)
-- Set up registry directory
local data_dir = vim.fn.stdpath('data') .. '/nvim-claude'
utils.ensure_dir(data_dir)
M.registry_path = data_dir .. '/registry.json'
-- Load existing registry
M.load()
end
-- Load registry from disk
function M.load()
local content = utils.read_file(M.registry_path)
if content then
local ok, data = pcall(vim.json.decode, content)
if ok and type(data) == 'table' then
M.agents = data
M.validate_agents()
else
M.agents = {}
end
else
M.agents = {}
end
end
-- Save registry to disk
function M.save()
if not M.registry_path then return false end
local content = vim.json.encode(M.agents)
return utils.write_file(M.registry_path, content)
end
-- Validate agents (remove stale entries)
function M.validate_agents()
local valid_agents = {}
local now = os.time()
for id, agent in pairs(M.agents) do
-- Check if agent directory still exists
if utils.file_exists(agent.work_dir .. '/mission.log') then
-- Check if tmux window still exists
local window_exists = M.check_window_exists(agent.window_id)
if window_exists then
agent.status = 'active'
valid_agents[id] = agent
else
-- Window closed, mark as completed
agent.status = 'completed'
agent.end_time = agent.end_time or now
valid_agents[id] = agent
end
end
end
M.agents = valid_agents
M.save()
end
-- Check if tmux window exists
function M.check_window_exists(window_id)
if not window_id then return false end
local cmd = string.format("tmux list-windows -F '#{window_id}' | grep -q '^%s$'", window_id)
local result = os.execute(cmd)
return result == 0
end
-- Register a new agent
function M.register(task, work_dir, window_id, window_name)
local id = utils.timestamp() .. '-' .. math.random(1000, 9999)
local agent = {
id = id,
task = task,
work_dir = work_dir,
window_id = window_id,
window_name = window_name,
start_time = os.time(),
status = 'active',
project_root = utils.get_project_root(),
}
M.agents[id] = agent
M.save()
return id
end
-- Get agent by ID
function M.get(id)
return M.agents[id]
end
-- Get all agents for current project
function M.get_project_agents()
local project_root = utils.get_project_root()
local project_agents = {}
for id, agent in pairs(M.agents) do
if agent.project_root == project_root then
project_agents[id] = agent
end
end
return project_agents
end
-- Get active agents count
function M.get_active_count()
local count = 0
for _, agent in pairs(M.agents) do
if agent.status == 'active' then
count = count + 1
end
end
return count
end
-- Update agent status
function M.update_status(id, status)
if M.agents[id] then
M.agents[id].status = status
if status == 'completed' or status == 'failed' then
M.agents[id].end_time = os.time()
end
M.save()
end
end
-- Remove agent
function M.remove(id)
M.agents[id] = nil
M.save()
end
-- Clean up old agents
function M.cleanup(days)
if not days or days < 0 then return end
local cutoff = os.time() - (days * 24 * 60 * 60)
local removed = 0
for id, agent in pairs(M.agents) do
if agent.status ~= 'active' and agent.end_time and agent.end_time < cutoff then
-- Remove work directory
if agent.work_dir and utils.file_exists(agent.work_dir) then
local cmd = string.format('rm -rf "%s"', agent.work_dir)
utils.exec(cmd)
end
M.agents[id] = nil
removed = removed + 1
end
end
if removed > 0 then
M.save()
end
return removed
end
-- Format agent for display
function M.format_agent(agent)
local age = os.difftime(os.time(), agent.start_time)
local age_str
if age < 60 then
age_str = string.format('%ds', age)
elseif age < 3600 then
age_str = string.format('%dm', math.floor(age / 60))
elseif age < 86400 then
age_str = string.format('%dh', math.floor(age / 3600))
else
age_str = string.format('%dd', math.floor(age / 86400))
end
return string.format(
'[%s] %s (%s) - %s',
agent.status:upper(),
agent.task,
age_str,
agent.window_name or 'unknown'
)
end
return M