diff --git a/codeagent-wrapper/backend.go b/codeagent-wrapper/backend.go index aed8617..ac7f617 100644 --- a/codeagent-wrapper/backend.go +++ b/codeagent-wrapper/backend.go @@ -36,19 +36,13 @@ func (ClaudeBackend) BuildArgs(cfg *Config, targetArg string) []string { args = append(args, "--dangerously-skip-permissions") } - workdir := cfg.WorkDir - if workdir == "" { - workdir = defaultWorkdir - } - if cfg.Mode == "resume" { if cfg.SessionID != "" { // Claude CLI uses -r for resume. args = append(args, "-r", cfg.SessionID) } - } else { - args = append(args, "-C", workdir) } + // Note: claude CLI doesn't support -C flag; workdir set via cmd.Dir args = append(args, "--output-format", "stream-json", "--verbose", targetArg) @@ -67,18 +61,12 @@ func (GeminiBackend) BuildArgs(cfg *Config, targetArg string) []string { } args := []string{"-o", "stream-json", "-y"} - workdir := cfg.WorkDir - if workdir == "" { - workdir = defaultWorkdir - } - if cfg.Mode == "resume" { if cfg.SessionID != "" { args = append(args, "-r", cfg.SessionID) } - } else { - args = append(args, "-C", workdir) } + // Note: gemini CLI doesn't support -C flag; workdir set via cmd.Dir args = append(args, "-p", targetArg) diff --git a/codeagent-wrapper/backend_test.go b/codeagent-wrapper/backend_test.go index a74e35c..c16779e 100644 --- a/codeagent-wrapper/backend_test.go +++ b/codeagent-wrapper/backend_test.go @@ -11,7 +11,7 @@ func TestClaudeBuildArgs_ModesAndPermissions(t *testing.T) { t.Run("new mode uses workdir without skip by default", func(t *testing.T) { cfg := &Config{Mode: "new", WorkDir: "/repo"} got := backend.BuildArgs(cfg, "todo") - want := []string{"-p", "-C", "/repo", "--output-format", "stream-json", "--verbose", "todo"} + want := []string{"-p", "--output-format", "stream-json", "--verbose", "todo"} if !reflect.DeepEqual(got, want) { t.Fatalf("got %v, want %v", got, want) } @@ -20,7 +20,7 @@ func TestClaudeBuildArgs_ModesAndPermissions(t *testing.T) { t.Run("new mode opt-in skip permissions with default workdir", func(t *testing.T) { cfg := &Config{Mode: "new", SkipPermissions: true} got := backend.BuildArgs(cfg, "-") - want := []string{"-p", "--dangerously-skip-permissions", "-C", defaultWorkdir, "--output-format", "stream-json", "--verbose", "-"} + want := []string{"-p", "--dangerously-skip-permissions", "--output-format", "stream-json", "--verbose", "-"} if !reflect.DeepEqual(got, want) { t.Fatalf("got %v, want %v", got, want) } @@ -56,7 +56,7 @@ func TestClaudeBuildArgs_GeminiAndCodexModes(t *testing.T) { backend := GeminiBackend{} cfg := &Config{Mode: "new", WorkDir: "/workspace"} got := backend.BuildArgs(cfg, "task") - want := []string{"-o", "stream-json", "-y", "-C", "/workspace", "-p", "task"} + want := []string{"-o", "stream-json", "-y", "-p", "task"} if !reflect.DeepEqual(got, want) { t.Fatalf("got %v, want %v", got, want) } diff --git a/codeagent-wrapper/executor.go b/codeagent-wrapper/executor.go index 4ea2fe5..d49a14f 100644 --- a/codeagent-wrapper/executor.go +++ b/codeagent-wrapper/executor.go @@ -23,6 +23,7 @@ type commandRunner interface { StdoutPipe() (io.ReadCloser, error) StdinPipe() (io.WriteCloser, error) SetStderr(io.Writer) + SetDir(string) Process() processHandle } @@ -72,6 +73,12 @@ func (r *realCmd) SetStderr(w io.Writer) { } } +func (r *realCmd) SetDir(dir string) { + if r.cmd != nil { + r.cmd.Dir = dir + } +} + func (r *realCmd) Process() processHandle { if r == nil || r.cmd == nil || r.cmd.Process == nil { return nil @@ -577,6 +584,12 @@ func runCodexTaskWithContext(parentCtx context.Context, taskSpec TaskSpec, backe cmd := newCommandRunner(ctx, commandName, codexArgs...) + // For backends that don't support -C flag (claude, gemini), set working directory via cmd.Dir + // Codex passes workdir via -C flag, so we skip setting Dir for it to avoid conflicts + if cfg.Mode != "resume" && commandName != "codex" && cfg.WorkDir != "" { + cmd.SetDir(cfg.WorkDir) + } + stderrWriters := []io.Writer{stderrBuf} if stderrLogger != nil { stderrWriters = append(stderrWriters, stderrLogger) diff --git a/codeagent-wrapper/executor_concurrent_test.go b/codeagent-wrapper/executor_concurrent_test.go index 57aed24..4c56961 100644 --- a/codeagent-wrapper/executor_concurrent_test.go +++ b/codeagent-wrapper/executor_concurrent_test.go @@ -117,6 +117,7 @@ func (f *execFakeRunner) StdinPipe() (io.WriteCloser, error) { return &writeCloserStub{}, nil } func (f *execFakeRunner) SetStderr(io.Writer) {} +func (f *execFakeRunner) SetDir(string) {} func (f *execFakeRunner) Process() processHandle { if f.process != nil { return f.process diff --git a/codeagent-wrapper/main_test.go b/codeagent-wrapper/main_test.go index 99bfc4a..40172d1 100644 --- a/codeagent-wrapper/main_test.go +++ b/codeagent-wrapper/main_test.go @@ -250,6 +250,10 @@ func (d *drainBlockingCmd) SetStderr(w io.Writer) { d.inner.SetStderr(w) } +func (d *drainBlockingCmd) SetDir(dir string) { + d.inner.SetDir(dir) +} + func (d *drainBlockingCmd) Process() processHandle { return d.inner.Process() } @@ -504,6 +508,8 @@ func (f *fakeCmd) SetStderr(w io.Writer) { f.stderr = w } +func (f *fakeCmd) SetDir(string) {} + func (f *fakeCmd) Process() processHandle { if f == nil { return nil @@ -1371,7 +1377,7 @@ func TestBackendBuildArgs_ClaudeBackend(t *testing.T) { backend := ClaudeBackend{} cfg := &Config{Mode: "new", WorkDir: defaultWorkdir} got := backend.BuildArgs(cfg, "todo") - want := []string{"-p", "-C", defaultWorkdir, "--output-format", "stream-json", "--verbose", "todo"} + want := []string{"-p", "--output-format", "stream-json", "--verbose", "todo"} if len(got) != len(want) { t.Fatalf("length mismatch") } @@ -1411,7 +1417,7 @@ func TestBackendBuildArgs_GeminiBackend(t *testing.T) { backend := GeminiBackend{} cfg := &Config{Mode: "new"} got := backend.BuildArgs(cfg, "task") - want := []string{"-o", "stream-json", "-y", "-C", defaultWorkdir, "-p", "task"} + want := []string{"-o", "stream-json", "-y", "-p", "task"} if len(got) != len(want) { t.Fatalf("length mismatch") }