From f0d1d5de89480188641c9d743abab44fa0e82117 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Wed, 8 Oct 2025 21:56:32 +0200 Subject: [PATCH] chore: apply requested changes --- apps/cli/src/commands/autopilot.command.ts | 2 +- .../src/services/preflight-checker.service.ts | 9 +++++--- packages/tm-core/src/utils/git-utils.ts | 21 +++++++++++++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/apps/cli/src/commands/autopilot.command.ts b/apps/cli/src/commands/autopilot.command.ts index 112847cf..d657de97 100644 --- a/apps/cli/src/commands/autopilot.command.ts +++ b/apps/cli/src/commands/autopilot.command.ts @@ -184,7 +184,7 @@ export class AutopilotCommand extends Command { padding: 1, borderStyle: 'round', borderColor: 'cyan', - width: process.stdout.columns * 0.95 || 100 + width: process.stdout.columns ? process.stdout.columns * 0.95 : 100 } ) ); diff --git a/packages/tm-core/src/services/preflight-checker.service.ts b/packages/tm-core/src/services/preflight-checker.service.ts index 30ff45e2..abb8870b 100644 --- a/packages/tm-core/src/services/preflight-checker.service.ts +++ b/packages/tm-core/src/services/preflight-checker.service.ts @@ -124,7 +124,8 @@ export class PreflightChecker { // Check for changes (staged/unstaged/untracked) without requiring HEAD const status = execSync('git status --porcelain', { cwd: this.projectRoot, - encoding: 'utf-8' + encoding: 'utf-8', + timeout: 5000 }); if (status.trim().length > 0) { return { @@ -266,7 +267,8 @@ export class PreflightChecker { const version = execSync(`${command} ${versionArgs.join(' ')}`, { cwd: this.projectRoot, encoding: 'utf-8', - stdio: 'pipe' + stdio: 'pipe', + timeout: 5000 }) .trim() .split('\n')[0]; @@ -294,7 +296,8 @@ export class PreflightChecker { const version = execSync('gh --version', { cwd: this.projectRoot, encoding: 'utf-8', - stdio: 'pipe' + stdio: 'pipe', + timeout: 5000 }) .trim() .split('\n')[0]; diff --git a/packages/tm-core/src/utils/git-utils.ts b/packages/tm-core/src/utils/git-utils.ts index 722614c2..f08e31d5 100644 --- a/packages/tm-core/src/utils/git-utils.ts +++ b/packages/tm-core/src/utils/git-utils.ts @@ -129,11 +129,12 @@ export async function getRemoteBranches( 'git branch -r --format="%(refname:short)"', { cwd: projectRoot, maxBuffer: 10 * 1024 * 1024 } ); - return stdout + const names = stdout .trim() .split('\n') .filter((branch) => branch.length > 0 && !branch.includes('HEAD')) .map((branch) => branch.replace(/^[^/]+\//, '').trim()); + return Array.from(new Set(names)); } catch (error) { return []; } @@ -220,7 +221,8 @@ export async function getDefaultBranch( // Parse `git remote show` (preferred) try { const { stdout } = await execAsync(`git remote show ${primary}`, { - cwd: projectRoot + cwd: projectRoot, + maxBuffer: 10 * 1024 * 1024 }); const m = stdout.match(/HEAD branch:\s+([^\s]+)/); if (m) return m[1].trim(); @@ -264,8 +266,10 @@ export async function isOnDefaultBranch(projectRoot: string): Promise { } try { - const currentBranch = await getCurrentBranch(projectRoot); - const defaultBranch = await getDefaultBranch(projectRoot); + const [currentBranch, defaultBranch] = await Promise.all([ + getCurrentBranch(projectRoot), + getDefaultBranch(projectRoot) + ]); return ( currentBranch !== null && defaultBranch !== null && @@ -357,6 +361,15 @@ export async function getWorktrees( for (const line of lines) { if (line.startsWith('worktree ')) { + // flush previous entry if present + if (current.path) { + worktrees.push({ + path: current.path, + branch: current.branch || null, + head: current.head || '' + }); + current = {}; + } current.path = line.substring(9); } else if (line.startsWith('HEAD ')) { current.head = line.substring(5);