import subprocess, pathlib, sys, json, time, sqlite3, datetime, re
checkout, home, side = sys.argv[1:]
root = pathlib.Path(__file__).parent
out = root / (side + '-' + datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))
out.mkdir()
repo = out / 'demo'
repo.mkdir()
from recorder import Recorder
sha=subprocess.check_output(["git","rev-parse","HEAD"],cwd=checkout,text=True).strip()
recorder=Recorder(out,side,sha)
entries=[]
t0=time.monotonic()
def emit(text):
    for value, replacement in [(str(repo),'<demo>'),(home,'<app-home>'),(checkout,'<checkout>'),(str(root),'<evidence>')]:
        text=text.replace(value,replacement)
    text=re.sub(r'\x1b\[[0-9;]*[A-Za-z]','',text)
    entries.append({'time':round(time.monotonic()-t0,3),'text':text})
    display=text
    if text.startswith('{'):
        try:
            raw, tail=text.rsplit('\n[exit ',1)
            obj=json.loads(raw)
            if 'thread' in obj:
                obj={'thread':{k:obj['thread'][k] for k in ['status','runCount','latestRunId','worktreePath']}}
            display=json.dumps(obj,indent=2)+'\n[exit '+tail
        except Exception: pass
    recorder.write(display)
    print(text,flush=True)
    (out/'transcript.txt').write_text('\n\n'.join(e['text'] for e in entries))
    (out/'timeline.json').write_text(json.dumps(entries,indent=2))
def command(args, cwd=None, label=None):
    emit('$ '+(label or ' '.join(args)))
    p=subprocess.run(args,cwd=cwd,text=True,capture_output=True)
    emit((p.stdout+p.stderr).strip()+'\n[exit '+str(p.returncode)+']')
    return p
sha=subprocess.check_output(['git','rev-parse','HEAD'],cwd=checkout,text=True).strip()
emit(f'{side.upper()} | commit {sha}\nReal T3 dev server; fresh database; Replay multi-turn; CLI uses MCP t3_thread_send')
command(['git','init','-q','--initial-branch=main'],repo)
(repo/'README.md').write_text('Synthetic reproduction for issue 36225\n')
command(['git','add','.'],repo)
command(['git','-c','user.name=Scenario','-c','user.email=scenario@example.invalid','commit','-qm','Initial commit'],repo)
def cli(args,label=None):
    return command(['node','apps/server/src/bin.ts',*args,'--base-dir',home],checkout,label or 't3 '+' '.join(args))
p=cli(['project','add',str(repo),'--title','Missing workspace demonstration'])
if p.returncode: sys.exit(1)
p=cli(['thread','start',str(repo),'Start','--title','Missing workspace demonstration','--provider','devReplay','--model','multi-turn','--worktree','main','--branch','t3/repro-c','--wait','--json'])
if p.returncode: sys.exit(2)
started=json.loads(p.stdout)
thread=started['threadId']
p=cli(['thread','show',thread,'--json'])
data=json.loads(p.stdout)
wt=data['thread']['worktreePath']
command(['git','worktree','remove','--force',wt],repo)
command(['git','checkout','t3/repro-c'],repo)
emit('Precondition: missing worktree folder = '+str(not pathlib.Path(wt).exists())+'; branch t3/repro-c is checked out in the main project folder.')
p=cli(['thread','send',thread,'Reply with the single word ok.','--json'])
# Observe asynchronous processing after the send has returned; this is a runtime capture, not a test.
time.sleep(5)
cli(['thread','show',thread,'--json'])
con=sqlite3.connect('file:'+home+'/userdata/statev2.sqlite?mode=ro',uri=True)
con.row_factory=sqlite3.Row
rows=[dict(r) for r in con.execute('select * from orchestration_v2_projection_runs where thread_id=? order by ordinal',(thread,))]
con.close()
summary=[{k:json.loads(r['payload_json']).get(k) for k in ['ordinal','status','requestedAt','startedAt','completedAt']} for r in rows]
emit('Read-only runs projection after send (selected fields):\n'+json.dumps(summary,indent=2))
(out/'result.json').write_text(json.dumps({'sha':sha,'sendExit':p.returncode,'sendStdout':p.stdout,'sendStderr':p.stderr,'runs':rows},indent=2))
emit('Recorded send response, exit '+str(p.returncode)+':\n'+(p.stdout+p.stderr).strip())
emit('Runs after send: '+json.dumps(summary,indent=2))
recorder.finish()
print('OUTPUT_DIRECTORY='+str(out),flush=True)
