import sys,json,uuid,pathlib,datetime
from control import command,rpc,dispatch
root=pathlib.Path(sys.argv[1]);step=sys.argv[2]
def checked(r):
 if r.get('_tag')!='Success':raise RuntimeError(r)
 return r['value']
def record(name,value):
 with open(root/'scenario.ndjson','a') as f:f.write(json.dumps({'utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'event':name,'result':value})+'\n')
def send(mid,text):return checked(dispatch({'type':'message.dispatch','threadId':'fixture-thread','messageId':mid,'text':text,'attachments':[],'createdBy':'user','creationSource':'web','dispatchMode':{'type':'start_immediately'}}))
if step=='seed':
 url=command({'action':'eval','expression':'location.href'})
 checked(rpc('projects.mutate',{'type':'project.create','commandId':str(uuid.uuid4()),'projectId':'fixture-project','title':'Claude query exit fixture','workspaceRoot':'/tmp/lead-33008-r2/capture/project'}))
 checked(dispatch({'type':'thread.create','threadId':'fixture-thread','projectId':'fixture-project','title':'Claude query exit fixture','modelSelection':{'instanceId':'claudeAgent','model':'synthetic-fixture'},'runtimeMode':'approval-required','interactionMode':'default','branch':None,'worktreePath':None,'createdBy':'user','creationSource':'web'}))
 parts=url.split('/');env=parts[3];origin='/'.join(parts[:3]);old=__import__('urllib.parse',fromlist=['unquote']).unquote(parts[4])
 if old.startswith('thread:project:'):
  checked(dispatch({'type':'thread.delete','threadId':old}))
  checked(rpc('projects.mutate',{'type':'project.delete','commandId':str(uuid.uuid4()),'projectId':old.split(':')[2],'force':True}))
 command({'action':'goto','url':origin+'/'+env+'/fixture-thread'})
 record('seed',send('fixture-turn-1','Establish the synthetic session.'))
elif step=='layout':
 command({'action':'eval','expression':'(()=>{const b=document.querySelector(\"button[aria-label=\\\"Toggle thread details panel\\\"]\");if(b?.getAttribute(\"aria-pressed\")===\"true\")b.click();document.activeElement?.blur()})()'})
elif step=='arm':
 (root/'armed').touch()
 checked(dispatch({'type':'thread.runtime-mode.set','threadId':'fixture-thread','runtimeMode':'full-access'}))
 record('silent-exit-turn',send('fixture-turn-2','Trigger the resumed query exit.'))
elif step=='stop':
 record('stop-click',command({'action':'click','name':'Stop generation'}))
elif step=='recover':
 # Disarm the synthetic CLI only; the T3 server and thread are retained.
 (root/'armed').rename(root/'disarmed')
 record('next-message',send('fixture-turn-3','RECOVERY: reply in this same thread.'))
