diff --git a/ClaudeCodeSharpSDK.Tests/Unit/ClaudeExecTests.cs b/ClaudeCodeSharpSDK.Tests/Unit/ClaudeExecTests.cs index 5928fa3..5a88110 100644 --- a/ClaudeCodeSharpSDK.Tests/Unit/ClaudeExecTests.cs +++ b/ClaudeCodeSharpSDK.Tests/Unit/ClaudeExecTests.cs @@ -26,6 +26,11 @@ public class ClaudeExecTests private const string DescriptionPropertyName = "Description"; private const string DescriptionPropertyNameCamel = "description"; private const string DisallowedToolsFlag = "--disallowed-tools"; + private const string EffortFlag = "--effort"; + private const string EffortHighValue = "high"; + private const string EffortLowValue = "low"; + private const string EffortMaxValue = "max"; + private const string EffortMediumValue = "medium"; private const string ExampleBaseUrl = "https://example.invalid"; private const string FeatureABeta = "feature-a"; private const string FeatureBBeta = "feature-b"; @@ -41,6 +46,7 @@ public class ClaudeExecTests private const string McpConfigPath = "/tmp/mcp.json"; private const string McpConfigTwo = """{"name":"two","command":"uvx","args":["c","d"]}"""; private const string ModelFlag = "--model"; + private const string NameFlag = "--name"; private const string OutputFormatFlag = "--output-format"; private const string OutputSchemaMessageFragment = "ReplayUserMessages"; private const string PerTurnHookValue = "per-turn-hook"; @@ -59,6 +65,7 @@ public class ClaudeExecTests private const string ResumeSessionId = "session-1"; private const string ReviewerAgentKey = "reviewer"; private const string ReviewerPrompt = "Review code changes"; + private const string SessionDisplayName = "my-session"; private const string SettingSourcesFlag = "--setting-sources"; private const string SettingsFlag = "--settings"; private const string StreamJsonOutputFormat = "stream-json"; @@ -206,6 +213,64 @@ public async Task BuildCommandArgs_WithReservedAdditionalCliFlag_Throws() await Assert.That(exception!.Message).Contains(ReservedOutputFormatFlag); } + [Test] + [Arguments(EffortLevel.Low, EffortLowValue)] + [Arguments(EffortLevel.Medium, EffortMediumValue)] + [Arguments(EffortLevel.High, EffortHighValue)] + [Arguments(EffortLevel.Max, EffortMaxValue)] + public async Task BuildCommandArgs_WithEffort_MapsToCliValue(EffortLevel effort, string expectedCliValue) + { + var exec = new ClaudeExec(executablePath: TestConstants.ClaudeExecutablePath); + + var commandArgs = exec.BuildCommandArgs(new ClaudeExecArgs + { + Input = SummarizeInput, + Effort = effort, + }); + + await Assert.That(GetRequiredFlagValue(commandArgs, EffortFlag)).IsEqualTo(expectedCliValue); + } + + [Test] + public async Task BuildCommandArgs_WithoutEffort_OmitsEffortFlag() + { + var exec = new ClaudeExec(executablePath: TestConstants.ClaudeExecutablePath); + + var commandArgs = exec.BuildCommandArgs(new ClaudeExecArgs + { + Input = SummarizeInput, + }); + + await Assert.That(commandArgs.Contains(EffortFlag)).IsFalse(); + } + + [Test] + public async Task BuildCommandArgs_WithName_MapsToCliFlag() + { + var exec = new ClaudeExec(executablePath: TestConstants.ClaudeExecutablePath); + + var commandArgs = exec.BuildCommandArgs(new ClaudeExecArgs + { + Input = SummarizeInput, + Name = SessionDisplayName, + }); + + await Assert.That(GetRequiredFlagValue(commandArgs, NameFlag)).IsEqualTo(SessionDisplayName); + } + + [Test] + public async Task BuildCommandArgs_WithoutName_OmitsNameFlag() + { + var exec = new ClaudeExec(executablePath: TestConstants.ClaudeExecutablePath); + + var commandArgs = exec.BuildCommandArgs(new ClaudeExecArgs + { + Input = SummarizeInput, + }); + + await Assert.That(commandArgs.Contains(NameFlag)).IsFalse(); + } + private static JsonObject CreateBaseSettings() { return new JsonObject diff --git a/ClaudeCodeSharpSDK/Client/ClaudeThread.cs b/ClaudeCodeSharpSDK/Client/ClaudeThread.cs index c76b749..6665b1c 100644 --- a/ClaudeCodeSharpSDK/Client/ClaudeThread.cs +++ b/ClaudeCodeSharpSDK/Client/ClaudeThread.cs @@ -273,8 +273,10 @@ private async IAsyncEnumerable RunStreamedInternalAsync( BaseUrl = _options.BaseUrl, ApiKey = _options.ApiKey, Model = _threadOptions.Model, + Name = _threadOptions.Name, Agent = _threadOptions.Agent, FallbackModel = _threadOptions.FallbackModel, + Effort = _threadOptions.Effort, WorkingDirectory = _threadOptions.WorkingDirectory, PermissionMode = _threadOptions.PermissionMode, DangerouslySkipPermissions = _threadOptions.DangerouslySkipPermissions, diff --git a/ClaudeCodeSharpSDK/Client/ThreadOptions.cs b/ClaudeCodeSharpSDK/Client/ThreadOptions.cs index 214f35f..af3a875 100644 --- a/ClaudeCodeSharpSDK/Client/ThreadOptions.cs +++ b/ClaudeCodeSharpSDK/Client/ThreadOptions.cs @@ -12,6 +12,14 @@ public enum PermissionMode Plan, } +public enum EffortLevel +{ + Low, + Medium, + High, + Max, +} + public enum SettingSource { User, @@ -25,10 +33,14 @@ public sealed record ThreadOptions { public string? Model { get; init; } + public string? Name { get; init; } + public string? Agent { get; init; } public string? FallbackModel { get; init; } + public EffortLevel? Effort { get; init; } + public string? WorkingDirectory { get; init; } public PermissionMode? PermissionMode { get; init; } diff --git a/ClaudeCodeSharpSDK/Execution/ClaudeExec.cs b/ClaudeCodeSharpSDK/Execution/ClaudeExec.cs index 6ca9a81..23de384 100644 --- a/ClaudeCodeSharpSDK/Execution/ClaudeExec.cs +++ b/ClaudeCodeSharpSDK/Execution/ClaudeExec.cs @@ -22,8 +22,10 @@ public sealed class ClaudeExec private const string IncludePartialMessagesFlag = "--include-partial-messages"; private const string ReplayUserMessagesFlag = "--replay-user-messages"; private const string ModelFlag = "--model"; + private const string NameFlag = "--name"; private const string AgentFlag = "--agent"; private const string FallbackModelFlag = "--fallback-model"; + private const string EffortFlag = "--effort"; private const string PermissionModeFlag = "--permission-mode"; private const string DangerouslySkipPermissionsFlag = "--dangerously-skip-permissions"; private const string AllowDangerouslySkipPermissionsFlag = "--allow-dangerously-skip-permissions"; @@ -158,6 +160,12 @@ internal IReadOnlyList BuildCommandArgs(ClaudeExecArgs args) commandArgs.Add(args.Model); } + if (!string.IsNullOrWhiteSpace(args.Name)) + { + commandArgs.Add(NameFlag); + commandArgs.Add(args.Name); + } + if (!string.IsNullOrWhiteSpace(args.Agent)) { commandArgs.Add(AgentFlag); @@ -170,6 +178,12 @@ internal IReadOnlyList BuildCommandArgs(ClaudeExecArgs args) commandArgs.Add(args.FallbackModel); } + if (args.Effort.HasValue) + { + commandArgs.Add(EffortFlag); + commandArgs.Add(args.Effort.Value.ToCliValue()); + } + if (args.PermissionMode.HasValue) { commandArgs.Add(PermissionModeFlag); diff --git a/ClaudeCodeSharpSDK/Execution/ClaudeExecArgs.cs b/ClaudeCodeSharpSDK/Execution/ClaudeExecArgs.cs index 700bdcf..b9eec97 100644 --- a/ClaudeCodeSharpSDK/Execution/ClaudeExecArgs.cs +++ b/ClaudeCodeSharpSDK/Execution/ClaudeExecArgs.cs @@ -13,10 +13,14 @@ public sealed record ClaudeExecArgs public string? Model { get; init; } + public string? Name { get; init; } + public string? Agent { get; init; } public string? FallbackModel { get; init; } + public EffortLevel? Effort { get; init; } + public string? WorkingDirectory { get; init; } public PermissionMode? PermissionMode { get; init; } diff --git a/ClaudeCodeSharpSDK/Internal/ClaudeCliValueExtensions.cs b/ClaudeCodeSharpSDK/Internal/ClaudeCliValueExtensions.cs index 3155bba..42147c3 100644 --- a/ClaudeCodeSharpSDK/Internal/ClaudeCliValueExtensions.cs +++ b/ClaudeCodeSharpSDK/Internal/ClaudeCliValueExtensions.cs @@ -14,6 +14,14 @@ private static class PermissionModeValues public const string Plan = "plan"; } + private static class EffortLevelValues + { + public const string Low = "low"; + public const string Medium = "medium"; + public const string High = "high"; + public const string Max = "max"; + } + private static class SettingSourceValues { public const string User = "user"; @@ -35,6 +43,18 @@ public static string ToCliValue(this PermissionMode permissionMode) }; } + public static string ToCliValue(this EffortLevel effortLevel) + { + return effortLevel switch + { + EffortLevel.Low => EffortLevelValues.Low, + EffortLevel.Medium => EffortLevelValues.Medium, + EffortLevel.High => EffortLevelValues.High, + EffortLevel.Max => EffortLevelValues.Max, + _ => throw new ArgumentOutOfRangeException(nameof(effortLevel), effortLevel, null), + }; + } + public static string ToCliValue(this SettingSource settingSource) { return settingSource switch diff --git a/global.json b/global.json index c335052..062772b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.103", + "version": "10.0.102", "rollForward": "latestFeature" }, "test": { diff --git a/submodules/anthropic-claude-code b/submodules/anthropic-claude-code index da80366..420a188 160000 --- a/submodules/anthropic-claude-code +++ b/submodules/anthropic-claude-code @@ -1 +1 @@ -Subproject commit da80366c484698e6370ad9e8abf121f33f8f79e0 +Subproject commit 420a1884671fe09addc881f9a62624dae952d21c