1- use crate :: config:: { get_claude_settings_path, read_json_file, write_json_file } ;
1+ use crate :: config:: { get_claude_settings_path, read_json_file} ;
22use serde:: { Deserialize , Serialize } ;
33use serde_json:: Value ;
44use std:: collections:: HashMap ;
@@ -36,27 +36,85 @@ impl Default for ClaudeSettings {
3636pub fn configure_claude_code ( base_url : String , api_key : String ) -> Result < ( ) , String > {
3737 let settings_path = get_claude_settings_path ( ) ;
3838
39- // 读取现有配置(如果存在),否则使用默认配置
40- let mut settings: ClaudeSettings = if settings_path. exists ( ) {
41- read_json_file ( & settings_path) . unwrap_or_default ( )
39+ // 读取现有配置JSON并提取未知字段
40+ let mut extra_env = HashMap :: new ( ) ;
41+ let mut extra_root = HashMap :: new ( ) ;
42+ let mut existing_permissions: Option < Value > = None ;
43+
44+ if settings_path. exists ( ) {
45+ if let Ok ( content) = std:: fs:: read_to_string ( & settings_path) {
46+ if let Ok ( existing) = serde_json:: from_str :: < Value > ( & content) {
47+ if let Some ( obj) = existing. as_object ( ) {
48+ // 提取env中的未知字段
49+ if let Some ( env) = obj. get ( "env" ) . and_then ( |v| v. as_object ( ) ) {
50+ for ( key, value) in env {
51+ if !matches ! ( key. as_str( ) ,
52+ "ANTHROPIC_AUTH_TOKEN" | "ANTHROPIC_BASE_URL" |
53+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"
54+ ) {
55+ extra_env. insert ( key. clone ( ) , value. clone ( ) ) ;
56+ }
57+ }
58+ }
59+
60+ // 保存permissions
61+ existing_permissions = obj. get ( "permissions" ) . cloned ( ) ;
62+
63+ // 提取根级别未知字段
64+ for ( key, value) in obj {
65+ if !matches ! ( key. as_str( ) , "env" | "permissions" ) {
66+ extra_root. insert ( key. clone ( ) , value. clone ( ) ) ;
67+ }
68+ }
69+ }
70+ }
71+ }
72+ }
73+
74+ // 按固定顺序构建JSON字符串
75+ let mut json_str = String :: from ( "{\n " ) ;
76+
77+ // 1. env对象(固定顺序)
78+ json_str. push_str ( " \" env\" : {\n " ) ;
79+ json_str. push_str ( & format ! ( " \" ANTHROPIC_AUTH_TOKEN\" : \" {}\" ,\n " ,
80+ api_key. replace( "\\ " , "\\ \\ " ) . replace( "\" " , "\\ \" " ) ) ) ;
81+ json_str. push_str ( & format ! ( " \" ANTHROPIC_BASE_URL\" : \" {}\" ,\n " ,
82+ base_url. replace( "\\ " , "\\ \\ " ) . replace( "\" " , "\\ \" " ) ) ) ;
83+ json_str. push_str ( " \" CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC\" : \" 1\" " ) ;
84+
85+ // 添加额外env字段
86+ for ( key, value) in & extra_env {
87+ json_str. push_str ( ",\n " ) ;
88+ json_str. push_str ( & format ! ( " \" {}\" : {}" , key,
89+ serde_json:: to_string( value) . unwrap_or_default( ) ) ) ;
90+ }
91+ json_str. push_str ( "\n },\n " ) ;
92+
93+ // 2. permissions对象
94+ json_str. push_str ( " \" permissions\" : " ) ;
95+ if let Some ( perms) = existing_permissions {
96+ json_str. push_str ( & serde_json:: to_string_pretty ( & perms) . unwrap_or_default ( ) . replace ( "\n " , "\n " ) ) ;
4297 } else {
43- ClaudeSettings :: default ( )
44- } ;
98+ json_str. push_str ( "{\n \" allow\" : [],\n \" deny\" : []\n }" ) ;
99+ }
100+
101+ // 3. 其他根级别字段
102+ for ( key, value) in & extra_root {
103+ json_str. push_str ( ",\n " ) ;
104+ json_str. push_str ( & format ! ( " \" {}\" : {}" , key,
105+ serde_json:: to_string_pretty( value) . unwrap_or_default( ) . replace( "\n " , "\n " ) ) ) ;
106+ }
107+
108+ json_str. push_str ( "\n }\n " ) ;
45109
46- // 更新环境变量
47- settings
48- . env
49- . insert ( "ANTHROPIC_AUTH_TOKEN" . to_string ( ) , api_key) ;
50- settings
51- . env
52- . insert ( "ANTHROPIC_BASE_URL" . to_string ( ) , base_url) ;
53- settings. env . insert (
54- "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC" . to_string ( ) ,
55- "1" . to_string ( ) ,
56- ) ;
57-
58- // 保存配置
59- write_json_file ( & settings_path, & settings) ?;
110+ // 写入配置文件
111+ if let Some ( parent) = settings_path. parent ( ) {
112+ std:: fs:: create_dir_all ( parent)
113+ . map_err ( |e| format ! ( "创建配置目录失败: {}" , e) ) ?;
114+ }
115+
116+ std:: fs:: write ( & settings_path, json_str)
117+ . map_err ( |e| format ! ( "写入配置文件失败: {}" , e) ) ?;
60118
61119 log:: info!( "Claude Code 配置成功: {:?}" , settings_path) ;
62120 Ok ( ( ) )
@@ -72,3 +130,65 @@ pub fn get_claude_config() -> Result<ClaudeSettings, String> {
72130
73131 read_json_file ( & settings_path)
74132}
133+
134+ /// 高级配置 Claude Code(直接写入用户提供的完整配置内容)
135+ pub fn configure_claude_advanced ( config_content : String ) -> Result < ( ) , String > {
136+ let settings_path = get_claude_settings_path ( ) ;
137+
138+ // 验证JSON格式
139+ let new_config: Value = serde_json:: from_str ( & config_content)
140+ . map_err ( |e| format ! ( "配置内容格式错误: {}" , e) ) ?;
141+
142+ // 读取现有配置
143+ let mut final_config = if settings_path. exists ( ) {
144+ if let Ok ( content) = std:: fs:: read_to_string ( & settings_path) {
145+ serde_json:: from_str :: < Value > ( & content) . unwrap_or ( new_config. clone ( ) )
146+ } else {
147+ new_config. clone ( )
148+ }
149+ } else {
150+ new_config. clone ( )
151+ } ;
152+
153+ // 合并新配置到现有配置
154+ if let ( Some ( final_obj) , Some ( new_obj) ) = ( final_config. as_object_mut ( ) , new_config. as_object ( ) ) {
155+ // 合并env字段
156+ if let Some ( new_env) = new_obj. get ( "env" ) . and_then ( |v| v. as_object ( ) ) {
157+ let final_env = final_obj. entry ( "env" )
158+ . or_insert_with ( || serde_json:: json!( { } ) )
159+ . as_object_mut ( )
160+ . unwrap ( ) ;
161+
162+ for ( key, value) in new_env {
163+ final_env. insert ( key. clone ( ) , value. clone ( ) ) ;
164+ }
165+ }
166+
167+ // 更新permissions(如果有)
168+ if let Some ( perms) = new_obj. get ( "permissions" ) {
169+ final_obj. insert ( "permissions" . to_string ( ) , perms. clone ( ) ) ;
170+ }
171+
172+ // 合并其他根级别字段
173+ for ( key, value) in new_obj {
174+ if key != "env" && key != "permissions" {
175+ final_obj. insert ( key. clone ( ) , value. clone ( ) ) ;
176+ }
177+ }
178+ }
179+
180+ // 写入配置(格式化输出)
181+ let json_str = serde_json:: to_string_pretty ( & final_config)
182+ . map_err ( |e| format ! ( "序列化配置失败: {}" , e) ) ?;
183+
184+ if let Some ( parent) = settings_path. parent ( ) {
185+ std:: fs:: create_dir_all ( parent)
186+ . map_err ( |e| format ! ( "创建配置目录失败: {}" , e) ) ?;
187+ }
188+
189+ std:: fs:: write ( & settings_path, json_str)
190+ . map_err ( |e| format ! ( "写入配置文件失败: {}" , e) ) ?;
191+
192+ log:: info!( "Claude Code 高级配置成功: {:?}" , settings_path) ;
193+ Ok ( ( ) )
194+ }
0 commit comments