@caretive/caret-cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.npmrc.tmp +2 -0
  2. package/README.md +72 -0
  3. package/cmd/cline/main.go +348 -0
  4. package/cmd/cline-host/main.go +71 -0
  5. package/e2e/default_update_test.go +154 -0
  6. package/e2e/helpers_test.go +378 -0
  7. package/e2e/main_test.go +47 -0
  8. package/e2e/mixed_stress_test.go +120 -0
  9. package/e2e/sqlite_helper.go +161 -0
  10. package/e2e/start_list_test.go +178 -0
  11. package/go.mod +64 -0
  12. package/go.sum +162 -0
  13. package/man/cline.1 +331 -0
  14. package/man/cline.1.md +332 -0
  15. package/package.json +54 -0
  16. package/pkg/cli/auth/auth_cline_provider.go +285 -0
  17. package/pkg/cli/auth/auth_menu.go +323 -0
  18. package/pkg/cli/auth/auth_subscription.go +130 -0
  19. package/pkg/cli/auth/byo_quick_setup.go +247 -0
  20. package/pkg/cli/auth/models_cline.go +141 -0
  21. package/pkg/cli/auth/models_list_fetch.go +156 -0
  22. package/pkg/cli/auth/models_list_static.go +69 -0
  23. package/pkg/cli/auth/providers_byo.go +184 -0
  24. package/pkg/cli/auth/providers_list.go +517 -0
  25. package/pkg/cli/auth/update_api_configurations.go +647 -0
  26. package/pkg/cli/auth/wizard_byo.go +764 -0
  27. package/pkg/cli/auth/wizard_byo_bedrock.go +193 -0
  28. package/pkg/cli/auth/wizard_byo_oca.go +366 -0
  29. package/pkg/cli/auth.go +43 -0
  30. package/pkg/cli/clerror/cline_error.go +187 -0
  31. package/pkg/cli/config/manager.go +208 -0
  32. package/pkg/cli/config/settings_renderer.go +198 -0
  33. package/pkg/cli/config.go +152 -0
  34. package/pkg/cli/display/ansi.go +27 -0
  35. package/pkg/cli/display/banner.go +211 -0
  36. package/pkg/cli/display/deduplicator.go +95 -0
  37. package/pkg/cli/display/markdown_renderer.go +139 -0
  38. package/pkg/cli/display/renderer.go +304 -0
  39. package/pkg/cli/display/segment_streamer.go +212 -0
  40. package/pkg/cli/display/streaming.go +134 -0
  41. package/pkg/cli/display/system_renderer.go +269 -0
  42. package/pkg/cli/display/tool_renderer.go +455 -0
  43. package/pkg/cli/display/tool_result_parser.go +371 -0
  44. package/pkg/cli/display/typewriter.go +210 -0
  45. package/pkg/cli/doctor.go +65 -0
  46. package/pkg/cli/global/cline-clients.go +501 -0
  47. package/pkg/cli/global/global.go +113 -0
  48. package/pkg/cli/global/registry.go +304 -0
  49. package/pkg/cli/handlers/ask_handlers.go +339 -0
  50. package/pkg/cli/handlers/handler.go +130 -0
  51. package/pkg/cli/handlers/say_handlers.go +521 -0
  52. package/pkg/cli/instances.go +506 -0
  53. package/pkg/cli/logs.go +382 -0
  54. package/pkg/cli/output/coordinator.go +167 -0
  55. package/pkg/cli/output/input_model.go +497 -0
  56. package/pkg/cli/sqlite/locks.go +366 -0
  57. package/pkg/cli/task/history_handler.go +72 -0
  58. package/pkg/cli/task/input_handler.go +577 -0
  59. package/pkg/cli/task/manager.go +1283 -0
  60. package/pkg/cli/task/settings_parser.go +754 -0
  61. package/pkg/cli/task/stream_coordinator.go +60 -0
  62. package/pkg/cli/task.go +675 -0
  63. package/pkg/cli/terminal/keyboard.go +695 -0
  64. package/pkg/cli/tui/HELP_WANTED.md +1 -0
  65. package/pkg/cli/types/history.go +17 -0
  66. package/pkg/cli/types/messages.go +329 -0
  67. package/pkg/cli/types/state.go +59 -0
  68. package/pkg/cli/updater/updater.go +409 -0
  69. package/pkg/cli/version.go +43 -0
  70. package/pkg/common/constants.go +6 -0
  71. package/pkg/common/schema.go +54 -0
  72. package/pkg/common/types.go +54 -0
  73. package/pkg/common/utils.go +185 -0
  74. package/pkg/generated/field_overrides.go +39 -0
  75. package/pkg/generated/providers.go +1584 -0
  76. package/pkg/hostbridge/diff.go +351 -0
  77. package/pkg/hostbridge/disabled/watch.go +39 -0
  78. package/pkg/hostbridge/disabled/window.go +63 -0
  79. package/pkg/hostbridge/disabled/workspace.go +66 -0
  80. package/pkg/hostbridge/env.go +166 -0
  81. package/pkg/hostbridge/grpc_server.go +113 -0
  82. package/pkg/hostbridge/simple.go +43 -0
  83. package/pkg/hostbridge/simple_workspace.go +85 -0
  84. package/pkg/hostbridge/window.go +129 -0
  85. package/scripts/publish-caret-cli.sh +39 -0
