Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 8 additions & 2 deletions Sources/ClaudeCodeSDK/API/ClaudeCodeConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ 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(
command: "claude",
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
)
}

Expand All @@ -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
}
}
15 changes: 10 additions & 5 deletions Sources/ClaudeCodeSDK/Client/ClaudeCodeClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand All @@ -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)

Expand Down