1616
1717import asyncio
1818import glob
19+ import hashlib
1920import json
2021import os
2122import re
@@ -222,8 +223,17 @@ def slugify(text: str, max_len: int = 40) -> str:
222223
223224def redact_secrets (text : str ) -> str :
224225 """Redact tokens and secrets from log output."""
226+ # GitHub and generic token-like values.
225227 text = re .sub (r"(ghp_|github_pat_|gho_|ghs_|ghr_)[A-Za-z0-9_]+" , r"\1***" , text )
226228 text = re .sub (r"(x-access-token:)[^\s@]+" , r"\1***" , text )
229+ text = re .sub (r"(authorization:\s*(?:bearer|token)\s+)[^\s]+" , r"\1***" , text , flags = re .I )
230+ text = re .sub (
231+ r"([?&](?:token|access_token|api_key|apikey|password)=)[^&\s]+" ,
232+ r"\1***" ,
233+ text ,
234+ flags = re .I ,
235+ )
236+ text = re .sub (r"(gh[opusr]_[A-Za-z0-9_]+)" , "***" , text )
227237 return text
228238
229239
@@ -1057,7 +1067,8 @@ def print_metrics(metrics: dict):
10571067 print ("METRICS REPORT" )
10581068 print ("=" * 60 )
10591069 for key , value in metrics .items ():
1060- print (f" { key :30s} : { value } " )
1070+ safe_value = redact_secrets (str (value ))
1071+ print (f" { key :30s} : { safe_value } " )
10611072 print ("=" * 60 )
10621073
10631074
@@ -1069,7 +1080,7 @@ def print_metrics(metrics: dict):
10691080def log (prefix : str , text : str ):
10701081 """Print a timestamped log line."""
10711082 ts = time .strftime ("%H:%M:%S" )
1072- print (f"[{ ts } ] { prefix } { text } " , flush = True )
1083+ print (f"[{ ts } ] { prefix } { redact_secrets ( str ( text )) } " , flush = True )
10731084
10741085
10751086def truncate (text : str , max_len : int = 200 ) -> str :
@@ -1876,11 +1887,8 @@ def run_task(
18761887def main ():
18771888 config = get_config ()
18781889
1879- print (f"Task ID: { config ['task_id' ]} " )
1880- print (f"Repository: { config ['repo_url' ]} " )
1881- print (f"Issue: { config ['issue_number' ] or '(none)' } " )
1882- print (f"Model: { config ['anthropic_model' ]} " )
1883- print (f"Dry run: { config ['dry_run' ]} " )
1890+ print ("Task configuration loaded." , flush = True )
1891+ print (f"Dry run: { config ['dry_run' ]} " , flush = True )
18841892 print ()
18851893
18861894 if config ["dry_run" ]:
@@ -1900,10 +1908,25 @@ def main():
19001908 overrides = config .get ("system_prompt_overrides" , "" )
19011909 if overrides :
19021910 system_prompt += f"\n \n ## Additional instructions\n \n { overrides } "
1903- print ("\n --- SYSTEM PROMPT ---" )
1904- print (system_prompt )
1905- print ("\n --- USER PROMPT ---" )
1906- print (prompt )
1911+ system_prompt_hash = hashlib .sha256 (system_prompt .encode ("utf-8" )).hexdigest ()[:12 ]
1912+ prompt_hash = hashlib .sha256 (prompt .encode ("utf-8" )).hexdigest ()[:12 ]
1913+ print ("\n --- SYSTEM PROMPT (REDACTED) ---" )
1914+ print (
1915+ f"length={ len (system_prompt )} chars sha256={ system_prompt_hash } "
1916+ "(set DEBUG_DRY_RUN_PROMPTS=1 to print full text)" ,
1917+ flush = True ,
1918+ )
1919+ print ("\n --- USER PROMPT (REDACTED) ---" )
1920+ print (
1921+ f"length={ len (prompt )} chars sha256={ prompt_hash } "
1922+ "(set DEBUG_DRY_RUN_PROMPTS=1 to print full text)" ,
1923+ flush = True ,
1924+ )
1925+ if os .environ .get ("DEBUG_DRY_RUN_PROMPTS" ) == "1" :
1926+ print ("\n --- SYSTEM PROMPT (DEBUG) ---" )
1927+ print (redact_secrets (system_prompt ), flush = True )
1928+ print ("\n --- USER PROMPT (DEBUG) ---" )
1929+ print (redact_secrets (prompt ), flush = True )
19071930 print ("\n --- DRY RUN COMPLETE ---" )
19081931 return
19091932
0 commit comments