#!/usr/bin/env python3
"""Synthetic visual projection fixtures; both migrated isolated servers must be stopped."""
import json,datetime,pathlib,subprocess,sys,copy
ROOT=pathlib.Path('/tmp/lead-32936-r1/capture')
templates=json.loads((ROOT/'replay-templates.json').read_text())
rows={k:[] for k in ['threads','runs','nodes','messages','turn_items','subagents']}
project='capture-project'; stamp='2026-11-08T08:00:00.000Z'
def payload(row): return json.loads(row['payload_json'])
def append(table,template,p,**cols):
 r=copy.deepcopy(template);r.update(cols);r['payload_json']=json.dumps(p,separators=(',',':'));rows[table].append(r)
def thread(tid,title,i=0,child=False):
 r=templates['threads'][0];p=payload(r);dt=f'2026-11-08T08:{i:02}:00.000Z'
 p.update(id=tid,projectId=project,title=title,createdBy='user',creationSource='mobile',activeProviderThreadId=None,createdAt=dt,updatedAt=dt,lastVisitedAt=None,lineage=dict(parentThreadId='capture-parent' if child else None,relationshipToParent='subagent' if child else None,rootThreadId='capture-parent' if child else tid))
 if child:p['creationSource']='provider';p['createdBy']='agent'
 append('threads',r,p,thread_id=tid,project_id=project,title=title,active_provider_thread_id=None,created_at=dt,updated_at=dt)
def run(tid,n):
 r=templates['runs'][0];p=payload(r);rid=f'{tid}:run:{n}';nid=f'{rid}:root';dt=f'2026-11-08T07:{n:02}:00.000Z'
 p.update(id=rid,threadId=tid,ordinal=n,providerThreadId=None,userMessageId=f'{rid}:user',rootNodeId=nid,activeAttemptId=None,requestedAt=dt,startedAt=dt,completedAt=dt,checkpointId=None)
 append('runs',r,p,run_id=rid,thread_id=tid,ordinal=n,provider_thread_id=None,requested_at=dt,completed_at=dt)
 root=templates['nodes'][0];np=payload(root);np.update(id=nid,threadId=tid,runId=rid,parentNodeId=None,rootNodeId=nid,providerThreadId=None,providerTurnId=None,startedAt=dt,completedAt=dt)
 append('nodes',root,np,node_id=nid,thread_id=tid,run_id=rid,parent_node_id=None,root_node_id=nid,provider_thread_id=None,provider_turn_id=None,started_at=dt,completed_at=dt)
 return rid,nid,dt
baseitems={x['type']:x for x in templates['turn_items']}
def item(tid,rid,nid,dt,ordinal,typ,text):
 t=baseitems[typ];p=payload(t);iid=f'{rid}:item:{ordinal}';p.update(id=iid,threadId=tid,runId=rid,nodeId=nid,providerThreadId=None,providerTurnId=None,nativeItemRef=None,parentItemId=None,ordinal=ordinal,startedAt=dt,completedAt=dt,updatedAt=dt,title=None)
 if typ in ('user_message','assistant_message'):
  mid=f'{iid}:message';p.update(messageId=mid,text=text,createdBy='user' if typ=='user_message' else 'agent',creationSource='mobile' if typ=='user_message' else 'provider')
  mt=next(x for x in templates['messages'] if x['role']==('user' if typ=='user_message' else 'assistant'));mp=payload(mt);mp.update(id=mid,threadId=tid,runId=rid,nodeId=nid,text=text,createdAt=dt,updatedAt=dt,createdBy=p['createdBy'],creationSource=p['creationSource'])
  append('messages',mt,mp,message_id=mid,thread_id=tid,run_id=rid,node_id=nid,created_at=dt,updated_at=dt)
 else:p.update(input=f'printf "{text}"',output=text,exitCode=0,title=text)
 append('turn_items',t,p,turn_item_id=iid,thread_id=tid,run_id=rid,node_id=nid,provider_thread_id=None,provider_turn_id=None,parent_item_id=None,ordinal=ordinal,updated_at=dt)
for i in range(20):thread(f'capture-sidebar-{i:02}',f'Stage {4 if i==19 else i+5}'+('' if i==19 else f' — Capture thread {i+1:02}'),i)
thread('capture-parent','Long parent — wrapped markdown and tools',21)
thread('capture-empty','Empty ready conversation',22)
thread('capture-short','Short conversation',23)
thread('capture-child','Inspect synthetic history',20,True)
for n in range(1,14):
 rid,nid,dt=run('capture-parent',n)
 item('capture-parent',rid,nid,dt,n*1000000+1,'user_message',f'PARENT ROW {n:02}: '+('needle-sea-glass ' if n==2 else '')+'Review the sidebar and conversation layout across native columns. This deliberately long prompt wraps at narrow widths.')
 item('capture-parent',rid,nid,dt,n*1000000+2,'assistant_message',f'## Checkpoint {n:02}\n\nThe conversation should remain readable beneath the native header. This paragraph wraps naturally when the inspector opens.\n\n- Keep the reading position.\n- Preserve the complete message.\n\n```ts\nconst columnWidth = measureColumn();\n```')
 item('capture-parent',rid,nid,dt,n*1000000+3,'command_execution',f'TOOL {n:02}: synthetic output with a long descriptive line that wraps when the native column becomes narrow.')
