Add orphaned features management routes and UI integration (#819)

* test(copilot): add edge case test for error with code field

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Changes from fix/bug-fixes-1-0

* refactor(auto-mode): enhance orphaned feature detection and improve project initialization

- Updated detectOrphanedFeatures method to accept preloaded features, reducing redundant disk reads.
- Improved project initialization by creating required directories and files in parallel for better performance.
- Adjusted planning mode handling in UI components to clarify approval requirements for different modes.
- Added refresh functionality for file editor tabs to ensure content consistency with disk state.

These changes enhance performance, maintainability, and user experience across the application.

* feat(orphaned-features): add orphaned features management routes and UI integration

- Introduced new routes for managing orphaned features, including listing, resolving, and bulk resolving.
- Updated the UI to include an Orphaned Features section in project settings and navigation.
- Enhanced the execution service to support new orphaned feature functionalities.

These changes improve the application's capability to handle orphaned features effectively, enhancing user experience and project management.

* fix: Normalize line endings and resolve stale dirty states in file editor

* chore: Update .gitignore and enhance orphaned feature handling

- Added a blank line in .gitignore for better readability.
- Introduced a hash to worktree paths in orphaned feature resolution to prevent conflicts.
- Added validation for target branch existence during orphaned feature resolution.
- Improved prompt formatting in execution service for clarity.
- Enhanced error handling in project selector for project initialization failures.
- Refactored orphaned features section to improve state management and UI responsiveness.

These changes improve code maintainability and user experience when managing orphaned features.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
gsxdsm
2026-02-27 22:14:41 -08:00
committed by GitHub
parent 0196911d59
commit 1c0e460dd1
36 changed files with 2048 additions and 406 deletions

View File

@@ -288,12 +288,51 @@ export function useAutoMode(worktree?: WorktreeInfo) {
try {
const sessionData = readAutoModeSession();
const currentBranchName = branchNameRef.current;
const currentKey = getWorktreeSessionKey(currentProject.path, currentBranchName);
const projectPath = currentProject.path;
if (sessionData[currentKey] === true) {
setAutoModeRunning(currentProject.id, currentBranchName, true);
logger.debug(`Restored auto mode state from session storage for key: ${currentKey}`);
// Track restored worktrees to avoid redundant state updates
const restoredKeys = new Set<string>();
// Find all session storage keys that match this project
Object.entries(sessionData).forEach(([sessionKey, isRunning]) => {
if (!isRunning) return;
// Parse the session key: "projectPath::branchName" or "projectPath::__main__"
// Use lastIndexOf to split from the right, since projectPath may contain the delimiter
const delimiterIndex = sessionKey.lastIndexOf(SESSION_KEY_DELIMITER);
if (delimiterIndex === -1) {
// Malformed session key - skip it
logger.warn(`Malformed session storage key: ${sessionKey}`);
return;
}
const keyProjectPath = sessionKey.slice(0, delimiterIndex);
const keyBranchName = sessionKey.slice(delimiterIndex + SESSION_KEY_DELIMITER.length);
if (keyProjectPath !== projectPath) return;
// Validate branch name: __main__ means null (main worktree)
if (keyBranchName !== MAIN_WORKTREE_MARKER && !keyBranchName) {
logger.warn(`Invalid branch name in session key: ${sessionKey}`);
return;
}
const branchName = keyBranchName === MAIN_WORKTREE_MARKER ? null : keyBranchName;
// Skip if we've already restored this worktree (prevents duplicates)
const worktreeKey = getWorktreeSessionKey(projectPath, branchName);
if (restoredKeys.has(worktreeKey)) {
return;
}
restoredKeys.add(worktreeKey);
// Restore the auto mode running state in the store
setAutoModeRunning(currentProject.id, branchName, true);
});
if (restoredKeys.size > 0) {
logger.debug(
`Restored auto mode state for ${restoredKeys.size} worktree(s) from session storage`
);
}
} catch (error) {
logger.error('Error restoring auto mode state from session storage:', error);