diff --git a/CLAUDE.md b/CLAUDE.md index d6642a5b..6d5577c8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -107,7 +107,7 @@ The project follows a modern SOLID architecture using Bubble Tea for the TUI and - `main.go`: Entry point that calls `cmd.Execute()` - `cmd/`: Contains all CLI command implementations using Cobra - `root.go`: Root command setup with global flags (`--config`, `--verbose`) - - `init.go`: Project initialization (`infer init`) + - `config.go`: Configuration management (`infer config`) - `status.go`: Status monitoring (`infer status`) - `chat.go`: Interactive chat (`infer chat`) - `version.go`: Version information (`infer version`) @@ -131,7 +131,7 @@ output: format: "text" # text, json, yaml quiet: false tools: - enabled: false # Set to true to enable tool execution for LLMs + enabled: true # Tools are enabled by default with safe read-only commands whitelist: commands: # Exact command matches - "ls" @@ -162,11 +162,21 @@ chat: - Root command: `infer` - Global flags: `--config`, `--verbose` - Subcommands: - - `init [--overwrite]`: Initialize local project configuration - `status`: Gateway status - `chat`: Interactive chat with model selection (or uses default model if configured) - `config`: Manage CLI configuration + - `init [--overwrite]`: Initialize local project configuration - `set-model [MODEL_NAME]`: Set default model for chat sessions + - `tools`: Manage tool execution settings + - `enable`: Enable tool execution for LLMs + - `disable`: Disable tool execution for LLMs + - `list [--format text|json]`: List whitelisted commands and patterns + - `validate `: Validate if a command is whitelisted + - `exec [--format text|json]`: Execute a whitelisted command directly + - `safety`: Manage safety approval settings + - `enable`: Enable safety approval prompts + - `disable`: Disable safety approval prompts + - `status`: Show current safety approval status - `version`: Version information ## Dependencies @@ -197,6 +207,12 @@ infer chat ### Configuration Management ```bash +# Initialize a new project configuration +infer config init + +# Initialize with overwrite existing config +infer config init --overwrite + # View current configuration (check .infer/config.yaml) cat .infer/config.yaml @@ -205,6 +221,32 @@ cat .infer/config.yaml # default_model: "gpt-4-turbo" ``` +### Tool Management +```bash +# Enable tool execution +infer config tools enable + +# Disable tool execution +infer config tools disable + +# List whitelisted commands and patterns +infer config tools list + +# List in JSON format +infer config tools list --format json + +# Validate if a command is whitelisted +infer config tools validate "ls -la" + +# Execute a whitelisted command directly +infer config tools exec "git status" + +# Manage safety approval settings +infer config tools safety enable +infer config tools safety disable +infer config tools safety status +``` + ## Code Style Guidelines - **Inline Comments**: Do not write inline comments unless the code is genuinely unclear or requires specific explanation. diff --git a/cmd/config.go b/cmd/config.go index 3d7e344e..aa814b92 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -1,9 +1,15 @@ package cmd import ( + "context" + "encoding/json" "fmt" + "os" + "time" "github.com/inference-gateway/cli/config" + "github.com/inference-gateway/cli/internal/container" + "github.com/inference-gateway/cli/internal/ui" "github.com/spf13/cobra" ) @@ -25,6 +31,105 @@ the chat command will skip the model selection view and use the configured model }, } +var configInitCmd = &cobra.Command{ + Use: "init", + Short: "Initialize a new project configuration", + Long: `Initialize a new .infer/config.yaml configuration file in the current directory. +This creates a local project configuration with default settings.`, + RunE: func(cmd *cobra.Command, args []string) error { + configPath := ".infer/config.yaml" + + if _, err := os.Stat(configPath); err == nil { + overwrite, _ := cmd.Flags().GetBool("overwrite") + if !overwrite { + return fmt.Errorf("configuration file %s already exists (use --overwrite to replace)", configPath) + } + } + + cfg := config.DefaultConfig() + + if err := cfg.SaveConfig(configPath); err != nil { + return fmt.Errorf("failed to create config file: %w", err) + } + + fmt.Printf("Successfully created %s\n", configPath) + fmt.Println("You can now customize the configuration for this project.") + + return nil + }, +} + +var configToolsCmd = &cobra.Command{ + Use: "tools", + Short: "Manage tool execution settings", + Long: `Manage the tool execution system that allows LLMs to execute whitelisted bash commands securely. +Tools must be explicitly enabled and commands must be whitelisted for execution.`, +} + +var configToolsEnableCmd = &cobra.Command{ + Use: "enable", + Short: "Enable tool execution for LLMs", + Long: `Enable the tool execution system, allowing LLMs to execute whitelisted bash commands.`, + RunE: enableTools, +} + +var configToolsDisableCmd = &cobra.Command{ + Use: "disable", + Short: "Disable tool execution for LLMs", + Long: `Disable the tool execution system, preventing LLMs from executing any commands.`, + RunE: disableTools, +} + +var configToolsListCmd = &cobra.Command{ + Use: "list", + Short: "List whitelisted commands and patterns", + Long: `Display all whitelisted commands and regex patterns that can be executed by LLMs.`, + RunE: listTools, +} + +var configToolsValidateCmd = &cobra.Command{ + Use: "validate ", + Short: "Validate if a command is whitelisted", + Long: `Check if a specific command would be allowed to execute without actually running it.`, + Args: cobra.ExactArgs(1), + RunE: validateTool, +} + +var configToolsExecCmd = &cobra.Command{ + Use: "exec ", + Short: "Execute a whitelisted command directly", + Long: `Execute a command directly if it passes whitelist validation.`, + Args: cobra.ExactArgs(1), + RunE: execTool, +} + +var configToolsSafetyCmd = &cobra.Command{ + Use: "safety", + Short: "Manage safety approval settings", + Long: `Manage safety approval prompts that are shown before executing commands.`, +} + +var configToolsSafetyEnableCmd = &cobra.Command{ + Use: "enable", + Short: "Enable safety approval prompts", + Long: `Enable safety approval prompts that ask for confirmation before executing commands.`, + RunE: enableSafety, +} + +var configToolsSafetyDisableCmd = &cobra.Command{ + Use: "disable", + Short: "Disable safety approval prompts", + Long: `Disable safety approval prompts, allowing commands to execute immediately.`, + RunE: disableSafety, +} + +var configToolsSafetyStatusCmd = &cobra.Command{ + Use: "status", + Short: "Show current safety approval status", + Long: `Display whether safety approval prompts are currently enabled or disabled.`, + RunE: safetyStatus, +} + func setDefaultModel(modelName string) error { cfg, err := config.LoadConfig("") if err != nil { @@ -44,5 +149,235 @@ func setDefaultModel(modelName string) error { func init() { configCmd.AddCommand(setModelCmd) + configCmd.AddCommand(configInitCmd) + configCmd.AddCommand(configToolsCmd) + + configToolsCmd.AddCommand(configToolsEnableCmd) + configToolsCmd.AddCommand(configToolsDisableCmd) + configToolsCmd.AddCommand(configToolsListCmd) + configToolsCmd.AddCommand(configToolsValidateCmd) + configToolsCmd.AddCommand(configToolsExecCmd) + configToolsCmd.AddCommand(configToolsSafetyCmd) + + configToolsSafetyCmd.AddCommand(configToolsSafetyEnableCmd) + configToolsSafetyCmd.AddCommand(configToolsSafetyDisableCmd) + configToolsSafetyCmd.AddCommand(configToolsSafetyStatusCmd) + + configInitCmd.Flags().Bool("overwrite", false, "Overwrite existing configuration file") + configToolsListCmd.Flags().StringP("format", "f", "text", "Output format (text, json)") + configToolsExecCmd.Flags().StringP("format", "f", "text", "Output format (text, json)") + rootCmd.AddCommand(configCmd) } + +func enableTools(cmd *cobra.Command, args []string) error { + cfg, err := loadAndUpdateConfig(func(c *config.Config) { + c.Tools.Enabled = true + }) + if err != nil { + return err + } + + fmt.Printf("%s\n", ui.FormatSuccess("Tools enabled successfully")) + fmt.Printf("Configuration saved to: %s\n", getConfigPath()) + fmt.Printf("Whitelisted commands: %d\n", len(cfg.Tools.Whitelist.Commands)) + fmt.Printf("Whitelisted patterns: %d\n", len(cfg.Tools.Whitelist.Patterns)) + return nil +} + +func disableTools(cmd *cobra.Command, args []string) error { + _, err := loadAndUpdateConfig(func(c *config.Config) { + c.Tools.Enabled = false + }) + if err != nil { + return err + } + + fmt.Printf("%s\n", ui.FormatErrorCLI("Tools disabled successfully")) + fmt.Printf("Configuration saved to: %s\n", getConfigPath()) + return nil +} + +func listTools(cmd *cobra.Command, args []string) error { + cfg, err := config.LoadConfig("") + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + format, _ := cmd.Flags().GetString("format") + + if format == "json" { + data := map[string]interface{}{ + "enabled": cfg.Tools.Enabled, + "commands": cfg.Tools.Whitelist.Commands, + "patterns": cfg.Tools.Whitelist.Patterns, + "safety": map[string]bool{ + "require_approval": cfg.Tools.Safety.RequireApproval, + }, + } + jsonOutput, err := json.MarshalIndent(data, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal output: %w", err) + } + fmt.Println(string(jsonOutput)) + return nil + } + + fmt.Printf("Tools Status: ") + if cfg.Tools.Enabled { + fmt.Printf("%s\n", ui.FormatSuccess("Enabled")) + } else { + fmt.Printf("%s\n", ui.FormatErrorCLI("Disabled")) + } + + fmt.Printf("\nWhitelisted Commands (%d):\n", len(cfg.Tools.Whitelist.Commands)) + for _, cmd := range cfg.Tools.Whitelist.Commands { + fmt.Printf(" • %s\n", cmd) + } + + fmt.Printf("\nWhitelisted Patterns (%d):\n", len(cfg.Tools.Whitelist.Patterns)) + for _, pattern := range cfg.Tools.Whitelist.Patterns { + fmt.Printf(" • %s\n", pattern) + } + + fmt.Printf("\nSafety Settings:\n") + if cfg.Tools.Safety.RequireApproval { + fmt.Printf(" • Approval required: %s\n", ui.FormatSuccess("Enabled")) + } else { + fmt.Printf(" • Approval required: %s\n", ui.FormatErrorCLI("Disabled")) + } + + return nil +} + +func validateTool(cmd *cobra.Command, args []string) error { + cfg, err := config.LoadConfig("") + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + if !cfg.Tools.Enabled { + fmt.Printf("%s\n", ui.FormatErrorCLI("Tools are disabled")) + return nil + } + + services := container.NewServiceContainer(cfg) + toolService := services.GetToolService() + + command := args[0] + toolArgs := map[string]interface{}{ + "command": command, + } + + err = toolService.ValidateTool("Bash", toolArgs) + if err != nil { + fmt.Printf("%s\n", ui.FormatErrorCLI(fmt.Sprintf("Command not allowed: %s", command))) + fmt.Printf("Reason: %s\n", err.Error()) + return nil + } + + fmt.Printf("%s\n", ui.FormatSuccess(fmt.Sprintf("Command is whitelisted: %s", command))) + return nil +} + +func execTool(cmd *cobra.Command, args []string) error { + cfg, err := config.LoadConfig("") + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + if !cfg.Tools.Enabled { + return fmt.Errorf("tools are not enabled") + } + + services := container.NewServiceContainer(cfg) + toolService := services.GetToolService() + + command := args[0] + format, _ := cmd.Flags().GetString("format") + + toolArgs := map[string]interface{}{ + "command": command, + "format": format, + } + + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) + defer cancel() + + result, err := toolService.ExecuteTool(ctx, "Bash", toolArgs) + if err != nil { + return fmt.Errorf("command execution failed: %w", err) + } + + fmt.Print(result) + return nil +} + +func enableSafety(cmd *cobra.Command, args []string) error { + _, err := loadAndUpdateConfig(func(c *config.Config) { + c.Tools.Safety.RequireApproval = true + }) + if err != nil { + return err + } + + fmt.Printf("%s\n", ui.FormatSuccess("Safety approval enabled")) + fmt.Printf("Commands will require approval before execution\n") + return nil +} + +func disableSafety(cmd *cobra.Command, args []string) error { + _, err := loadAndUpdateConfig(func(c *config.Config) { + c.Tools.Safety.RequireApproval = false + }) + if err != nil { + return err + } + + fmt.Printf("%s\n", ui.FormatWarning("Safety approval disabled")) + fmt.Printf("Commands will execute immediately without approval\n") + return nil +} + +func safetyStatus(cmd *cobra.Command, args []string) error { + cfg, err := config.LoadConfig("") + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + fmt.Printf("Safety Approval Status: ") + if cfg.Tools.Safety.RequireApproval { + fmt.Printf("%s\n", ui.FormatSuccess("Enabled")) + fmt.Printf("Commands require approval before execution\n") + } else { + fmt.Printf("%s\n", ui.FormatErrorCLI("Disabled")) + fmt.Printf("Commands execute immediately without approval\n") + } + + return nil +} + +func loadAndUpdateConfig(updateFn func(*config.Config)) (*config.Config, error) { + configPath := getConfigPath() + cfg, err := config.LoadConfig("") + if err != nil { + return nil, fmt.Errorf("failed to load config: %w", err) + } + + updateFn(cfg) + + err = cfg.SaveConfig(configPath) + if err != nil { + return nil, fmt.Errorf("failed to save config: %w", err) + } + + return cfg, nil +} + +func getConfigPath() string { + configPath := ".infer/config.yaml" + if _, err := os.Stat(configPath); os.IsNotExist(err) { + configPath = ".infer.yaml" + } + return configPath +} diff --git a/cmd/init.go b/cmd/init.go deleted file mode 100644 index 8c4cd35a..00000000 --- a/cmd/init.go +++ /dev/null @@ -1,43 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - - "github.com/inference-gateway/cli/config" - "github.com/spf13/cobra" -) - -var initCmd = &cobra.Command{ - Use: "init", - Short: "Initialize a new project configuration", - Long: `Initialize a new .infer/config.yaml configuration file in the current directory. -This creates a local project configuration with default settings.`, - RunE: func(cmd *cobra.Command, args []string) error { - configPath := ".infer/config.yaml" - - if _, err := os.Stat(configPath); err == nil { - overwrite, _ := cmd.Flags().GetBool("overwrite") - if !overwrite { - return fmt.Errorf("configuration file %s already exists (use --overwrite to replace)", configPath) - } - } - - cfg := config.DefaultConfig() - - if err := cfg.SaveConfig(configPath); err != nil { - return fmt.Errorf("failed to create config file: %w", err) - } - - fmt.Printf("Successfully created %s\n", configPath) - fmt.Println("You can now customize the configuration for this project.") - - return nil - }, -} - -func init() { - rootCmd.AddCommand(initCmd) - - initCmd.Flags().Bool("overwrite", false, "Overwrite existing configuration file") -} diff --git a/cmd/tools.go b/cmd/tools.go deleted file mode 100644 index 60acf676..00000000 --- a/cmd/tools.go +++ /dev/null @@ -1,315 +0,0 @@ -package cmd - -import ( - "context" - "encoding/json" - "fmt" - "os" - "time" - - "github.com/inference-gateway/cli/config" - "github.com/inference-gateway/cli/internal/container" - "github.com/inference-gateway/cli/internal/ui" - "github.com/spf13/cobra" -) - -var toolsCmd = &cobra.Command{ - Use: "tools", - Short: "Manage and execute tools for LLM interaction", - Long: `Manage the tool execution system that allows LLMs to execute whitelisted bash commands securely. -Tools must be explicitly enabled and commands must be whitelisted for execution.`, -} - -var toolsEnableCmd = &cobra.Command{ - Use: "enable", - Short: "Enable tool execution for LLMs", - Long: `Enable the tool execution system, allowing LLMs to execute whitelisted bash commands.`, - RunE: enableTools, -} - -var toolsDisableCmd = &cobra.Command{ - Use: "disable", - Short: "Disable tool execution for LLMs", - Long: `Disable the tool execution system, preventing LLMs from executing any commands.`, - RunE: disableTools, -} - -var toolsListCmd = &cobra.Command{ - Use: "list", - Short: "List whitelisted commands and patterns", - Long: `Display all whitelisted commands and regex patterns that can be executed by LLMs.`, - RunE: listTools, -} - -var toolsValidateCmd = &cobra.Command{ - Use: "validate ", - Short: "Validate if a command is whitelisted", - Long: `Check if a specific command would be allowed to execute without actually running it.`, - Args: cobra.ExactArgs(1), - RunE: validateTool, -} - -var toolsExecCmd = &cobra.Command{ - Use: "exec ", - Short: "Execute a whitelisted command directly", - Long: `Execute a command directly if it passes whitelist validation.`, - Args: cobra.ExactArgs(1), - RunE: execTool, -} - -var toolsSafetyCmd = &cobra.Command{ - Use: "safety", - Short: "Manage safety approval settings", - Long: `Manage safety approval prompts that are shown before executing commands.`, -} - -var toolsSafetyEnableCmd = &cobra.Command{ - Use: "enable", - Short: "Enable safety approval prompts", - Long: `Enable safety approval prompts that ask for confirmation before executing commands.`, - RunE: enableSafety, -} - -var toolsSafetyDisableCmd = &cobra.Command{ - Use: "disable", - Short: "Disable safety approval prompts", - Long: `Disable safety approval prompts, allowing commands to execute immediately.`, - RunE: disableSafety, -} - -var toolsSafetyStatusCmd = &cobra.Command{ - Use: "status", - Short: "Show current safety approval status", - Long: `Display whether safety approval prompts are currently enabled or disabled.`, - RunE: safetyStatus, -} - -func init() { - rootCmd.AddCommand(toolsCmd) - - toolsCmd.AddCommand(toolsEnableCmd) - toolsCmd.AddCommand(toolsDisableCmd) - toolsCmd.AddCommand(toolsListCmd) - toolsCmd.AddCommand(toolsValidateCmd) - toolsCmd.AddCommand(toolsExecCmd) - toolsCmd.AddCommand(toolsSafetyCmd) - - toolsSafetyCmd.AddCommand(toolsSafetyEnableCmd) - toolsSafetyCmd.AddCommand(toolsSafetyDisableCmd) - toolsSafetyCmd.AddCommand(toolsSafetyStatusCmd) - - toolsListCmd.Flags().StringP("format", "f", "text", "Output format (text, json)") - toolsExecCmd.Flags().StringP("format", "f", "text", "Output format (text, json)") -} - -func enableTools(cmd *cobra.Command, args []string) error { - cfg, err := loadAndUpdateConfig(func(c *config.Config) { - c.Tools.Enabled = true - }) - if err != nil { - return err - } - - fmt.Printf("%s\n", ui.FormatSuccess("Tools enabled successfully")) - fmt.Printf("Configuration saved to: %s\n", getConfigPath()) - fmt.Printf("Whitelisted commands: %d\n", len(cfg.Tools.Whitelist.Commands)) - fmt.Printf("Whitelisted patterns: %d\n", len(cfg.Tools.Whitelist.Patterns)) - return nil -} - -func disableTools(cmd *cobra.Command, args []string) error { - _, err := loadAndUpdateConfig(func(c *config.Config) { - c.Tools.Enabled = false - }) - if err != nil { - return err - } - - fmt.Printf("%s\n", ui.FormatErrorCLI("Tools disabled successfully")) - fmt.Printf("Configuration saved to: %s\n", getConfigPath()) - return nil -} - -func listTools(cmd *cobra.Command, args []string) error { - cfg, err := config.LoadConfig("") - if err != nil { - return fmt.Errorf("failed to load config: %w", err) - } - - format, _ := cmd.Flags().GetString("format") - - if format == "json" { - data := map[string]interface{}{ - "enabled": cfg.Tools.Enabled, - "commands": cfg.Tools.Whitelist.Commands, - "patterns": cfg.Tools.Whitelist.Patterns, - "safety": map[string]bool{ - "require_approval": cfg.Tools.Safety.RequireApproval, - }, - } - jsonOutput, err := json.MarshalIndent(data, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal output: %w", err) - } - fmt.Println(string(jsonOutput)) - return nil - } - - fmt.Printf("Tools Status: ") - if cfg.Tools.Enabled { - fmt.Printf("%s\n", ui.FormatSuccess("Enabled")) - } else { - fmt.Printf("%s\n", ui.FormatErrorCLI("Disabled")) - } - - fmt.Printf("\nWhitelisted Commands (%d):\n", len(cfg.Tools.Whitelist.Commands)) - for _, cmd := range cfg.Tools.Whitelist.Commands { - fmt.Printf(" • %s\n", cmd) - } - - fmt.Printf("\nWhitelisted Patterns (%d):\n", len(cfg.Tools.Whitelist.Patterns)) - for _, pattern := range cfg.Tools.Whitelist.Patterns { - fmt.Printf(" • %s\n", pattern) - } - - fmt.Printf("\nSafety Settings:\n") - if cfg.Tools.Safety.RequireApproval { - fmt.Printf(" • Approval required: %s\n", ui.FormatSuccess("Enabled")) - } else { - fmt.Printf(" • Approval required: %s\n", ui.FormatErrorCLI("Disabled")) - } - - return nil -} - -func validateTool(cmd *cobra.Command, args []string) error { - cfg, err := config.LoadConfig("") - if err != nil { - return fmt.Errorf("failed to load config: %w", err) - } - - if !cfg.Tools.Enabled { - fmt.Printf("%s\n", ui.FormatErrorCLI("Tools are disabled")) - return nil - } - - services := container.NewServiceContainer(cfg) - toolService := services.GetToolService() - - command := args[0] - toolArgs := map[string]interface{}{ - "command": command, - } - - err = toolService.ValidateTool("Bash", toolArgs) - if err != nil { - fmt.Printf("%s\n", ui.FormatErrorCLI(fmt.Sprintf("Command not allowed: %s", command))) - fmt.Printf("Reason: %s\n", err.Error()) - return nil - } - - fmt.Printf("%s\n", ui.FormatSuccess(fmt.Sprintf("Command is whitelisted: %s", command))) - return nil -} - -func execTool(cmd *cobra.Command, args []string) error { - cfg, err := config.LoadConfig("") - if err != nil { - return fmt.Errorf("failed to load config: %w", err) - } - - if !cfg.Tools.Enabled { - return fmt.Errorf("tools are not enabled") - } - - services := container.NewServiceContainer(cfg) - toolService := services.GetToolService() - - command := args[0] - format, _ := cmd.Flags().GetString("format") - - toolArgs := map[string]interface{}{ - "command": command, - "format": format, - } - - ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) - defer cancel() - - result, err := toolService.ExecuteTool(ctx, "Bash", toolArgs) - if err != nil { - return fmt.Errorf("command execution failed: %w", err) - } - - fmt.Print(result) - return nil -} - -func enableSafety(cmd *cobra.Command, args []string) error { - _, err := loadAndUpdateConfig(func(c *config.Config) { - c.Tools.Safety.RequireApproval = true - }) - if err != nil { - return err - } - - fmt.Printf("%s\n", ui.FormatSuccess("Safety approval enabled")) - fmt.Printf("Commands will require approval before execution\n") - return nil -} - -func disableSafety(cmd *cobra.Command, args []string) error { - _, err := loadAndUpdateConfig(func(c *config.Config) { - c.Tools.Safety.RequireApproval = false - }) - if err != nil { - return err - } - - fmt.Printf("%s\n", ui.FormatWarning("Safety approval disabled")) - fmt.Printf("Commands will execute immediately without approval\n") - return nil -} - -func safetyStatus(cmd *cobra.Command, args []string) error { - cfg, err := config.LoadConfig("") - if err != nil { - return fmt.Errorf("failed to load config: %w", err) - } - - fmt.Printf("Safety Approval Status: ") - if cfg.Tools.Safety.RequireApproval { - fmt.Printf("%s\n", ui.FormatSuccess("Enabled")) - fmt.Printf("Commands require approval before execution\n") - } else { - fmt.Printf("%s\n", ui.FormatErrorCLI("Disabled")) - fmt.Printf("Commands execute immediately without approval\n") - } - - return nil -} - -func loadAndUpdateConfig(updateFn func(*config.Config)) (*config.Config, error) { - configPath := getConfigPath() - cfg, err := config.LoadConfig("") - if err != nil { - return nil, fmt.Errorf("failed to load config: %w", err) - } - - updateFn(cfg) - - err = cfg.SaveConfig(configPath) - if err != nil { - return nil, fmt.Errorf("failed to save config: %w", err) - } - - return cfg, nil -} - -func getConfigPath() string { - configPath := ".infer/config.yaml" - if _, err := os.Stat(configPath); os.IsNotExist(err) { - configPath = ".infer.yaml" - } - return configPath -} diff --git a/config/config.go b/config/config.go index 16049b89..7bf5db19 100644 --- a/config/config.go +++ b/config/config.go @@ -73,7 +73,7 @@ func DefaultConfig() *Config { Quiet: false, }, Tools: ToolsConfig{ - Enabled: false, + Enabled: true, Whitelist: ToolWhitelistConfig{ Commands: []string{ "ls", "pwd", "echo", "cat", "head", "tail",