Fix deleting worktree crash and improve UX (#798)

* Changes from fix/deleting-worktree

* fix: Improve worktree deletion safety and branch cleanup logic

* fix: Improve error handling and async operations across auto-mode and worktree services

* Update apps/server/src/routes/auto-mode/routes/analyze-project.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
gsxdsm
2026-02-22 00:58:00 -08:00
committed by GitHub
parent 1d732916f1
commit 2f071a1ba3
15 changed files with 300 additions and 110 deletions

View File

@@ -910,7 +910,7 @@ export class AutoModeServiceFacade {
if (feature) {
title = feature.title;
description = feature.description;
branchName = feature.branchName;
branchName = feature.branchName ?? undefined;
}
} catch {
// Silently ignore
@@ -1140,10 +1140,31 @@ export class AutoModeServiceFacade {
// ===========================================================================
/**
* Save execution state for recovery
* Save execution state for recovery.
*
* Uses the active auto-loop config for each worktree so that the persisted
* state reflects the real branch and maxConcurrency values rather than the
* hard-coded fallbacks (null / DEFAULT_MAX_CONCURRENCY).
*/
private async saveExecutionState(): Promise<void> {
return this.saveExecutionStateForProject(null, DEFAULT_MAX_CONCURRENCY);
const projectWorktrees = this.autoLoopCoordinator
.getActiveWorktrees()
.filter((w) => w.projectPath === this.projectPath);
if (projectWorktrees.length === 0) {
// No active auto loops — save with defaults as a best-effort fallback.
return this.saveExecutionStateForProject(null, DEFAULT_MAX_CONCURRENCY);
}
// Save state for every active worktree using its real config values.
for (const { branchName } of projectWorktrees) {
const config = this.autoLoopCoordinator.getAutoLoopConfigForProject(
this.projectPath,
branchName
);
const maxConcurrency = config?.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
await this.saveExecutionStateForProject(branchName, maxConcurrency);
}
}
/**

View File

@@ -159,7 +159,7 @@ export class GlobalAutoModeService {
if (feature) {
title = feature.title;
description = feature.description;
branchName = feature.branchName;
branchName = feature.branchName ?? undefined;
}
} catch {
// Silently ignore