Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions apps/backend/core/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,13 @@ def get_sdk_env_vars() -> dict[str, str]:
# The empty string ensures Python doesn't add any extra paths to sys.path.
env["PYTHONPATH"] = ""

# Disable user's pre-commit hooks during Auto-Claude managed git operations
env["HUSKY"] = "0"

# NOTE: Git environment variable isolation (GIT_INDEX_FILE, GIT_DIR, etc.) is handled
# in client.py by deleting these vars from os.environ before SDK instantiation.
# We cannot set them to "" here because git interprets empty string as a path value.

return env


Expand Down
16 changes: 16 additions & 0 deletions apps/backend/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
from pathlib import Path
from typing import Any

<<<<<<< HEAD
from core.fast_mode import ensure_fast_mode_in_user_settings
=======
# Git environment isolation - prevents worktree operation failures from inherited env vars
from core.git_executable import GIT_ENV_VARS_TO_CLEAR
>>>>>>> refs/remotes/upstream/pr/1599
from core.platform import (
is_windows,
validate_cli_path,
Expand Down Expand Up @@ -505,6 +510,7 @@ def create_client(
# Collect env vars to pass to SDK (ANTHROPIC_BASE_URL, CLAUDE_CONFIG_DIR, etc.)
sdk_env = get_sdk_env_vars()

<<<<<<< HEAD
# Get the config dir for profile-specific credential lookup
# CLAUDE_CONFIG_DIR enables per-profile Keychain entries with SHA256-hashed service names
config_dir = sdk_env.get("CLAUDE_CONFIG_DIR")
Expand Down Expand Up @@ -532,6 +538,16 @@ def create_client(
)
else:
logger.info("[Fast Mode] inactive — not requested for this client")
=======
# CRITICAL: Clear git environment variables from os.environ BEFORE SDK instantiation.
# The SDK merges os.environ with our env dict, so contaminated git vars (GIT_INDEX_FILE,
# GIT_DIR, etc.) inherited from parent processes would leak through and cause
# git operation errors in worktree operations.
# We must DELETE these vars from os.environ, not set them to "" (empty string is a value
# that git interprets as "use empty path", which fails).
for var in GIT_ENV_VARS_TO_CLEAR:
os.environ.pop(var, None)
>>>>>>> refs/remotes/upstream/pr/1599

# Debug: Log git-bash path detection on Windows
if "CLAUDE_CODE_GIT_BASH_PATH" in sdk_env:
Expand Down
8 changes: 6 additions & 2 deletions apps/frontend/src/main/agent/agent-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { readSettingsFile } from '../settings-utils';
import type { AppSettings } from '../../shared/types/settings';
import { getOAuthModeClearVars } from './env-utils';
import { getAugmentedEnv } from '../env-utils';
import { getIsolatedGitEnv } from '../utils/git-isolation';
import { getToolInfo, getClaudeCliPathForSdk } from '../cli-tool-manager';
import { killProcessGracefully, isWindows } from '../platform';
import { debugLog } from '../../shared/utils/debug-logger';
Expand Down Expand Up @@ -203,8 +204,11 @@ export class AgentProcessManager {
});

// Use getAugmentedEnv() to ensure common tool paths (dotnet, homebrew, etc.)
// are available even when app is launched from Finder/Dock
const augmentedEnv = getAugmentedEnv();
// are available even when app is launched from Finder/Dock.
// Wrap with getIsolatedGitEnv() to clear GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE,
// and other git env vars that can contaminate worktree operations when inherited
// from parent processes (pre-commit hooks, IDE integrations, Electron app).
const augmentedEnv = getIsolatedGitEnv(getAugmentedEnv());

// On Windows, detect and pass git-bash path for Claude Code CLI
// Electron can detect git via where.exe, but Python subprocess may not have the same PATH
Expand Down