diff --git a/README.md b/README.md index c755370..a0563e2 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,10 @@ func main() { Prompt: "Create a simple hello.go file that prints 'Hello, World!'", Options: &claudecode.Options{ MaxTurns: intPtr(3), - AllowedTools: []string{"Read", "Write"}, SystemPrompt: stringPtr("You are a helpful Go programming assistant"), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "Write"}, + }, }, } @@ -95,9 +97,11 @@ func main() { request := claudecode.QueryRequest{ Prompt: "Analyze this Go project and suggest improvements", Options: &claudecode.Options{ - AllowedTools: []string{"Read", "LS", "Grep"}, OutputFormat: outputFormatPtr(claudecode.OutputFormatStreamJSON), Verbose: boolPtr(true), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "LS", "Grep"}, + }, }, } @@ -143,9 +147,12 @@ type Options struct { // Conversation control MaxTurns *int // Limit conversation turns - // Tool configuration - AllowedTools []string // Tools Claude can use - DisallowedTools []string // Tools Claude cannot use + // Tool configuration (new structured approach) + Tools *ToolConfig // Tool access control + + // Deprecated fields (maintained for backward compatibility) + AllowedTools []string // Use Tools.Allowed instead + DisallowedTools []string // Use Tools.Disallowed instead // Session management Resume *string // Resume session by ID @@ -155,9 +162,14 @@ type Options struct { OutputFormat *OutputFormat // text, json, stream-json Verbose *bool // Enable verbose logging + // Permission configuration (new structured approach) + Permissions *PermissionConfig // Permission and security settings + // MCP (Model Context Protocol) MCPConfig *string // Path to MCP config JSON - PermissionPromptTool *string // MCP tool for permissions + + // Deprecated fields (maintained for backward compatibility) + PermissionPromptTool *string // Use Permissions.PromptTool instead // System WorkingDirectory *string // Working directory @@ -230,14 +242,35 @@ claudecode.QueryWithRequest(ctx, claudecode.QueryRequest{ request := claudecode.QueryRequest{ Prompt: "Analyze project files", Options: &claudecode.Options{ - MCPConfig: stringPtr("mcp-servers.json"), - AllowedTools: []string{"mcp__filesystem__read_file", "mcp__filesystem__list_directory"}, - PermissionPromptTool: stringPtr("mcp__permissions__approve"), + MCPConfig: stringPtr("mcp-servers.json"), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"mcp__filesystem__read_file", "mcp__filesystem__list_directory"}, + }, + Permissions: &claudecode.PermissionConfig{ + PromptTool: stringPtr("mcp__permissions__approve"), + }, + }, +} +``` + +### Tool and Permission Configuration + +#### New Structured Approach (Recommended) + +```go +options := &claudecode.Options{ + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "LS", "Grep"}, + Disallowed: []string{"Bash", "Write"}, + }, + Permissions: &claudecode.PermissionConfig{ + Mode: stringPtr("acceptEdits"), + DangerouslySkip: boolPtr(false), }, } ``` -### Tool Restrictions +#### Legacy Approach (Deprecated but still supported) ```go options := &claudecode.Options{ @@ -409,4 +442,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file - [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code) - [Claude Code CLI](https://www.npmjs.com/package/@anthropic-ai/claude-code) - [Claude Code TypeScript SDK](https://www.npmjs.com/package/@anthropic-ai/claude-code) -- [Claude Code Python SDK](https://pypi.org/project/claude-code-sdk/) \ No newline at end of file +- [Claude Code Python SDK](https://pypi.org/project/claude-code-sdk/) diff --git a/claude.go b/claude.go index 4464e49..ed1b922 100644 --- a/claude.go +++ b/claude.go @@ -393,12 +393,23 @@ func addModelAndToolArgs(args []string, options *Options) []string { if options.Model != nil && *options.Model != "" { args = append(args, "--model", *options.Model) } + + if options.Tools != nil { + if len(options.Tools.Allowed) > 0 { + args = append(args, "--allowedTools", strings.Join(options.Tools.Allowed, ",")) + } + if len(options.Tools.Disallowed) > 0 { + args = append(args, "--disallowedTools", strings.Join(options.Tools.Disallowed, ",")) + } + } + if len(options.AllowedTools) > 0 { args = append(args, "--allowedTools", strings.Join(options.AllowedTools, ",")) } if len(options.DisallowedTools) > 0 { args = append(args, "--disallowedTools", strings.Join(options.DisallowedTools, ",")) } + return args } @@ -444,6 +455,18 @@ func addMCPArgs(args []string, options *Options) []string { } func addPermissionArgs(args []string, options *Options) []string { + if options.Permissions != nil { + if options.Permissions.Mode != nil && *options.Permissions.Mode != "" { + args = append(args, "--permission-mode", *options.Permissions.Mode) + } + if options.Permissions.PromptTool != nil && *options.Permissions.PromptTool != "" { + args = append(args, "--permission-prompt-tool", *options.Permissions.PromptTool) + } + if options.Permissions.DangerouslySkip != nil && *options.Permissions.DangerouslySkip { + args = append(args, "--dangerously-skip-permissions") + } + } + if options.PermissionMode != nil && *options.PermissionMode != "" { args = append(args, "--permission-mode", *options.PermissionMode) } @@ -453,6 +476,7 @@ func addPermissionArgs(args []string, options *Options) []string { if options.DangerouslySkipPermissions != nil && *options.DangerouslySkipPermissions { args = append(args, "--dangerously-skip-permissions") } + return args } diff --git a/examples/advanced/README.md b/examples/advanced/README.md index f86a4b3..cf34530 100644 --- a/examples/advanced/README.md +++ b/examples/advanced/README.md @@ -32,9 +32,13 @@ go run main.go ### MCP Integration ```go Options: &claudecode.Options{ - MCPConfig: stringPtr("mcp-servers.json"), - AllowedTools: []string{"mcp__filesystem__read_file"}, - PermissionPromptTool: stringPtr("mcp__permissions__approve"), + MCPConfig: stringPtr("mcp-servers.json"), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"mcp__filesystem__read_file"}, + }, + Permissions: &claudecode.PermissionConfig{ + PromptTool: stringPtr("mcp__permissions__approve"), + }, } ``` @@ -49,8 +53,10 @@ Options: &claudecode.Options{ ### Tool Restrictions ```go Options: &claudecode.Options{ - AllowedTools: []string{"Read", "LS", "Grep"}, - DisallowedTools: []string{"Write", "Bash"}, + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "LS", "Grep"}, + Disallowed: []string{"Write", "Bash"}, + }, } ``` @@ -93,4 +99,4 @@ To use all features, you would need: ## Performance -The example includes real-time streaming analysis which may take several minutes to complete as it performs comprehensive project analysis. \ No newline at end of file +The example includes real-time streaming analysis which may take several minutes to complete as it performs comprehensive project analysis. diff --git a/examples/advanced/main.go b/examples/advanced/main.go index 6f7e43b..845e6ae 100644 --- a/examples/advanced/main.go +++ b/examples/advanced/main.go @@ -21,12 +21,16 @@ func main() { _ = claudecode.QueryRequest{ Prompt: "Use filesystem tools to analyze the project structure", Options: &claudecode.Options{ - MaxTurns: intPtr(5), - AllowedTools: []string{"mcp__filesystem__read_file", "mcp__filesystem__list_directory"}, - MCPConfig: stringPtr("mcp-servers.json"), - PermissionPromptTool: stringPtr("mcp__permissions__approve"), - OutputFormat: outputFormatPtr(claudecode.OutputFormatJSON), - Verbose: boolPtr(true), + MaxTurns: intPtr(5), + MCPConfig: stringPtr("mcp-servers.json"), + OutputFormat: outputFormatPtr(claudecode.OutputFormatJSON), + Verbose: boolPtr(true), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"mcp__filesystem__read_file", "mcp__filesystem__list_directory"}, + }, + Permissions: &claudecode.PermissionConfig{ + PromptTool: stringPtr("mcp__permissions__approve"), + }, }, } @@ -45,8 +49,10 @@ func main() { Prompt: "Create a simple Go function that calculates fibonacci numbers", Options: &claudecode.Options{ MaxTurns: intPtr(2), - AllowedTools: []string{"Write"}, OutputFormat: outputFormatPtr(claudecode.OutputFormatJSON), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Write"}, + }, }, } @@ -73,8 +79,10 @@ func main() { Options: &claudecode.Options{ Resume: stringPtr(sessionID), MaxTurns: intPtr(2), - AllowedTools: []string{"Write"}, OutputFormat: outputFormatPtr(claudecode.OutputFormatText), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Write"}, + }, }, } @@ -95,10 +103,12 @@ func main() { SystemPrompt: stringPtr("You are a senior Go architect. Focus on performance, maintainability, and best practices."), AppendSystemPrompt: stringPtr("Always provide specific, actionable recommendations."), MaxTurns: intPtr(3), - AllowedTools: []string{"Read", "LS", "Grep"}, - DisallowedTools: []string{"Write", "Bash"}, OutputFormat: outputFormatPtr(claudecode.OutputFormatStreamJSON), Verbose: boolPtr(false), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "LS", "Grep"}, + Disallowed: []string{"Write", "Bash"}, + }, }, } @@ -164,8 +174,10 @@ nextExample: Prompt: "List the Go files in this project", Options: &claudecode.Options{ MaxTurns: intPtr(1), - AllowedTools: []string{"LS", "Glob"}, OutputFormat: &format, + Tools: &claudecode.ToolConfig{ + Allowed: []string{"LS", "Glob"}, + }, }, } @@ -210,4 +222,4 @@ func boolPtr(b bool) *bool { func outputFormatPtr(format claudecode.OutputFormat) *claudecode.OutputFormat { return &format -} \ No newline at end of file +} diff --git a/examples/basic/main.go b/examples/basic/main.go index ee4a0da..c16ca75 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -19,8 +19,10 @@ func main() { request := claudecode.QueryRequest{ Prompt: "Create a simple hello.go file that prints 'Hello, World!'", Options: &claudecode.Options{ - AllowedTools: []string{"Read", "Write"}, SystemPrompt: stringPtr("You are a helpful Go programming assistant"), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "Write"}, + }, }, } @@ -69,4 +71,4 @@ func stringPtr(s string) *string { func outputFormatPtr(format claudecode.OutputFormat) *claudecode.OutputFormat { return &format -} \ No newline at end of file +} diff --git a/examples/quick_start.go b/examples/quick_start.go index 486517e..5a48fe4 100644 --- a/examples/quick_start.go +++ b/examples/quick_start.go @@ -69,8 +69,10 @@ func withToolsExample(ctx context.Context) { request := claudecode.QueryRequest{ Prompt: "Create a file called hello.txt with 'Hello, World!' in it", Options: &claudecode.Options{ - AllowedTools: []string{"Read", "Write"}, SystemPrompt: stringPtr("You are a helpful file assistant."), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "Write"}, + }, }, } @@ -115,4 +117,4 @@ func intPtr(i int) *int { func stringPtr(s string) *string { return &s -} \ No newline at end of file +} diff --git a/examples/streaming/main.go b/examples/streaming/main.go index dbc261e..54c510b 100644 --- a/examples/streaming/main.go +++ b/examples/streaming/main.go @@ -20,10 +20,12 @@ func main() { Prompt: "List the files in the current directory and create a simple README.md", Options: &claudecode.Options{ MaxTurns: intPtr(3), - AllowedTools: []string{"Read", "Write"}, SystemPrompt: stringPtr("You are a helpful coding assistant. Be concise and direct."), OutputFormat: outputFormatPtr(claudecode.OutputFormatStreamJSON), Verbose: boolPtr(true), + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "Write"}, + }, }, } @@ -34,10 +36,12 @@ func main() { fmt.Println("\n=== Example 2: Traditional QueryStream with new features ===") options := &claudecode.Options{ MaxTurns: intPtr(2), - AllowedTools: []string{"Read", "LS"}, AppendSystemPrompt: stringPtr("Focus on showing file structure clearly."), OutputFormat: outputFormatPtr(claudecode.OutputFormatStreamJSON), - DisallowedTools: []string{"Bash"}, + Tools: &claudecode.ToolConfig{ + Allowed: []string{"Read", "LS"}, + Disallowed: []string{"Bash"}, + }, } // Execute streaming query @@ -114,4 +118,4 @@ func boolPtr(b bool) *bool { func outputFormatPtr(format claudecode.OutputFormat) *claudecode.OutputFormat { return &format -} \ No newline at end of file +} diff --git a/types.go b/types.go index 91d9e1e..50057ac 100644 --- a/types.go +++ b/types.go @@ -188,6 +188,29 @@ type Usage struct { OutputTokens int `json:"output_tokens"` } +// ToolConfig represents tool access configuration +type ToolConfig struct { + // Allowed specifies which tools Claude can use + Allowed []string `json:"allowed,omitempty"` + + // Disallowed specifies which tools Claude cannot use + Disallowed []string `json:"disallowed,omitempty"` +} + +// PermissionConfig represents permission and security settings +type PermissionConfig struct { + // Mode defines the interaction permission level + // Options: "default", "acceptEdits", "bypassPermissions", "plan" + Mode *string `json:"mode,omitempty"` + + // PromptTool specifies the MCP tool to use for permission prompts + PromptTool *string `json:"prompt_tool,omitempty"` + + // DangerouslySkip bypasses all permission checks + // Recommended only for sandboxes with no internet access + DangerouslySkip *bool `json:"dangerously_skip,omitempty"` +} + // QueryRequest represents a query request compatible with TypeScript/Python SDKs type QueryRequest struct { // Prompt is the query to send to Claude Code @@ -220,11 +243,7 @@ type Options struct { Resume *string `json:"resume,omitempty"` // Tool configuration - // AllowedTools specifies which tools Claude can use (comma or space-separated) - AllowedTools []string `json:"allowed_tools,omitempty"` - - // DisallowedTools specifies which tools Claude cannot use (comma or space-separated) - DisallowedTools []string `json:"disallowed_tools,omitempty"` + Tools *ToolConfig `json:"tools,omitempty"` // MCP (Model Context Protocol) configuration // MCPTools specifies MCP tools to use @@ -236,17 +255,8 @@ type Options struct { // MCPConfig specifies the path to MCP server configuration JSON file or JSON string MCPConfig *string `json:"mcp_config,omitempty"` - // Permission and security - // PermissionMode defines the interaction permission level - // Options: "default", "acceptEdits", "bypassPermissions", "plan" - PermissionMode *string `json:"permission_mode,omitempty"` - - // PermissionPromptTool specifies the MCP tool to use for permission prompts - PermissionPromptTool *string `json:"permission_prompt_tool,omitempty"` - - // DangerouslySkipPermissions bypasses all permission checks - // Recommended only for sandboxes with no internet access - DangerouslySkipPermissions *bool `json:"dangerously_skip_permissions,omitempty"` + // Permission and security configuration + Permissions *PermissionConfig `json:"permissions,omitempty"` // Directory and environment // Cwd sets the working directory for Claude Code @@ -276,4 +286,22 @@ type Options struct { // Executable specifies a custom path to the Claude Code CLI Executable *string `json:"executable,omitempty"` + + // Deprecated fields - maintained for backward compatibility + // AllowedTools specifies which tools Claude can use (comma or space-separated) + AllowedTools []string `json:"allowed_tools,omitempty"` + + // DisallowedTools specifies which tools Claude cannot use (comma or space-separated) + DisallowedTools []string `json:"disallowed_tools,omitempty"` + + // PermissionMode defines the interaction permission level + // Options: "default", "acceptEdits", "bypassPermissions", "plan" + PermissionMode *string `json:"permission_mode,omitempty"` + + // PermissionPromptTool specifies the MCP tool to use for permission prompts + PermissionPromptTool *string `json:"permission_prompt_tool,omitempty"` + + // DangerouslySkipPermissions bypasses all permission checks + // Recommended only for sandboxes with no internet access + DangerouslySkipPermissions *bool `json:"dangerously_skip_permissions,omitempty"` }