diff --git a/internal/agent/codex.go b/internal/agent/codex.go index cbd7482..1e95336 100644 --- a/internal/agent/codex.go +++ b/internal/agent/codex.go @@ -32,7 +32,7 @@ func (p *CodexProvider) CLIPath() string { return p.cliPath } // LoopCommand implements loop.Provider. func (p *CodexProvider) LoopCommand(ctx context.Context, prompt, workDir string) *exec.Cmd { - cmd := exec.CommandContext(ctx, p.cliPath, "exec", "--json", "--yolo", "-C", workDir, "-") + cmd := exec.CommandContext(ctx, p.cliPath, "exec", "--json", "--yolo", "--skip-git-repo-check", "-C", workDir, "-") cmd.Dir = workDir cmd.Stdin = strings.NewReader(prompt) return cmd @@ -52,8 +52,10 @@ func (p *CodexProvider) ConvertCommand(workDir, prompt string) (*exec.Cmd, loop. return nil, 0, "", fmt.Errorf("failed to create temp file for conversion output: %w", err) } outPath := f.Name() - f.Close() - cmd := exec.Command(p.cliPath, "exec", "--sandbox", "read-only", "-o", outPath, "-") + if err := f.Close(); err != nil { + return nil, 0, "", fmt.Errorf("failed to close temp file for conversion output: %w", err) + } + cmd := exec.Command(p.cliPath, "exec", "--sandbox", "read-only", "--skip-git-repo-check", "-o", outPath, "-") cmd.Dir = workDir cmd.Stdin = strings.NewReader(prompt) return cmd, loop.OutputFromFile, outPath, nil @@ -66,8 +68,10 @@ func (p *CodexProvider) FixJSONCommand(prompt string) (*exec.Cmd, loop.OutputMod return nil, 0, "", fmt.Errorf("failed to create temp file for fix output: %w", err) } outPath := f.Name() - f.Close() - cmd := exec.Command(p.cliPath, "exec", "--sandbox", "read-only", "-o", outPath, "-") + if err := f.Close(); err != nil { + return nil, 0, "", fmt.Errorf("failed to close temp file for fix output: %w", err) + } + cmd := exec.Command(p.cliPath, "exec", "--sandbox", "read-only", "--skip-git-repo-check", "-o", outPath, "-") cmd.Stdin = strings.NewReader(prompt) return cmd, loop.OutputFromFile, outPath, nil } diff --git a/internal/agent/codex_test.go b/internal/agent/codex_test.go index 3a9d2c0..5ed1ec9 100644 --- a/internal/agent/codex_test.go +++ b/internal/agent/codex_test.go @@ -41,7 +41,7 @@ func TestCodexProvider_LoopCommand(t *testing.T) { if cmd.Path != "/bin/codex" { t.Errorf("LoopCommand Path = %q, want /bin/codex", cmd.Path) } - wantArgs := []string{"/bin/codex", "exec", "--json", "--yolo", "-C", "/work/dir", "-"} + wantArgs := []string{"/bin/codex", "exec", "--json", "--yolo", "--skip-git-repo-check", "-C", "/work/dir", "-"} if len(cmd.Args) != len(wantArgs) { t.Fatalf("LoopCommand Args len = %d, want %d: %v", len(cmd.Args), len(wantArgs), cmd.Args) } @@ -76,15 +76,21 @@ func TestCodexProvider_ConvertCommand(t *testing.T) { t.Errorf("ConvertCommand Path = %q", cmd.Path) } foundO := false + foundSkipGitRepoCheck := false for i, a := range cmd.Args { if a == "-o" && i+1 < len(cmd.Args) && cmd.Args[i+1] == outPath { foundO = true - break + } + if a == "--skip-git-repo-check" { + foundSkipGitRepoCheck = true } } if !foundO { t.Errorf("ConvertCommand should have -o %q in args: %v", outPath, cmd.Args) } + if !foundSkipGitRepoCheck { + t.Errorf("ConvertCommand should include --skip-git-repo-check: %v", cmd.Args) + } if cmd.Dir != "/prd/dir" { t.Errorf("ConvertCommand Dir = %q, want /prd/dir", cmd.Dir) } @@ -103,15 +109,21 @@ func TestCodexProvider_FixJSONCommand(t *testing.T) { t.Error("FixJSONCommand outPath should be non-empty temp file") } foundO := false + foundSkipGitRepoCheck := false for i, a := range cmd.Args { if a == "-o" && i+1 < len(cmd.Args) && cmd.Args[i+1] == outPath { foundO = true - break + } + if a == "--skip-git-repo-check" { + foundSkipGitRepoCheck = true } } if !foundO { t.Errorf("FixJSONCommand should have -o %q in args: %v", outPath, cmd.Args) } + if !foundSkipGitRepoCheck { + t.Errorf("FixJSONCommand should include --skip-git-repo-check: %v", cmd.Args) + } } func TestCodexProvider_InteractiveCommand(t *testing.T) { @@ -120,8 +132,14 @@ func TestCodexProvider_InteractiveCommand(t *testing.T) { if cmd.Dir != "/work" { t.Errorf("InteractiveCommand Dir = %q, want /work", cmd.Dir) } - if len(cmd.Args) < 2 || cmd.Args[0] != "codex" || cmd.Args[1] != "my prompt" { - t.Errorf("InteractiveCommand Args = %v", cmd.Args) + wantArgs := []string{"codex", "my prompt"} + if len(cmd.Args) != len(wantArgs) { + t.Fatalf("InteractiveCommand Args len = %d, want %d: %v", len(cmd.Args), len(wantArgs), cmd.Args) + } + for i, w := range wantArgs { + if cmd.Args[i] != w { + t.Errorf("InteractiveCommand Args[%d] = %q, want %q", i, cmd.Args[i], w) + } } } diff --git a/internal/agent/resolve_test.go b/internal/agent/resolve_test.go index fa199f8..2a30bda 100644 --- a/internal/agent/resolve_test.go +++ b/internal/agent/resolve_test.go @@ -67,37 +67,61 @@ func TestResolve_env(t *testing.T) { savePath := os.Getenv(keyPath) defer func() { if saveAgent != "" { - os.Setenv(keyAgent, saveAgent) + if err := os.Setenv(keyAgent, saveAgent); err != nil { + t.Fatalf("restore %s: %v", keyAgent, err) + } } else { - os.Unsetenv(keyAgent) + if err := os.Unsetenv(keyAgent); err != nil { + t.Fatalf("unset %s: %v", keyAgent, err) + } } if savePath != "" { - os.Setenv(keyPath, savePath) + if err := os.Setenv(keyPath, savePath); err != nil { + t.Fatalf("restore %s: %v", keyPath, err) + } } else { - os.Unsetenv(keyPath) + if err := os.Unsetenv(keyPath); err != nil { + t.Fatalf("unset %s: %v", keyPath, err) + } } }() - os.Unsetenv(keyAgent) - os.Unsetenv(keyPath) + if err := os.Unsetenv(keyAgent); err != nil { + t.Fatalf("unset %s: %v", keyAgent, err) + } + if err := os.Unsetenv(keyPath); err != nil { + t.Fatalf("unset %s: %v", keyPath, err) + } // Env provider when no flag - os.Setenv(keyAgent, "codex") + if err := os.Setenv(keyAgent, "codex"); err != nil { + t.Fatalf("set %s: %v", keyAgent, err) + } got := mustResolve(t, "", "", nil) if got.Name() != "Codex" { t.Errorf("with CHIEF_AGENT=codex, name = %q, want Codex", got.Name()) } - os.Unsetenv(keyAgent) + if err := os.Unsetenv(keyAgent); err != nil { + t.Fatalf("unset %s: %v", keyAgent, err) + } // Env path when no flag path - os.Setenv(keyAgent, "codex") - os.Setenv(keyPath, "/env/codex") + if err := os.Setenv(keyAgent, "codex"); err != nil { + t.Fatalf("set %s: %v", keyAgent, err) + } + if err := os.Setenv(keyPath, "/env/codex"); err != nil { + t.Fatalf("set %s: %v", keyPath, err) + } got = mustResolve(t, "", "", nil) if got.CLIPath() != "/env/codex" { t.Errorf("with CHIEF_AGENT_PATH, CLIPath = %q, want /env/codex", got.CLIPath()) } - os.Unsetenv(keyPath) - os.Unsetenv(keyAgent) + if err := os.Unsetenv(keyPath); err != nil { + t.Fatalf("unset %s: %v", keyPath, err) + } + if err := os.Unsetenv(keyAgent); err != nil { + t.Fatalf("unset %s: %v", keyAgent, err) + } } func TestResolve_normalize(t *testing.T) {