fix(done): handle getcwd errors when worktree deleted (hq-3xaxy)
gt done now completes successfully even if the polecat's worktree is deleted mid-operation by the Witness or another process. Changes: - Add FindFromCwdWithFallback() that returns townRoot from GT_TOWN_ROOT env var when getcwd fails - Update runDone() to use fallback paths and env vars (GT_BRANCH, GT_POLECAT) when cwd is unavailable - Update updateAgentStateOnDone() to use env vars (GT_ROLE, GT_RIG, GT_POLECAT) for role detection fallback - All bead operations are now explicitly non-fatal with warnings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
beads/crew/emma
parent
392ff1d31b
commit
f9ca7bb87b
@@ -92,14 +92,46 @@ func FindFromCwd() (string, error) {
|
||||
}
|
||||
|
||||
// FindFromCwdOrError is like FindFromCwd but returns an error if not found.
|
||||
// If getcwd fails (e.g., worktree deleted), falls back to GT_TOWN_ROOT env var.
|
||||
func FindFromCwdOrError() (string, error) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
// Fallback: try GT_TOWN_ROOT env var (set by polecat sessions)
|
||||
if townRoot := os.Getenv("GT_TOWN_ROOT"); townRoot != "" {
|
||||
// Verify it's actually a workspace
|
||||
if _, statErr := os.Stat(filepath.Join(townRoot, PrimaryMarker)); statErr == nil {
|
||||
return townRoot, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("getting current directory: %w", err)
|
||||
}
|
||||
return FindOrError(cwd)
|
||||
}
|
||||
|
||||
// FindFromCwdWithFallback is like FindFromCwdOrError but returns (townRoot, cwd, error).
|
||||
// If getcwd fails, returns (townRoot, "", nil) using GT_TOWN_ROOT fallback.
|
||||
// This is useful for commands like `gt done` that need to continue even if the
|
||||
// working directory is deleted (e.g., polecat worktree nuked by Witness).
|
||||
func FindFromCwdWithFallback() (townRoot string, cwd string, err error) {
|
||||
cwd, err = os.Getwd()
|
||||
if err != nil {
|
||||
// Fallback: try GT_TOWN_ROOT env var
|
||||
if townRoot = os.Getenv("GT_TOWN_ROOT"); townRoot != "" {
|
||||
// Verify it's actually a workspace
|
||||
if _, statErr := os.Stat(filepath.Join(townRoot, PrimaryMarker)); statErr == nil {
|
||||
return townRoot, "", nil // cwd is gone but townRoot is valid
|
||||
}
|
||||
}
|
||||
return "", "", fmt.Errorf("getting current directory: %w", err)
|
||||
}
|
||||
|
||||
townRoot, err = FindOrError(cwd)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return townRoot, cwd, nil
|
||||
}
|
||||
|
||||
// IsWorkspace checks if the given directory is a Gas Town workspace root.
|
||||
// A directory is a workspace if it has a primary marker (mayor/town.json)
|
||||
// or a secondary marker (mayor/ directory).
|
||||
|
||||
Reference in New Issue
Block a user