@@ -16,6 +16,15 @@ import os from "os";
1616const SETTINGS = path . join ( os . homedir ( ) , ".claude" , "settings.json" ) ;
1717const PORT = 8787 ;
1818const PID_FILE = path . join ( os . homedir ( ) , ".claude" , ".headroom-service.pid" ) ;
19+ const SERVICE_LOG = path . join ( os . homedir ( ) , ".claude" , ".headroom-service.log" ) ;
20+
21+ function log ( message ) {
22+ const line = `[${ new Date ( ) . toISOString ( ) } ] ${ message } \n` ;
23+ try {
24+ fs . appendFileSync ( SERVICE_LOG , line , "utf-8" ) ;
25+ } catch { }
26+ console . log ( message ) ;
27+ }
1928
2029function readSettings ( ) {
2130 return JSON . parse ( fs . readFileSync ( SETTINGS , "utf-8" ) ) ;
@@ -51,39 +60,45 @@ function startProxy(targetUrl) {
5160 proxyProcess . kill ( "SIGTERM" ) ;
5261 proxyProcess = null ;
5362 }
54- console . log ( `[headroom] 启动 proxy → ${ targetUrl } ` ) ;
63+ log ( `[headroom] 启动 proxy -> ${ targetUrl } ` ) ;
5564 const LOG_FILE = path . join ( os . homedir ( ) , ".claude" , ".headroom-proxy.log" ) ;
5665 proxyProcess = spawn ( "headroom" , [
5766 "proxy" , "--port" , String ( PORT ) ,
5867 "--anthropic-api-url" , targetUrl ,
5968 "--code-aware" ,
6069 "--log-file" , LOG_FILE ,
6170 "--log-messages" ,
62- ] , { stdio : "inherit" , detached : false } ) ;
71+ ] , { stdio : "ignore" , windowsHide : true , detached : true } ) ;
72+ proxyProcess . unref ( ) ;
73+ proxyProcess . on ( "error" , ( error ) => {
74+ log ( `[headroom] proxy 启动失败: ${ error . message } ` ) ;
75+ proxyProcess = null ;
76+ } ) ;
6377 proxyProcess . on ( "exit" , ( code ) => {
64- console . log ( `[headroom] proxy 退出 (code=${ code } )` ) ;
78+ log ( `[headroom] proxy 退出 (code=${ code } )` ) ;
6579 proxyProcess = null ;
6680 } ) ;
6781}
6882
6983// 初次启动
7084const config = readSettings ( ) ;
71- const target = config . env ?. ANTHROPIC_BASE_URL ;
85+ const currentBaseUrl = config . env ?. ANTHROPIC_BASE_URL ;
86+ const target = config . env ?. _HEADROOM_ORIGINAL_URL || currentBaseUrl ;
7287if ( ! target || target . includes ( "localhost:8787" ) ) {
73- // 已是代理模式,不重复启动
88+ // Already in proxy mode without a saved upstream target.
7489 process . exit ( 0 ) ;
7590}
7691
7792// 保存原始地址,指向本地代理
7893config . env . _HEADROOM_ORIGINAL_URL = target ;
79- config . env . ANTHROPIC_BASE_URL = `http://localhost:${ PORT } /v1 ` ;
94+ config . env . ANTHROPIC_BASE_URL = `http://localhost:${ PORT } ` ;
8095writeSettings ( config ) ;
8196
8297startProxy ( target ) ;
8398
8499// 写 PID 文件
85100fs . writeFileSync ( PID_FILE , String ( process . pid ) , "utf-8" ) ;
86- console . log ( `[headroom] 服务已启动 (PID: ${ process . pid } ), 监听 settings.json 变化...` ) ;
101+ log ( `[headroom] 服务已启动 (PID: ${ process . pid } ), 监听 settings.json 变化...` ) ;
87102
88103// 监听 settings.json 变化
89104let lastMtime = fs . statSync ( SETTINGS ) . mtimeMs ;
@@ -96,10 +111,10 @@ setInterval(() => {
96111 const c = readSettings ( ) ;
97112 const newTarget = c . env ?. ANTHROPIC_BASE_URL ;
98113 if ( newTarget && ! newTarget . includes ( "localhost:8787" ) && newTarget !== target ) {
99- console . log ( `[headroom] 检测到 URL 变更: ${ target } → ${ newTarget } ` ) ;
114+ log ( `[headroom] 检测到 URL 变更: ${ target } -> ${ newTarget } ` ) ;
100115 // 更新保存的原始地址
101116 c . env . _HEADROOM_ORIGINAL_URL = newTarget ;
102- c . env . ANTHROPIC_BASE_URL = `http://localhost:${ PORT } /v1 ` ;
117+ c . env . ANTHROPIC_BASE_URL = `http://localhost:${ PORT } ` ;
103118 writeSettings ( c ) ;
104119 startProxy ( newTarget ) ;
105120 }
0 commit comments