mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 20:43:36 +00:00
feat: enhance worktree management and feature filtering
- Added logic to show all local branches as suggestions in the branch autocomplete, allowing users to type new branch names. - Implemented current worktree information retrieval for filtering features based on the selected worktree's branch. - Updated feature handling to filter backlog features by the currently selected worktree branch, ensuring only relevant features are displayed. - Enhanced the WorktreeSelector component to utilize branch names for determining the appropriate worktree for features. - Introduced integration tests for worktree creation, deletion, and feature management to ensure robust functionality.
This commit is contained in:
@@ -62,6 +62,7 @@ interface DevServerInfo {
|
||||
interface FeatureInfo {
|
||||
id: string;
|
||||
worktreePath?: string;
|
||||
branchName?: string; // Used as fallback to determine which worktree the spinner should show on
|
||||
}
|
||||
|
||||
interface WorktreeSelectorProps {
|
||||
@@ -302,14 +303,25 @@ export function WorktreeSelector({
|
||||
const feature = features.find((f) => f.id === featureId);
|
||||
if (!feature) return false;
|
||||
|
||||
// For main worktree, check features with no worktreePath or matching projectPath
|
||||
// First, check if worktreePath is set and matches
|
||||
// Use pathsEqual for cross-platform compatibility (Windows uses backslashes)
|
||||
if (worktree.isMain) {
|
||||
return !feature.worktreePath || pathsEqual(feature.worktreePath, projectPath);
|
||||
if (feature.worktreePath) {
|
||||
if (worktree.isMain) {
|
||||
// Feature has worktreePath - show on main only if it matches projectPath
|
||||
return pathsEqual(feature.worktreePath, projectPath);
|
||||
}
|
||||
// For non-main worktrees, check if worktreePath matches
|
||||
return pathsEqual(feature.worktreePath, worktreeKey);
|
||||
}
|
||||
|
||||
// For other worktrees, check if worktreePath matches
|
||||
return pathsEqual(feature.worktreePath, worktreeKey);
|
||||
// If worktreePath is not set, use branchName as fallback
|
||||
if (feature.branchName) {
|
||||
// Feature has a branchName - show spinner on the worktree with matching branch
|
||||
return worktree.branch === feature.branchName;
|
||||
}
|
||||
|
||||
// No worktreePath and no branchName - default to main
|
||||
return worktree.isMain;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ interface UseBoardActionsProps {
|
||||
outputFeature: Feature | null;
|
||||
projectPath: string | null;
|
||||
onWorktreeCreated?: () => void;
|
||||
currentWorktreeBranch: string | null; // Branch name of the selected worktree for filtering
|
||||
}
|
||||
|
||||
export function useBoardActions({
|
||||
@@ -65,6 +66,7 @@ export function useBoardActions({
|
||||
outputFeature,
|
||||
projectPath,
|
||||
onWorktreeCreated,
|
||||
currentWorktreeBranch,
|
||||
}: UseBoardActionsProps) {
|
||||
const {
|
||||
addFeature,
|
||||
@@ -720,7 +722,24 @@ export function useBoardActions({
|
||||
);
|
||||
|
||||
const handleStartNextFeatures = useCallback(async () => {
|
||||
const backlogFeatures = features.filter((f) => f.status === "backlog");
|
||||
// Filter backlog features by the currently selected worktree branch
|
||||
// This ensures "G" only starts features from the filtered list
|
||||
const backlogFeatures = features.filter((f) => {
|
||||
if (f.status !== "backlog") return false;
|
||||
|
||||
// Determine the feature's branch (default to "main" if not set)
|
||||
const featureBranch = f.branchName || "main";
|
||||
|
||||
// If no worktree is selected (currentWorktreeBranch is null or main-like),
|
||||
// show features with no branch or "main"/"master" branch
|
||||
if (!currentWorktreeBranch || currentWorktreeBranch === "main" || currentWorktreeBranch === "master") {
|
||||
return !f.branchName || featureBranch === "main" || featureBranch === "master";
|
||||
}
|
||||
|
||||
// Otherwise, only show features matching the selected worktree branch
|
||||
return featureBranch === currentWorktreeBranch;
|
||||
});
|
||||
|
||||
const availableSlots =
|
||||
useAppStore.getState().maxConcurrency - runningAutoTasks.length;
|
||||
|
||||
@@ -734,7 +753,9 @@ export function useBoardActions({
|
||||
|
||||
if (backlogFeatures.length === 0) {
|
||||
toast.info("Backlog empty", {
|
||||
description: "No features in backlog to start.",
|
||||
description: currentWorktreeBranch && currentWorktreeBranch !== "main" && currentWorktreeBranch !== "master"
|
||||
? `No features in backlog for branch "${currentWorktreeBranch}".`
|
||||
: "No features in backlog to start.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -764,6 +785,7 @@ export function useBoardActions({
|
||||
getOrCreateWorktreeForFeature,
|
||||
persistFeatureUpdate,
|
||||
onWorktreeCreated,
|
||||
currentWorktreeBranch,
|
||||
]);
|
||||
|
||||
const handleDeleteAllVerified = useCallback(async () => {
|
||||
|
||||
Reference in New Issue
Block a user