refactor: normalize branch name handling and enhance auto mode settings merging

- Updated branch name normalization to align with UI conventions, treating "main" as null for consistency.
- Implemented deep merging of `autoModeByWorktree` settings to preserve existing entries during updates.
- Enhanced the BoardView component to persist max concurrency settings to the server, ensuring accurate capacity checks.
- Added error handling for feature rollback persistence in useBoardActions.

These changes improve the reliability and consistency of auto mode settings across the application.
This commit is contained in:
webdevcody
2026-01-22 09:43:28 -05:00
parent 0155da0be5
commit 0fdda11b09
5 changed files with 50 additions and 4 deletions

View File

@@ -534,7 +534,11 @@ export class AutoModeService {
const autoModeByWorktree = settings.autoModeByWorktree;
if (projectId && autoModeByWorktree && typeof autoModeByWorktree === 'object') {
const key = `${projectId}::${branchName ?? '__main__'}`;
// Normalize branch name to match UI convention:
// - null or "main" -> "__main__" (UI treats "main" as the main worktree)
// This ensures consistency with how the UI stores worktree settings
const normalizedBranch = branchName === 'main' ? null : branchName;
const key = `${projectId}::${normalizedBranch ?? '__main__'}`;
const entry = autoModeByWorktree[key];
if (entry && typeof entry.maxConcurrency === 'number') {
return entry.maxConcurrency;
@@ -1039,7 +1043,9 @@ export class AutoModeService {
}> {
// Load feature to get branchName
const feature = await this.loadFeature(projectPath, featureId);
const branchName = feature?.branchName ?? null;
const rawBranchName = feature?.branchName ?? null;
// Normalize "main" to null to match UI convention for main worktree
const branchName = rawBranchName === 'main' ? null : rawBranchName;
// Get per-worktree limit
const maxAgents = await this.resolveMaxConcurrency(projectPath, branchName);

View File

@@ -621,6 +621,21 @@ export class SettingsService {
};
}
// Deep merge autoModeByWorktree if provided (preserves other worktree entries)
if (sanitizedUpdates.autoModeByWorktree) {
type WorktreeEntry = { maxConcurrency: number; branchName: string | null };
const mergedAutoModeByWorktree: Record<string, WorktreeEntry> = {
...current.autoModeByWorktree,
};
for (const [key, value] of Object.entries(sanitizedUpdates.autoModeByWorktree)) {
mergedAutoModeByWorktree[key] = {
...mergedAutoModeByWorktree[key],
...value,
};
}
updated.autoModeByWorktree = mergedAutoModeByWorktree;
}
await writeSettingsJson(settingsPath, updated);
logger.info('Global settings updated');