// SPEC: PJ2026-01040111 长程观测 draft-2026-06-20-p0-passive-web-probe-observer.
// Responsibility: Offline CLI view renderers for HWLAB web-probe observe artifacts.
import { shellQuote } from "./ssh";

export type NodeWebProbeObserveCollectView = "files" | "turn-summary" | "trace-frame" | "timeline" | "workbench-triad" | "project-summary" | "project-mdtodo-summary" | "performance-summary";

export function parseNodeWebProbeObserveCollectView(value: string): NodeWebProbeObserveCollectView {
  if (value === "files" || value === "turn-summary" || value === "trace-frame" || value === "timeline" || value === "workbench-triad" || value === "project-summary" || value === "project-mdtodo-summary" || value === "performance-summary") return value;
  throw new Error(`web-probe observe collect --view must be files, turn-summary, trace-frame, timeline, workbench-triad, project-summary, project-mdtodo-summary, or performance-summary; got ${value}`);
}

export function nodeWebObserveCollectViewNodeScript(input: {
  maxFiles: number;
  view: NodeWebProbeObserveCollectView;
  traceId: string | null;
  sampleSeq: number | null;
  timestamp: string | null;
  turn: number | null;
  commandId: string | null;
  windowMs: number | null;
}): string {
  const requestedSampleSeq = input.sampleSeq === null ? "null" : String(input.sampleSeq);
  const requestedTurn = input.turn === null ? "null" : String(input.turn);
  const requestedWindowMs = input.windowMs === null ? "null" : String(input.windowMs);
  return `node -e ${shellQuote(`
const fs=require('fs'),path=require('path'),crypto=require('crypto');
const dir=process.argv[1]; const maxFiles=${input.maxFiles}; const view=${JSON.stringify(input.view)}; const requestedTraceId=${JSON.stringify(input.traceId)}; const requestedSampleSeq=${requestedSampleSeq}; const requestedTimestamp=${JSON.stringify(input.timestamp)}; const requestedTurn=${requestedTurn}; const requestedCommandId=${JSON.stringify(input.commandId)}; const requestedWindowMs=${requestedWindowMs};
const sha=(value)=>'sha256:'+crypto.createHash('sha256').update(String(value||'')).digest('hex');
const short=(value,limit=96)=>{const text=String(value||'').replace(/\\s+/gu,' ').trim(); return text.length>limit?text.slice(0,Math.max(1,limit-1))+'...':text;};
const textOf=(value)=>String(value?.text||value?.textPreview||value?.preview||'');
const readJson=(rel)=>{try{return JSON.parse(fs.readFileSync(path.join(dir,rel),'utf8'))}catch{return null}};
const readJsonl=(rel)=>{try{return fs.readFileSync(path.join(dir,rel),'utf8').split(/\\r?\\n/u).filter(Boolean).map((line)=>{try{return JSON.parse(line)}catch{return {parseError:true,rawHash:sha(line)}}})}catch{return []}};
const out=[]; const skippedFiles=[];
const skipFile=(file,reason,error=null)=>skippedFiles.push({path:file,relative:path.relative(dir,file),reason,message:error?.message?short(error.message,160):null,valuesRedacted:true});
const walk=(p)=>{let entries=[]; try{entries=fs.readdirSync(p,{withFileTypes:true});}catch(error){skipFile(p,'readdir-failed',error); return;} for(const ent of entries){const full=path.join(p,ent.name); if(ent.isDirectory()) walk(full); else out.push(full); if(out.length>=maxFiles) return;}};
walk(dir);
const files=out.slice(0,maxFiles).map(file=>{try{const st=fs.statSync(file); if(!st.isFile())return null; const bytes=fs.readFileSync(file); const hash=crypto.createHash('sha256').update(bytes).digest('hex'); return {path:file,relative:path.relative(dir,file),byteCount:st.size,sha256:'sha256:'+hash}}catch(error){skipFile(file,'stat-or-read-failed',error); return null;}}).filter(Boolean);
const totalBytes=files.reduce((sum,item)=>sum+item.byteCount,0);
if(view==='files'){
  console.log(JSON.stringify({ok:true,command:'web-probe-observe collect',view,stateDir:dir,fileCount:files.length,skippedFileCount:skippedFiles.length,totalBytes,files,skippedFiles:skippedFiles.slice(0,20),valuesRedacted:true},null,2));
  process.exit(0);
}
const samples=readJsonl('samples.jsonl');
const control=readJsonl('control.jsonl');
const network=readJsonl('network.jsonl');
const browserProcess=readJsonl('browser-process.jsonl');
const performanceRows=readJsonl('performance-events.jsonl');
const manifest=readJson('manifest.json')||{};
const heartbeat=readJson('heartbeat.json')||{};
const report=readJson('analysis/report.json')||{};
function unique(values){return Array.from(new Set(values.filter(Boolean)));}
function numOrNull(value){const n=Number(value); return Number.isFinite(n)?n:null}
function promptIndexOf(value){const n=Number(value); return Number.isInteger(n)&&n>0?n:null}
function tsMs(value){const ms=Date.parse(String(value||'')); return Number.isFinite(ms)?ms:null}
function sessionIdFromUrl(value){const match=String(value||'').match(/\\/workbench\\/sessions\\/(ses_[A-Za-z0-9_-]+)/u); return match?match[1]:null}
function commandSessionId(item){return item?.sessionId||item?.detail?.sessionId||item?.input?.sessionId||sessionIdFromUrl(item?.afterUrl)||sessionIdFromUrl(item?.detail?.afterUrl)||null}
function commandTraceId(item){return item?.traceId||item?.detail?.chatSubmit?.traceId||item?.detail?.traceId||item?.input?.traceId||null}
function completedNewSessionIdsBefore(ts){
  const limit=tsMs(ts);
  return control
    .filter((item)=>item.type==='newSession'&&item.phase==='completed')
    .filter((item)=>limit===null||tsMs(item.ts)===null||tsMs(item.ts)<=limit)
    .map(commandSessionId)
    .filter(Boolean);
}
function authoritativeSessionIdForPrompts(prompts){
  const firstPromptTs=prompts[0]?.firstTs||null;
  const newSessionIds=completedNewSessionIdsBefore(firstPromptTs);
  const promptSessionIds=unique(prompts.map((item)=>item.sessionId));
  return newSessionIds.slice(-1)[0]||promptSessionIds[0]||null;
}
function promptCommands(){
  const map=new Map();
  for(const item of control){
    if(item.type!=='sendPrompt'||(item.phase!=='started'&&item.phase!=='completed'&&item.phase!=='failed')) continue;
    const id=item.commandId||item.seq||String(map.size+1);
    const existing=map.get(id)||{};
    map.set(id,{...existing,...item,input:{...(existing.input||{}),...(item.input||{})},sessionId:existing.sessionId||commandSessionId(item),traceId:existing.traceId||commandTraceId(item),firstTs:existing.firstTs||item.ts,lastTs:item.ts});
  }
  const prompts=Array.from(map.values()).filter((item)=>tsMs(item.firstTs)!==null).sort((a,b)=>tsMs(a.firstTs)-tsMs(b.firstTs));
  const sessionId=authoritativeSessionIdForPrompts(prompts);
  if(!sessionId) return prompts;
  const scoped=prompts.filter((item)=>item.sessionId===sessionId);
  return scoped.length>0?scoped:prompts;
}
function segmentFor(index,prompts){
  const start=tsMs(prompts[index]?.firstTs); const end=index+1<prompts.length?tsMs(prompts[index+1].firstTs):Infinity;
  return samples.filter((sample)=>{const ms=tsMs(sample.ts); return ms!==null&&ms>=start&&ms<end});
}
function controlsFor(index,prompts){
  const start=tsMs(prompts[index]?.firstTs); const end=index+1<prompts.length?tsMs(prompts[index+1].firstTs):Infinity;
  return control.filter((item)=>{const ms=tsMs(item.ts); return ms!==null&&ms>=start&&ms<end});
}
function firstTraceId(text){const match=String(text||'').match(/\\btrc_[A-Za-z0-9_-]+\\b/u); return match?match[0]:null}
function itemTraceId(item){return item?.traceId||firstTraceId(textOf(item))||null}
function entryGroups(sample){
  return [
    ...(Array.isArray(sample.turns)?sample.turns.map((item)=>({group:'turn',item})):[]),
    ...(Array.isArray(sample.traceRows)?sample.traceRows.map((item)=>({group:'traceRow',item})):[]),
    ...(Array.isArray(sample.messages)?sample.messages.map((item)=>({group:'message',item})):[]),
  ];
}
function traceIdStats(items){
  const map=new Map();
  for(const sample of items){
    const seq=numOrNull(sample.seq);
    for(const entry of entryGroups(sample)){
      const id=itemTraceId(entry.item); if(!id) continue;
      const current=map.get(id)||{traceId:id,count:0,firstSeq:null,lastSeq:null,terminalCount:0};
      current.count+=1;
      current.firstSeq=current.firstSeq===null?seq:seq===null?current.firstSeq:Math.min(current.firstSeq,seq);
      current.lastSeq=current.lastSeq===null?seq:seq===null?current.lastSeq:Math.max(current.lastSeq,seq);
      if(terminalText(textOf(entry.item))||String(entry.item?.status||'').match(/complete|fail|cancel|terminal/iu)) current.terminalCount+=1;
      map.set(id,current);
    }
  }
  return Array.from(map.values()).sort((a,b)=>(a.firstSeq??0)-(b.firstSeq??0)||String(a.traceId).localeCompare(String(b.traceId)));
}
function traceIdsFromSamples(items){return traceIdStats(items).map((item)=>item.traceId)}
function collectReportTurnColumns(value,out=[]){
  if(!value||typeof value!=='object') return out;
  if(Array.isArray(value)){for(const item of value) collectReportTurnColumns(item,out); return out;}
  if(Array.isArray(value.turnColumns)){
    for(const item of value.turnColumns){
      if(!item||typeof item!=='object') continue;
      const traceId=String(item.traceId||'').trim();
      if(!traceId) continue;
      out.push({...item,traceId,promptIndex:promptIndexOf(item.promptIndex),lastPromptIndex:promptIndexOf(item.lastPromptIndex),firstSeq:numOrNull(item.firstSeq),lastSeq:numOrNull(item.lastSeq)});
    }
  }
  for(const key of ['sampleMetrics','analysis','analysisWindow','recentWindow','windows','recent','archive','summary']){
    if(value[key]&&value[key]!==value) collectReportTurnColumns(value[key],out);
  }
  return out;
}
const reportTurnColumns=(()=>{const seen=new Set(); const rows=[]; for(const item of collectReportTurnColumns(report)){const key=[item.traceId,item.promptIndex,item.lastPromptIndex,item.firstSeq,item.lastSeq,item.source,item.pageRole,item.messageId].join('|'); if(seen.has(key)) continue; seen.add(key); rows.push(item);} return rows.sort((a,b)=>(a.firstSeq??0)-(b.firstSeq??0)||(a.promptIndex??9999)-(b.promptIndex??9999));})();
function columnOverlapsSegment(column,segment){
  if(segment.length===0) return true;
  const first=numOrNull(segment[0]?.seq); const last=numOrNull(segment[segment.length-1]?.seq);
  if(first===null||last===null||column.firstSeq===null||column.lastSeq===null) return true;
  return column.lastSeq>=first&&column.firstSeq<=last;
}
function reportColumnsForPrompt(index,segment){
  const promptIndex=index+1;
  const segmentIds=new Set(traceIdsFromSamples(segment));
  return reportTurnColumns
    .filter((column)=>(column.promptIndex===promptIndex||column.lastPromptIndex===promptIndex)&&columnOverlapsSegment(column,segment))
    .filter((column)=>segmentIds.size===0||segmentIds.has(column.traceId)||column.source==='turn')
    .sort((a,b)=>(a.firstSeq??0)-(b.firstSeq??0)||(a.lastSeq??0)-(b.lastSeq??0)||String(a.label||'').localeCompare(String(b.label||'')));
}
function choosePrimaryTraceId(index,segment,prompt=null){
  const promptTraceId=commandTraceId(prompt)||prompt?.traceId||null;
  if(promptTraceId){
    const segmentIds=new Set(traceIdsFromSamples(segment));
    if(segmentIds.size===0||segmentIds.has(promptTraceId)) return {traceId:promptTraceId,columns:reportColumnsForPrompt(index,segment)};
  }
  const columns=reportColumnsForPrompt(index,segment);
  const promptIndex=index+1;
  const promptColumns=columns.filter((column)=>column.promptIndex===promptIndex);
  const preferred=promptColumns.length>0?promptColumns:columns;
  if(preferred.length>0) return {traceId:preferred[0].traceId,columns};
  const stats=traceIdStats(segment).sort((a,b)=>(b.lastSeq??0)-(a.lastSeq??0)||(b.firstSeq??0)-(a.firstSeq??0));
  return {traceId:stats[0]?.traceId||null,columns:[]};
}
function samplesForTrace(items,traceId,maxSeq=null){
  if(!traceId) return items;
  return items.filter((sample)=>{
    const seq=numOrNull(sample.seq);
    return (maxSeq===null||seq===null||seq<=maxSeq)&&traceIdsFromSamples([sample]).includes(traceId);
  });
}
function latestSampleForTrace(items,traceId,maxSeq=null){
  return samplesForTrace(items,traceId,maxSeq).slice(-1)[0]||null;
}
function sampleHasTerminalForTrace(sample,traceId){
  if(!sample) return false;
  const status=statusFor([sample],traceId);
  if(terminalFinalStatus(status)) return true;
  const final=finalResponseFor([sample],traceId);
  if(final&&!final.empty) return true;
  return traceEntries([sample],traceId).some((entry)=>terminalText(entry.text)||terminalFinalStatus(entry.item?.status));
}
function bestTraceFrameSample(traceId,maxSeq=null){
  if(!traceId) return null;
  const matched=samples.filter((sample)=>traceIdsFromSamples([sample]).includes(traceId));
  if(matched.length===0) return null;
  const terminal=matched.filter((sample)=>sampleHasTerminalForTrace(sample,traceId)).slice(-1)[0];
  if(terminal) return terminal;
  if(maxSeq!==null){
    const before=matched.filter((sample)=>{const seq=numOrNull(sample.seq); return seq===null||seq<=maxSeq;}).slice(-1)[0];
    if(before) return before;
  }
  return matched.slice(-1)[0]||null;
}
function traceEntries(items,traceId){
  const entries=[];
  for(const sample of items){
    for(const entry of entryGroups(sample)){
      const text=textOf(entry.item);
      const id=itemTraceId(entry.item);
      if(!traceId||id===traceId||text.includes(traceId)) entries.push({...entry,sample,text});
    }
  }
  return entries;
}
function textsFor(items,traceId=null){
  const entries=traceId?traceEntries(items,traceId):items.flatMap((sample)=>entryGroups(sample).map((entry)=>({...entry,sample,text:textOf(entry.item)})));
  return entries.length>0?entries.map((entry)=>entry.text):[];
}
function parseElapsed(text){
  const values=[]; const raw=String(text||'');
  for(const m of raw.matchAll(/(?:耗时|总耗时|total\\s*=?)\\s*(?:(\\d+)\\s*(?:小时|h)\\s*)?(?:(\\d+)\\s*(?:分|分钟|m)\\s*)?(?:(\\d+)\\s*(?:秒|s))?/giu)){
    const total=Number(m[1]||0)*3600+Number(m[2]||0)*60+Number(m[3]||0); if(total>0) values.push(total);
  }
  for(const m of raw.matchAll(/\\b(?:total|elapsed)\\s*=\\s*(?:(\\d{1,2}):)?(\\d{1,2}):(\\d{2})\\b/giu)){
    values.push(Number(m[1]||0)*3600+Number(m[2]||0)*60+Number(m[3]||0));
  }
  return values.length?Math.max(...values):null;
}
function parseRecent(text){const m=String(text||'').match(/最近\\s*(\\d+)\\s*(秒|分钟|分|小时)前/u); if(!m)return null; const n=Number(m[1]); return m[2]==='小时'?n*3600:m[2]==='秒'?n:n*60}
function fmtDuration(seconds){if(seconds===null||seconds===undefined||!Number.isFinite(Number(seconds)))return '-'; const value=Math.max(0,Math.round(Number(seconds))); const h=Math.floor(value/3600), m=Math.floor((value%3600)/60), s=value%60; return (h>0?String(h).padStart(2,'0')+':':'')+String(m).padStart(2,'0')+':'+String(s).padStart(2,'0')}
function terminalText(text){return /轮次完成|轮次失败|轮次取消|已记录|final response|sealed final response|turn completed|turn failed|turn canceled|completed|failed|canceled|cancelled|terminal/iu.test(String(text||''))}
function normalizeLifecycleStatus(value){
  const raw=String(value||'').trim().toLowerCase();
  if(/^(canceled|cancelled)$/u.test(raw))return 'canceled';
  if(/^(failed|failure|error)$/u.test(raw))return 'failed';
  if(/^(completed|complete|succeeded|success|terminal)$/u.test(raw))return 'completed';
  if(/^(running|admitting|queued|pending|in_progress|in-progress)$/u.test(raw))return 'running';
  return null;
}
function statusFor(items,traceId=null){
  const matchedEntries=traceId?traceEntries(items,traceId):items.flatMap((sample)=>entryGroups(sample).map((entry)=>({...entry,sample,text:textOf(entry.item)})));
  const lastTurn=matchedEntries.filter((entry)=>entry.group==='turn').slice(-1)[0]?.item||null;
  const turnStatus=normalizeLifecycleStatus(lastTurn?.status);
  if(turnStatus)return turnStatus;
  const lastMessage=matchedEntries.filter((entry)=>entry.group==='message').slice(-1)[0]?.item||null;
  const messageStatus=normalizeLifecycleStatus(lastMessage?.status);
  if(messageStatus)return messageStatus;
  return 'unknown';
}
function userMessageFor(items,prompt){
  const hash=prompt?.input?.textHash||null;
  for(const sample of items){
    for(const message of Array.isArray(sample.messages)?sample.messages:[]){
      if(hash&&message.textHash===hash)return {preview:short(textOf(message),90),textHash:message.textHash||hash,textBytes:message.textBytes??prompt?.input?.textBytes??null};
    }
  }
  return {preview:short(prompt?.input?.textPreview||'',90)||'(hash only)',textHash:hash,textBytes:prompt?.input?.textBytes??null};
}
function promptFailedBeforeTrace(prompt,segment){
  if(prompt?.phase!=='failed')return false;
  if(commandTraceId(prompt)||prompt?.traceId)return false;
  const hash=prompt?.input?.textHash||null;
  if(hash){
    for(const sample of segment){
      for(const message of Array.isArray(sample.messages)?sample.messages:[]){
        if(message?.textHash===hash)return false;
      }
    }
  }
  return true;
}
function cleanFinalResponseText(text){
  const raw=String(text||'').trim();
  if(!raw) return '';
  if(/^Code Agent\\s*(?:running|completed|failed|canceled|cancelled)?$/iu.test(raw)) return '';
  if(/^耗时\\s*\\d+\\s*(?:秒|分钟|分|小时)$/u.test(raw)) return '';
  if(/^(completed|failed|canceled|cancelled)!?$/iu.test(raw)) return '';
  if(/^!+$/u.test(raw)) return '';
  if(/Code Agent\\s*耗时[\\s\\S]*运行记录/iu.test(raw)) return '';
  if(/^sent\\s+当前 AgentRun 请求已取消/u.test(raw)) return '';
  if(/^(admitted|run|ok|error)\\s+/iu.test(raw)) return '';
  if(/^(AgentRun|Code Agent turn was durably admitted|commandExecution|runner-job|command -v|node --version|npm --version|cd |mkdir -p|npm install|npx )/iu.test(raw)) return '';
  if(/(?:^|\\s)轮次(完成|失败|取消)（?总耗时/iu.test(raw)) return '';
  if(/^(轮次完成|轮次失败|轮次取消|已记录)$/u.test(raw.replace(/\\s+/gu,' ').trim())) return '';
  return raw;
}
function emptyFinalResponse(){return {preview:'(空内容)',textHash:null,textBytes:0,empty:true}}
function terminalFinalStatus(value){return /^(completed|failed|canceled|cancelled|terminal)$/u.test(String(value||'').trim().toLowerCase())}
function entryRole(entry){return String(entry.item?.role||entry.item?.dataRole||entry.item?.authorRole||entry.item?.messageRole||entry.item?.speaker||'').toLowerCase()}
function finalCandidateText(entry){
  const explicit=textOf(entry.item?.finalResponse);
  if(explicit) return explicit;
  if(entry.group==='message') return entry.text;
  if(entry.group==='traceRow'&&/助手消息|assistant\\s*message/iu.test(entry.text)){
    return String(entry.text||'').replace(/^.*?(?:助手消息|assistant\\s*message)\\s*/iu,'');
  }
  return '';
}
function sameAsUserPrompt(entry,text,user){
  if(!user) return false;
  if(user.textHash&&entry.item?.textHash===user.textHash) return true;
  const userPrefix=short(user.preview||'',48).replace(/\\s+/gu,' ').trim().slice(0,32);
  const textPrefix=String(text||'').replace(/\\s+/gu,' ').trim().slice(0,32);
  return userPrefix.length>=18&&textPrefix===userPrefix;
}
function finalResponseFor(items,traceId,user=null){
  if(!terminalFinalStatus(statusFor(items,traceId))) return emptyFinalResponse();
  const scoped=traceId?traceEntries(items,traceId):items.flatMap((sample)=>entryGroups(sample).map((entry)=>({...entry,sample,text:textOf(entry.item)})));
  const unscopedMessages=traceId?items.flatMap((sample)=>entryGroups(sample)
    .filter((entry)=>entry.group==='message'&&!itemTraceId(entry.item))
    .map((entry)=>({...entry,sample,text:textOf(entry.item)}))):[];
  const candidates=[...scoped,...unscopedMessages].slice().reverse();
  for(const entry of candidates){
    const role=entryRole(entry);
    const entryStatus=String(entry.item?.status||'');
    if(entry.group==='message'&&role&&!/assistant|agent|system/u.test(role)) continue;
    if(/用户|user/iu.test(role)||/用户|user/iu.test(entryStatus)) continue;
    const status=String(entry.item?.status||'').toLowerCase(); const text=cleanFinalResponseText(finalCandidateText(entry));
    if(!text) continue;
    if(/^第\\d+轮\\/\\d+[：:]?\\s*请/u.test(text)||/^请(执行|帮|回答|修复|调查|用|不要|直接)/u.test(text)) continue;
    if(sameAsUserPrompt(entry,text,user)) continue;
    if(status.includes('running')&&!terminalText(entry.text)&&entry.group==='turn')continue;
    const preview=short(text,180);
    if(preview)return {preview,textHash:entry.item?.textHash||sha(text),textBytes:entry.item?.textBytes??Buffer.byteLength(text),empty:false};
  }
  return emptyFinalResponse();
}
function turnSummaryRows(){
  const prompts=promptCommands();
  if(prompts.length===0){
    const allTraceIds=traceIdsFromSamples(samples);
    const turnStatus=statusFor(samples,allTraceIds[0]||null);
    return [{round:0,commandId:null,commandType:null,controlExecutionStatus:'not-applicable',turnSubmissionStatus:'not-observed',turnStatus,turnTerminalObserved:terminalFinalStatus(turnStatus),userPreview:'(无 sendPrompt control 记录)',userHash:null,userBytes:null,traceId:allTraceIds[0]||null,status:turnStatus,elapsedSeconds:null,recentUpdateSeconds:null,marks:'-',firstSeq:samples[0]?.seq??null,lastSeq:samples[samples.length-1]?.seq??null,lastTs:samples[samples.length-1]?.ts??null,finalResponse:finalResponseFor(samples,allTraceIds[0]||null),valuesRedacted:true}];
  }
  return prompts.map((prompt,index)=>{
    const segment=segmentFor(index,prompts); const segmentControls=controlsFor(index,prompts); const failedBeforeTrace=promptFailedBeforeTrace(prompt,segment); const selected=failedBeforeTrace?{traceId:null,columns:[]}:choosePrimaryTraceId(index,segment,prompt); const traceId=selected.traceId; const user=userMessageFor(segment,prompt);
    const primaryColumn=selected.columns.find((column)=>column.traceId===traceId)||null;
    const traceSample=latestSampleForTrace(segment,traceId,primaryColumn?.lastSeq??null);
    const texts=textsFor(segment,traceId);
    const elapsedValues=texts.map(parseElapsed).filter((value)=>value!==null); const recentValues=texts.map(parseRecent).filter((value)=>value!==null);
    const marks=unique([...segmentControls.map((item)=>item.type==='cancel'?'cancel':item.type==='steer'?'steer':null),failedBeforeTrace?'command-failed':null]).join(',')||'-';
    const controlExecutionStatus=prompt.phase==='failed'?'failed':prompt.phase==='completed'?'completed':'processing';
    const turnSubmissionStatus=failedBeforeTrace?'failed':commandTraceId(prompt)?'accepted':prompt.phase==='completed'?'not-observed':'pending';
    const turnStatus=failedBeforeTrace?'not-started':statusFor(segment,traceId);
    return {round:index+1,commandId:prompt.commandId||null,commandType:prompt.type||null,sessionId:prompt.sessionId||null,controlExecutionStatus,turnSubmissionStatus,turnStatus,turnTerminalObserved:terminalFinalStatus(turnStatus),userPreview:user.preview,userHash:user.textHash,userBytes:user.textBytes,traceId,traceIds:failedBeforeTrace?[]:unique([traceId,...selected.columns.map((column)=>column.traceId),...traceIdsFromSamples(segment)]).slice(0,8),status:turnStatus,elapsedSeconds:failedBeforeTrace?null:(elapsedValues.length?Math.max(...elapsedValues):null),recentUpdateSeconds:failedBeforeTrace?null:(recentValues.length?Math.max(...recentValues):null),marks,firstSeq:segment[0]?.seq??primaryColumn?.firstSeq??null,lastSeq:failedBeforeTrace?(segment[segment.length-1]?.seq??null):(traceSample?.seq??primaryColumn?.lastSeq??segment[segment.length-1]?.seq??null),lastTs:failedBeforeTrace?(segment[segment.length-1]?.ts??null):(traceSample?.ts??segment[segment.length-1]?.ts??null),finalResponse:failedBeforeTrace?emptyFinalResponse():finalResponseFor(segment,traceId,user),valuesRedacted:true};
  });
}
function selectTurnSummaryRows(rows){
  if(!requestedCommandId)return {ok:true,status:'collected',filter:{mode:'all',requestedCommandId:null,matchedCount:rows.length,availableTurnCount:rows.length,exact:true,valuesRedacted:true},rows,error:null};
  const matched=rows.filter((row)=>String(row.commandId||'')===String(requestedCommandId));
  if(matched.length>0)return {ok:true,status:'matched',filter:{mode:'exact-command-id',requestedCommandId,matchedCount:matched.length,availableTurnCount:rows.length,exact:true,valuesRedacted:true},rows:matched,error:null};
  return {ok:false,status:'not-found',filter:{mode:'exact-command-id',requestedCommandId,matchedCount:0,availableTurnCount:rows.length,exact:true,valuesRedacted:true},rows:[],error:{code:'turn-summary-command-not-found',message:'requested commandId was not found; unrelated turns were not returned',requestedCommandId,availableTurnCount:rows.length,valuesRedacted:true}};
}
function pad(value,width){const text=short(value,width); return text+Array(Math.max(0,width-text.length)+1).join(' ')}
function renderTurnSummary(rows,selection){
  const prompts=promptCommands();
  const anchorSessionId=authoritativeSessionIdForPrompts(prompts)||rows.find((row)=>row.sessionId)?.sessionId||samples[0]?.routeSessionId||samples[0]?.activeSessionId||samples[samples.length-1]?.routeSessionId||samples[samples.length-1]?.activeSessionId||'-';
  const observedSessions=unique(samples.flatMap((sample)=>[sample.routeSessionId,sample.activeSessionId]));
  const driftSuffix=observedSessions.length>1?'                     sessionDrift='+observedSessions.length:'';
  const title='Workbench Session '+anchorSessionId+'                     observer '+(manifest.jobId||'-')+driftSuffix;
  const filterLine=selection?.filter?.mode==='exact-command-id'?'filter commandId='+String(selection.filter.requestedCommandId||'-')+' exact=true matched='+String(selection.filter.matchedCount??0):'filter commandId=- mode=all matched='+String(rows.length);
  const header='轮次  用户消息                    Trace        Control    Submit       Async turn  耗时/最近     Final Response';
  const body=rows.map((row)=>pad(row.round,5)+' '+pad((row.userHash?row.userHash.slice(0,14)+' ':'')+row.userPreview,27)+' '+pad(row.traceId||'-',12)+' '+pad(row.controlExecutionStatus||'-',10)+' '+pad(row.turnSubmissionStatus||'-',12)+' '+pad(row.turnStatus||row.status||'-',11)+' '+pad(fmtDuration(row.elapsedSeconds)+'/'+(row.recentUpdateSeconds===null?'-':String(row.recentUpdateSeconds)+'s'),13)+' '+short(row.finalResponse?.preview||'(空内容)',80)).join('\\n');
  const empty=selection?.status==='not-found'?'NOT_FOUND turn-summary-command-not-found; unrelated turns were not returned':'(空内容)';
  const exactIdentity=selection?.filter?.mode==='exact-command-id'&&rows.length===1
    ?['','Identity','  commandId='+String(rows[0].commandId||'-')+' traceId='+String(rows[0].traceId||'-')+' sessionId='+String(rows[0].sessionId||anchorSessionId||'-')]
    :[];
  return [title,'=======================================================',filterLine,header,body||empty,...exactIdentity,'', 'DISCLOSURE', '  Control=observer browser action; Submit=turn admission evidence; Async turn=independently sampled business lifecycle.', '', 'NEXT', '  detail: bun scripts/cli.ts web-probe observe collect '+(manifest.jobId||'<observer>')+' --view trace-frame --trace-id <traceId> --sample-seq <seq>'].join('\\n');
}
function diagnosticRows(label,items,limit=6){
  const selected=items.slice(-limit);
  const skipped=Math.max(0,items.length-selected.length);
  const prefix=skipped>0?'last '+selected.length+'/'+items.length:items.length+'';
  return selected.map((item,index)=>{
    const traceId=itemTraceId(item)||item.traceId||'-';
    const status=String(item?.status||item?.kind||item?.type||'-');
    return label+' '+prefix+' #'+(skipped+index+1)+' trace='+short(traceId,22)+' status='+short(status,18)+' text='+short(textOf(item),120);
  });
}
function traceFrameDiagnosticLines(sample,traceId,matchedTraceRows){
  const allTraceRows=Array.isArray(sample.traceRows)?sample.traceRows:[];
  const allTurns=Array.isArray(sample.turns)?sample.turns:[];
  const allMessages=Array.isArray(sample.messages)?sample.messages:[];
  const allIds=unique([...allTraceRows,...allTurns,...allMessages].map((item)=>itemTraceId(item)||item?.traceId||firstTraceId(textOf(item)))).slice(0,12);
  return [
    'TRACE DIAGNOSTIC',
    'pageRole='+(sample.pageRole||'-')+' pageId='+(sample.pageId||'-')+' traceRows='+allTraceRows.length+' turns='+allTurns.length+' messages='+allMessages.length,
    'requestedTraceId='+(traceId||'-')+' matchedTraceRows='+matchedTraceRows.length+' sampleTraceIds='+(allIds.join(',')||'-'),
    ...diagnosticRows('traceRow',allTraceRows),
    ...diagnosticRows('turn',allTurns,4),
    ...diagnosticRows('message',allMessages,4),
  ];
}
function selectSample(rows){
  if(requestedSampleSeq!==null){const exact=samples.find((sample)=>Number(sample.seq)===requestedSampleSeq); if(exact)return exact;}
  if(requestedTimestamp){const target=tsMs(requestedTimestamp); if(target!==null){const before=samples.filter((sample)=>{const ms=tsMs(sample.ts); return ms!==null&&ms<=target}).slice(-1)[0]; if(before)return before;}}
  const requestedRow=requestedTurn!==null?rows[requestedTurn-1]:null;
  if(requestedRow?.traceId){const byTrace=bestTraceFrameSample(requestedRow.traceId,numOrNull(requestedRow.lastSeq)); if(byTrace)return byTrace;}
  if(requestedRow&&requestedRow.lastSeq!==null&&requestedRow.lastSeq!==undefined){const byTurn=samples.find((sample)=>Number(sample.seq)===Number(requestedRow.lastSeq)); if(byTurn)return byTurn;}
  if(requestedTraceId){const byTrace=bestTraceFrameSample(requestedTraceId); if(byTrace)return byTrace;}
  return samples[samples.length-1]||null;
}
function renderTraceFrame(sample,rows){
  if(!sample)return {ok:false,renderedText:'TRACE_FRAME_BLOCKER\\nno sample matched --sample-seq/--timestamp/--trace-id/--turn',blocker:'sample-not-found'};
  const requestedRow=requestedTurn!==null?rows[requestedTurn-1]:null;
  const sampleTraceIds=traceIdsFromSamples([sample]); const traceId=requestedTraceId||requestedRow?.traceId||rows.find((row)=>row.lastSeq===sample.seq)?.traceId||sampleTraceIds[0]||null;
  const traceRows=(Array.isArray(sample.traceRows)?sample.traceRows:[]).filter((row)=>!traceId||row.traceId===traceId||!row.traceId||textOf(row).includes(traceId));
  const turns=(Array.isArray(sample.turns)?sample.turns:[]).filter((turn)=>!traceId||turn.traceId===traceId||textOf(turn).includes(traceId));
  const texts=[...turns.map(textOf),...traceRows.map(textOf)];
  const elapsed=Math.max(-1,...texts.map(parseElapsed).filter((value)=>value!==null)); const recent=Math.max(-1,...texts.map(parseRecent).filter((value)=>value!==null));
  const status=statusFor([sample],traceId); const finalResponse=finalResponseFor([sample],traceId);
  const visibleTraceRows=traceRows.slice(-24);
  const rowLines=visibleTraceRows.map((row,index)=>{const text=textOf(row); return short((row.status?row.status+' ':'')+text,180)||('row#'+index+' '+(row.textHash||'-'));});
  if(traceRows.length>visibleTraceRows.length) rowLines.unshift('(已省略 '+(traceRows.length-visibleTraceRows.length)+' 条较早 trace rows；需要原始数据请看 samples.jsonl)');
  const terminalProjectionVisible=status==='completed'&&finalResponse&&!finalResponse.empty&&turns.some((turn)=>String(turn?.status||'').toLowerCase()==='completed'||/completed|轮次完成|final response/iu.test(textOf(turn)));
  if(rowLines.length===0&&terminalProjectionVisible) rowLines.push('(trace rows collapsed; terminal turn and Final Response are visible)');
  const missingRows=rowLines.length===0;
  const laterTerminalSample=traceId?samples.filter((candidate)=>Number(candidate.seq??0)>Number(sample.seq??0)&&traceIdsFromSamples([candidate]).includes(traceId)&&sampleHasTerminalForTrace(candidate,traceId)).slice(-1)[0]||null:null;
  const sampleNotice=laterTerminalSample?['TRACE SAMPLE NOTICE','current sample is non-terminal but a later terminal sample exists: seq='+(laterTerminalSample.seq??'-')+' ts='+(laterTerminalSample.ts||'-')+'; rerun with --sample-seq '+(laterTerminalSample.seq??'<seq>')+' or omit explicit sample selection.']:[];
  const bodyRows=missingRows?['(无 trace rows；这是 blocker，不能当业务通过证据)',...traceFrameDiagnosticLines(sample,traceId,traceRows)]:rowLines;
  const rendered=['Code Agent 耗时 '+(elapsed>=0?fmtDuration(elapsed):'-')+'               最近 '+(recent>=0?String(recent)+' 秒前':'-')+' （'+status+'）','=======================================================','sample seq='+(sample.seq??'-')+' ts='+(sample.ts||'-')+' traceId='+(traceId||'-')+' routeSession='+(sample.routeSessionId||'-')+' activeSession='+(sample.activeSessionId||'-'),...sampleNotice,...bodyRows,'==========================','Final Response',finalResponse.preview||'(空内容)'].join('\\n');
  return {ok:!missingRows,renderedText:rendered,blocker:missingRows?'trace-rows-missing':null,sampleSeq:sample.seq??null,traceId,finalResponse,laterTerminalSample:laterTerminalSample?{seq:laterTerminalSample.seq??null,ts:laterTerminalSample.ts??null}:null,traceDiagnostic:missingRows?{pageRole:sample.pageRole||null,pageId:sample.pageId||null,traceRows:Array.isArray(sample.traceRows)?sample.traceRows.length:0,turns:Array.isArray(sample.turns)?sample.turns.length:0,messages:Array.isArray(sample.messages)?sample.messages.length:0,sampleTraceIds:traceIdsFromSamples([sample]).slice(0,12)}:null,valuesRedacted:true};
}
function firstPresent(values){
  for(const value of values){
    if(value!==null&&value!==undefined&&String(value)!=='') return value;
  }
  return null;
}
function commandIdOf(item){return item?.commandId||item?.id||item?.detail?.commandId||item?.input?.commandId||null}
function controlSessionId(item){
  const detail=item?.detail&&typeof item.detail==='object'?item.detail:{};
  return commandSessionId(item)||detail.sessionId||detail.result?.sessionId||detail.observer?.sessionId||null;
}
function controlTraceId(item){
  const detail=item?.detail&&typeof item.detail==='object'?item.detail:{};
  return commandTraceId(item)||detail.traceId||detail.chatSubmit?.traceId||detail.result?.traceId||detail.result?.chatSubmit?.traceId||null;
}
function safeListJsonFiles(rel){
  const root=path.join(dir,rel); let entries=[];
  try{entries=fs.readdirSync(root,{withFileTypes:true});}catch{return [];}
  return entries.filter((entry)=>entry.isFile()&&entry.name.endsWith('.json')).map((entry)=>rel+'/'+entry.name);
}
function readCommandFiles(){
  const buckets=['pending','processing','done','failed','abandoned'];
  const rows=[];
  for(const bucket of buckets){
    for(const rel of safeListJsonFiles('commands/'+bucket)){
      const data=readJson(rel)||{}; let stat=null;
      try{stat=fs.statSync(path.join(dir,rel));}catch{}
      const name=path.basename(rel);
      rows.push({bucket,relative:rel,name,data,mtime:stat?stat.mtime.toISOString():null,valuesRedacted:true});
    }
  }
  return rows.sort((a,b)=>(tsMs(commandFileTs(a))??0)-(tsMs(commandFileTs(b))??0)||a.relative.localeCompare(b.relative));
}
function commandFileId(row){return row?.data?.id||row?.data?.commandId||String(row?.name||'').replace(/[.]json$/u,'')||null}
function commandFileType(row){return row?.data?.type||row?.data?.commandType||row?.data?.input?.type||row?.data?.result?.type||null}
function commandFileTs(row){return firstPresent([row?.data?.createdAt,row?.data?.completedAt,row?.data?.failedAt,row?.data?.abandonedAt,row?.data?.ts,row?.mtime])}
function commandFileSessionId(row){
  const data=row?.data||{}; const result=data.result&&typeof data.result==='object'?data.result:{}; const command=data.command&&typeof data.command==='object'?data.command:{};
  return data.sessionId||data.input?.sessionId||command.sessionId||result.sessionId||result.observer?.sessionId||sessionIdFromUrl(result.afterUrl)||null;
}
function commandFileTraceId(row){
  const data=row?.data||{}; const result=data.result&&typeof data.result==='object'?data.result:{}; const error=data.error&&typeof data.error==='object'?data.error:{};
  return data.traceId||data.input?.traceId||result.traceId||result.chatSubmit?.traceId||error.traceId||null;
}
function commandFileSummary(row){
  const data=row?.data||{}; const result=data.result&&typeof data.result==='object'?data.result:{}; const error=data.error&&typeof data.error==='object'?data.error:{};
  const parts=['file='+short(row.relative,48),'ok='+String(data.ok===true),'bucket='+row.bucket];
  const duration=firstPresent([result.durationMs,result.observer?.durationMs,error.durationMs]);
  if(duration!==null) parts.push('durationMs='+String(duration));
  const status=firstPresent([result.status,result.phase,error.name,error.failureKind]);
  if(status!==null) parts.push('status='+short(status,32));
  const message=firstPresent([error.message,result.message,result.error?.message]);
  if(message!==null) parts.push('message='+short(message,120));
  return parts.join(' ');
}
function controlSummary(item){
  const detail=item?.detail&&typeof item.detail==='object'?item.detail:{};
  const input=item?.input&&typeof item.input==='object'?item.input:{};
  const error=detail.error&&typeof detail.error==='object'?detail.error:null;
  const parts=[];
  if(input.textHash||input.hash) parts.push('textHash='+short(input.textHash||input.hash,24));
  if(input.textBytes!==undefined) parts.push('textBytes='+String(input.textBytes));
  if(detail.durationMs!==undefined) parts.push('durationMs='+String(detail.durationMs));
  if(detail.retry||detail.retryLabel) parts.push('retry='+short(detail.retry||detail.retryLabel,24));
  if(error?.message) parts.push('error='+short(error.message,120));
  const afterPath=pathOnly(item?.afterUrl||detail.afterUrl);
  if(afterPath) parts.push('afterPath='+short(afterPath,64));
  return parts.join(' ')||'-';
}
function sampleSummary(sample){
  const traceIds=traceIdsFromSamples([sample]).slice(0,4);
  const counts='turns='+(Array.isArray(sample.turns)?sample.turns.length:0)+' traceRows='+(Array.isArray(sample.traceRows)?sample.traceRows.length:0)+' messages='+(Array.isArray(sample.messages)?sample.messages.length:0);
  const pathText=sample.path||pathOnly(sample.url)||pathOnly(sample.currentUrl)||'-';
  return 'path='+short(pathText,64)+' pageRole='+short(sample.pageRole||'-',18)+' '+counts+' traceIds='+(traceIds.join(',')||'-');
}
function isoOrNull(ms){return ms===null||ms===Infinity||ms===-Infinity?null:new Date(ms).toISOString()}
function timelineAnchor(rows,commandFiles){
  if(requestedCommandId){
    const controls=control.filter((item)=>String(commandIdOf(item)||'')===requestedCommandId);
    const files=commandFiles.filter((item)=>String(commandFileId(item)||'')===requestedCommandId);
    const times=[...controls.map((item)=>tsMs(item.ts)),...files.map((item)=>tsMs(commandFileTs(item)))].filter((value)=>value!==null);
    const start=times.length?Math.min(...times):null; const end=times.length?Math.max(...times):null;
    return {mode:'command-id',value:requestedCommandId,startMs:start,endMs:end,anchorMs:end??start,matchedControlCount:controls.length,matchedCommandFileCount:files.length,valuesRedacted:true};
  }
  if(requestedTurn!==null&&rows[requestedTurn-1]){
    const row=rows[requestedTurn-1]; const segment=samples.filter((sample)=>{const seq=numOrNull(sample.seq); return seq!==null&&row.firstSeq!==null&&row.lastSeq!==null&&seq>=Number(row.firstSeq)&&seq<=Number(row.lastSeq);});
    const times=[tsMs(row.lastTs),...segment.map((sample)=>tsMs(sample.ts))].filter((value)=>value!==null);
    const start=times.length?Math.min(...times):null; const end=times.length?Math.max(...times):null;
    return {mode:'turn',value:String(requestedTurn),commandId:row.commandId||null,traceId:row.traceId||null,startMs:start,endMs:end,anchorMs:end??start,valuesRedacted:true};
  }
  if(requestedTraceId){
    const matched=samples.filter((sample)=>traceIdsFromSamples([sample]).includes(requestedTraceId));
    const times=matched.map((sample)=>tsMs(sample.ts)).filter((value)=>value!==null);
    const start=times.length?Math.min(...times):null; const end=times.length?Math.max(...times):null;
    return {mode:'trace-id',value:requestedTraceId,startMs:start,endMs:end,anchorMs:end??start,matchedSampleCount:matched.length,valuesRedacted:true};
  }
  if(requestedSampleSeq!==null){
    const sample=samples.find((item)=>Number(item.seq)===requestedSampleSeq)||null;
    const anchorMs=tsMs(sample?.ts);
    return {mode:'sample-seq',value:String(requestedSampleSeq),startMs:anchorMs,endMs:anchorMs,anchorMs,valuesRedacted:true};
  }
  if(requestedTimestamp){
    const anchorMs=tsMs(requestedTimestamp);
    return {mode:'timestamp',value:requestedTimestamp,startMs:anchorMs,endMs:anchorMs,anchorMs,valuesRedacted:true};
  }
  const latestTimes=[...samples.map((sample)=>tsMs(sample.ts)),...control.map((item)=>tsMs(item.ts)),...commandFiles.map((item)=>tsMs(commandFileTs(item)))].filter((value)=>value!==null);
  const anchorMs=latestTimes.length?Math.max(...latestTimes):null;
  return {mode:'latest',value:null,startMs:anchorMs,endMs:anchorMs,anchorMs,valuesRedacted:true};
}
function timelineWindow(anchor){
  const windowMs=requestedWindowMs??120000;
  if(anchor.startMs!==null&&anchor.endMs!==null&&anchor.startMs!==anchor.endMs){
    return {fromMs:Math.max(0,anchor.startMs-1000),toMs:anchor.endMs+1000,windowMs,anchorMode:anchor.mode,valuesRedacted:true};
  }
  if(anchor.anchorMs!==null){
    return {fromMs:Math.max(0,anchor.anchorMs-windowMs),toMs:anchor.anchorMs+windowMs,windowMs,anchorMode:anchor.mode,valuesRedacted:true};
  }
  return {fromMs:null,toMs:null,windowMs,anchorMode:anchor.mode,valuesRedacted:true};
}
function inTimelineWindow(ts,window){
  const ms=tsMs(ts);
  if(ms===null) return window.fromMs===null&&window.toMs===null;
  if(window.fromMs!==null&&ms<window.fromMs) return false;
  if(window.toMs!==null&&ms>window.toMs) return false;
  return true;
}
function timelineEventRows(anchor,window,commandFiles){
  const commandId=anchor.mode==='command-id'?anchor.value:null;
  const matchedControl=control.filter((item)=>(commandId&&String(commandIdOf(item)||'')===commandId)||inTimelineWindow(item.ts,window));
  const matchedSamples=samples.filter((sample)=>inTimelineWindow(sample.ts,window));
  const matchedCommands=commandFiles.filter((item)=>(commandId&&String(commandFileId(item)||'')===commandId)||inTimelineWindow(commandFileTs(item),window));
  const rows=[
    ...matchedControl.map((item)=>({ts:item.ts||null,seq:item.seq??null,kind:'control',phase:item.phase||'-',type:item.type||'-',commandId:commandIdOf(item),sessionId:controlSessionId(item),traceId:controlTraceId(item),summary:controlSummary(item),valuesRedacted:true})),
    ...matchedSamples.map((sample)=>({ts:sample.ts||null,seq:sample.seq??null,kind:'sample',phase:'sample',type:sample.reason||sample.pageRole||'-',commandId:sample.commandId||null,sessionId:sample.routeSessionId||sample.activeSessionId||null,traceId:traceIdsFromSamples([sample])[0]||null,summary:sampleSummary(sample),valuesRedacted:true})),
    ...matchedCommands.map((item)=>({ts:commandFileTs(item),seq:null,kind:'command-file',phase:item.bucket,type:commandFileType(item)||'-',commandId:commandFileId(item),sessionId:commandFileSessionId(item),traceId:commandFileTraceId(item),summary:commandFileSummary(item),valuesRedacted:true})),
  ].filter((item)=>item.ts!==null||item.commandId!==null)
    .sort((a,b)=>(tsMs(a.ts)??0)-(tsMs(b.ts)??0)||String(a.kind).localeCompare(String(b.kind))||String(a.commandId||'').localeCompare(String(b.commandId||'')));
  const cap=12;
  let visible=rows;
  if(rows.length>cap){
    const evidence=rows.filter((row)=>row.kind!=='sample');
    const sampleRows=rows.filter((row)=>row.kind==='sample');
    visible=evidence.length>=cap?evidence.slice(evidence.length-cap):[...evidence,...sampleRows.slice(sampleRows.length-(cap-evidence.length))]
      .sort((a,b)=>(tsMs(a.ts)??0)-(tsMs(b.ts)??0)||String(a.kind).localeCompare(String(b.kind))||String(a.commandId||'').localeCompare(String(b.commandId||'')));
  }
  return {rows:visible,omittedRowCount:Math.max(0,rows.length-visible.length),matchedControlCount:matchedControl.length,matchedSampleCount:matchedSamples.length,matchedCommandFileCount:matchedCommands.length,valuesRedacted:true};
}
function renderTimeline(anchor,window,eventRows){
  const lines=['Observe artifact timeline '+(manifest.jobId||'-'),'======================================================='];
  lines.push('stateDir='+dir);
  lines.push('anchor='+anchor.mode+' value='+(anchor.value||'-')+' from='+(isoOrNull(window.fromMs)||'-')+' to='+(isoOrNull(window.toMs)||'-')+' windowMs='+String(window.windowMs));
  lines.push('counts control='+String(eventRows.matchedControlCount)+' samples='+String(eventRows.matchedSampleCount)+' commandFiles='+String(eventRows.matchedCommandFileCount)+' shown='+String(eventRows.rows.length)+' omitted='+String(eventRows.omittedRowCount));
  lines.push('', 'TIMELINE');
  lines.push(pad('TS',24)+' '+pad('SEQ',5)+' '+pad('KIND',12)+' '+pad('PHASE',12)+' '+pad('TYPE',24)+' '+pad('COMMAND',28)+' '+pad('SESSION',18)+' '+pad('TRACE',18)+' SUMMARY');
  if(eventRows.rows.length===0) lines.push('(no artifact rows matched; widen --window-ms or choose another --command-id/--timestamp/--turn)');
  for(const row of eventRows.rows){
    lines.push(pad(row.ts||'-',24)+' '+pad(row.seq??'-',5)+' '+pad(row.kind,12)+' '+pad(row.phase,12)+' '+pad(row.type,24)+' '+pad(row.commandId||'-',28)+' '+pad(row.sessionId||'-',18)+' '+pad(row.traceId||'-',18)+' '+short(row.summary,100));
  }
  const id=manifest.jobId||'<observer>';
  lines.push('', 'NEXT');
  lines.push('  turn summary: bun scripts/cli.ts web-probe observe collect '+id+' --view turn-summary');
  lines.push('  trace frame:  bun scripts/cli.ts web-probe observe collect '+id+' --view trace-frame --trace-id <traceId> --sample-seq <seq>');
  lines.push('  command window: bun scripts/cli.ts web-probe observe collect '+id+' --view timeline --command-id <commandId>');
  lines.push('  raw control grep: bun scripts/cli.ts web-probe observe collect '+id+' --view files --file control.jsonl --grep <commandId>');
  lines.push('', 'DISCLOSURE valuesRedacted=true valuesPrinted=false source=existing observe artifacts');
  return lines.join('\\n');
}
function timelineView(rows){
  const commandFiles=readCommandFiles();
  const anchor=timelineAnchor(rows,commandFiles);
  const window=timelineWindow(anchor);
  const eventRows=timelineEventRows(anchor,window,commandFiles);
  const timelineRows=eventRows.rows.map((row)=>({ts:row.ts?short(row.ts,32):null,seq:row.seq??null,kind:row.kind,phase:short(row.phase,24),type:short(row.type,40),commandId:row.commandId?short(row.commandId,64):null,sessionId:row.sessionId?short(row.sessionId,64):null,traceId:row.traceId?short(row.traceId,64):null,summary:short(row.summary,140),valuesRedacted:true}));
  return {anchor:{...anchor,from:isoOrNull(anchor.startMs),to:isoOrNull(anchor.endMs),startMs:undefined,endMs:undefined,anchorMs:undefined},window:{from:isoOrNull(window.fromMs),to:isoOrNull(window.toMs),windowMs:window.windowMs,anchorMode:window.anchorMode,valuesRedacted:true},counts:{control:control.length,samples:samples.length,commandFiles:commandFiles.length,matchedControl:eventRows.matchedControlCount,matchedSamples:eventRows.matchedSampleCount,matchedCommandFiles:eventRows.matchedCommandFileCount,shown:timelineRows.length,omitted:eventRows.omittedRowCount,valuesRedacted:true},timelineRows,renderedText:renderTimeline(anchor,window,eventRows),valuesRedacted:true};
}
function findingById(id){
  return (Array.isArray(report.findings)?report.findings:[]).find((item)=>String(item?.id||item?.kind||item?.code||'')===id)||null;
}
function compactFinding(item){
  if(!item)return null;
  return {
    id:String(item.id||item.kind||item.code||''),
    severity:item.severity||item.level||null,
    count:item.count??item.sampleCount??null,
    summary:short(item.summary||item.message||'',220),
    rootCause:item.rootCause||null,
    rootCauseStatus:item.rootCauseStatus||null,
    rootCauseConfidence:item.rootCauseConfidence||null,
    sourceOfTruth:item.sourceOfTruth?short(item.sourceOfTruth,180):null,
    valuesRedacted:true
  };
}
function recoveryAuthorityFromFindings(){
  const finding=findingById('workbench-automatic-recovery-fanout-authority');
  const authority=finding?.recoveryAuthority&&typeof finding.recoveryAuthority==='object'?finding.recoveryAuthority:null;
  const summary=authority?.summary&&typeof authority.summary==='object'?authority.summary:null;
  const syncEvidence=Array.isArray(authority?.syncEvidence)?authority.syncEvidence.slice(-6):[];
  const forbidden=Array.isArray(authority?.forbiddenAutomaticRecovery)?authority.forbiddenAutomaticRecovery.slice(0,6):[];
  const fanout=Array.isArray(authority?.legacyFanoutWindows)?authority.legacyFanoutWindows.slice(0,4):[];
  const gaps=Array.isArray(authority?.observabilityGaps)?authority.observabilityGaps.slice(0,4):[];
  return {
    findingPresent:Boolean(finding),
    forbiddenAutomaticRecoveryCount:Number(summary?.forbiddenAutomaticRecoveryCount??0),
    legacyFanoutWindowCount:Number(summary?.legacyFanoutWindowCount??0),
    syncReplayEvidenceCount:Number(summary?.syncReplayEvidenceCount??0),
    syncReplayAppliedCount:Number(summary?.syncReplayAppliedCount??0),
    syncNetworkReadCount:Number(summary?.syncNetworkReadCount??0),
    oldEndpointReadCount:Number(summary?.oldEndpointReadCount??0),
    observabilityGapCount:Number(summary?.observabilityGapCount??0),
    latestSyncEvidence:syncEvidence.slice(-1)[0]||null,
    forbiddenAutomaticRecovery:forbidden,
    legacyFanoutWindows:fanout,
    observabilityGaps:gaps,
    valuesRedacted:true
  };
}
function traceIdFromUrl(value){
  const match=String(value||'').match(/\\/v1\\/workbench\\/(?:turns|traces)\\/(trc_[A-Za-z0-9_-]+)/u);
  return match?match[1]:null;
}
function pathKindForNetwork(item){
  const summary=item?.bodySummary&&typeof item.bodySummary==='object'?item.bodySummary:null;
  if(summary?.pathKind)return String(summary.pathKind);
  const url=String(item?.url||item?.requestUrl||'');
  if(url.includes('/v1/workbench/turns/'))return 'workbench-turn';
  if(url.includes('/v1/workbench/traces/')&&url.includes('/events'))return 'workbench-trace-events';
  if(url.includes('/v1/workbench/sessions'))return 'workbench-sessions';
  return null;
}
function networkEvidenceForTrace(traceId){
  const rows=network.filter((item)=>{
    const kind=pathKindForNetwork(item);
    if(kind!=='workbench-turn'&&kind!=='workbench-trace-events')return false;
    const ids=Array.isArray(item?.bodySummary?.traceIds)?item.bodySummary.traceIds:[traceIdFromUrl(item?.url||item?.requestUrl)];
    return !traceId||ids.includes(traceId)||traceIdFromUrl(item?.url||item?.requestUrl)===traceId;
  });
  const responses=rows.filter((item)=>item.type==='response');
  const requests=rows.filter((item)=>item.type==='request');
  const failed=rows.filter((item)=>item.type==='requestfailed');
  const terminalResponses=responses.filter((item)=>Number(item?.bodySummary?.terminalEvidenceCount??0)>0||Number(item?.bodySummary?.terminalStatusCount??0)>0||Number(item?.bodySummary?.finalTextByteCount??0)>0);
  const byKind=(kind)=>responses.filter((item)=>pathKindForNetwork(item)===kind);
  const latest=(items)=>items.slice(-1)[0]||null;
  const compactNet=(item)=>item?{ts:item.ts||null,sampleSeq:item.sampleSeq??null,status:item.status??null,pathKind:pathKindForNetwork(item),traceId:traceIdFromUrl(item.url||item.requestUrl),urlPath:pathOnly(item.url||item.requestUrl),failure:item.failure||item.errorText||null,bodySummary:item.bodySummary?{terminalStatusCount:item.bodySummary.terminalStatusCount??null,runningStatusCount:item.bodySummary.runningStatusCount??null,traceEventLikeCount:item.bodySummary.traceEventLikeCount??null,finalTextByteCount:item.bodySummary.finalTextByteCount??null,terminalEvidenceCount:item.bodySummary.terminalEvidenceCount??null,valuesRedacted:true}:null,valuesRedacted:true}:null;
  return {requestCount:requests.length,responseCount:responses.length,failedCount:failed.length,terminalResponseCount:terminalResponses.length,turnResponseCount:byKind('workbench-turn').length,traceEventsResponseCount:byKind('workbench-trace-events').length,latestTurnResponse:compactNet(latest(byKind('workbench-turn'))),latestTraceEventsResponse:compactNet(latest(byKind('workbench-trace-events'))),failed:failed.slice(-2).map(compactNet),valuesRedacted:true};
}
function commandOtelTraceId(item){
  return item?.otelTraceId||item?.detail?.chatSubmit?.otelTraceId||item?.detail?.otelTraceId||item?.result?.chatSubmit?.otelTraceId||item?.result?.otelTraceId||null;
}
function otelEvidenceForTrace(traceId,row){
  const matched=control.filter((item)=>{
    if(row?.commandId&&String(item?.commandId||'')===String(row.commandId))return true;
    return traceId&&commandTraceId(item)===traceId;
  });
  const source=matched.slice().reverse().find((item)=>commandOtelTraceId(item)||commandTraceId(item))||null;
  const otelTraceId=commandOtelTraceId(source);
  return {
    status:otelTraceId?'trace-reference-present':traceId?'business-trace-reference-only':'trace-reference-missing',
    businessTraceId:traceId||null,
    otelTraceId:otelTraceId||null,
    coverageStatus:'not-evaluated-by-offline-artifact-view',
    businessTerminalStatus:null,
    businessTerminalObserved:false,
    evidenceScope:'control-artifact-reference-only',
    diagnoseCommand:traceId?'bun scripts/cli.ts platform-infra observability diagnose-code-agent --target <node> --business-trace-id '+traceId:null,
    valuesRedacted:true
  };
}
function reconcileTriadEvidence(traceId,row,networkEvidence){
  const localStatus=networkEvidence.responseCount>0?'captured':networkEvidence.requestCount>0||networkEvidence.failedCount>0?'partial':'missing';
  const artifactMissing=localStatus==='missing';
  const otel=otelEvidenceForTrace(traceId,row);
  return {
    status:artifactMissing?'artifact-evidence-missing':localStatus==='partial'?'artifact-evidence-partial':'artifact-evidence-captured',
    localApiArtifact:{
      status:localStatus,
      requestCount:networkEvidence.requestCount,
      responseCount:networkEvidence.responseCount,
      failedCount:networkEvidence.failedCount,
      sourceFile:'network.jsonl',
      valuesRedacted:true
    },
    otel,
    businessApiOccurrence:networkEvidence.responseCount>0?'observed-in-local-artifact':'not-determined-by-local-artifact',
    businessApiAbsenceProven:false,
    interpretationCode:artifactMissing?'local-api-artifact-missing-requires-otel-reconciliation':'local-api-artifact-present',
    message:artifactMissing?'artifact evidence missing: observer network.jsonl did not capture a matching API response; this does not mean the business API did not occur. Reconcile with controlled OTel evidence.':'local API artifact evidence is present; OTel remains an independent business lifecycle source.',
    valuesRedacted:true
  };
}
function traceDomSnapshot(traceId){
  const matched=samples.filter((sample)=>!traceId||traceIdsFromSamples([sample]).includes(traceId));
  const latest=matched.slice(-1)[0]||samples[samples.length-1]||null;
  if(!latest)return {sampleSeq:null,ts:null,status:'unknown',traceRowCount:0,messageCount:0,turnCount:0,finalResponse:emptyFinalResponse(),pageRole:null,path:null,valuesRedacted:true};
  const traceRows=(Array.isArray(latest.traceRows)?latest.traceRows:[]).filter((row)=>!traceId||row.traceId===traceId||textOf(row).includes(traceId));
  const messages=(Array.isArray(latest.messages)?latest.messages:[]).filter((message)=>!traceId||message.traceId===traceId||textOf(message).includes(traceId)||!itemTraceId(message));
  const turns=(Array.isArray(latest.turns)?latest.turns:[]).filter((turn)=>!traceId||turn.traceId===traceId||textOf(turn).includes(traceId));
  const final=finalResponseFor([latest],traceId);
  return {sampleSeq:latest.seq??null,ts:latest.ts||null,path:latest.path||pathOnly(latest.url)||pathOnly(latest.currentUrl)||null,pageRole:latest.pageRole||null,routeSessionId:latest.routeSessionId||null,activeSessionId:latest.activeSessionId||null,status:statusFor([latest],traceId),traceRowCount:traceRows.length,messageCount:messages.length,turnCount:turns.length,finalResponse:final,valuesRedacted:true};
}
function browserFreezeEvidence(){
  const blockers=browserProcess.filter((item)=>item&&item.type==='browser-freeze-blocker');
  const responsiveness=browserProcess.filter((item)=>item&&item.type==='browser-process-sample').flatMap((item)=>{
    const pages=Array.isArray(item.pages)?item.pages:[];
    return pages.map((page)=>({ts:item.ts||null,sampleSeq:item.sampleSeq??item.seq??null,pageRole:page?.pageRole||null,pageId:page?.pageId||null,responsivenessLatencyMs:page?.responsiveness?.latencyMs??null,responsivenessTimeout:page?.responsiveness?.timeout===true,cdpTimeoutCount:page?.cdp?.timeoutCount??null,cdpErrorCount:page?.cdp?.errorCount??null,valuesRedacted:true}));
  }).filter((item)=>item.responsivenessTimeout===true||Number(item.responsivenessLatencyMs??0)>0||Number(item.cdpTimeoutCount??0)>0);
  const compactBlocker=(item)=>{
    const observed=item?.observed&&typeof item.observed==='object'?item.observed:{};
    const page=item?.page&&typeof item.page==='object'?item.page:{};
    const kill=item?.browserKill&&typeof item.browserKill==='object'?item.browserKill:{};
    return {ts:item?.ts||null,sampleSeq:item?.sampleSeq??item?.seq??null,pageRole:item?.pageRole||page.pageRole||null,summary:short(item?.summary||'',220),rootCause:item?.rootCause||null,rootCauseStatus:item?.rootCauseStatus||null,rootCauseConfidence:item?.rootCauseConfidence||null,policySource:item?.policySource||null,fallbackAllowed:item?.fallbackAllowed===true,observerRefreshAllowed:item?.observerRefreshAllowed===true,observed:{responsivenessLatencyMs:observed.responsivenessLatencyMs??null,responsivenessTimeout:observed.responsivenessTimeout===true,cdpMetricsTimeoutCount:observed.cdpMetricsTimeoutCount??null,valuesRedacted:true},page:{pageRole:page.pageRole||null,pageId:page.pageId||null,timeoutMs:page.timeoutMs??null,responsivenessLatencyMs:page.responsivenessLatencyMs??null,responsivenessTimeout:page.responsivenessTimeout===true,cdpTimeoutCount:page.cdpTimeoutCount??null,cdpErrorCount:page.cdpErrorCount??null,valuesRedacted:true},browserKill:{ok:kill.ok===true,reason:kill.reason||null,valuesRedacted:true},valuesRedacted:true};
  };
  return {blockerCount:blockers.length,latestBlocker:compactBlocker(blockers.slice(-1)[0]||null),responsivenessEventCount:responsiveness.length,valuesRedacted:true};
}
function workbenchTriadView(rows){
  const requestedRow=requestedTurn!==null?rows[requestedTurn-1]:null;
  const traceId=requestedTraceId||requestedRow?.traceId||rows.slice().reverse().find((row)=>row.traceId)?.traceId||traceIdsFromSamples(samples).slice(-1)[0]||null;
  const row=rows.find((item)=>item.traceId===traceId)||requestedRow||rows.slice(-1)[0]||null;
  const findings=[
    compactFinding(findingById('workbench-automatic-recovery-fanout-authority')),
    compactFinding(findingById('workbench-terminal-api-dom-not-refreshed-in-place')),
    compactFinding(findingById('workbench-terminal-trace-not-hydrated-in-place')),
    compactFinding(findingById('workbench-turn-state-triad-inconsistent')),
    compactFinding(findingById('frontend-browser-freeze-runner-blocker')),
    compactFinding(findingById('frontend-playwright-responsiveness-red')),
    compactFinding(findingById('frontend-cdp-metrics-timeout-red')),
  ].filter(Boolean);
  const networkEvidence=networkEvidenceForTrace(traceId);
  const dom=traceDomSnapshot(traceId);
  const freeze=browserFreezeEvidence();
  const recoveryAuthority=recoveryAuthorityFromFindings();
  const evidenceReconciliation=reconcileTriadEvidence(traceId,row,networkEvidence);
  const statusGap={
    traceId,
    turnSummaryStatus:row?.status??null,
    domStatus:dom.status,
    domTraceRows:dom.traceRowCount,
    domFinalResponseEmpty:dom.finalResponse?.empty===true,
    terminalApiEvidence:networkEvidence.terminalResponseCount>0,
    terminalTurnApiEvidence:Number(networkEvidence.latestTurnResponse?.bodySummary?.terminalEvidenceCount??0)>0||Number(networkEvidence.latestTurnResponse?.bodySummary?.finalTextByteCount??0)>0,
    terminalTraceEventsEvidence:Number(networkEvidence.latestTraceEventsResponse?.bodySummary?.terminalEvidenceCount??0)>0||Number(networkEvidence.latestTraceEventsResponse?.bodySummary?.traceEventLikeCount??0)>0,
    browserFreezeBlocker:freeze.blockerCount>0,
    valuesRedacted:true
  };
  const compactRow=row?{round:row.round??null,commandId:row.commandId??null,sessionId:row.sessionId??null,traceId:row.traceId??null,controlExecutionStatus:row.controlExecutionStatus??null,turnSubmissionStatus:row.turnSubmissionStatus??null,turnStatus:row.turnStatus??row.status??null,turnTerminalObserved:row.turnTerminalObserved===true,status:row.status??null,elapsedSeconds:row.elapsedSeconds??null,recentUpdateSeconds:row.recentUpdateSeconds??null,marks:row.marks??null,firstSeq:row.firstSeq??null,lastSeq:row.lastSeq??null,lastTs:row.lastTs??null,finalResponse:row.finalResponse??null,valuesRedacted:true}:null;
  return {traceId,row:compactRow,dom,networkEvidence,evidenceReconciliation,freeze,recoveryAuthority,findings, statusGap,renderedText:renderWorkbenchTriad({traceId,row:compactRow,dom,networkEvidence,evidenceReconciliation,freeze,recoveryAuthority,findings,statusGap}),valuesRedacted:true};
}
function renderWorkbenchTriad(input){
  const lines=['Workbench triad offline diagnosis '+(manifest.jobId||'-'),'======================================================='];
  lines.push('trace='+String(input.traceId||'-')+' round='+String(input.row?.round??'-')+' turnSummary='+String(input.row?.status??'-')+' domStatus='+String(input.dom.status||'-')+' domTraceRows='+String(input.dom.traceRowCount??0)+' finalEmpty='+String(input.dom.finalResponse?.empty===true));
  lines.push('dom sample seq='+String(input.dom.sampleSeq??'-')+' ts='+String(input.dom.ts||'-')+' path='+String(input.dom.path||'-')+' routeSession='+String(input.dom.routeSessionId||'-')+' activeSession='+String(input.dom.activeSessionId||'-'));
  const turnSummary=input.networkEvidence.latestTurnResponse?.bodySummary||{};
  const traceSummary=input.networkEvidence.latestTraceEventsResponse?.bodySummary||{};
  lines.push('api evidence responses='+String(input.networkEvidence.responseCount)+' terminalResponses='+String(input.networkEvidence.terminalResponseCount)+' failed='+String(input.networkEvidence.failedCount)+' turnTerminal='+String(turnSummary.terminalEvidenceCount??'-')+' turnFinalBytes='+String(turnSummary.finalTextByteCount??'-')+' traceEvents='+String(traceSummary.traceEventLikeCount??'-')+' traceTerminal='+String(traceSummary.terminalEvidenceCount??'-'));
  const reconciliation=input.evidenceReconciliation||{};
  const localApi=reconciliation.localApiArtifact||{};
  const otel=reconciliation.otel||{};
  lines.push('evidence reconciliation status='+String(reconciliation.status||'-')+' localApiArtifact='+String(localApi.status||'-')+' businessApiAbsenceProven='+String(reconciliation.businessApiAbsenceProven===true)+' otel='+String(otel.status||'-')+' otelCoverage='+String(otel.coverageStatus||'-'));
  if(reconciliation.message)lines.push(String(reconciliation.message));
  if(otel.otelTraceId)lines.push('otel trace reference='+String(otel.otelTraceId)+' scope='+String(otel.evidenceScope||'-'));
  if(input.networkEvidence.latestTurnResponse) lines.push('latest turn API '+String(input.networkEvidence.latestTurnResponse.ts||'-')+' status='+String(input.networkEvidence.latestTurnResponse.status??'-')+' sample='+String(input.networkEvidence.latestTurnResponse.sampleSeq??'-')+' path='+String(input.networkEvidence.latestTurnResponse.urlPath||'-'));
  if(input.networkEvidence.latestTraceEventsResponse) lines.push('latest trace events API '+String(input.networkEvidence.latestTraceEventsResponse.ts||'-')+' status='+String(input.networkEvidence.latestTraceEventsResponse.status??'-')+' sample='+String(input.networkEvidence.latestTraceEventsResponse.sampleSeq??'-')+' path='+String(input.networkEvidence.latestTraceEventsResponse.urlPath||'-'));
  const recovery=input.recoveryAuthority||{};
  lines.push('recovery authority forbidden='+String(recovery.forbiddenAutomaticRecoveryCount??0)+' legacyFanout='+String(recovery.legacyFanoutWindowCount??0)+' syncEvidence='+String(recovery.syncReplayEvidenceCount??0)+' syncApplied='+String(recovery.syncReplayAppliedCount??0)+' syncNetwork='+String(recovery.syncNetworkReadCount??0)+' oldReads='+String(recovery.oldEndpointReadCount??0)+' gaps='+String(recovery.observabilityGapCount??0));
  if(recovery.latestSyncEvidence) lines.push('latest sync replay '+String(recovery.latestSyncEvidence.ts||'-')+' source='+String(recovery.latestSyncEvidence.source||'-')+' events='+String(recovery.latestSyncEvidence.eventCount??'-')+' since='+String(recovery.latestSyncEvidence.sinceOutboxSeq??'-')+' cursor='+String(recovery.latestSyncEvidence.syncCursorOutboxSeq??'-')+' authority='+String(recovery.latestSyncEvidence.realtimeAuthority||'-')+' terminalSeal='+String(recovery.latestSyncEvidence.terminalSeal??'-'));
  if(input.freeze.latestBlocker) lines.push('browser freeze '+String(input.freeze.latestBlocker.ts||'-')+' sample='+String(input.freeze.latestBlocker.sampleSeq??'-')+' rootCause='+String(input.freeze.latestBlocker.rootCause||'-')+' status='+String(input.freeze.latestBlocker.rootCauseStatus||'-')+' fallbackAllowed='+String(input.freeze.latestBlocker.fallbackAllowed===true));
  lines.push('','Findings');
  if(input.findings.length===0) lines.push('-');
  for(const finding of input.findings) lines.push(String(finding.severity||'-')+' '+String(finding.id||'-')+' count='+String(finding.count??'-')+' root='+String(finding.rootCause||finding.rootCauseStatus||'-')+' '+short(finding.summary||'',150));
  if(input.networkEvidence.failed.length>0){
    lines.push('','Network failed tail');
    for(const item of input.networkEvidence.failed) lines.push(String(item.ts||'-')+' '+String(item.pathKind||'-')+' '+String(item.failure||'-')+' '+String(item.urlPath||'-'));
  }
  const id=manifest.jobId||'<observer>';
  lines.push('','NEXT');
  if(input.traceId) lines.push('  trace-frame: bun scripts/cli.ts web-probe observe collect '+id+' --view trace-frame --trace-id '+input.traceId);
  if(input.traceId) lines.push('  otel: bun scripts/cli.ts platform-infra observability diagnose-code-agent --target <node> --business-trace-id '+input.traceId);
  lines.push('  findings: bun scripts/cli.ts web-probe observe collect '+id+' --view files --file analysis/report.json --finding workbench-terminal-api-dom-not-refreshed-in-place');
  lines.push('','DISCLOSURE source=existing artifacts valuesRedacted=true; this view does not start browser/probe or mutate runtime.');
  return lines.join('\\n');
}
function pathOnly(value){try{return value?new URL(String(value),'http://x').pathname:null}catch{return null}}
function projectSummaryFromSamples(){
  const projectSamples=samples.filter((sample)=>sample?.projectManagement&&typeof sample.projectManagement==='object');
  const latest=projectSamples[projectSamples.length-1]||null;
  const latestProject=latest?.projectManagement||null;
  const projectCommandTypes=new Set(['gotoProjectMdtodo','openMdtodoSourceConfig','closeMdtodoSourceConfig','configureMdtodoHwpodSource','probeMdtodoSource','reindexMdtodoSource','selectProjectSource','selectMdtodoSource','selectMdtodoFile','selectMdtodoTask','expandMdtodoTask','openMdtodoReportPreview','toggleMdtodoReportFullscreen','editMdtodoTaskInline','editMdtodoTaskTitle','editMdtodoTaskBody','toggleMdtodoTaskStatus','addMdtodoRootTask','addMdtodoSubTask','continueMdtodoTask','deleteMdtodoTask','launchWorkbenchFromTask','launchWorkbenchFromMdtodo']);
  const mutationTypes=new Set(['configureMdtodoHwpodSource','probeMdtodoSource','reindexMdtodoSource','editMdtodoTaskInline','editMdtodoTaskTitle','editMdtodoTaskBody','toggleMdtodoTaskStatus','addMdtodoRootTask','addMdtodoSubTask','continueMdtodoTask','deleteMdtodoTask']);
  const commandRows=control.filter((item)=>projectCommandTypes.has(item.type)&&(item.phase==='completed'||item.phase==='failed')).map((item)=>{
    const detail=item.detail&&typeof item.detail==='object'?item.detail:{};
    const error=detail.error&&typeof detail.error==='object'?detail.error:{};
    return {ts:item.ts||null,phase:item.phase||null,type:item.type||null,commandId:item.commandId||null,afterPath:pathOnly(item.afterUrl),selectedTaskHash:detail.selectedTask?.hash??detail.projectBeforeClick?.selectedTaskRef?.hash??detail.afterProject?.selectedTaskRef?.hash??null,status:detail.launchStatus??error.details?.launchStatus??null,chatObserved:detail.chatObserved??error.details?.chatObserved??null,workbenchMessageCount:detail.workbenchSnapshot?.messageCount??error.details?.workbenchSnapshot?.messageCount??null,workbenchTraceRowCount:detail.workbenchSnapshot?.traceRowCount??error.details?.workbenchSnapshot?.traceRowCount??null,message:error.message?short(error.message,160):null,valuesRedacted:true};
  });
  const mutations=commandRows.filter((item)=>mutationTypes.has(item.type));
  const launches=control.filter((item)=>(item.type==='launchWorkbenchFromTask'||item.type==='launchWorkbenchFromMdtodo')&&(item.phase==='completed'||item.phase==='failed')).map((item)=>{
    const detail=item.detail&&typeof item.detail==='object'?item.detail:{};
    const error=detail.error&&typeof detail.error==='object'?detail.error:{};
    return {ts:item.ts||null,phase:item.phase||null,commandId:item.commandId||null,status:detail.launchStatus??error.details?.launchStatus??null,sessionId:detail.sessionId??error.details?.sessionId??null,workbenchUrl:detail.workbenchUrl??error.details?.workbenchUrl??null,otelTraceId:detail.otelTraceId??error.details?.otelTraceId??null,chatObserved:detail.chatObserved??error.details?.chatObserved??null,chatStatus:detail.chatStatus??error.details?.chatStatus??null,chatTraceId:detail.chatTraceId??error.details?.chatTraceId??null,workbenchMessageCount:detail.workbenchSnapshot?.messageCount??error.details?.workbenchSnapshot?.messageCount??null,workbenchTraceRowCount:detail.workbenchSnapshot?.traceRowCount??error.details?.workbenchSnapshot?.traceRowCount??null,taskHash:detail.selectedTask?.hash??detail.projectBeforeClick?.selectedTaskRef?.hash??null,message:error.message?short(error.message,160):null,valuesRedacted:true};
  });
  const findings=Array.isArray(report.findings)?report.findings.filter((item)=>String(item?.id||item?.kind||'').match(/project-management|mdtodo|workbench-launch/u)).slice(0,20):[];
  const summary=report.projectManagement?.summary||{};
  const mdtodoSampleCount=projectSamples.filter((sample)=>sample.projectManagement?.pageKind==='project-management-mdtodo').length;
  const derived={enabled:summary.enabled===true||projectSamples.length>0,projectSampleCount:Math.max(Number(summary.projectSampleCount??0),projectSamples.length),mdtodoSampleCount:Math.max(Number(summary.mdtodoSampleCount??0),mdtodoSampleCount),latestPageKind:summary.latestPageKind??latestProject?.pageKind??null,latestPath:summary.latestPath??latest?.path??null,latestSeq:summary.latestSeq??latest?.seq??null,latestTs:summary.latestTs??latest?.ts??null,latestSourceCount:summary.latestSourceCount??latestProject?.sourceCount??null,latestFileCount:summary.latestFileCount??latestProject?.fileCount??null,latestTaskCount:summary.latestTaskCount??latestProject?.taskCount??null,latestSelectedTaskRefHash:summary.latestSelectedTaskRefHash??latestProject?.selectedTaskRef?.hash??null,latestSelectedTaskRefPreview:summary.latestSelectedTaskRefPreview??latestProject?.selectedTaskRef?.preview??null,latestSelectedFileLabelPreview:summary.latestSelectedFileLabelPreview??latestProject?.selectedFileLabel?.textPreview??null,latestSelectedFileLabelLooksDirect:summary.latestSelectedFileLabelLooksDirect??latestProject?.selectedFileLabelLooksDirect??null,selectedTaskBodyVisibleSamples:summary.selectedTaskBodyVisibleSamples??projectSamples.filter((sample)=>sample.projectManagement?.taskBodyVisible===true).length,reportLinkVisibleSamples:summary.reportLinkVisibleSamples??projectSamples.filter((sample)=>Number(sample.projectManagement?.reportLinkCount??0)>0).length,reportPreviewVisibleSamples:summary.reportPreviewVisibleSamples??projectSamples.filter((sample)=>sample.projectManagement?.reportPreviewVisible===true).length,reportFullscreenVisibleSamples:summary.reportFullscreenVisibleSamples??projectSamples.filter((sample)=>sample.projectManagement?.reportFullscreenVisible===true).length,severePaneGapSampleCount:summary.severePaneGapSampleCount??0,ignoredPaneGapSampleCount:summary.ignoredPaneGapSampleCount??0,projectCommandCount:commandRows.length,mutationCommandCount:mutations.length,mutationFailureCount:mutations.filter((item)=>item.phase==='failed').length,launchCommandCount:summary.launchCommandCount??launches.length,launchSuccessCount:summary.launchSuccessCount??launches.filter((item)=>Number(item.status)>=200&&Number(item.status)<300).length,launchFailureCount:summary.launchFailureCount??launches.filter((item)=>item.phase==='failed'||Number(item.status)>=400).length,launchNonEmptyCount:summary.launchNonEmptyCount??launches.filter((item)=>item.chatObserved===true&&(Number(item.workbenchMessageCount??0)>0||Number(item.workbenchTraceRowCount??0)>0)).length,launchEmptyCount:summary.launchEmptyCount??launches.filter((item)=>item.chatObserved!==true||(Number(item.workbenchMessageCount??0)===0&&Number(item.workbenchTraceRowCount??0)===0)).length,launchWithOtelTraceHeaderCount:summary.launchWithOtelTraceHeaderCount??launches.filter((item)=>item.otelTraceId).length,projectApiResponseCount:summary.projectApiResponseCount??null,projectApiFailureCount:summary.projectApiFailureCount??null,projectApiRequestFailedCount:summary.projectApiRequestFailedCount??null,projectApiSlowPathCount:summary.projectApiSlowPathCount??null,valuesRedacted:true};
  return {summary:derived,commands:commandRows.slice(-24),mutations:mutations.slice(-16),launches:launches.slice(-12),findings,sampleRows:projectSamples.slice(-12).map((sample)=>({seq:sample.seq??null,ts:sample.ts??null,pageRole:sample.pageRole??null,path:sample.path??null,pageKind:sample.projectManagement?.pageKind??null,sourceCount:sample.projectManagement?.sourceCount??null,fileCount:sample.projectManagement?.fileCount??null,taskCount:sample.projectManagement?.taskCount??null,selectedFileLabelPreview:sample.projectManagement?.selectedFileLabel?.textPreview??null,selectedFileLabelLooksDirect:sample.projectManagement?.selectedFileLabelLooksDirect??null,selectedTaskRefHash:sample.projectManagement?.selectedTaskRef?.hash??null,selectedTaskStatus:sample.projectManagement?.selectedTaskStatus??null,taskBodyVisible:sample.projectManagement?.taskBodyVisible===true,taskBodyBytes:sample.projectManagement?.taskBody?.textBytes??0,reportLinkCount:sample.projectManagement?.reportLinkCount??0,reportPreviewVisible:sample.projectManagement?.reportPreviewVisible===true,reportPreviewBytes:sample.projectManagement?.reportPreview?.textBytes??0,reportFullscreenVisible:sample.projectManagement?.reportFullscreenVisible===true,launchButtonEnabled:sample.projectManagement?.launchButtonEnabled===true,workbenchLinkCount:sample.projectManagement?.workbenchLinkCount??0,valuesRedacted:true})),valuesRedacted:true};
}
function targetNodeFromStateDir(){
  const parts=String(dir||'').split(/[\\\\/]+/u);
  const index=parts.lastIndexOf('web-observe');
  return index>=0&&parts[index+1]?parts[index+1]:null;
}
function perfFrameKey(frame){
  return {functionName:short(frame?.functionName||frame?.name||'(anonymous)',48),url:short(frame?.url||frame?.sourceURL||frame?.scriptUrl||'',72),sourceFile:short(frame?.sourceFile||'',48),sourceLine:frame?.sourceLine??null,sourceColumn:frame?.sourceColumn??null,sourceMapStatus:frame?.sourceMapStatus??null,scriptId:frame?.scriptId??null,lineNumber:frame?.lineNumber??frame?.line??null,columnNumber:frame?.columnNumber??frame?.column??null,valuesRedacted:true};
}
function compactProfileHotspot(item){
  return {functionName:short(item?.functionName||item?.name||'(anonymous)',64),url:short(item?.url||item?.sourceURL||item?.scriptUrl||'',88),sourceFile:short(item?.sourceFile||'',48),sourceLine:item?.sourceLine??null,sourceColumn:item?.sourceColumn??null,sourceMapStatus:item?.sourceMapStatus??null,scriptId:item?.scriptId??null,lineNumber:item?.lineNumber??item?.line??null,columnNumber:item?.columnNumber??item?.column??null,selfTimeMs:item?.selfTimeMs??item?.selfMs??null,totalTimeMs:item?.totalTimeMs??item?.totalMs??null,hitCount:item?.hitCount??item?.sampleCount??null,captureCount:item?.captureCount??null,valuesRedacted:true};
}
function compactProfileStack(item){
  const leaf=item?.leaf&&typeof item.leaf==='object'?item.leaf:null;
  const frames=Array.isArray(item?.frames)?item.frames.slice(0,3).map(perfFrameKey):[];
  return {functionName:short(item?.functionName||item?.name||leaf?.functionName||'(anonymous)',64),url:short(item?.url||item?.sourceURL||item?.scriptUrl||leaf?.url||'',88),sourceFile:short(item?.sourceFile||leaf?.sourceFile||'',48),sourceLine:item?.sourceLine??leaf?.sourceLine??null,sourceColumn:item?.sourceColumn??leaf?.sourceColumn??null,sourceMapStatus:item?.sourceMapStatus??leaf?.sourceMapStatus??null,scriptId:item?.scriptId??leaf?.scriptId??null,lineNumber:item?.lineNumber??item?.line??leaf?.lineNumber??null,columnNumber:item?.columnNumber??item?.column??leaf?.columnNumber??null,selfTimeMs:item?.selfTimeMs??item?.selfMs??null,totalTimeMs:item?.totalTimeMs??item?.totalMs??null,hitCount:item?.hitCount??item?.sampleCount??null,frameCount:Array.isArray(item?.frames)?item.frames.length:null,frames,framesOmitted:Math.max(0,(Array.isArray(item?.frames)?item.frames.length:0)-frames.length),valuesRedacted:true};
}
function compactScriptHotspot(item){
  return {sourceFunctionName:short(item?.sourceFunctionName||item?.functionName||item?.invoker||'(anonymous)',64),sourceURL:short(item?.sourceURL||item?.url||'',88),sourceFile:short(item?.sourceFile||'',48),sourceLine:item?.sourceLine??null,sourceColumn:item?.sourceColumn??null,sourceMapStatus:item?.sourceMapStatus??null,sourceCharPosition:item?.sourceCharPosition??null,lineNumber:item?.lineNumber??item?.line??null,columnNumber:item?.columnNumber??item?.column??null,totalDurationMs:item?.totalDurationMs??item?.durationMs??null,count:item?.count??item?.hitCount??null,invoker:short(item?.invoker||'',64),valuesRedacted:true};
}
function compactPerfEvent(item){
  return {ts:item?.ts??null,startAt:item?.startAt??null,endAt:item?.endAt??null,kind:item?.kind??null,durationMs:item?.durationMs??null,pageRole:item?.pageRole??null,pageId:item?.pageId??null,sampleSeq:item?.sampleSeq??item?.seq??null,scriptCount:item?.scriptCount??(Array.isArray(item?.scripts)?item.scripts.length:null),url:short(item?.url||item?.sourceURL||'',88),valuesRedacted:true};
}
function compactPerfCapture(item){
  return {ts:item?.ts??null,startAt:item?.startAt??null,endAt:item?.endAt??null,captureId:item?.captureId??null,commandId:item?.commandId??null,status:item?.status??null,durationMs:item?.durationMs??item?.profileDurationMs??null,sampleCount:item?.sampleCount??item?.profileSampleCount??item?.samples??null,nodeCount:item?.nodeCount??item?.nodes??null,profileTimelineStatus:item?.profileTimelineStatus??null,profileTimelineSampleCount:item?.profileTimelineSampleCount??null,profileTimelineTotalTimeMs:item?.profileTimelineTotalTimeMs??null,file:short(item?.file||item?.path||item?.relativePath||'',88),valuesRedacted:true};
}
function compactPerformanceWindow(item){
  const capture=item?.capture&&typeof item.capture==='object'?item.capture:null;
  const script=item?.topLoafScript&&typeof item.topLoafScript==='object'?item.topLoafScript:null;
  return {kind:item?.kind??null,ts:item?.ts??null,startAt:item?.startAt??null,endAt:item?.endAt??null,durationMs:item?.durationMs??null,blockingDurationMs:item?.blockingDurationMs??null,pageRole:item?.pageRole??null,pageId:item?.pageId??null,sampleSeq:item?.sampleSeq??null,cpuProfileCoverageStatus:item?.cpuProfileCoverageStatus??null,coverageReason:short(item?.coverageReason||'',90),capture:capture?{captureId:capture.captureId??null,commandId:capture.commandId??null,startAt:capture.startAt??null,endAt:capture.endAt??null,durationMs:capture.durationMs??null,windowDistanceMs:capture.windowDistanceMs??null,profileSampleCount:capture.profileSampleCount??null,profileTimelineStatus:capture.profileTimelineStatus??null,profileTimelineSampleCount:capture.profileTimelineSampleCount??null,valuesRedacted:true}:null,topLoafScript:script?compactScriptHotspot(script):null,relatedNetwork:Array.isArray(item?.relatedNetwork)?item.relatedNetwork.slice(0,1).map((row)=>({ts:row?.ts??null,sampleSeq:row?.sampleSeq??null,phase:row?.phase??null,method:row?.method??null,status:row?.status??null,urlPath:short(row?.urlPath||'',56),bodyByteCount:row?.bodyByteCount??null,traceId:short(row?.traceId||'',32),routeSessionId:short(row?.routeSessionId||'',32),valuesRedacted:true})):[],relatedSamples:Array.isArray(item?.relatedSamples)?item.relatedSamples.slice(0,1).map((row)=>({ts:row?.ts??null,sampleSeq:row?.sampleSeq??null,pageRole:row?.pageRole??null,path:short(row?.path||'',40),routeSessionId:short(row?.routeSessionId||'',32),activeSessionId:short(row?.activeSessionId||'',32),traceIds:Array.isArray(row?.traceIds)?row.traceIds.slice(0,1).map((id)=>short(id,32)):[],valuesRedacted:true})):[],profileEvidence:item?.profileEvidence?{evidenceScope:item.profileEvidence.evidenceScope??null,timelineStatus:item.profileEvidence.timelineStatus??null,sampleCount:item.profileEvidence.sampleCount??null,totalTimeMs:item.profileEvidence.totalTimeMs??null,note:short(item.profileEvidence.note||'',100),topFunctions:Array.isArray(item.profileEvidence.topFunctions)?item.profileEvidence.topFunctions.slice(0,1).map(compactProfileHotspot):[],topStacks:Array.isArray(item.profileEvidence.topStacks)?item.profileEvidence.topStacks.slice(0,1).map(compactProfileStack):[],valuesRedacted:true}:null,valuesRedacted:true};
}
function compactPerfFinding(item){
  return {severity:item?.severity??item?.level??null,id:short(item?.id||item?.kind||item?.code||'',56),count:item?.count??item?.sampleCount??null,rootCause:item?.rootCause??item?.rootCauseStatus??null,summary:short(item?.summary||item?.message||'',110),valuesRedacted:true};
}
function compactWebPerformanceDiagnosticGroup(item){
  return {diagnosticCode:short(item?.diagnosticCode||'',64),reason:short(item?.reason||'',48),module:short(item?.module||'',48),eventType:short(item?.eventType||'',48),count:item?.count??null,eventCount:item?.eventCount??null,deliveredCount:item?.deliveredCount??null,chunkCount:item?.chunkCount??null,droppedCount:item?.droppedCount??null,maxFlushDurationMs:item?.maxFlushDurationMs??null,maxItemsPerChunk:item?.maxItemsPerChunk??null,maxChunkMs:item?.maxChunkMs??null,replacedByKeyCount:item?.replacedByKeyCount??null,firstAt:item?.firstAt??null,lastAt:item?.lastAt??null,traceIds:Array.isArray(item?.traceIds)?item.traceIds.slice(0,2).map((id)=>short(id,32)):[],valuesRedacted:true};
}
function compactWebPerformancePayloadState(item){
  return {state:short(item?.state||'',48),count:item?.count??null,valuesRedacted:true};
}
function compactPerfCommand(row){
  return {bucket:row?.bucket||null,id:short(commandFileId(row)||'',40),type:short(commandFileType(row)||'',32),ts:short(commandFileTs(row)||'',32),ageSeconds:row?.data?.ageSeconds??null,relative:short(row?.relative||'',72),valuesRedacted:true};
}
function runnerStatusForPerformance(){
  const status=String(report?.heartbeat?.status||heartbeat?.status||report?.manifest?.status||manifest?.status||'').trim();
  const terminal=/^(completed|failed|force-stopped|stopped|abandoned)$/u.test(status);
  const failed=/^(failed|force-stopped|abandoned|not-running)$/u.test(status);
  return {status:status||null,terminal,notRunningOrFailed:failed,updatedAt:report?.heartbeat?.updatedAt||heartbeat?.updatedAt||heartbeat?.lastSampleAt||null,valuesRedacted:true};
}
function performanceCaptureCommandStatus(commandFiles){
  const rows=commandFiles.filter((row)=>commandFileType(row)==='performanceCapture');
  const byBucket=(bucket)=>rows.filter((row)=>row.bucket===bucket);
  return {
    total:rows.length,
    pendingCount:byBucket('pending').length,
    processingCount:byBucket('processing').length,
    doneCount:byBucket('done').length,
    failedCount:byBucket('failed').length,
    abandonedCount:byBucket('abandoned').length,
    pending:byBucket('pending').slice(0,6).map(compactPerfCommand),
    processing:byBucket('processing').slice(0,6).map(compactPerfCommand),
    failed:byBucket('failed').slice(-4).map(compactPerfCommand),
    done:byBucket('done').slice(-4).map(compactPerfCommand),
    valuesRedacted:true
  };
}
function performanceToolFindings(){
  const ids=new Set(['tool-pending-commands-unconsumed','tool-runner-heartbeat-stale','tool-target-page-not-ready','tool-runner-force-stopped','frontend-browser-freeze-runner-blocker','frontend-playwright-responsiveness-red','frontend-cdp-metrics-timeout-red','frontend-performance-probe-drain-errors','frontend-performance-loaf-only-no-cpu-profile']);
  return (Array.isArray(report.findings)?report.findings:[]).filter((item)=>ids.has(String(item?.id||item?.kind||item?.code||''))).slice(0,10).map(compactPerfFinding);
}
function performanceEvidenceMode(perf, commandFiles){
  const s=perf.summary||{};
  const captureCount=Number(s.captureCount??0);
  const hasCpuProfile=captureCount>0;
  const hasPerformanceObserverEvidence=
    Number(s.longTaskCount??0)>0||
    Number(s.longAnimationFrameCount??0)>0||
    Number(s.eventLoopGapCount??0)>0||
    Number(s.scriptHotspotCount??0)>0||
    (Array.isArray(perf.longTasks)&&perf.longTasks.length>0)||
    (Array.isArray(perf.longAnimationFrames)&&perf.longAnimationFrames.length>0)||
    (Array.isArray(perf.eventLoopGaps)&&perf.eventLoopGaps.length>0)||
    (Array.isArray(perf.scriptHotspots)&&perf.scriptHotspots.length>0);
  const commands=performanceCaptureCommandStatus(commandFiles);
  const runner=runnerStatusForPerformance();
  const pendingPerformanceCapture=commands.pendingCount>0||commands.processingCount>0;
  const coveredWindowCount=Number(s.cpuProfileWindowCoveredCount??0);
  const overlappedWindowCount=Number(s.cpuProfileWindowOverlappedCount??0);
  const missedWindowCount=Number(s.cpuProfileWindowMissedCount??0);
  const cpuProfileMissedPerformanceWindows=hasCpuProfile&&missedWindowCount>0&&coveredWindowCount===0&&overlappedWindowCount===0;
  const cpuProfileStatus=hasCpuProfile?String(s.cpuProfileStatus||'captured'):pendingPerformanceCapture?'pending-command-no-cpu-profile':'no-cpu-profile';
  const attributionMode=cpuProfileMissedPerformanceWindows?String(s.attributionMode||'cpu-profile-missed-performance-window'):hasCpuProfile?String(s.attributionMode||'cpu-profile-and-performance-observer'):hasPerformanceObserverEvidence?'loaf-only-no-cpu-profile':'no-frontend-performance-evidence';
  const statement=hasCpuProfile
    ? cpuProfileMissedPerformanceWindows
      ? 'CPU profile artifacts exist but missed severe performance windows; do not cite CPU profile hotspots as same-window evidence.'
      : missedWindowCount>0&&(coveredWindowCount>0||overlappedWindowCount>0)
        ? 'CPU profile artifacts overlap some severe performance windows; cite CPU hotspots as same-window evidence only for rows marked covered/overlapped.'
        : 'CPU profile artifacts are present; hotspot rows may be used as CPU profile evidence.'
    : pendingPerformanceCapture
      ? 'LoAF-only / no CPU profile: performanceCapture is pending or processing, so CPU profile hotspots are unavailable for this run.'
      : 'LoAF-only / no CPU profile: no completed performanceCapture artifact is present, so do not cite CPU profile hotspots.';
  return {attributionMode,cpuProfileStatus,hasCpuProfile,noCpuProfile:!hasCpuProfile,loafOnly:!hasCpuProfile&&hasPerformanceObserverEvidence,pendingPerformanceCapture,cpuProfileMissedPerformanceWindows,runner,performanceCaptureCommands:commands,statement,valuesRedacted:true};
}
function performanceWindowsForSummary(rows){
  const source=Array.isArray(rows)?rows:[];
  const selected=source.slice(0,3);
  const hasCovered=selected.some((item)=>item?.cpuProfileCoverageStatus==='covered'||item?.cpuProfileCoverageStatus==='overlapped');
  const covered=hasCovered?null:source.find((item)=>item?.cpuProfileCoverageStatus==='covered'||item?.cpuProfileCoverageStatus==='overlapped');
  if(covered){
    if(selected.length>=3) selected[2]=covered;
    else selected.push(covered);
  }
  return selected.map(compactPerformanceWindow);
}
function performanceSummaryFromReport(){
  const perf=report.frontendPerformance&&typeof report.frontendPerformance==='object'?report.frontendPerformance:{};
  const summary=perf.summary&&typeof perf.summary==='object'?perf.summary:{};
  const runtime=report.runtimeAlerts&&typeof report.runtimeAlerts==='object'?report.runtimeAlerts:{};
  const runtimeSummary=runtime.summary&&typeof runtime.summary==='object'?runtime.summary:{};
  const payloadStates=runtime.webPerformancePayloadStates&&typeof runtime.webPerformancePayloadStates==='object'?runtime.webPerformancePayloadStates:{};
  const findings=Array.isArray(report.findings)?report.findings.filter((item)=>String(item?.id||item?.kind||'').match(/^frontend-(?:long|event-loop|cpu-profile|performance)/u)).slice(0,6).map(compactPerfFinding):[];
  const captureRows=Array.isArray(perf.captures)?perf.captures:[];
  const commandFiles=readCommandFiles();
  const model={summary:{...summary, rawPerformanceRowCount:performanceRows.length, valuesRedacted:true},
    longTasks:Array.isArray(perf.longTasks)?perf.longTasks.slice(0,3).map(compactPerfEvent):[],
    longAnimationFrames:Array.isArray(perf.longAnimationFrames)?perf.longAnimationFrames.slice(0,3).map(compactPerfEvent):[],
    eventLoopGaps:Array.isArray(perf.eventLoopGaps)?perf.eventLoopGaps.slice(0,3).map(compactPerfEvent):[],
    performanceWindows:performanceWindowsForSummary(perf.performanceWindows),
    scriptHotspots:Array.isArray(perf.scriptHotspots)?perf.scriptHotspots.slice(0,4).map(compactScriptHotspot):[],
    profileHotspots:Array.isArray(perf.profileHotspots)?perf.profileHotspots.slice(0,4).map(compactProfileHotspot):[],
    profileStacks:Array.isArray(perf.profileStacks)?perf.profileStacks.slice(0,2).map(compactProfileStack):[],
    captures:captureRows.slice(-3).map(compactPerfCapture),
    sourceAttribution:perf.sourceAttribution&&typeof perf.sourceAttribution==='object'?{sourceMapStatus:perf.sourceAttribution.sourceMapStatus??null,note:short(perf.sourceAttribution.note||'',120),sourceFiles:Array.isArray(perf.sourceAttribution.sourceFiles)?perf.sourceAttribution.sourceFiles.slice(0,4):[],valuesRedacted:true}:null,
    webPerformanceRuntime:{summary:{payloadRequestCount:runtimeSummary.webPerformancePayloadRequestCount??0,payloadParsedCount:runtimeSummary.webPerformancePayloadParsedCount??0,payloadParseIssueCount:runtimeSummary.webPerformancePayloadParseIssueCount??0,runtimeDiagnosticCount:runtimeSummary.webPerformanceRuntimeDiagnosticCount??0,runtimeDiagnosticGroupCount:runtimeSummary.webPerformanceRuntimeDiagnosticGroupCount??0,capturedEventCount:payloadStates.capturedEventCount??0,storedEventCount:payloadStates.storedEventCount??0,valuesRedacted:true},states:Array.isArray(payloadStates.states)?payloadStates.states.slice(0,6).map(compactWebPerformancePayloadState):[],groups:Array.isArray(runtime.webPerformanceRuntimeDiagnosticsByCode)?runtime.webPerformanceRuntimeDiagnosticsByCode.slice(0,6).map(compactWebPerformanceDiagnosticGroup):[],valuesRedacted:true},
    findings,
    toolFindings:performanceToolFindings(),
    valuesRedacted:true
  };
  model.evidenceMode=performanceEvidenceMode(model,commandFiles);
  return {
    ...model
  };
}
function renderPerformanceSummary(perf){
  const s=perf.summary||{};
  const mode=perf.evidenceMode||{};
  const captureCommands=mode.performanceCaptureCommands||{};
  const runner=mode.runner||{};
  const lines=['WEB-PROBE frontend performance '+(manifest.jobId||'-'),'======================================================='];
  lines.push('events='+String(s.eventCount??0)+' rawRows='+String(s.rawPerformanceRowCount??0)+' longTask='+String(s.longTaskCount??0)+' loaf='+String(s.longAnimationFrameCount??0)+' eventLoopGap='+String(s.eventLoopGapCount??0)+' captures='+String(s.captureCount??0));
  lines.push('max longTask='+String(s.maxLongTaskMs??'-')+'ms budget='+String(s.longTaskRedMs??'-')+'ms; max LoAF='+String(s.maxLongAnimationFrameMs??'-')+'ms budget='+String(s.longAnimationFrameRedMs??'-')+'ms; max gap='+String(s.maxEventLoopGapMs??'-')+'ms budget='+String(s.eventLoopGapRedMs??'-')+'ms');
  lines.push('evidence attribution='+String(mode.attributionMode||s.attributionMode||'-')+' cpuProfile='+String(mode.cpuProfileStatus||s.cpuProfileStatus||'-')+' pendingPerformanceCapture='+String(captureCommands.pendingCount??0)+' processingPerformanceCapture='+String(captureCommands.processingCount??0)+' runner='+String(runner.status||'-')+' runnerNotRunningOrFailed='+String(runner.notRunningOrFailed===true));
  if(mode.statement) lines.push('status: '+mode.statement);
  if(mode.pendingPerformanceCapture===true){
    const pending=[...(captureCommands.pending||[]),...(captureCommands.processing||[])].slice(0,4).map((item)=>String(item.id||'-')+'('+String(item.bucket||'-')+')').join(', ');
    lines.push('pending performanceCapture: '+(pending||'-'));
  }
  if(runner.notRunningOrFailed===true) lines.push('runner state: not-running/failed for performance evidence; treat missing CPU profile as tool state, not as proof that no CPU hotspot exists.');
  lines.push('window correlation='+String(s.windowCorrelationCount??perf.performanceWindows.length??0)+' covered='+String(s.cpuProfileWindowCoveredCount??0)+' overlapped='+String(s.cpuProfileWindowOverlappedCount??0)+' missed='+String(s.cpuProfileWindowMissedCount??0)+' missing='+String(s.cpuProfileWindowMissingCount??0)+' sourceMap='+String(s.sourceMapStatus||perf.sourceAttribution?.sourceMapStatus||'-'));
  if(perf.sourceAttribution?.note) lines.push('source attribution: '+perf.sourceAttribution.note);
  lines.push('','CPU profile hotspots');
  if(perf.profileHotspots.length===0) lines.push(mode.noCpuProfile===true?'(no CPU profile hotspots; no completed performanceCapture artifact in this run)':'-');
  for(const item of perf.profileHotspots.slice(0,4)) lines.push(String(item.selfTimeMs??0)+'ms self '+short(item.functionName||'(anonymous)',40)+' '+short(item.sourceFile||item.url||item.scriptId||'-',70)+' sourceLine='+String(item.sourceLine??'-')+' rawLine='+String(item.lineNumber??'-')+' sourceMap='+String(item.sourceMapStatus||'-')+' captures='+String(item.captureCount??'-'));
  lines.push('','CPU profile stacks');
  if(perf.profileStacks.length===0) lines.push('-');
  for(const item of perf.profileStacks.slice(0,2)){
    const frames=Array.isArray(item.frames)?item.frames.slice(0,3).map((frame)=>short(frame.functionName||'(anonymous)',28)+'@'+short(frame.sourceFile||frame.url||frame.scriptId||'-',36)+':'+String(frame.sourceLine??frame.lineNumber??'-')).join(' <- '):'-';
    lines.push(String(item.selfTimeMs??0)+'ms self '+short(item.functionName||'(anonymous)',44)+' sourceLine='+String(item.sourceLine??'-')+' rawLine='+String(item.lineNumber??'-')+' frames='+frames+(item.framesOmitted?(' omitted='+String(item.framesOmitted)):''));
  }
  lines.push('','LoAF script hotspots');
  if(perf.scriptHotspots.length===0) lines.push('-');
  for(const item of perf.scriptHotspots.slice(0,4)) lines.push(String(item.totalDurationMs??0)+'ms total count='+String(item.count??0)+' '+short(item.sourceFunctionName||item.invoker||'(anonymous)',40)+' '+short(item.sourceFile||item.sourceURL||'-',70)+' sourceLine='+String(item.sourceLine??'-')+' rawLine='+String(item.lineNumber??'-')+' char='+String(item.sourceCharPosition??'-')+' sourceMap='+String(item.sourceMapStatus||'-'));
  const webPerf=perf.webPerformanceRuntime||{};
  const webPerfSummary=webPerf.summary||{};
  lines.push('','Web performance runtime diagnostics');
  lines.push('payloads='+String(webPerfSummary.payloadRequestCount??0)+' parsed='+String(webPerfSummary.payloadParsedCount??0)+' parseIssues='+String(webPerfSummary.payloadParseIssueCount??0)+' events='+String(webPerfSummary.runtimeDiagnosticCount??0)+' groups='+String(webPerfSummary.runtimeDiagnosticGroupCount??0));
  if(Array.isArray(webPerf.states)&&webPerf.states.length>0) lines.push('  payload states='+webPerf.states.map((item)=>String(item.state||'-')+':'+String(item.count??0)).join(', '));
  if(!Array.isArray(webPerf.groups)||webPerf.groups.length===0) lines.push('-');
  for(const item of (webPerf.groups||[]).slice(0,6)) lines.push(String(item.diagnosticCode||item.eventType||'-')+' reason='+String(item.reason||'-')+' module='+String(item.module||'-')+' count='+String(item.count??0)+' eventCount='+String(item.eventCount??'-')+' delivered='+String(item.deliveredCount??'-')+' chunks='+String(item.chunkCount??'-')+' flushMax='+String(item.maxFlushDurationMs??'-')+'ms dropped='+String(item.droppedCount??'-')+' maxItemsPerChunk='+String(item.maxItemsPerChunk??'-')+' maxChunkMs='+String(item.maxChunkMs??'-')+' replacedByKey='+String(item.replacedByKeyCount??'-'));
  lines.push('','Time-window correlation');
  if(!Array.isArray(perf.performanceWindows)||perf.performanceWindows.length===0) lines.push('-');
  for(const item of (perf.performanceWindows||[]).slice(0,3)){
    const capture=item.capture?String(item.capture.captureId||item.capture.commandId||'-')+' dist='+String(item.capture.windowDistanceMs??'-')+'ms':'-';
    const script=item.topLoafScript?short(item.topLoafScript.sourceFunctionName||item.topLoafScript.invoker||'(anonymous)',40)+'@'+short(item.topLoafScript.sourceFile||item.topLoafScript.sourceURL||'-',48)+':'+String(item.topLoafScript.sourceLine??item.topLoafScript.lineNumber??'-'):'-';
    const samples=(item.relatedSamples||[]).map((row)=>'#'+String(row.sampleSeq??'-')+' session='+String(row.activeSessionId||row.routeSessionId||'-')+' trace='+String((row.traceIds||[])[0]||'-')).join('; ');
    const network=(item.relatedNetwork||[]).map((row)=>String(row.status??'-')+' '+String(row.method||'-')+' '+short(row.urlPath||'-',44)+' bytes='+String(row.bodyByteCount??'-')).join('; ');
    lines.push(String(item.startAt||item.ts||'-')+' '+String(item.kind||'-')+' duration='+String(item.durationMs??'-')+'ms sample='+String(item.sampleSeq??'-')+' cpuWindow='+String(item.cpuProfileCoverageStatus||'-')+' capture='+capture);
    lines.push('  reason='+String(item.coverageReason||'-')+' script='+script);
    if(samples) lines.push('  samples='+samples);
    if(network) lines.push('  network='+network);
    if(item.profileEvidence?.topFunctions?.length>0){
      const scope=item.profileEvidence.timelineStatus==='window-samples'?'same-window topFunction':'cpu profile context topFunction';
      const suffix=item.profileEvidence.timelineStatus?(' timeline='+String(item.profileEvidence.timelineStatus)+' samples='+String(item.profileEvidence.sampleCount??'-')+' total='+String(item.profileEvidence.totalTimeMs??'-')+'ms'):'';
      lines.push('  '+scope+'='+item.profileEvidence.topFunctions.map((fn)=>String(fn.selfTimeMs??0)+'ms self '+String(fn.totalTimeMs??0)+'ms total '+short(fn.functionName||'(anonymous)',28)+'@'+short(fn.sourceFile||fn.url||'-',32)+' sourceMap='+String(fn.sourceMapStatus||'-')).join('; ')+suffix);
    }
    if(item.profileEvidence?.topStacks?.length>0){
      lines.push('  same-window topStack='+item.profileEvidence.topStacks.map((stack)=>String(stack.selfTimeMs??0)+'ms '+short(stack.functionName||stack.leaf?.functionName||'(anonymous)',28)+' frames='+String(stack.frameCount??'-')).join('; '));
    }
    if(item.profileEvidence?.note) lines.push('  cpu profile note='+item.profileEvidence.note);
  }
  lines.push('','Longest events');
  for(const item of [...perf.longTasks.slice(0,3),...perf.longAnimationFrames.slice(0,3),...perf.eventLoopGaps.slice(0,3)].sort((a,b)=>Number(b.durationMs??0)-Number(a.durationMs??0)).slice(0,6)) lines.push(String(item.ts||'-')+' '+String(item.kind||'-')+' duration='+String(item.durationMs??'-')+'ms role='+String(item.pageRole||'-')+' sample='+String(item.sampleSeq??'-')+' scripts='+String(item.scriptCount??0));
  lines.push('','Findings');
  if(perf.findings.length===0) lines.push('-');
  for(const item of perf.findings.slice(0,6)) lines.push(String(item.severity||'-')+': '+String(item.id||item.kind||'-')+' count='+String(item.count??'-')+' '+short(item.summary||item.message||'',120));
  lines.push('','Tool status');
  if(!Array.isArray(perf.toolFindings)||perf.toolFindings.length===0) lines.push('-');
  for(const item of (perf.toolFindings||[]).slice(0,6)) lines.push(String(item.severity||'-')+': '+String(item.id||'-')+' count='+String(item.count??'-')+' '+short(item.summary||'',120));
  lines.push('','NEXT','  capture: bun scripts/cli.ts web-probe observe command '+(manifest.jobId||'<observer>')+' --type performanceCapture --duration-ms 5000 --wait-ms 8000','  analyze:  bun scripts/cli.ts web-probe observe analyze '+(manifest.jobId||'<observer>'),'DISCLOSURE source=existing artifacts valuesRedacted=true; this view does not start browser/probe or mutate runtime.');
  return lines.join('\\n');
}
function renderProjectSummary(project){
  const s=project.summary||{};
  const lines=['Project MDTODO observer '+(manifest.jobId||'-'),'=======================================================','enabled='+String(s.enabled===true)+' samples='+String(s.projectSampleCount??0)+' mdtodo='+String(s.mdtodoSampleCount??0)+' latest='+String(s.latestPageKind||'-')+' path='+String(s.latestPath||'-'),'counts source='+String(s.latestSourceCount??'-')+' file='+String(s.latestFileCount??'-')+' task='+String(s.latestTaskCount??'-')+' selectedTask='+String(s.latestSelectedTaskRefHash||'-'),'fileLabel='+short(s.latestSelectedFileLabelPreview||'-',80)+' direct='+String(s.latestSelectedFileLabelLooksDirect??'-')+' bodyVisibleSamples='+String(s.selectedTaskBodyVisibleSamples??'-')+' reportPreviewSamples='+String(s.reportPreviewVisibleSamples??'-')+' reportFullscreenSamples='+String(s.reportFullscreenVisibleSamples??'-'),'paneGap actionable='+String(s.severePaneGapSampleCount??0)+' ignoredInitialEmptyDetail='+String(s.ignoredPaneGapSampleCount??0),'commands='+String(s.projectCommandCount??0)+' mutations='+String(s.mutationCommandCount??0)+' mutationFailures='+String(s.mutationFailureCount??0),'launch commands='+String(s.launchCommandCount??0)+' success='+String(s.launchSuccessCount??0)+' failure='+String(s.launchFailureCount??0)+' nonEmpty='+String(s.launchNonEmptyCount??'-')+' empty='+String(s.launchEmptyCount??'-')+' otelTraceHeader='+String(s.launchWithOtelTraceHeaderCount??0),'api responses='+String(s.projectApiResponseCount??'-')+' failures='+String(s.projectApiFailureCount??'-')+'/'+String(s.projectApiRequestFailedCount??'-')+' slowPaths='+String(s.projectApiSlowPathCount??'-'),'','Recent samples'];
  for(const row of project.sampleRows.slice(-12)) lines.push('#'+String(row.seq??'-')+' '+String(row.ts||'-')+' '+String(row.pageRole||'-')+' '+String(row.pageKind||'-')+' src='+String(row.sourceCount??'-')+' files='+String(row.fileCount??'-')+' tasks='+String(row.taskCount??'-')+' fileLabel='+short(row.selectedFileLabelPreview||'-',50)+' body='+String(row.taskBodyVisible===true)+' report='+String(row.reportPreviewVisible===true)+' fullscreen='+String(row.reportFullscreenVisible===true)+' selected='+String(row.selectedTaskRefHash||'-')+' launch='+String(row.launchButtonEnabled===true)+' links='+String(row.workbenchLinkCount??0));
  lines.push('','Launches');
  if(project.launches.length===0) lines.push('-');
  for(const item of project.launches.slice(-12)) lines.push(String(item.ts||'-')+' '+String(item.phase||'-')+' status='+String(item.status??'-')+' session='+String(item.sessionId||'-')+' chat='+String(item.chatObserved===true)+' chatStatus='+String(item.chatStatus??'-')+' msg='+String(item.workbenchMessageCount??'-')+' traceRows='+String(item.workbenchTraceRowCount??'-')+' otel='+String(item.otelTraceId||'-')+' task='+String(item.taskHash||'-'));
  lines.push('','MDTODO commands');
  if(project.commands.length===0) lines.push('-');
  for(const item of project.commands.slice(-24)) lines.push(String(item.ts||'-')+' '+String(item.phase||'-')+' '+String(item.type||'-')+' path='+String(item.afterPath||'-')+' task='+String(item.selectedTaskHash||'-')+' status='+String(item.status??'-')+(item.message?' message='+short(item.message,120):''));
  lines.push('','MDTODO mutations');
  if(project.mutations.length===0) lines.push('-');
  for(const item of project.mutations.slice(-16)) lines.push(String(item.ts||'-')+' '+String(item.phase||'-')+' '+String(item.type||'-')+' task='+String(item.selectedTaskHash||'-')+' status='+String(item.status??'-')+(item.message?' message='+short(item.message,120):''));
  const otelLaunches=project.launches.filter((item)=>item.otelTraceId).slice(-4);
  if(otelLaunches.length>0){
    const target=targetNodeFromStateDir()||'<target>';
    lines.push('','OTel trace drill-down');
    for(const item of otelLaunches) lines.push('bun scripts/cli.ts platform-infra observability trace --target '+target+' --trace-id '+String(item.otelTraceId));
  }
  lines.push('','Findings');
  if(project.findings.length===0) lines.push('-');
  for(const item of project.findings.slice(0,12)) lines.push(String(item.severity||'-')+': '+String(item.id||item.kind||'-')+' count='+String(item.count??'-')+' '+short(item.summary||item.message||'',140));
  return lines.join('\\n');
}
const rows=turnSummaryRows();
const turnSelection=selectTurnSummaryRows(rows);
if(view==='performance-summary'){
  const perf=performanceSummaryFromReport();
  console.log(JSON.stringify({ok:true,command:'web-probe-observe collect',view,stateDir:dir,summary:perf.summary,evidenceMode:perf.evidenceMode,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,renderedText:renderPerformanceSummary(perf),sourceFiles:['performance-events.jsonl','network.jsonl','samples.jsonl','artifacts.jsonl','analysis/report.json','commands/pending/*.json','commands/processing/*.json','heartbeat.json','manifest.json'],drillDown:'bun scripts/cli.ts web-probe observe collect '+String(manifest.jobId||'<observer>')+' --view files --file analysis/report.json',valuesRedacted:true}));
  process.exit(0);
}
if(view==='project-summary'||view==='project-mdtodo-summary'){
  const project=projectSummaryFromSamples();
  const projectSummary={...project.summary,latestSelectedTaskRefPreview:short(project.summary?.latestSelectedTaskRefPreview,80)};
  const projectSampleRows=project.sampleRows.slice(-4).map((item)=>({seq:item.seq??null,ts:short(item.ts,24),pageRole:short(item.pageRole,18),path:short(item.path,36),pageKind:short(item.pageKind,28),sourceCount:item.sourceCount??null,fileCount:item.fileCount??null,taskCount:item.taskCount??null,selectedFileLabelPreview:short(item.selectedFileLabelPreview,80),selectedFileLabelLooksDirect:item.selectedFileLabelLooksDirect??null,selectedTaskRefHash:short(item.selectedTaskRefHash,24),selectedTaskStatus:short(item.selectedTaskStatus,20),taskBodyVisible:item.taskBodyVisible===true,taskBodyBytes:item.taskBodyBytes??0,reportLinkCount:item.reportLinkCount??0,reportPreviewVisible:item.reportPreviewVisible===true,reportPreviewBytes:item.reportPreviewBytes??0,reportFullscreenVisible:item.reportFullscreenVisible===true,launchButtonEnabled:item.launchButtonEnabled===true,workbenchLinkCount:item.workbenchLinkCount??0,valuesRedacted:true}));
  const compactCommand=(item)=>({ts:short(item.ts,24),phase:item.phase??null,type:short(item.type,28),commandId:short(item.commandId,24),afterPath:short(item.afterPath,36),selectedTaskHash:short(item.selectedTaskHash,24),status:item.status??null,message:item.message?short(item.message,80):null,valuesRedacted:true});
  const projectCommands=project.commands.slice(-14).map(compactCommand);
  const projectMutations=project.mutations.slice(-10).map(compactCommand);
  const projectLaunches=project.launches.slice(-4).map((item)=>({ts:short(item.ts,24),phase:item.phase??null,commandId:short(item.commandId,24),status:item.status??null,sessionId:short(item.sessionId,28),workbenchUrl:short(item.workbenchUrl,52),otelTraceId:short(item.otelTraceId,28),chatObserved:item.chatObserved??null,chatStatus:item.chatStatus??null,chatTraceId:short(item.chatTraceId,28),workbenchMessageCount:item.workbenchMessageCount??null,workbenchTraceRowCount:item.workbenchTraceRowCount??null,taskHash:short(item.taskHash,24),message:item.message?short(item.message,80):null,valuesRedacted:true}));
  const projectFindings=project.findings.slice(0,4).map((item)=>({severity:item.severity??item.level??null,id:short(item.id??item.kind??item.code,48),count:item.count??item.sampleCount??null,summary:short(item.summary??item.message,96),valuesRedacted:true}));
  console.log(JSON.stringify({ok:true,command:'web-probe-observe collect',view,stateDir:dir,summary:projectSummary,sampleRowCount:project.sampleRows.length,commandCount:project.commands.length,mutationCount:project.mutations.length,launchCount:project.launches.length,findingCount:project.findings.length,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,skippedFiles:skippedFiles.slice(0,20),sampleRows:projectSampleRows,commands:projectCommands,mutations:projectMutations,launches:projectLaunches,findings:projectFindings,sourceFiles:['samples.jsonl','control.jsonl','analysis/report.json'],valuesRedacted:true}));
  process.exit(0);
}
if(view==='turn-summary'){
  console.log(JSON.stringify({ok:turnSelection.ok,command:'web-probe-observe collect',view,status:turnSelection.status,stateDir:dir,turnCount:turnSelection.rows.length,availableTurnCount:rows.length,filter:turnSelection.filter,error:turnSelection.error,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,skippedFiles:skippedFiles.slice(0,20),rows:turnSelection.rows.slice(0,80),renderedText:renderTurnSummary(turnSelection.rows,turnSelection),sourceFiles:['samples.jsonl','control.jsonl','analysis/report.json'],valuesRedacted:true},null,2));
  process.exit(0);
}
if(view==='timeline'){
  const timeline=timelineView(rows);
  console.log(JSON.stringify({ok:true,command:'web-probe-observe collect',view,stateDir:dir,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,skippedFiles:skippedFiles.slice(0,20),...timeline,sourceFiles:['samples.jsonl','control.jsonl','commands/pending/*.json','commands/processing/*.json','commands/done/*.json','commands/failed/*.json','commands/abandoned/*.json'],valuesRedacted:true}));
  process.exit(0);
}
if(view==='workbench-triad'){
  const triad=workbenchTriadView(rows);
  console.log(JSON.stringify({ok:true,command:'web-probe-observe collect',view,stateDir:dir,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,skippedFiles:skippedFiles.slice(0,8),traceId:triad.traceId,dom:triad.dom,networkEvidence:triad.networkEvidence,evidenceReconciliation:triad.evidenceReconciliation,freeze:triad.freeze,recoveryAuthority:triad.recoveryAuthority,findings:triad.findings,statusGap:triad.statusGap,renderedText:triad.renderedText,sourceFiles:['samples.jsonl','network.jsonl','browser-process.jsonl','control.jsonl','analysis/report.json'],valuesRedacted:true}));
  process.exit(0);
}
const frame=renderTraceFrame(selectSample(rows),rows);
console.log(JSON.stringify({ok:frame.ok!==false,command:'web-probe-observe collect',view,stateDir:dir,artifactFileCount:files.length,skippedFileCount:skippedFiles.length,skippedFiles:skippedFiles.slice(0,20),...frame,sourceFiles:['samples.jsonl','control.jsonl','analysis/report.json'],valuesRedacted:true},null,2));
`)} "$state_dir"`;
}
