diff --git a/README.md b/README.md index 81e8884..1cf036d 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,27 @@ Task { ## Key Features +### Command Suffix Support + +The SDK supports adding a suffix after the command, which is useful when the command requires specific argument ordering: + +```swift +// Configure with a command suffix +var config = ClaudeCodeConfiguration.default +config.commandSuffix = "--" // Adds "--" after "claude" + +let client = ClaudeCodeClient(configuration: config) + +// This generates commands like: "claude -- -p --verbose --max-turns 50" +let result = try await client.runSinglePrompt( + prompt: "Write a sorting algorithm", + outputFormat: .text, + options: ClaudeCodeOptions() +) +``` + +This is particularly useful when your command executable requires specific argument positioning or when using command wrappers that need arguments separated with `--`. + ### Different Output Formats Choose from three output formats depending on your needs: @@ -145,7 +166,8 @@ var configuration = ClaudeCodeConfiguration( workingDirectory: "/path/to/project", // Set working directory environment: ["API_KEY": "value"], // Additional environment variables enableDebugLogging: true, // Enable debug logs - additionalPaths: ["/custom/bin"] // Additional PATH directories + additionalPaths: ["/custom/bin"], // Additional PATH directories + commandSuffix: "--" // Optional suffix after command (e.g., "claude --") ) // Initialize client with custom configuration @@ -154,6 +176,7 @@ let client = ClaudeCodeClient(configuration: configuration) // Or modify configuration at runtime client.configuration.enableDebugLogging = false client.configuration.workingDirectory = "/new/path" +client.configuration.commandSuffix = "--" // Add suffix for commands like "claude -- -p --verbose" ``` ### Customization Options diff --git a/Sources/ClaudeCodeSDK/API/ClaudeCodeConfiguration.swift b/Sources/ClaudeCodeSDK/API/ClaudeCodeConfiguration.swift index 51dd444..97c34f3 100644 --- a/Sources/ClaudeCodeSDK/API/ClaudeCodeConfiguration.swift +++ b/Sources/ClaudeCodeSDK/API/ClaudeCodeConfiguration.swift @@ -24,6 +24,9 @@ public struct ClaudeCodeConfiguration { /// Additional paths to add to PATH environment variable public var additionalPaths: [String] + /// Optional suffix to append after the command (e.g., "--" for "airchat --") + public var commandSuffix: String? + /// Default configuration public static var `default`: ClaudeCodeConfiguration { ClaudeCodeConfiguration( @@ -31,7 +34,8 @@ public struct ClaudeCodeConfiguration { workingDirectory: nil, environment: [:], enableDebugLogging: false, - additionalPaths: ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin"] + additionalPaths: ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin"], + commandSuffix: nil ) } @@ -40,12 +44,14 @@ public struct ClaudeCodeConfiguration { workingDirectory: String? = nil, environment: [String: String] = [:], enableDebugLogging: Bool = false, - additionalPaths: [String] = ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin"] + additionalPaths: [String] = ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin"], + commandSuffix: String? = nil ) { self.command = command self.workingDirectory = workingDirectory self.environment = environment self.enableDebugLogging = enableDebugLogging self.additionalPaths = additionalPaths + self.commandSuffix = commandSuffix } } diff --git a/Sources/ClaudeCodeSDK/Client/ClaudeCodeClient.swift b/Sources/ClaudeCodeSDK/Client/ClaudeCodeClient.swift index 2647697..bf5e4e1 100644 --- a/Sources/ClaudeCodeSDK/Client/ClaudeCodeClient.swift +++ b/Sources/ClaudeCodeSDK/Client/ClaudeCodeClient.swift @@ -84,7 +84,8 @@ public final class ClaudeCodeClient: ClaudeCode, @unchecked Sendable { let args = opts.toCommandArgs() let argsString = args.joined(separator: " ") - let commandString = "\(configuration.command) \(argsString)" + let suffix = configuration.commandSuffix.map { " \($0)" } ?? "" + let commandString = "\(configuration.command)\(suffix) \(argsString)" return try await executeClaudeCommand( command: commandString, @@ -113,7 +114,8 @@ public final class ClaudeCodeClient: ClaudeCode, @unchecked Sendable { args.append(outputFormat.commandArgument) // Do NOT append the prompt as a quoted argument! - let commandString = "\(configuration.command) \(args.joined(separator: " "))" + let suffix = configuration.commandSuffix.map { " \($0)" } ?? "" + let commandString = "\(configuration.command)\(suffix) \(args.joined(separator: " "))" // Always send the prompt via stdin return try await executeClaudeCommand( @@ -144,7 +146,8 @@ public final class ClaudeCodeClient: ClaudeCode, @unchecked Sendable { args.append(outputFormat.commandArgument) // Construct the full command (no prompt appended!) - let commandString = "\(configuration.command) \(args.joined(separator: " "))" + let suffix = configuration.commandSuffix.map { " \($0)" } ?? "" + let commandString = "\(configuration.command)\(suffix) \(args.joined(separator: " "))" // Pass prompt via stdin (or nil if not provided) return try await executeClaudeCommand( @@ -177,7 +180,8 @@ public final class ClaudeCodeClient: ClaudeCode, @unchecked Sendable { args.append(outputFormat.commandArgument) // Build the command without the prompt - let commandString = "\(configuration.command) \(args.joined(separator: " "))" + let suffix = configuration.commandSuffix.map { " \($0)" } ?? "" + let commandString = "\(configuration.command)\(suffix) \(args.joined(separator: " "))" // Use stdin for prompt return try await executeClaudeCommand( @@ -190,7 +194,8 @@ public final class ClaudeCodeClient: ClaudeCode, @unchecked Sendable { } public func listSessions() async throws -> [SessionInfo] { - let commandString = "\(configuration.command) logs --output-format json" + let suffix = configuration.commandSuffix.map { " \($0)" } ?? "" + let commandString = "\(configuration.command)\(suffix) logs --output-format json" let process = configuredProcess(for: commandString)