@@ -0,0 +1,754 @@
1
+ package task
2
+
3
+ import (
4
+ "fmt"
5
+ "strconv"
6
+ "strings"
7
+
8
+ "github.com/cline/grpc-go/cline"
9
+ )
10
+
11
+
12
+ func ParseTaskSettings(settingsFlags []string) (*cline.Settings, *cline.Secrets, error) {
13
+ if len(settingsFlags) == 0 {
14
+ return nil, nil, nil
15
+ }
16
+
17
+ settings := &cline.Settings{}
18
+ secrets := &cline.Secrets{}
19
+ nestedSettings := make(map[string]map[string]string)
20
+
21
+ for _, flag := range settingsFlags {
22
+ // Parse key=value
23
+ parts := strings.SplitN(flag, "=", 2)
24
+ if len(parts) != 2 {
25
+ return nil, nil, fmt.Errorf("invalid setting format '%s': expected key=value", flag)
26
+ }
27
+
28
+ key := strings.TrimSpace(parts[0])
29
+ value := strings.TrimSpace(parts[1])
30
+
31
+ // Convert kebab-case to snake_case
32
+ key = kebabToSnake(key)
33
+
34
+ // Check if this is a nested setting (contains a dot)
35
+ if strings.Contains(key, ".") {
36
+ dotParts := strings.SplitN(key, ".", 2)
37
+ parentField := dotParts[0]
38
+ childField := dotParts[1]
39
+
40
+ if nestedSettings[parentField] == nil {
41
+ nestedSettings[parentField] = make(map[string]string)
42
+ }
43
+ nestedSettings[parentField][childField] = value
44
+ } else {
45
+ // Check if it's a secret field first, then settings field
46
+ if err := setSecretField(secrets, key, value); err == nil {
47
+ // Successfully set as secret, continue
48
+ continue
49
+ }
50
+ // Not a secret, try as a settings field
51
+ if err := setSimpleField(settings, key, value); err != nil {
52
+ return nil, nil, fmt.Errorf("error setting field '%s': %w", key, err)
53
+ }
54
+ }
55
+ }
56
+
57
+ // Process nested settings
58
+ for parentField, childFields := range nestedSettings {
59
+ if err := setNestedField(settings, parentField, childFields); err != nil {
60
+ return nil, nil, fmt.Errorf("error setting nested field '%s': %w", parentField, err)
61
+ }
62
+ }
63
+
64
+ return settings, secrets, nil
65
+ }
66
+
67
+ // kebabToSnake converts kebab-case to snake_case
68
+ func kebabToSnake(s string) string {
69
+ return strings.ReplaceAll(s, "-", "_")
70
+ }
71
+
72
+ // Pointer helper functions for optional protobuf fields
73
+ func strPtr(s string) *string { return &s }
74
+ func boolPtr(b bool) *bool { return &b }
75
+ func int32Ptr(i int32) *int32 { return &i }
76
+ func int64Ptr(i int64) *int64 { return &i }
77
+ func float64Ptr(f float64) *float64 { return &f }
78
+
79
+ // setSimpleField sets a simple (non-nested) field on Settings
80
+ func setSimpleField(settings *cline.Settings, key, value string) error {
81
+ switch key {
82
+ // String fields
83
+ case "aws_region":
84
+ settings.AwsRegion = strPtr(value)
85
+ case "aws_bedrock_endpoint":
86
+ settings.AwsBedrockEndpoint = strPtr(value)
87
+ case "aws_profile":
88
+ settings.AwsProfile = strPtr(value)
89
+ case "aws_authentication":
90
+ settings.AwsAuthentication = strPtr(value)
91
+ case "vertex_project_id":
92
+ settings.VertexProjectId = strPtr(value)
93
+ case "vertex_region":
94
+ settings.VertexRegion = strPtr(value)
95
+ case "requesty_base_url":
96
+ settings.RequestyBaseUrl = strPtr(value)
97
+ case "open_ai_base_url":
98
+ settings.OpenAiBaseUrl = strPtr(value)
99
+ case "ollama_base_url":
100
+ settings.OllamaBaseUrl = strPtr(value)
101
+ case "ollama_api_options_ctx_num":
102
+ settings.OllamaApiOptionsCtxNum = strPtr(value)
103
+ case "lm_studio_base_url":
104
+ settings.LmStudioBaseUrl = strPtr(value)
105
+ case "lm_studio_max_tokens":
106
+ settings.LmStudioMaxTokens = strPtr(value)
107
+ case "anthropic_base_url":
108
+ settings.AnthropicBaseUrl = strPtr(value)
109
+ case "gemini_base_url":
110
+ settings.GeminiBaseUrl = strPtr(value)
111
+ case "azure_api_version":
112
+ settings.AzureApiVersion = strPtr(value)
113
+ case "open_router_provider_sorting":
114
+ settings.OpenRouterProviderSorting = strPtr(value)
115
+ case "lite_llm_base_url":
116
+ settings.LiteLlmBaseUrl = strPtr(value)
117
+ case "qwen_api_line":
118
+ settings.QwenApiLine = strPtr(value)
119
+ case "moonshot_api_line":
120
+ settings.MoonshotApiLine = strPtr(value)
121
+ case "zai_api_line":
122
+ settings.ZaiApiLine = strPtr(value)
123
+ case "telemetry_setting":
124
+ settings.TelemetrySetting = strPtr(value)
125
+ case "asksage_api_url":
126
+ settings.AsksageApiUrl = strPtr(value)
127
+ case "default_terminal_profile":
128
+ settings.DefaultTerminalProfile = strPtr(value)
129
+ case "sap_ai_core_token_url":
130
+ settings.SapAiCoreTokenUrl = strPtr(value)
131
+ case "sap_ai_core_base_url":
132
+ settings.SapAiCoreBaseUrl = strPtr(value)
133
+ case "sap_ai_resource_group":
134
+ settings.SapAiResourceGroup = strPtr(value)
135
+ case "claude_code_path":
136
+ settings.ClaudeCodePath = strPtr(value)
137
+ case "qwen_code_oauth_path":
138
+ settings.QwenCodeOauthPath = strPtr(value)
139
+ case "preferred_language":
140
+ settings.PreferredLanguage = strPtr(value)
141
+ case "custom_prompt":
142
+ settings.CustomPrompt = strPtr(value)
143
+ case "dify_base_url":
144
+ settings.DifyBaseUrl = strPtr(value)
145
+ case "oca_base_url":
146
+ settings.OcaBaseUrl = strPtr(value)
147
+ case "plan_mode_api_model_id":
148
+ settings.PlanModeApiModelId = strPtr(value)
149
+ case "plan_mode_reasoning_effort":
150
+ settings.PlanModeReasoningEffort = strPtr(value)
151
+ case "plan_mode_aws_bedrock_custom_model_base_id":
152
+ settings.PlanModeAwsBedrockCustomModelBaseId = strPtr(value)
153
+ case "plan_mode_open_router_model_id":
154
+ settings.PlanModeOpenRouterModelId = strPtr(value)
155
+ case "plan_mode_open_ai_model_id":
156
+ settings.PlanModeOpenAiModelId = strPtr(value)
157
+ case "plan_mode_ollama_model_id":
158
+ settings.PlanModeOllamaModelId = strPtr(value)
159
+ case "plan_mode_lm_studio_model_id":
160
+ settings.PlanModeLmStudioModelId = strPtr(value)
161
+ case "plan_mode_lite_llm_model_id":
162
+ settings.PlanModeLiteLlmModelId = strPtr(value)
163
+ case "plan_mode_requesty_model_id":
164
+ settings.PlanModeRequestyModelId = strPtr(value)
165
+ case "plan_mode_together_model_id":
166
+ settings.PlanModeTogetherModelId = strPtr(value)
167
+ case "plan_mode_fireworks_model_id":
168
+ settings.PlanModeFireworksModelId = strPtr(value)
169
+ case "plan_mode_sap_ai_core_model_id":
170
+ settings.PlanModeSapAiCoreModelId = strPtr(value)
171
+ case "plan_mode_sap_ai_core_deployment_id":
172
+ settings.PlanModeSapAiCoreDeploymentId = strPtr(value)
173
+ case "plan_mode_groq_model_id":
174
+ settings.PlanModeGroqModelId = strPtr(value)
175
+ case "plan_mode_baseten_model_id":
176
+ settings.PlanModeBasetenModelId = strPtr(value)
177
+ case "plan_mode_hugging_face_model_id":
178
+ settings.PlanModeHuggingFaceModelId = strPtr(value)
179
+ case "plan_mode_huawei_cloud_maas_model_id":
180
+ settings.PlanModeHuaweiCloudMaasModelId = strPtr(value)
181
+ case "plan_mode_oca_model_id":
182
+ settings.PlanModeOcaModelId = strPtr(value)
183
+ case "act_mode_api_model_id":
184
+ settings.ActModeApiModelId = strPtr(value)
185
+ case "act_mode_reasoning_effort":
186
+ settings.ActModeReasoningEffort = strPtr(value)
187
+ case "act_mode_aws_bedrock_custom_model_base_id":
188
+ settings.ActModeAwsBedrockCustomModelBaseId = strPtr(value)
189
+ case "act_mode_open_router_model_id":
190
+ settings.ActModeOpenRouterModelId = strPtr(value)
191
+ case "act_mode_open_ai_model_id":
192
+ settings.ActModeOpenAiModelId = strPtr(value)
193
+ case "act_mode_ollama_model_id":
194
+ settings.ActModeOllamaModelId = strPtr(value)
195
+ case "act_mode_lm_studio_model_id":
196
+ settings.ActModeLmStudioModelId = strPtr(value)
197
+ case "act_mode_lite_llm_model_id":
198
+ settings.ActModeLiteLlmModelId = strPtr(value)
199
+ case "act_mode_requesty_model_id":
200
+ settings.ActModeRequestyModelId = strPtr(value)
201
+ case "act_mode_together_model_id":
202
+ settings.ActModeTogetherModelId = strPtr(value)
203
+ case "act_mode_fireworks_model_id":
204
+ settings.ActModeFireworksModelId = strPtr(value)
205
+ case "act_mode_sap_ai_core_model_id":
206
+ settings.ActModeSapAiCoreModelId = strPtr(value)
207
+ case "act_mode_sap_ai_core_deployment_id":
208
+ settings.ActModeSapAiCoreDeploymentId = strPtr(value)
209
+ case "act_mode_groq_model_id":
210
+ settings.ActModeGroqModelId = strPtr(value)
211
+ case "act_mode_baseten_model_id":
212
+ settings.ActModeBasetenModelId = strPtr(value)
213
+ case "act_mode_hugging_face_model_id":
214
+ settings.ActModeHuggingFaceModelId = strPtr(value)
215
+ case "act_mode_huawei_cloud_maas_model_id":
216
+ settings.ActModeHuaweiCloudMaasModelId = strPtr(value)
217
+ case "act_mode_oca_model_id":
218
+ settings.ActModeOcaModelId = strPtr(value)
219
+
220
+ // Boolean fields
221
+ case "aws_use_cross_region_inference":
222
+ val, err := parseBool(value)
223
+ if err != nil {
224
+ return err
225
+ }
226
+ settings.AwsUseCrossRegionInference = boolPtr(val)
227
+ case "aws_bedrock_use_prompt_cache":
228
+ val, err := parseBool(value)
229
+ if err != nil {
230
+ return err
231
+ }
232
+ settings.AwsBedrockUsePromptCache = boolPtr(val)
233
+ case "aws_use_profile":
234
+ val, err := parseBool(value)
235
+ if err != nil {
236
+ return err
237
+ }
238
+ settings.AwsUseProfile = boolPtr(val)
239
+ case "lite_llm_use_prompt_cache":
240
+ val, err := parseBool(value)
241
+ if err != nil {
242
+ return err
243
+ }
244
+ settings.LiteLlmUsePromptCache = boolPtr(val)
245
+ case "plan_act_separate_models_setting":
246
+ val, err := parseBool(value)
247
+ if err != nil {
248
+ return err
249
+ }
250
+ settings.PlanActSeparateModelsSetting = boolPtr(val)
251
+ case "enable_checkpoints_setting":
252
+ val, err := parseBool(value)
253
+ if err != nil {
254
+ return err
255
+ }
256
+ settings.EnableCheckpointsSetting = boolPtr(val)
257
+ case "sap_ai_core_use_orchestration_mode":
258
+ val, err := parseBool(value)
259
+ if err != nil {
260
+ return err
261
+ }
262
+ settings.SapAiCoreUseOrchestrationMode = boolPtr(val)
263
+ case "strict_plan_mode_enabled":
264
+ val, err := parseBool(value)
265
+ if err != nil {
266
+ return err
267
+ }
268
+ settings.StrictPlanModeEnabled = boolPtr(val)
269
+ case "yolo_mode_toggled":
270
+ val, err := parseBool(value)
271
+ if err != nil {
272
+ return err
273
+ }
274
+ settings.YoloModeToggled = boolPtr(val)
275
+ case "use_auto_condense":
276
+ val, err := parseBool(value)
277
+ if err != nil {
278
+ return err
279
+ }
280
+ settings.UseAutoCondense = boolPtr(val)
281
+ case "plan_mode_aws_bedrock_custom_selected":
282
+ val, err := parseBool(value)
283
+ if err != nil {
284
+ return err
285
+ }
286
+ settings.PlanModeAwsBedrockCustomSelected = boolPtr(val)
287
+ case "act_mode_aws_bedrock_custom_selected":
288
+ val, err := parseBool(value)
289
+ if err != nil {
290
+ return err
291
+ }
292
+ settings.ActModeAwsBedrockCustomSelected = boolPtr(val)
293
+
294
+ // Integer fields
295
+ case "request_timeout_ms":
296
+ val, err := parseInt32(value)
297
+ if err != nil {
298
+ return err
299
+ }
300
+ settings.RequestTimeoutMs = int32Ptr(val)
301
+ case "shell_integration_timeout":
302
+ val, err := parseInt32(value)
303
+ if err != nil {
304
+ return err
305
+ }
306
+ settings.ShellIntegrationTimeout = int32Ptr(val)
307
+ case "terminal_output_line_limit":
308
+ val, err := parseInt32(value)
309
+ if err != nil {
310
+ return err
311
+ }
312
+ settings.TerminalOutputLineLimit = int32Ptr(val)
313
+ case "max_consecutive_mistakes":
314
+ val, err := parseInt32(value)
315
+ if err != nil {
316
+ return err
317
+ }
318
+ settings.MaxConsecutiveMistakes = int32Ptr(val)
319
+ case "fireworks_model_max_completion_tokens":
320
+ val, err := parseInt32(value)
321
+ if err != nil {
322
+ return err
323
+ }
324
+ settings.FireworksModelMaxCompletionTokens = int32Ptr(val)
325
+ case "fireworks_model_max_tokens":
326
+ val, err := parseInt32(value)
327
+ if err != nil {
328
+ return err
329
+ }
330
+ settings.FireworksModelMaxTokens = int32Ptr(val)
331
+
332
+ // Int64 fields
333
+ case "plan_mode_thinking_budget_tokens":
334
+ val, err := parseInt64(value)
335
+ if err != nil {
336
+ return err
337
+ }
338
+ settings.PlanModeThinkingBudgetTokens = int64Ptr(val)
339
+ case "act_mode_thinking_budget_tokens":
340
+ val, err := parseInt64(value)
341
+ if err != nil {
342
+ return err
343
+ }
344
+ settings.ActModeThinkingBudgetTokens = int64Ptr(val)
345
+
346
+ // Double fields
347
+ case "auto_condense_threshold":
348
+ val, err := parseFloat64(value)
349
+ if err != nil {
350
+ return err
351
+ }
352
+ settings.AutoCondenseThreshold = float64Ptr(val)
353
+
354
+ // Enum fields
355
+ // Note: We can use &val directly for enums because the parser functions return a new local variable.
356
+ // This is different from using &value (the loop variable), which would cause all fields to share
357
+ // the same memory address.
358
+ case "openai_reasoning_effort":
359
+ val, err := parseOpenaiReasoningEffort(value)
360
+ if err != nil {
361
+ return err
362
+ }
363
+ settings.OpenaiReasoningEffort = &val
364
+ case "mode":
365
+ val, err := parsePlanActMode(value)
366
+ if err != nil {
367
+ return err
368
+ }
369
+ settings.Mode = &val
370
+ case "plan_mode_api_provider":
371
+ val, err := parseApiProvider(value)
372
+ if err != nil {
373
+ return err
374
+ }
375
+ settings.PlanModeApiProvider = &val
376
+ case "act_mode_api_provider":
377
+ val, err := parseApiProvider(value)
378
+ if err != nil {
379
+ return err
380
+ }
381
+ settings.ActModeApiProvider = &val
382
+
383
+ default:
384
+ return fmt.Errorf("unsupported field '%s'", key)
385
+ }
386
+
387
+ return nil
388
+ }
389
+
390
+ // setNestedField sets a nested field on Settings
391
+ // Currently supports: auto_approval_settings, browser_settings
392
+ func setNestedField(settings *cline.Settings, parentField string, childFields map[string]string) error {
393
+ switch parentField {
394
+ case "auto_approval_settings":
395
+ if settings.AutoApprovalSettings == nil {
396
+ settings.AutoApprovalSettings = &cline.AutoApprovalSettings{}
397
+ }
398
+ return setAutoApprovalSettings(settings.AutoApprovalSettings, childFields)
399
+
400
+ case "browser_settings":
401
+ if settings.BrowserSettings == nil {
402
+ settings.BrowserSettings = &cline.BrowserSettings{}
403
+ }
404
+ return setBrowserSettings(settings.BrowserSettings, childFields)
405
+
406
+ default:
407
+ return fmt.Errorf("unsupported nested field '%s' (complex nested types are not supported via -s flags)", parentField)
408
+ }
409
+ }
410
+
411
+ // setAutoApprovalSettings sets fields on AutoApprovalSettings
412
+ func setAutoApprovalSettings(settings *cline.AutoApprovalSettings, fields map[string]string) error {
413
+ for key, value := range fields {
414
+ switch key {
415
+ case "enable_notifications":
416
+ val, err := parseBool(value)
417
+ if err != nil {
418
+ return err
419
+ }
420
+ settings.EnableNotifications = boolPtr(val)
421
+ case "actions":
422
+ return fmt.Errorf("auto_approval_settings.actions requires nested dot notation (e.g., auto-approval-settings.actions.read-files=true)")
423
+ default:
424
+ // Check if this is an action field (actions.*)
425
+ if strings.HasPrefix(key, "actions.") {
426
+ actionField := strings.TrimPrefix(key, "actions.")
427
+ if settings.Actions == nil {
428
+ settings.Actions = &cline.AutoApprovalActions{}
429
+ }
430
+ if err := setAutoApprovalAction(settings.Actions, actionField, value); err != nil {
431
+ return err
432
+ }
433
+ // Continue processing other fields
434
+ } else {
435
+ return fmt.Errorf("unsupported auto_approval_settings field '%s'", key)
436
+ }
437
+ }
438
+ }
439
+ return nil
440
+ }
441
+
442
+ // setAutoApprovalAction sets fields on AutoApprovalActions
443
+ func setAutoApprovalAction(actions *cline.AutoApprovalActions, key, value string) error {
444
+ val, err := parseBool(value)
445
+ if err != nil {
446
+ return err
447
+ }
448
+
449
+ switch key {
450
+ case "read_files":
451
+ actions.ReadFiles = boolPtr(val)
452
+ case "read_files_externally":
453
+ actions.ReadFilesExternally = boolPtr(val)
454
+ case "edit_files":
455
+ actions.EditFiles = boolPtr(val)
456
+ case "edit_files_externally":
457
+ actions.EditFilesExternally = boolPtr(val)
458
+ case "execute_safe_commands":
459
+ actions.ExecuteSafeCommands = boolPtr(val)
460
+ case "execute_all_commands":
461
+ actions.ExecuteAllCommands = boolPtr(val)
462
+ case "use_browser":
463
+ actions.UseBrowser = boolPtr(val)
464
+ case "use_mcp":
465
+ actions.UseMcp = boolPtr(val)
466
+ default:
467
+ return fmt.Errorf("unsupported auto_approval_actions field '%s'", key)
468
+ }
469
+
470
+ return nil
471
+ }
472
+
473
+ // setBrowserSettings sets fields on BrowserSettings
474
+ func setBrowserSettings(settings *cline.BrowserSettings, fields map[string]string) error {
475
+ for key, value := range fields {
476
+ switch key {
477
+ case "viewport_width":
478
+ val, err := parseInt32(value)
479
+ if err != nil {
480
+ return err
481
+ }
482
+ if settings.Viewport == nil {
483
+ settings.Viewport = &cline.Viewport{}
484
+ }
485
+ settings.Viewport.Width = val
486
+ case "viewport_height":
487
+ val, err := parseInt32(value)
488
+ if err != nil {
489
+ return err
490
+ }
491
+ if settings.Viewport == nil {
492
+ settings.Viewport = &cline.Viewport{}
493
+ }
494
+ settings.Viewport.Height = val
495
+ case "remote_browser_host":
496
+ settings.RemoteBrowserHost = strPtr(value)
497
+ case "remote_browser_enabled":
498
+ val, err := parseBool(value)
499
+ if err != nil {
500
+ return err
501
+ }
502
+ settings.RemoteBrowserEnabled = boolPtr(val)
503
+ case "chrome_executable_path":
504
+ settings.ChromeExecutablePath = strPtr(value)
505
+ case "disable_tool_use":
506
+ val, err := parseBool(value)
507
+ if err != nil {
508
+ return err
509
+ }
510
+ settings.DisableToolUse = boolPtr(val)
511
+ case "custom_args":
512
+ settings.CustomArgs = strPtr(value)
513
+ default:
514
+ return fmt.Errorf("unsupported browser_settings field '%s'", key)
515
+ }
516
+ }
517
+ return nil
518
+ }
519
+
520
+ // Type parsing helpers
521
+ func parseBool(value string) (bool, error) {
522
+ lower := strings.ToLower(value)
523
+ switch lower {
524
+ case "true", "t", "yes", "y", "1":
525
+ return true, nil
526
+ case "false", "f", "no", "n", "0":
527
+ return false, nil
528
+ default:
529
+ return false, fmt.Errorf("invalid boolean value '%s': expected true/false", value)
530
+ }
531
+ }
532
+
533
+ func parseInt32(value string) (int32, error) {
534
+ val, err := strconv.ParseInt(value, 10, 32)
535
+ if err != nil {
536
+ return 0, fmt.Errorf("invalid integer value '%s': %w", value, err)
537
+ }
538
+ return int32(val), nil
539
+ }
540
+
541
+ func parseInt64(value string) (int64, error) {
542
+ val, err := strconv.ParseInt(value, 10, 64)
543
+ if err != nil {
544
+ return 0, fmt.Errorf("invalid integer value '%s': %w", value, err)
545
+ }
546
+ return val, nil
547
+ }
548
+
549
+ func parseFloat64(value string) (float64, error) {
550
+ val, err := strconv.ParseFloat(value, 64)
551
+ if err != nil {
552
+ return 0, fmt.Errorf("invalid float value '%s': %w", value, err)
553
+ }
554
+ return val, nil
555
+ }
556
+
557
+ // Enum parsing helpers
558
+ func parseOpenaiReasoningEffort(value string) (cline.OpenaiReasoningEffort, error) {
559
+ lower := strings.ToLower(value)
560
+ switch lower {
561
+ case "low":
562
+ return cline.OpenaiReasoningEffort_LOW, nil
563
+ case "medium":
564
+ return cline.OpenaiReasoningEffort_MEDIUM, nil
565
+ case "high":
566
+ return cline.OpenaiReasoningEffort_HIGH, nil
567
+ default:
568
+ return cline.OpenaiReasoningEffort_LOW, fmt.Errorf("invalid openai_reasoning_effort '%s': expected low/medium/high", value)
569
+ }
570
+ }
571
+
572
+ func parsePlanActMode(value string) (cline.PlanActMode, error) {
573
+ lower := strings.ToLower(value)
574
+ switch lower {
575
+ case "plan":
576
+ return cline.PlanActMode_PLAN, nil
577
+ case "act":
578
+ return cline.PlanActMode_ACT, nil
579
+ default:
580
+ return cline.PlanActMode_ACT, fmt.Errorf("invalid mode '%s': expected plan/act", value)
581
+ }
582
+ }
583
+
584
+ func parseApiProvider(value string) (cline.ApiProvider, error) {
585
+ lower := strings.ToLower(value)
586
+ switch lower {
587
+ case "anthropic":
588
+ return cline.ApiProvider_ANTHROPIC, nil
589
+ case "openrouter":
590
+ return cline.ApiProvider_OPENROUTER, nil
591
+ case "bedrock":
592
+ return cline.ApiProvider_BEDROCK, nil
593
+ case "vertex":
594
+ return cline.ApiProvider_VERTEX, nil
595
+ case "openai":
596
+ return cline.ApiProvider_OPENAI, nil
597
+ case "ollama":
598
+ return cline.ApiProvider_OLLAMA, nil
599
+ case "lmstudio":
600
+ return cline.ApiProvider_LMSTUDIO, nil
601
+ case "gemini":
602
+ return cline.ApiProvider_GEMINI, nil
603
+ case "openai_native":
604
+ return cline.ApiProvider_OPENAI_NATIVE, nil
605
+ case "requesty":
606
+ return cline.ApiProvider_REQUESTY, nil
607
+ case "together":
608
+ return cline.ApiProvider_TOGETHER, nil
609
+ case "deepseek":
610
+ return cline.ApiProvider_DEEPSEEK, nil
611
+ case "qwen":
612
+ return cline.ApiProvider_QWEN, nil
613
+ case "doubao":
614
+ return cline.ApiProvider_DOUBAO, nil
615
+ case "mistral":
616
+ return cline.ApiProvider_MISTRAL, nil
617
+ case "vscode_lm":
618
+ return cline.ApiProvider_VSCODE_LM, nil
619
+ case "cline":
620
+ return cline.ApiProvider_CLINE, nil
621
+ case "litellm":
622
+ return cline.ApiProvider_LITELLM, nil
623
+ case "nebius":
624
+ return cline.ApiProvider_NEBIUS, nil
625
+ case "fireworks":
626
+ return cline.ApiProvider_FIREWORKS, nil
627
+ case "asksage":
628
+ return cline.ApiProvider_ASKSAGE, nil
629
+ case "xai", "grok":
630
+ return cline.ApiProvider_XAI, nil
631
+ case "sambanova":
632
+ return cline.ApiProvider_SAMBANOVA, nil
633
+ case "cerebras":
634
+ return cline.ApiProvider_CEREBRAS, nil
635
+ case "groq":
636
+ return cline.ApiProvider_GROQ, nil
637
+ case "sapaicore", "sap_ai_core":
638
+ return cline.ApiProvider_SAPAICORE, nil
639
+ case "claude_code":
640
+ return cline.ApiProvider_CLAUDE_CODE, nil
641
+ case "moonshot":
642
+ return cline.ApiProvider_MOONSHOT, nil
643
+ case "huggingface":
644
+ return cline.ApiProvider_HUGGINGFACE, nil
645
+ case "huawei_cloud_maas":
646
+ return cline.ApiProvider_HUAWEI_CLOUD_MAAS, nil
647
+ case "baseten":
648
+ return cline.ApiProvider_BASETEN, nil
649
+ case "zai":
650
+ return cline.ApiProvider_ZAI, nil
651
+ case "vercel_ai_gateway":
652
+ return cline.ApiProvider_VERCEL_AI_GATEWAY, nil
653
+ case "qwen_code":
654
+ return cline.ApiProvider_QWEN_CODE, nil
655
+ case "dify":
656
+ return cline.ApiProvider_DIFY, nil
657
+ case "oca":
658
+ return cline.ApiProvider_OCA, nil
659
+ case "minimax":
660
+ return cline.ApiProvider_MINIMAX, nil
661
+ default:
662
+ return cline.ApiProvider_ANTHROPIC, fmt.Errorf("invalid api_provider '%s'", value)
663
+ }
664
+ }
665
+
666
+ // setSecretField sets a secret field on Secrets
667
+ // All secret fields are optional strings
668
+ // Returns nil if field was successfully set, error otherwise
669
+ func setSecretField(secrets *cline.Secrets, key, value string) error {
670
+ switch key {
671
+ case "api_key":
672
+ secrets.ApiKey = strPtr(value)
673
+ case "open_router_api_key":
674
+ secrets.OpenRouterApiKey = strPtr(value)
675
+ case "aws_access_key":
676
+ secrets.AwsAccessKey = strPtr(value)
677
+ case "aws_secret_key":
678
+ secrets.AwsSecretKey = strPtr(value)
679
+ case "aws_session_token":
680
+ secrets.AwsSessionToken = strPtr(value)
681
+ case "aws_bedrock_api_key":
682
+ secrets.AwsBedrockApiKey = strPtr(value)
683
+ case "open_ai_api_key":
684
+ secrets.OpenAiApiKey = strPtr(value)
685
+ case "gemini_api_key":
686
+ secrets.GeminiApiKey = strPtr(value)
687
+ case "open_ai_native_api_key":
688
+ secrets.OpenAiNativeApiKey = strPtr(value)
689
+ case "ollama_api_key":
690
+ secrets.OllamaApiKey = strPtr(value)
691
+ case "deep_seek_api_key":
692
+ secrets.DeepSeekApiKey = strPtr(value)
693
+ case "requesty_api_key":
694
+ secrets.RequestyApiKey = strPtr(value)
695
+ case "together_api_key":
696
+ secrets.TogetherApiKey = strPtr(value)
697
+ case "fireworks_api_key":
698
+ secrets.FireworksApiKey = strPtr(value)
699
+ case "qwen_api_key":
700
+ secrets.QwenApiKey = strPtr(value)
701
+ case "doubao_api_key":
702
+ secrets.DoubaoApiKey = strPtr(value)
703
+ case "mistral_api_key":
704
+ secrets.MistralApiKey = strPtr(value)
705
+ case "lite_llm_api_key":
706
+ secrets.LiteLlmApiKey = strPtr(value)
707
+ case "auth_nonce":
708
+ secrets.AuthNonce = strPtr(value)
709
+ case "asksage_api_key":
710
+ secrets.AsksageApiKey = strPtr(value)
711
+ case "xai_api_key":
712
+ secrets.XaiApiKey = strPtr(value)
713
+ case "moonshot_api_key":
714
+ secrets.MoonshotApiKey = strPtr(value)
715
+ case "zai_api_key":
716
+ secrets.ZaiApiKey = strPtr(value)
717
+ case "hugging_face_api_key":
718
+ secrets.HuggingFaceApiKey = strPtr(value)
719
+ case "nebius_api_key":
720
+ secrets.NebiusApiKey = strPtr(value)
721
+ case "sambanova_api_key":
722
+ secrets.SambanovaApiKey = strPtr(value)
723
+ case "cerebras_api_key":
724
+ secrets.CerebrasApiKey = strPtr(value)
725
+ case "sap_ai_core_client_id":
726
+ secrets.SapAiCoreClientId = strPtr(value)
727
+ case "sap_ai_core_client_secret":
728
+ secrets.SapAiCoreClientSecret = strPtr(value)
729
+ case "groq_api_key":
730
+ secrets.GroqApiKey = strPtr(value)
731
+ case "huawei_cloud_maas_api_key":
732
+ secrets.HuaweiCloudMaasApiKey = strPtr(value)
733
+ case "baseten_api_key":
734
+ secrets.BasetenApiKey = strPtr(value)
735
+ case "dify_api_key":
736
+ secrets.DifyApiKey = strPtr(value)
737
+ case "oca_api_key":
738
+ secrets.OcaApiKey = strPtr(value)
739
+ case "oca_refresh_token":
740
+ secrets.OcaRefreshToken = strPtr(value)
741
+ case "hicap_api_key":
742
+ secrets.HicapApiKey = strPtr(value)
743
+ default:
744
+ return fmt.Errorf("unsupported secret field '%s'", key)
745
+ }
746
+
747
+ return nil
748
+ }
749
+
750
+ // Note: message types not supported via -s flags:
751
+ // - OpenRouterModelInfo, OpenAiCompatibleModelInfo, LiteLLMModelInfo, OcaModelInfo
752
+ // - LanguageModelChatSelector
753
+ // - DictationSettings
754
+ // - FocusChainSettings