package main // Backend defines the contract for invoking different AI CLI backends. // Each backend is responsible for supplying the executable command and // building the argument list based on the wrapper config. type Backend interface { Name() string BuildArgs(cfg *Config, targetArg string) []string Command() string } type CodexBackend struct{} func (CodexBackend) Name() string { return "codex" } func (CodexBackend) Command() string { return "codex" } func (CodexBackend) BuildArgs(cfg *Config, targetArg string) []string { return buildCodexArgs(cfg, targetArg) } type ClaudeBackend struct{} func (ClaudeBackend) Name() string { return "claude" } func (ClaudeBackend) Command() string { return "claude" } func (ClaudeBackend) BuildArgs(cfg *Config, targetArg string) []string { if cfg == nil { return nil } args := []string{"-p"} // Default to skip permissions for Claude backend if !cfg.SkipPermissions { args = append(args, "--dangerously-skip-permissions") } workdir := cfg.WorkDir if workdir == "" { workdir = defaultWorkdir } if cfg.Mode == "resume" { if cfg.SessionID != "" { args = append(args, "--session-id", cfg.SessionID) } } else { args = append(args, "-C", workdir) } args = append(args, "--output-format", "stream-json", "--verbose", targetArg) return args } type GeminiBackend struct{} func (GeminiBackend) Name() string { return "gemini" } func (GeminiBackend) Command() string { return "gemini" } func (GeminiBackend) BuildArgs(cfg *Config, targetArg string) []string { if cfg == nil { return nil } args := []string{"-o", "stream-json", "-y"} workdir := cfg.WorkDir if workdir == "" { workdir = defaultWorkdir } if cfg.Mode == "resume" { if cfg.SessionID != "" { args = append(args, "--session-id", cfg.SessionID) } } else { args = append(args, "-C", workdir) } args = append(args, "-p", targetArg) return args }