* Changes from feature/worktree-view-customization * Feature: Git sync, set-tracking, and push divergence handling (#796) * Add quick-add feature with improved workflows (#802) * Changes from feature/quick-add * feat: Clarify system prompt and improve error handling across services. Address PR Feedback * feat: Improve PR description parsing and refactor event handling * feat: Add context options to pipeline orchestrator initialization * fix: Deduplicate React and handle CJS interop for use-sync-external-store Resolve "Cannot read properties of null (reading 'useState')" errors by deduplicating React/react-dom and ensuring use-sync-external-store is bundled together with React to prevent CJS packages from resolving to different React instances. * Changes from feature/worktree-view-customization * refactor: Remove unused worktree swap and highlight props * refactor: Consolidate feature completion logic and improve thinking level defaults * feat: Increase max turn limit to 10000 - Update DEFAULT_MAX_TURNS from 1000 to 10000 in settings-helpers.ts and agent-executor.ts - Update MAX_ALLOWED_TURNS from 2000 to 10000 in settings-helpers.ts - Update UI clamping logic from 2000 to 10000 in app-store.ts - Update fallback values from 1000 to 10000 in use-settings-sync.ts - Update default value from 1000 to 10000 in DEFAULT_GLOBAL_SETTINGS - Update documentation to reflect new range: 1-10000 Allows agents to perform up to 10000 turns for complex feature execution. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * feat: Add model resolution, improve session handling, and enhance UI stability * refactor: Remove unused sync and tracking branch props from worktree components * feat: Add PR number update functionality to worktrees. Address pr feedback * feat: Optimize Gemini CLI startup and add tool result tracking * refactor: Improve error handling and simplify worktree task cleanup --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
@automaker/git-utils
Git operations and utilities for AutoMaker.
Overview
This package provides git-related utilities including repository detection, status parsing, and diff generation for both tracked and untracked files.
Installation
npm install @automaker/git-utils
Exports
Repository Detection
Check if a path is a git repository.
import { isGitRepo } from '@automaker/git-utils';
const isRepo = await isGitRepo('/project/path');
if (isRepo) {
console.log('This is a git repository');
}
Status Parsing
Parse git status output into structured data.
import { parseGitStatus } from '@automaker/git-utils';
import type { FileStatus } from '@automaker/git-utils';
const statusOutput = await execAsync('git status --porcelain');
const files: FileStatus[] = parseGitStatus(statusOutput.stdout);
files.forEach((file) => {
console.log(`${file.statusText}: ${file.path}`);
// Example: "Modified: src/index.ts"
// Example: "Untracked: new-file.ts"
});
Diff Generation
Generate diffs including untracked files.
import {
generateSyntheticDiffForNewFile,
appendUntrackedFileDiffs,
getGitRepositoryDiffs,
} from '@automaker/git-utils';
// Generate diff for single untracked file
const diff = await generateSyntheticDiffForNewFile('/project/path', 'src/new-file.ts');
// Get complete repository diffs (tracked + untracked)
const result = await getGitRepositoryDiffs('/project/path');
console.log(result.diff); // Combined diff string
console.log(result.files); // Array of FileStatus
console.log(result.hasChanges); // Boolean
Non-Git Directory Support
Handle non-git directories by treating all files as new.
import { listAllFilesInDirectory, generateDiffsForNonGitDirectory } from '@automaker/git-utils';
// List all files (excluding build artifacts)
const files = await listAllFilesInDirectory('/project/path');
// Generate diffs for non-git directory
const result = await generateDiffsForNonGitDirectory('/project/path');
console.log(result.diff); // Synthetic diffs for all files
console.log(result.files); // All files as "New" status
Types
FileStatus
interface FileStatus {
status: string; // Git status code (M/A/D/R/C/U/?/!)
path: string; // File path relative to repo root
statusText: string; // Human-readable status
}
Status Codes
M- ModifiedA- AddedD- DeletedR- RenamedC- CopiedU- Updated?- Untracked!- Ignored- Unmodified
Status Text Examples
"Modified"- File has changes"Added"- New file in staging"Deleted"- File removed"Renamed"- File renamed"Untracked"- New file not in git"Modified (staged), Modified (unstaged)"- Changes in both areas
Usage Example
import { isGitRepo, getGitRepositoryDiffs, parseGitStatus } from '@automaker/git-utils';
async function getProjectChanges(projectPath: string) {
const isRepo = await isGitRepo(projectPath);
if (!isRepo) {
console.log('Not a git repository, analyzing all files...');
}
const result = await getGitRepositoryDiffs(projectPath);
if (!result.hasChanges) {
console.log('No changes detected');
return;
}
console.log(`Found ${result.files.length} changed files:\n`);
// Group by status
const byStatus = result.files.reduce(
(acc, file) => {
acc[file.statusText] = acc[file.statusText] || [];
acc[file.statusText].push(file.path);
return acc;
},
{} as Record<string, string[]>
);
Object.entries(byStatus).forEach(([status, paths]) => {
console.log(`${status}:`);
paths.forEach((path) => console.log(` - ${path}`));
});
return result.diff;
}
Features
Binary File Detection
Automatically detects binary files by extension and generates appropriate diff markers.
Supported binary extensions:
- Images:
.png,.jpg,.jpeg,.gif,.svg, etc. - Documents:
.pdf,.doc,.docx, etc. - Archives:
.zip,.tar,.gz, etc. - Media:
.mp3,.mp4,.wav, etc. - Fonts:
.ttf,.otf,.woff, etc.
Large File Handling
Files larger than 1MB show size information instead of full content.
Synthetic Diff Format
Generates unified diff format for untracked files:
diff --git a/new-file.ts b/new-file.ts
new file mode 100644
index 0000000..0000000
--- /dev/null
+++ b/new-file.ts
@@ -0,0 +1,10 @@
+export function hello() {
+ console.log('Hello');
+}
Directory Filtering
When scanning non-git directories, automatically excludes:
node_modules,.git,.automaker- Build outputs:
dist,build,out,tmp,.tmp - Framework caches:
.next,.nuxt,.cache,coverage - Language-specific:
__pycache__(Python),target(Rust),vendor(Go/PHP),.gradle(Gradle),.venv/venv(Python)
Error Handling
Git operations can fail for various reasons. This package provides graceful error handling patterns:
Common Error Scenarios
1. Repository Not Found
const isRepo = await isGitRepo('/path/does/not/exist');
// Returns: false (no exception thrown)
2. Not a Git Repository
const result = await getGitRepositoryDiffs('/not/a/git/repo');
// Fallback behavior: treats all files as "new"
// Returns synthetic diffs for all files in directory
3. Git Command Failures
// Permission errors, corrupted repos, or git not installed
try {
const result = await getGitRepositoryDiffs('/project');
} catch (error) {
// Handle errors from git commands
// Errors are logged via @automaker/utils logger
console.error('Git operation failed:', error);
}
4. File Read Errors
// When generating synthetic diffs for inaccessible files
const diff = await generateSyntheticDiffForNewFile('/path', 'locked-file.txt');
// Returns placeholder: "[Unable to read file content]"
// Error is logged but doesn't throw
Best Practices
-
Check repository status first:
const isRepo = await isGitRepo(path); if (!isRepo) { // Handle non-git case appropriately } -
Expect non-git directories:
getGitRepositoryDiffs()automatically handles both cases- Always returns a valid result structure
-
Monitor logs:
- Errors are logged with the
[GitUtils]prefix - Check logs for permission issues or git configuration problems
- Errors are logged with the
-
Handle edge cases:
- Empty repositories (no commits yet)
- Detached HEAD states
- Corrupted git repositories
- Missing git binary
Dependencies
@automaker/types- FileStatus type definition@automaker/utils- Logger utilities
Used By
@automaker/server- Git routes, worktree operations, feature context