#!/usr/bin/env python3
"""Replay two provider turns while running real sleep processes; no model is called."""
import sys,json,uuid,subprocess,threading,time,signal,atexit,os
if '--version' in sys.argv: print('codex-cli 0.159.0');sys.exit()
lock=threading.Lock(); children=[]; sessions={}
def send(v):
 with lock: print(json.dumps(v),flush=True)
def event(method,params): send({'method':method,'params':params})
def cleanup(*args):
 for p in children:
  if p.poll() is None: p.terminate()
 if args: sys.exit()
atexit.register(cleanup);signal.signal(signal.SIGTERM,cleanup);signal.signal(signal.SIGINT,cleanup)
def turnobj(t,status): return {'id':t,'items':[],'itemsView':'notLoaded','status':status,'error':None,'startedAt':int(time.time()),'completedAt':int(time.time()) if status=='completed' else None,'durationMs':None}
def command(id,cmd,p,status='inProgress'): return {'type':'commandExecution','id':id,'command':cmd,'cwd':os.getcwd(),'processId':str(p.pid),'source':'unifiedExecStartup','status':status,'commandActions':[{'type':'unknown','command':cmd}],'aggregatedOutput':None if status=='inProgress' else '', 'exitCode':None if status=='inProgress' else 0,'durationMs':None}
def runturn(m):
 s=m['params']['threadId']; state=sessions[s]; state['count']+=1;n=2 if 'sleep 15' in str(m['params'].get('input',[])) else 1;t=str(uuid.uuid4())
 send({'id':m['id'],'result':{'turn':turnobj(t,'inProgress')}});event('turn/started',{'threadId':s,'turn':turnobj(t,'inProgress')})
 p=subprocess.Popen(['sleep','600' if n==1 else '15']);children.append(p)
 item=command('background-sleep' if n==1 else 'foreground-sleep','sleep 600' if n==1 else 'sleep 15',p)
 event('item/started',{'threadId':s,'turnId':t,'item':item,'startedAtMs':int(time.time()*1000)})
 if n>1: p.wait(); event('item/completed',{'threadId':s,'turnId':t,'item':command(item['id'],'sleep 15',p,'completed'),'completedAtMs':int(time.time()*1000)})
 text='Background command started. The sleep 600 process is still running.' if n==1 else 'The foreground command finished. The earlier sleep 600 continues in the background.'
 event('item/completed',{'threadId':s,'turnId':t,'item':{'type':'agentMessage','id':'answer-'+t,'text':text,'phase':'final_answer','memoryCitation':None},'completedAtMs':int(time.time()*1000)})
 event('turn/completed',{'threadId':s,'turn':turnobj(t,'completed')})
for line in sys.stdin:
 try: m=json.loads(line)
 except ValueError: continue
 method=m.get('method','');p=m.get('params',{});r={}
 if method=='initialize':r={'userAgent':'T3 evidence replay','codexHome':os.getcwd(),'platformFamily':'unix','platformOs':'linux'}
 elif method in ['thread/start','thread/resume']:
  s=p.get('threadId',str(uuid.uuid4()));sessions[s]={'count':0}
  r={'thread':{'id':s,'sessionId':s,'projectId':None,'forkedFromId':None,'preview':'','ephemeral':False,'modelProvider':'openai','createdAt':int(time.time()),'updatedAt':int(time.time()),'status':{'type':'idle'},'path':None,'cwd':os.getcwd(),'cliVersion':'0.159.0','source':'vscode','threadSource':None,'agentNickname':None,'agentRole':None,'gitInfo':None,'name':None,'turns':[]},'model':'background-demo','modelProvider':'openai','serviceTier':None,'cwd':os.getcwd(),'instructionSources':[],'approvalPolicy':'never','approvalsReviewer':'user','sandbox':{'type':'dangerFullAccess'},'reasoningEffort':'low'}
 elif method=='turn/start':threading.Thread(target=runturn,args=(m,),daemon=True).start();continue
 elif method=='account/read':r={'account':None,'requiresOpenaiAuth':False}
 elif method=='account/rateLimits/read':r={'rateLimits':None,'rateLimitsByLimitId':{}}
 elif method=='model/list':r={'data':[{'id':'background-demo','model':'background-demo','displayName':'Background demo','description':'Synthetic background task replay','hidden':False,'isDefault':True,'supportedReasoningEfforts':[],'defaultReasoningEffort':'low','inputModalities':['text'],'supportsPersonality':False}], 'nextCursor':None}
 elif method=='thread/backgroundTerminals/list':r={'terminals':[]}
 elif method=='thread/backgroundTerminals/terminate':cleanup();r={'terminated':True}
 if 'id' in m:send({'id':m['id'],'result':r})
