mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 20:43:36 +00:00
Merge branch 'feature/worktrees' of github.com:AutoMaker-Org/automaker into feature/worktrees
This commit is contained in:
@@ -41,7 +41,12 @@ async function findExistingWorktreeForBranch(
|
|||||||
} else if (line === "" && currentPath && currentBranch) {
|
} else if (line === "" && currentPath && currentBranch) {
|
||||||
// End of a worktree entry
|
// End of a worktree entry
|
||||||
if (currentBranch === branchName) {
|
if (currentBranch === branchName) {
|
||||||
return { path: currentPath, branch: currentBranch };
|
// Resolve to absolute path - git may return relative paths
|
||||||
|
// Critical for cross-platform compatibility (Windows, macOS, Linux)
|
||||||
|
const resolvedPath = path.isAbsolute(currentPath)
|
||||||
|
? path.resolve(currentPath)
|
||||||
|
: path.resolve(projectPath, currentPath);
|
||||||
|
return { path: resolvedPath, branch: currentBranch };
|
||||||
}
|
}
|
||||||
currentPath = null;
|
currentPath = null;
|
||||||
currentBranch = null;
|
currentBranch = null;
|
||||||
@@ -50,7 +55,11 @@ async function findExistingWorktreeForBranch(
|
|||||||
|
|
||||||
// Check the last entry (if file doesn't end with newline)
|
// Check the last entry (if file doesn't end with newline)
|
||||||
if (currentPath && currentBranch && currentBranch === branchName) {
|
if (currentPath && currentBranch && currentBranch === branchName) {
|
||||||
return { path: currentPath, branch: currentBranch };
|
// Resolve to absolute path for cross-platform compatibility
|
||||||
|
const resolvedPath = path.isAbsolute(currentPath)
|
||||||
|
? path.resolve(currentPath)
|
||||||
|
: path.resolve(projectPath, currentPath);
|
||||||
|
return { path: resolvedPath, branch: currentBranch };
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -144,10 +153,13 @@ export function createCreateHandler() {
|
|||||||
// Track the branch so it persists in the UI even after worktree is removed
|
// Track the branch so it persists in the UI even after worktree is removed
|
||||||
await trackBranch(projectPath, branchName);
|
await trackBranch(projectPath, branchName);
|
||||||
|
|
||||||
|
// Resolve to absolute path for cross-platform compatibility
|
||||||
|
// normalizePath converts to forward slashes for API consistency
|
||||||
|
const absoluteWorktreePath = path.resolve(worktreePath);
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
worktree: {
|
worktree: {
|
||||||
path: normalizePath(worktreePath),
|
path: normalizePath(absoluteWorktreePath),
|
||||||
branch: branchName,
|
branch: branchName,
|
||||||
isNew: !branchExists,
|
isNew: !branchExists,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -207,10 +207,26 @@ export class AutoModeService {
|
|||||||
|
|
||||||
// Use provided worktree path if given, otherwise setup new worktree if enabled
|
// Use provided worktree path if given, otherwise setup new worktree if enabled
|
||||||
if (providedWorktreePath) {
|
if (providedWorktreePath) {
|
||||||
// User selected a specific worktree - use it directly
|
// Resolve to absolute path - critical for cross-platform compatibility
|
||||||
worktreePath = providedWorktreePath;
|
// On Windows, relative paths or paths with forward slashes may not work correctly with cwd
|
||||||
console.log(`[AutoMode] Using provided worktree path: ${worktreePath}`);
|
// On all platforms, absolute paths ensure commands execute in the correct directory
|
||||||
} else if (useWorktrees) {
|
try {
|
||||||
|
// Resolve relative paths relative to projectPath, absolute paths as-is
|
||||||
|
const resolvedPath = path.isAbsolute(providedWorktreePath)
|
||||||
|
? path.resolve(providedWorktreePath)
|
||||||
|
: path.resolve(projectPath, providedWorktreePath);
|
||||||
|
|
||||||
|
// Verify the path exists before using it
|
||||||
|
await fs.access(resolvedPath);
|
||||||
|
worktreePath = resolvedPath;
|
||||||
|
console.log(`[AutoMode] Using provided worktree path (resolved): ${worktreePath}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[AutoMode] Provided worktree path invalid or doesn't exist: ${providedWorktreePath}`, error);
|
||||||
|
// Fall through to create new worktree or use project path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!worktreePath && useWorktrees) {
|
||||||
// No specific worktree provided, create a new one for this feature
|
// No specific worktree provided, create a new one for this feature
|
||||||
worktreePath = await this.setupWorktree(
|
worktreePath = await this.setupWorktree(
|
||||||
projectPath,
|
projectPath,
|
||||||
@@ -219,7 +235,8 @@ export class AutoModeService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const workDir = worktreePath || projectPath;
|
// Ensure workDir is always an absolute path for cross-platform compatibility
|
||||||
|
const workDir = worktreePath ? path.resolve(worktreePath) : path.resolve(projectPath);
|
||||||
|
|
||||||
this.runningFeatures.set(featureId, {
|
this.runningFeatures.set(featureId, {
|
||||||
featureId,
|
featureId,
|
||||||
@@ -382,14 +399,21 @@ export class AutoModeService {
|
|||||||
|
|
||||||
// Use the provided worktreePath (from the feature's assigned branch)
|
// Use the provided worktreePath (from the feature's assigned branch)
|
||||||
// Fall back to project path if not provided
|
// Fall back to project path if not provided
|
||||||
let workDir = projectPath;
|
let workDir = path.resolve(projectPath);
|
||||||
let worktreePath: string | null = null;
|
let worktreePath: string | null = null;
|
||||||
|
|
||||||
if (providedWorktreePath) {
|
if (providedWorktreePath) {
|
||||||
try {
|
try {
|
||||||
await fs.access(providedWorktreePath);
|
// Resolve to absolute path - critical for cross-platform compatibility
|
||||||
workDir = providedWorktreePath;
|
// On Windows, relative paths or paths with forward slashes may not work correctly with cwd
|
||||||
worktreePath = providedWorktreePath;
|
// On all platforms, absolute paths ensure commands execute in the correct directory
|
||||||
|
const resolvedPath = path.isAbsolute(providedWorktreePath)
|
||||||
|
? path.resolve(providedWorktreePath)
|
||||||
|
: path.resolve(projectPath, providedWorktreePath);
|
||||||
|
|
||||||
|
await fs.access(resolvedPath);
|
||||||
|
workDir = resolvedPath;
|
||||||
|
worktreePath = resolvedPath;
|
||||||
} catch {
|
} catch {
|
||||||
// Worktree path provided but doesn't exist, use project path
|
// Worktree path provided but doesn't exist, use project path
|
||||||
console.log(`[AutoMode] Provided worktreePath doesn't exist: ${providedWorktreePath}, using project path`);
|
console.log(`[AutoMode] Provided worktreePath doesn't exist: ${providedWorktreePath}, using project path`);
|
||||||
@@ -863,7 +887,13 @@ Format your response as a structured markdown document.`;
|
|||||||
} else if (line === "" && currentPath && currentBranch) {
|
} else if (line === "" && currentPath && currentBranch) {
|
||||||
// End of a worktree entry
|
// End of a worktree entry
|
||||||
if (currentBranch === branchName) {
|
if (currentBranch === branchName) {
|
||||||
return currentPath;
|
// Resolve to absolute path - git may return relative paths
|
||||||
|
// On Windows, this is critical for cwd to work correctly
|
||||||
|
// On all platforms, absolute paths ensure consistent behavior
|
||||||
|
const resolvedPath = path.isAbsolute(currentPath)
|
||||||
|
? path.resolve(currentPath)
|
||||||
|
: path.resolve(projectPath, currentPath);
|
||||||
|
return resolvedPath;
|
||||||
}
|
}
|
||||||
currentPath = null;
|
currentPath = null;
|
||||||
currentBranch = null;
|
currentBranch = null;
|
||||||
@@ -872,7 +902,11 @@ Format your response as a structured markdown document.`;
|
|||||||
|
|
||||||
// Check the last entry (if file doesn't end with newline)
|
// Check the last entry (if file doesn't end with newline)
|
||||||
if (currentPath && currentBranch && currentBranch === branchName) {
|
if (currentPath && currentBranch && currentBranch === branchName) {
|
||||||
return currentPath;
|
// Resolve to absolute path for cross-platform compatibility
|
||||||
|
const resolvedPath = path.isAbsolute(currentPath)
|
||||||
|
? path.resolve(currentPath)
|
||||||
|
: path.resolve(projectPath, currentPath);
|
||||||
|
return resolvedPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -889,6 +923,7 @@ Format your response as a structured markdown document.`;
|
|||||||
// First, check if git already has a worktree for this branch (anywhere)
|
// First, check if git already has a worktree for this branch (anywhere)
|
||||||
const existingWorktree = await this.findExistingWorktreeForBranch(projectPath, branchName);
|
const existingWorktree = await this.findExistingWorktreeForBranch(projectPath, branchName);
|
||||||
if (existingWorktree) {
|
if (existingWorktree) {
|
||||||
|
// Path is already resolved to absolute in findExistingWorktreeForBranch
|
||||||
console.log(`[AutoMode] Found existing worktree for branch "${branchName}" at: ${existingWorktree}`);
|
console.log(`[AutoMode] Found existing worktree for branch "${branchName}" at: ${existingWorktree}`);
|
||||||
return existingWorktree;
|
return existingWorktree;
|
||||||
}
|
}
|
||||||
@@ -902,7 +937,8 @@ Format your response as a structured markdown document.`;
|
|||||||
// Check if worktree directory already exists (might not be linked to branch)
|
// Check if worktree directory already exists (might not be linked to branch)
|
||||||
try {
|
try {
|
||||||
await fs.access(worktreePath);
|
await fs.access(worktreePath);
|
||||||
return worktreePath;
|
// Return absolute path for cross-platform compatibility
|
||||||
|
return path.resolve(worktreePath);
|
||||||
} catch {
|
} catch {
|
||||||
// Create new worktree
|
// Create new worktree
|
||||||
}
|
}
|
||||||
@@ -919,13 +955,13 @@ Format your response as a structured markdown document.`;
|
|||||||
await execAsync(`git worktree add "${worktreePath}" ${branchName}`, {
|
await execAsync(`git worktree add "${worktreePath}" ${branchName}`, {
|
||||||
cwd: projectPath,
|
cwd: projectPath,
|
||||||
});
|
});
|
||||||
|
// Return absolute path for cross-platform compatibility
|
||||||
|
return path.resolve(worktreePath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Worktree creation failed, fall back to direct execution
|
// Worktree creation failed, fall back to direct execution
|
||||||
console.error(`[AutoMode] Worktree creation failed:`, error);
|
console.error(`[AutoMode] Worktree creation failed:`, error);
|
||||||
return projectPath;
|
return path.resolve(projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return worktreePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadFeature(
|
private async loadFeature(
|
||||||
|
|||||||
Reference in New Issue
Block a user