From 4f1689c13c5e7295c8e1be66b1ee0735b07882b3 Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Sun, 8 Mar 2026 11:45:42 +0000 Subject: [PATCH] feat: default seguro para working_dir en claude-code provider Cuando WorkingDir esta vacio, se crea un directorio temporal aislado en lugar de heredar el CWD del launcher (raiz del repo). Esto evita que el subproceso claude -p tenga acceso de lectura/escritura al codigo fuente del proyecto. Si WorkingDir tiene valor, se asegura que el directorio exista creandolo con MkdirAll. Se loguea WARN cuando se usa el tmpdir para que el operador lo note y configure explicitamente. Co-Authored-By: Claude Opus 4.6 --- shell/llm/claudecode.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/shell/llm/claudecode.go b/shell/llm/claudecode.go index f410f5c..95c7e87 100644 --- a/shell/llm/claudecode.go +++ b/shell/llm/claudecode.go @@ -58,6 +58,26 @@ func NewClaudeCodeComplete(cfg config.ClaudeCodeCfg, log *slog.Logger) coretypes timeout = defaultClaudeTimeout } + // Resolve working directory once at init time. + workDir := cfg.WorkingDir + if workDir == "" { + tmp, err := os.MkdirTemp("", "claude-agent-*") + if err != nil { + log.Error("claude-code: failed to create temp working dir", "err", err) + // Fall through — cmd.Dir will remain empty (inherits CWD). + } else { + workDir = tmp + log.Warn("claude-code working_dir is empty, using temporary directory", + "dir", workDir, + ) + } + } else { + // Ensure configured directory exists. + if err := os.MkdirAll(workDir, 0o755); err != nil { + log.Error("claude-code: failed to create working dir", "dir", workDir, "err", err) + } + } + return func(ctx context.Context, req coretypes.CompletionRequest) (coretypes.CompletionResponse, error) { ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() @@ -70,11 +90,12 @@ func NewClaudeCodeComplete(cfg config.ClaudeCodeCfg, log *slog.Logger) coretypes "binary", binary, "args", strings.Join(args, " "), "prompt_len", len(prompt), + "working_dir", workDir, ) cmd := exec.CommandContext(ctx, binary, args...) - if cfg.WorkingDir != "" { - cmd.Dir = cfg.WorkingDir + if workDir != "" { + cmd.Dir = workDir } // Build clean env: inherit parent but remove ANTHROPIC_API_KEY // so claude uses its own OAuth auth instead of a potentially invalid key.