feat: TUI usa SIGHUP para hot-reload de agente individual

restartAgent() ahora escribe run/reload.txt con el agentID y envía
SIGHUP al launcher en lugar de matar y reiniciar el proceso completo.
Si el launcher no está corriendo, conserva el comportamiento anterior
(stop + start completo).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 18:42:05 +00:00
parent 069f8758b1
commit 0b74513369
+17
View File
@@ -4,8 +4,10 @@ package tui
import ( import (
"fmt" "fmt"
"os"
"os/exec" "os/exec"
"strings" "strings"
"syscall"
"time" "time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
@@ -140,6 +142,9 @@ func (a *Adapter) disableAgent(id string) tea.Cmd {
func (a *Adapter) restartAgent(id string) tea.Cmd { func (a *Adapter) restartAgent(id string) tea.Cmd {
return func() tea.Msg { return func() tea.Msg {
pid := a.mgr.UnifiedPID()
if pid <= 0 {
// Launcher not running — fall back to full restart.
_ = a.mgr.StopUnified() _ = a.mgr.StopUnified()
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
err := a.mgr.StartUnified() err := a.mgr.StartUnified()
@@ -148,6 +153,18 @@ func (a *Adapter) restartAgent(id string) tea.Cmd {
} }
return puretui.MsgActionDone{AgentID: id, Action: "Restart", Err: err} return puretui.MsgActionDone{AgentID: id, Action: "Restart", Err: err}
} }
// Launcher is running — write target and send SIGHUP for hot-reload.
if id != "" {
_ = os.WriteFile("run/reload.txt", []byte(id), 0o644)
}
err := syscall.Kill(pid, syscall.SIGHUP)
if err != nil {
return puretui.MsgActionDone{AgentID: id, Action: "Restart", Err: err}
}
time.Sleep(1 * time.Second)
return puretui.MsgActionDone{AgentID: id, Action: "Restart", Err: nil}
}
} }
func (a *Adapter) startLauncher() tea.Cmd { func (a *Adapter) startLauncher() tea.Cmd {