fix: security hook cwd extraction and PATH issues (#555, #556) (#587)

* fix(security): extract cwd from input_data instead of context

The bash_security_hook was checking context.cwd, but the Claude Agent
SDK passes cwd in input_data dict, not context object. This caused the
hook to always fall back to os.getcwd() which returns the runner
directory (apps/backend/) instead of the project directory.

According to Claude Agent SDK docs, PreToolUse hooks receive cwd in
input_data, not context. The context parameter is reserved for future
use in the Python SDK.

Fixes #555

Signed-off-by: Hunter Luisi <hluisi@gmail.com>

* fix(frontend): use getAugmentedEnv for PATH in agent processes

When Electron launches from Finder/Dock on macOS, process.env.PATH is
minimal and doesn't include user shell paths. This caused tools like
dotnet, cargo, etc. to fail with 'command not found'.

Solution:
1. Use getAugmentedEnv() in agent-process.ts instead of raw process.env
2. Add /usr/local/share/dotnet and ~/.dotnet/tools to COMMON_BIN_PATHS

getAugmentedEnv() already exists and is used throughout the frontend
for Git/GitHub/GitLab operations. It adds common tool directories to
PATH based on platform.

Fixes #556

Signed-off-by: Hunter Luisi <hluisi@gmail.com>

* chore: pin electron version to 39.2.7

Pinning electron version (removing caret) so electron-builder can
compute the version from installed modules in monorepo setup.

Signed-off-by: Hunter Luisi <hluisi@gmail.com>

* fix: handle empty cwd fallback and add Linux .NET paths

- Use 'or' pattern for cwd fallback to handle empty string case
- Add ~/.dotnet/tools to Linux COMMON_BIN_PATHS for parity with macOS

Addresses review suggestions from Auto Claude PR Review.

---------

Signed-off-by: Hunter Luisi <hluisi@gmail.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
This commit is contained in:
Hunter Luisi
2026-01-03 12:45:18 -08:00
committed by GitHub
parent 556f0b2129
commit 4ec9db8c38
3 changed files with 10 additions and 6 deletions
+2 -5
View File
@@ -65,11 +65,8 @@ async def bash_security_hook(
if not command:
return {}
# Get the working directory from context or use current directory
# In the actual client, this would be set by the ClaudeSDKClient
cwd = os.getcwd()
if context and hasattr(context, "cwd"):
cwd = context.cwd
# Get the working directory from input_data (SDK passes it there, not in context)
cwd = input_data.get("cwd") or os.getcwd()
# Get or create security profile
# Note: In actual use, spec_dir would be passed through context
@@ -16,6 +16,7 @@ import { buildMemoryEnvVars } from '../memory-env-builder';
import { readSettingsFile } from '../settings-utils';
import type { AppSettings } from '../../shared/types/settings';
import { getOAuthModeClearVars } from './env-utils';
import { getAugmentedEnv } from '../env-utils';
/**
* Process spawning and lifecycle management
@@ -55,8 +56,11 @@ export class AgentProcessManager {
extraEnv: Record<string, string>
): NodeJS.ProcessEnv {
const profileEnv = getProfileEnv();
// Use getAugmentedEnv() to ensure common tool paths (dotnet, homebrew, etc.)
// are available even when app is launched from Finder/Dock
const augmentedEnv = getAugmentedEnv();
return {
...process.env,
...augmentedEnv,
...extraEnv,
...profileEnv,
PYTHONUNBUFFERED: '1',
+3
View File
@@ -64,15 +64,18 @@ const COMMON_BIN_PATHS: Record<string, string[]> = {
darwin: [
'/opt/homebrew/bin', // Apple Silicon Homebrew
'/usr/local/bin', // Intel Homebrew / system
'/usr/local/share/dotnet', // .NET SDK
'/opt/homebrew/sbin', // Apple Silicon Homebrew sbin
'/usr/local/sbin', // Intel Homebrew sbin
'~/.local/bin', // User-local binaries (Claude CLI)
'~/.dotnet/tools', // .NET global tools
],
linux: [
'/usr/local/bin',
'/usr/bin', // System binaries (Python, etc.)
'/snap/bin', // Snap packages
'~/.local/bin', // User-local binaries
'~/.dotnet/tools', // .NET global tools
'/usr/sbin', // System admin binaries
],
win32: [