for n in range(1,14):
 rid,nid,dt=run('capture-child',n)
 item('capture-child',rid,nid,dt,n*1000000+1,'user_message',f'CHILD ROW {n:02}: Inspect synthetic fixture file {n:03}.ts and report a wrapped result.')
 item('capture-child',rid,nid,dt,n*1000000+2,'command_execution',f'CHILD TOOL {n:03}: inspected synthetic fixture file {n:03}.ts')
 item('capture-child',rid,nid,dt,n*1000000+3,'assistant_message',f'Child checkpoint {n:02}: synthetic review completed. The tool output and this text should remain visible below the native bar at narrow widths.')
rid,nid,dt=run('capture-short',1)
item('capture-short',rid,nid,dt,1000001,'user_message','Hello from the short fixture.')
item('capture-short',rid,nid,dt,1000002,'assistant_message','Ready for the next message.')
# A native-child card opens the real inspector/fullscreen route. No model label is published.
rid='capture-parent:run:13';nid=rid+':root';sid='capture-subagent';iid=rid+':subagent'
p=payload(baseitems['command_execution']);p={k:v for k,v in p.items() if k not in ['input','output','exitCode']};p.update(id=iid,threadId='capture-parent',runId=rid,nodeId=nid,providerThreadId=None,providerTurnId=None,nativeItemRef=None,parentItemId=None,ordinal=13000004,type='subagent',title='Inspect synthetic history',subagentId=sid,origin='provider_native',driver='acp',providerInstanceId='devReplay',childThreadId='capture-child',prompt='Inspect the synthetic history fixture.',result='Completed the synthetic review.',startedAt=stamp,completedAt=stamp,updatedAt=stamp)
append('turn_items',baseitems['command_execution'],p,turn_item_id=iid,thread_id='capture-parent',run_id=rid,node_id=nid,provider_thread_id=None,provider_turn_id=None,parent_item_id=None,ordinal=13000004,type='subagent',updated_at=stamp)
sp=dict(id=sid,threadId='capture-parent',runId=rid,parentNodeId=nid,origin='provider_native',createdBy='agent',driver='acp',providerInstanceId='devReplay',providerThreadId=None,childThreadId='capture-child',nativeTaskRef=None,prompt=p['prompt'],title=p['title'],model=None,status='completed',result=p['result'],startedAt=stamp,completedAt=stamp,updatedAt=stamp)
rows['subagents'].append(dict(subagent_id=sid,thread_id='capture-parent',run_id=rid,parent_node_id=nid,provider='devReplay',provider_thread_id=None,child_thread_id='capture-child',origin='provider_native',status='completed',started_at=stamp,completed_at=stamp,updated_at=stamp,payload_json=json.dumps(sp),driver='acp',provider_instance_id='devReplay',completion_delivery_state=None))
def q(v):return 'NULL' if v is None else str(v) if isinstance(v,(int,float)) else "'"+str(v).replace("'","''")+"'"
sqls=[]
# This script only targets fresh isolated task state; never a live T3 home.
for t in ['subagents','turn_items','messages','nodes','run_attempts','runs','provider_turns','provider_threads','provider_sessions','threads']:
 sqls.append(f'DELETE FROM orchestration_v2_projection_{t};')
sqls.append('DELETE FROM projection_projects;')
sqls.append("INSERT INTO projection_projects(project_id,title,workspace_root,scripts_json,created_at,updated_at,auto_pull) VALUES ('capture-project','Capture Fixture','/tmp/lead-32936-r1/capture','[]','2026-11-08T07:00:00.000Z','2026-11-08T07:00:00.000Z',0);")
for t,rr in rows.items():
 cols=list(rr[0]);sqls.append('INSERT INTO orchestration_v2_projection_'+t+' ('+','.join(cols)+') VALUES '+','.join('('+','.join(q(r.get(c)) for c in cols)+')' for r in rr)+';')
run_dir=ROOT/('seed-'+datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%SZ'));run_dir.mkdir()
for i,s in enumerate(sqls):
 f=run_dir/f'{i:02}.sql';f.write_text(s)
 subprocess.run(['node','apps/server/scripts/t3-sqlite-state.ts','exec','--base-dir',sys.argv[1],'--file',str(f)],check=True,stdout=subprocess.DEVNULL)
print('Seeded synthetic projections:',{t:len(x) for t,x in rows.items()},run_dir)
