Files
fn_registry/functions/infra/agent_cleanup_worktree.go
egutierrez fe0265c3bf docs(0133): MIGRATION.md + growth log placeholder + drift fix
- modules/data_table/MIGRATION.md: porting guide + release checklist 1.0.0-stable
- data_table.md: growth log entry commented for post-gate bump
- data_table.md: fix error_type Go remnant ("error_go_core" -> "") in C++ module
- cpp/CMakeLists.txt: SQLite3 optional dep for data_table_bench (cross-windows)
- agent_cleanup_worktree.go: !windows build tag (uses unix-only syscalls)
- dev/issues/0133-cpp-data-table-10m-rows.md: issue tracking

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:56:14 +02:00

62 lines
1.8 KiB
Go

//go:build !windows
package infra
import (
"fmt"
"os/exec"
"strings"
"syscall"
"time"
)
// AgentCleanupWorktree tears down a worktree previously created by
// AgentLaunchWorktree: kills the claude PID (SIGTERM, then SIGKILL after 1s),
// removes the git worktree (force) and deletes the branch.
//
// All three steps are best-effort; we only return an error when ALL three
// fail, so callers can call this on partially-initialised runs safely.
//
// Impure: signals processes, runs git, touches the filesystem.
func AgentCleanupWorktree(repoRoot, branch, worktreePath string, pid int) error {
var killErr, wtErr, brErr error
// 1. Kill the process tree if a PID was provided.
if pid > 0 {
if err := syscall.Kill(pid, syscall.SIGTERM); err != nil {
killErr = err
} else {
// Give it ~1s to exit gracefully, then SIGKILL if still alive.
time.Sleep(1 * time.Second)
if alive := syscall.Kill(pid, 0); alive == nil {
if err := syscall.Kill(pid, syscall.SIGKILL); err != nil {
killErr = err
}
}
}
}
// 2. Remove worktree (force).
if worktreePath != "" {
out, err := exec.Command("git", "-C", repoRoot, "worktree", "remove", "--force", worktreePath).CombinedOutput()
if err != nil {
wtErr = fmt.Errorf("worktree remove: %v: %s", err, strings.TrimSpace(string(out)))
}
}
// 3. Delete the branch.
if branch != "" {
out, err := exec.Command("git", "-C", repoRoot, "branch", "-D", branch).CombinedOutput()
if err != nil {
brErr = fmt.Errorf("branch -D: %v: %s", err, strings.TrimSpace(string(out)))
}
}
// Only error out if every requested step failed. Individual failures are
// expected (e.g. cleanup called twice, dangling branch already gone).
if killErr != nil && wtErr != nil && brErr != nil {
return fmt.Errorf("cleanup failed: kill=%v; worktree=%v; branch=%v", killErr, wtErr, brErr)
}
return nil
}