1818import time
1919from pathlib import Path
2020
21+ from account_health import collect_account_status , discover_account_homes
22+
2123REAL_HOME = os .environ .get ("HOME" , os .path .expanduser ("~" ))
2224
2325
@@ -75,7 +77,7 @@ def try_refresh_token(creds_file: Path) -> dict | None:
7577 return {"expires_in" : expires_in , "remaining_min" : expires_in // 60 }
7678
7779
78- def check_oauth_token (home_dir : str | None = None ) -> dict :
80+ def check_oauth_token (home_dir : str | None = None , allow_refresh : bool = False ) -> dict :
7981 """Check OAuth token validity and time remaining."""
8082 home = home_dir or REAL_HOME
8183 creds_file = Path (home ) / ".claude" / ".credentials.json"
@@ -107,8 +109,8 @@ def check_oauth_token(home_dir: str | None = None) -> dict:
107109 has_refresh = bool (oauth .get ("refreshToken" ))
108110
109111 if remaining_s <= 0 :
110- # Access token expired — try to refresh it
111- if has_refresh :
112+ if has_refresh and allow_refresh :
113+ # Access token expired — optional refresh path
112114 refresh_result = try_refresh_token (creds_file )
113115 if refresh_result :
114116 return {
@@ -128,12 +130,14 @@ def check_oauth_token(home_dir: str | None = None) -> dict:
128130 "has_refresh_token" : has_refresh ,
129131 "home" : home ,
130132 }
133+ status = "WARN" if has_refresh else "FAIL"
134+ action = "refresh/login recommended" if has_refresh else "Run: claude login"
131135 return {
132136 "check" : "oauth_token" ,
133- "status" : "FAIL" ,
134- "message" : f"Token EXPIRED ({ abs (remaining_min )} min ago), no refresh token. Run: claude login " ,
137+ "status" : status ,
138+ "message" : f"Token EXPIRED ({ abs (remaining_min )} min ago), { action } " ,
135139 "remaining_minutes" : remaining_min ,
136- "has_refresh_token" : False ,
140+ "has_refresh_token" : has_refresh ,
137141 "home" : home ,
138142 }
139143 elif remaining_s < 1800 : # < 30 min
@@ -156,32 +160,29 @@ def check_oauth_token(home_dir: str | None = None) -> dict:
156160 }
157161
158162
159- def check_multi_account_tokens () -> list [dict ]:
163+ def check_multi_account_tokens (allow_refresh : bool = False ) -> list [dict ]:
160164 """Check tokens for all accounts under ~/.claude-homes/."""
161- results = []
162- homes_dir = Path (REAL_HOME ) / ".claude-homes"
163-
164- if not homes_dir .is_dir ():
165- # Single account mode
166- results .append (check_oauth_token ())
167- return results
168-
169- account_num = 1
170- found_any = False
171- while True :
172- account_home = homes_dir / f"account{ account_num } "
173- creds = account_home / ".claude" / ".credentials.json"
174- if creds .is_file ():
175- found_any = True
176- results .append (check_oauth_token (str (account_home )))
177- account_num += 1
178- else :
179- break
165+ real_home_path = Path (REAL_HOME )
166+ return [
167+ check_oauth_token (
168+ None if home == real_home_path else str (home ),
169+ allow_refresh = allow_refresh ,
170+ )
171+ for home in discover_account_homes (real_home_path )
172+ ]
180173
181- if not found_any :
182- results .append (check_oauth_token ())
183174
184- return results
175+ def check_account_readiness () -> dict :
176+ """Summarize launch-safe accounts using deterministic local signals."""
177+ report = collect_account_status ()
178+ summary = report ["summary" ]
179+ action = report ["recommended_action" ]
180+ status = "OK" if report ["ok_to_launch" ] else "FAIL"
181+ return {
182+ "check" : "account_readiness" ,
183+ "status" : status ,
184+ "message" : f"{ summary } ; action={ action } " ,
185+ }
185186
186187
187188def check_env_local () -> dict :
@@ -380,7 +381,7 @@ def format_table(results: list[dict]) -> str:
380381 elif warns :
381382 lines .append (f"\033 [93mREADY with { warns } warning(s). Runs may partially fail.\033 [0m" )
382383 else :
383- lines .append (f "\033 [92mALL CLEAR: Infrastructure ready for benchmark runs.\033 [0m" )
384+ lines .append ("\033 [92mALL CLEAR: Infrastructure ready for benchmark runs.\033 [0m" )
384385
385386 return "\n " .join (lines )
386387
@@ -390,12 +391,18 @@ def main():
390391 description = "Check infrastructure readiness before benchmark runs."
391392 )
392393 parser .add_argument ("--format" , choices = ["table" , "json" ], default = "table" )
394+ parser .add_argument (
395+ "--refresh-tokens" ,
396+ action = "store_true" ,
397+ help = "Allow OAuth token refresh during infra check." ,
398+ )
393399 args = parser .parse_args ()
394400
395401 results = []
396402
397403 # Token checks (handles multi-account)
398- results .extend (check_multi_account_tokens ())
404+ results .extend (check_multi_account_tokens (allow_refresh = args .refresh_tokens ))
405+ results .append (check_account_readiness ())
399406
400407 # Environment
401408 results .append (check_env_local ())
0 commit comments