awaitly-visualizer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/index.browser.cjs +1677 -0
  2. package/dist/index.browser.cjs.map +1 -0
  3. package/dist/index.browser.d.cts +166 -0
  4. package/dist/index.browser.d.ts +166 -0
  5. package/dist/index.browser.js +1677 -0
  6. package/dist/index.browser.js.map +1 -0
  7. package/dist/index.cjs +1680 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.cts +242 -0
  10. package/dist/index.d.ts +242 -0
  11. package/dist/index.js +1680 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/kroki/fetch.cjs +3 -0
  14. package/dist/kroki/fetch.cjs.map +1 -0
  15. package/dist/kroki/fetch.d.cts +86 -0
  16. package/dist/kroki/fetch.d.ts +86 -0
  17. package/dist/kroki/fetch.js +3 -0
  18. package/dist/kroki/fetch.js.map +1 -0
  19. package/dist/notifiers/discord.cjs +3 -0
  20. package/dist/notifiers/discord.cjs.map +1 -0
  21. package/dist/notifiers/discord.d.cts +70 -0
  22. package/dist/notifiers/discord.d.ts +70 -0
  23. package/dist/notifiers/discord.js +3 -0
  24. package/dist/notifiers/discord.js.map +1 -0
  25. package/dist/notifiers/slack.cjs +38 -0
  26. package/dist/notifiers/slack.cjs.map +1 -0
  27. package/dist/notifiers/slack.d.cts +95 -0
  28. package/dist/notifiers/slack.d.ts +95 -0
  29. package/dist/notifiers/slack.js +38 -0
  30. package/dist/notifiers/slack.js.map +1 -0
  31. package/dist/notifiers/webhook.cjs +3 -0
  32. package/dist/notifiers/webhook.cjs.map +1 -0
  33. package/dist/notifiers/webhook.d.cts +115 -0
  34. package/dist/notifiers/webhook.d.ts +115 -0
  35. package/dist/notifiers/webhook.js +3 -0
  36. package/dist/notifiers/webhook.js.map +1 -0
  37. package/dist/performance-analyzer-B5VF5b1F.d.ts +663 -0
  38. package/dist/performance-analyzer-BNwE4AiO.d.cts +663 -0
  39. package/dist/types-BIZSmXif.d.ts +350 -0
  40. package/dist/types-BnWc9Wlr.d.cts +350 -0
  41. package/dist/url-PkfQz4V5.d.cts +750 -0
  42. package/dist/url-PkfQz4V5.d.ts +750 -0
  43. package/package.json +105 -0
@@ -0,0 +1,1677 @@
1
+ function B(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1).replace(/\.0$/,"")}s`;let t=Math.floor(e/6e4),r=Math.round(e%6e4/1e3);return r>=60&&(t+=1,r=0),r===0?`${t}m`:`${t}m ${r}s`}function ke(){return`node_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function Rt(e){for(let t of e)if((t.type==="parallel"||t.type==="race"||t.type==="sequence")&&!t.id.startsWith("detected_")||t.type==="decision")return!0;return!1}function ve(e,t={}){if(Rt(e))return e;let{minOverlapMs:r=0,maxGapMs:o=5}=t,i=[],n=[];for(let c=0;c<e.length;c++){let l=e[c];l.type==="step"&&l.startTs!==void 0?i.push({node:l,startTs:l.startTs,endTs:l.endTs??l.startTs+(l.durationMs??0),originalIndex:c}):n.push({node:l,originalIndex:c})}if(i.length<=1)return e;i.sort((c,l)=>c.startTs-l.startTs);let a=[],s=[i[0]];for(let c=1;c<i.length;c++){let l=i[c],p=Math.min(...s.map($=>$.startTs)),g=Math.max(...s.map($=>$.endTs)),f=l.startTs<=p+o,y=l.startTs<g;if(!f&&!y){a.push(s),s=[l];continue}let k=y?Math.min(l.endTs,g)-l.startTs:0;f||k>=r?s.push(l):(a.push(s),s=[l])}a.push(s);let u=[];for(let c of a){let l=Math.min(...c.map(p=>p.originalIndex));if(c.length===1)u.push({node:c[0].node,position:l});else{let p=c.map(k=>k.node),g=Math.min(...c.map(k=>k.startTs)),f=Math.max(...c.map(k=>k.endTs)),y={type:"parallel",id:`detected_parallel_${g}`,name:`${p.length} parallel steps`,state:It(p),mode:"all",children:p,startTs:g,endTs:f,durationMs:f-g};u.push({node:y,position:l})}}for(let{node:c,originalIndex:l}of n)u.push({node:c,position:l});return u.sort((c,l)=>c.position-l.position),u.map(c=>c.node)}function It(e){return e.some(n=>n.state==="error")?"error":e.some(n=>n.state==="running")?"running":e.some(n=>n.state==="pending")?"pending":(e.every(n=>n.state==="success"||n.state==="cached"),"success")}function $t(e={}){return{detect:t=>ve(t,e)}}function he(e={}){let{detectParallel:t=!0,parallelDetection:r,enableSnapshots:o=!1,maxSnapshots:i=1e3}=e,n=o,a=ke(),s,u,c,l="pending",p,g,f=new Map,y=[],k=[],$=new Map,M=[],N=Date.now(),I=N,v={onAfterStep:new Map},x,m=[],w=0;function R(d){return d.stepId??d.stepKey??d.name??ke()}function D(d){if(y.length>0){y[y.length-1].children.push(d),I=Date.now();return}if(k.length>0){let b=k[k.length-1];for(let h of b.branches.values())if(h.taken){h.children.push(d),I=Date.now();return}b.pendingChildren.push(d),I=Date.now();return}M.push(d),I=Date.now()}function E(d){if(!n)return;let b=ne(),h=new Map;for(let[C,Y]of f)h.set(C,{id:Y.id,name:Y.name,key:Y.key,startTs:Y.startTs,retryCount:Y.retryCount,timedOut:Y.timedOut,timeoutMs:Y.timeoutMs});let A={id:`snapshot_${w}`,eventIndex:w,event:structuredClone(d),ir:structuredClone(b),timestamp:Date.now(),activeSteps:h};m.push(A),m.length>i&&m.shift(),w++}function T(d){switch(d.type){case"workflow_start":{M=[],c=void 0,g=void 0,p=void 0,f.clear(),y.length=0,k.length=0,$.clear(),s=d.workflowId,u=d.ts,l="running",N=Date.now(),I=N,x!==void 0&&x!==d.workflowId&&(v.shouldRun=void 0,v.onBeforeStart=void 0),x=d.workflowId,v.onAfterStep=new Map;break}case"workflow_success":l="success",c=d.ts,g=d.durationMs,I=Date.now();break;case"workflow_error":l="error",c=d.ts,p=d.error,g=d.durationMs,I=Date.now();break;case"workflow_cancelled":l="aborted",c=d.ts,g=d.durationMs,I=Date.now();break;case"step_start":{let b=R(d);f.set(b,{id:b,name:d.name,key:d.stepKey,startTs:d.ts,retryCount:0,timedOut:!1}),I=Date.now();break}case"step_success":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"success",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_error":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"error",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,error:d.error,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_aborted":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"aborted",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_cache_hit":{let h={type:"step",id:R(d),name:d.name,key:d.stepKey,state:"cached",startTs:d.ts,endTs:d.ts,durationMs:0};D(h);break}case"step_cache_miss":break;case"step_complete":break;case"step_timeout":{let b=R(d),h=f.get(b);h&&(h.timedOut=!0,h.timeoutMs=d.timeoutMs),I=Date.now();break}case"step_retry":{let b=R(d),h=f.get(b);h&&(h.retryCount=(d.attempt??1)-1),I=Date.now();break}case"step_retries_exhausted":I=Date.now();break;case"step_skipped":{let h={type:"step",id:R(d),name:d.name,key:d.stepKey,state:"skipped",startTs:d.ts,endTs:d.ts,durationMs:0};D(h);break}case"hook_should_run":{let b={type:"shouldRun",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.shouldRun=b,x=d.workflowId,I=Date.now();break}case"hook_should_run_error":{let b={type:"shouldRun",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.shouldRun=b,x=d.workflowId,I=Date.now();break}case"hook_before_start":{let b={type:"onBeforeStart",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.onBeforeStart=b,x=d.workflowId,I=Date.now();break}case"hook_before_start_error":{let b={type:"onBeforeStart",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.onBeforeStart=b,x=d.workflowId,I=Date.now();break}case"hook_after_step":{let b={type:"onAfterStep",state:"success",ts:d.ts,durationMs:d.durationMs,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,b),I=Date.now();break}case"hook_after_step_error":{let b={type:"onAfterStep",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,b),I=Date.now();break}case"stream_created":{let b=`${d.workflowId}:${d.namespace}`;$.set(b,{id:ke(),namespace:d.namespace,startTs:d.ts,writeCount:0,readCount:0,streamState:"active",backpressureOccurred:!1,finalPosition:0}),I=Date.now();break}case"stream_write":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&(h.writeCount++,h.finalPosition=Math.max(h.finalPosition,d.position)),I=Date.now();break}case"stream_read":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&h.readCount++,I=Date.now();break}case"stream_close":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);if(h){h.streamState="closed",h.finalPosition=d.finalPosition;let A={type:"stream",id:h.id,namespace:h.namespace,state:"success",startTs:h.startTs,endTs:d.ts,durationMs:d.ts-h.startTs,writeCount:h.writeCount,readCount:h.readCount,finalPosition:d.finalPosition,streamState:"closed",backpressureOccurred:h.backpressureOccurred};D(A),$.delete(b)}I=Date.now();break}case"stream_error":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);if(h){h.streamState="error";let A={type:"stream",id:h.id,namespace:h.namespace,state:"error",error:d.error,startTs:h.startTs,endTs:d.ts,durationMs:d.ts-h.startTs,writeCount:h.writeCount,readCount:h.readCount,finalPosition:d.position,streamState:"error",backpressureOccurred:h.backpressureOccurred};D(A),$.delete(b)}I=Date.now();break}case"stream_backpressure":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&(h.backpressureOccurred=!0),I=Date.now();break}}E(d)}function P(d){if(d.type==="scope_start")y.push({id:d.scopeId,name:d.name,type:d.scopeType,startTs:d.ts,children:[]}),I=Date.now();else if(d.type==="scope_end"){let b=y.findIndex(C=>C.id===d.scopeId);if(b===-1)return;for(;y.length>b+1;){let C=y.pop(),Y=C.type==="race"?{type:"race",id:C.id,name:C.name,state:_(C.children),startTs:C.startTs,endTs:d.ts,children:C.children}:{type:"parallel",id:C.id,name:C.name,state:_(C.children),startTs:C.startTs,endTs:d.ts,children:C.children,mode:C.type==="allSettled"?"allSettled":"all"};y[y.length-1].children.push(Y)}let[h]=y.splice(b,1),A=h.type==="race"?{type:"race",id:h.id,name:h.name,state:_(h.children),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,children:h.children,winnerId:d.winnerId}:{type:"parallel",id:h.id,name:h.name,state:_(h.children),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,children:h.children,mode:h.type==="allSettled"?"allSettled":"all"};D(A)}}function U(d){if(d.type==="decision_start")k.push({id:d.decisionId,name:d.name,condition:d.condition,decisionValue:d.decisionValue,startTs:d.ts,branches:new Map,pendingChildren:[]}),I=Date.now();else if(d.type==="decision_branch"){let b=k.find(h=>h.id===d.decisionId);if(b){let h=d.branchLabel,A=b.branches.get(h);if(A)A.taken=d.taken,d.taken&&b.pendingChildren.length>0&&(A.children.unshift(...b.pendingChildren),b.pendingChildren=[]);else{let C=d.taken?[...b.pendingChildren]:[];d.taken&&(b.pendingChildren=[]),b.branches.set(h,{label:d.branchLabel,condition:d.condition,taken:d.taken,children:C})}I=Date.now()}}else if(d.type==="decision_end"){let b=k.findIndex(h=>h.id===d.decisionId);if(b!==-1){let[h]=k.splice(b,1),A=k.splice(b),C=Array.from(h.branches.values());C.length===0&&h.pendingChildren.length>0&&(C=[{label:"default",taken:!0,children:[...h.pendingChildren]}]);let Y=C.find(ye=>ye.taken)?.label,St={type:"decision",id:h.id,name:h.name,state:_(C.flatMap(ye=>ye.taken?ye.children:[])),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,condition:h.condition,decisionValue:h.decisionValue,branchTaken:d.branchTaken??Y,branches:C};D(St),k.push(...A),I=Date.now()}}}function _(d){return d.length===0?"success":d.some(C=>C.state==="error")?"error":d.every(C=>C.state==="success"||C.state==="cached")?"success":d.some(C=>C.state==="running")?"running":"pending"}function re(){let d=[...M];for(let[,b]of f)d.push({type:"step",id:b.id,name:b.name,key:b.key,state:"running",startTs:b.startTs,...b.retryCount>0&&{retryCount:b.retryCount},...b.timedOut&&{timedOut:!0,timeoutMs:b.timeoutMs}});for(let[,b]of $)d.push({type:"stream",id:b.id,namespace:b.namespace,state:"running",startTs:b.startTs,writeCount:b.writeCount,readCount:b.readCount,finalPosition:b.finalPosition,streamState:b.streamState,backpressureOccurred:b.backpressureOccurred});return d}function ne(){let d=re();t&&(d=ve(d,r));let b={type:"workflow",id:s??a,workflowId:s??a,state:l,startTs:u,endTs:c,durationMs:g,children:d,error:p},h=v.shouldRun!==void 0||v.onBeforeStart!==void 0||v.onAfterStep.size>0;return{root:b,metadata:{createdAt:N,lastUpdatedAt:I},...h&&{hooks:v}}}function oe(){s=void 0,u=void 0,c=void 0,l="pending",p=void 0,g=void 0,f.clear(),y.length=0,k.length=0,$.clear(),M=[],N=Date.now(),I=N,v={onAfterStep:new Map},x=void 0,m.length=0,w=0}function yt(){return[...m]}function kt(d){return m[d]}function vt(d){return m[d]?.ir}function xt(){m.length=0,w=0}return{handleEvent:T,handleScopeEvent:P,handleDecisionEvent:U,getIR:ne,reset:oe,getSnapshots:yt,getSnapshotAt:kt,getIRAt:vt,clearSnapshots:xt,get hasActiveSteps(){return f.size>0},get state(){return l},get snapshotCount(){return m.length},get snapshotsEnabled(){return n},setSnapshotsEnabled(d){n=d}}}import{ok as Lt,err as _t}from"awaitly";function K(e){return e.type==="step"}function Ge(e){return e.type==="sequence"}function j(e){return e.type==="parallel"}function F(e){return e.type==="race"}function J(e){return e.type==="decision"}function ee(e){return e.type==="stream"}function an(e){return"children"in e||e.type==="decision"&&"branches"in e}var Le="\x1B[0m",Et="\x1B[1m",Je="\x1B[2m",Nt="\x1B[31m",Mt="\x1B[32m",Tt="\x1B[33m",Ot="\x1B[34m",Ye="\x1B[90m",Dt="\x1B[37m";function X(e,t){return t?`${t}${e}${Le}`:e}function ge(e){return`${Et}${e}${Le}`}function O(e){return`${Je}${e}${Le}`}var V={pending:Dt,running:Tt,success:Mt,error:Nt,aborted:Ye,cached:Ot,skipped:Je+Ye};function Ct(e){switch(e){case"pending":return"\u25CB";case"running":return"\u27F3";case"success":return"\u2713";case"error":return"\u2717";case"aborted":return"\u2298";case"cached":return"\u21BA";case"skipped":return"\u2298"}}function we(e,t){let r=Ct(e);return X(r,t[e])}function xe(e,t,r){return X(e,r[t])}function Q(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}var S={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeRight:"\u251C",teeLeft:"\u2524",teeDown:"\u252C",teeUp:"\u2534",cross:"\u253C"},de={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},Wt="\x1B[0m";function Bt(e){return e<.2?de.cold:e<.4?de.cool:e<.6?de.neutral:e<.8?de.warm:e<.95?de.hot:de.critical}function Xe(e,t){let r=Bt(t);return r?`${r}${e}${Wt}`:e}function At(e){try{return Lt(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return _t("STRINGIFY_ERROR")}}function qe(e){let t=At(e);return t.ok?t.value:"[unserializable]"}var Ze="\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";function We(e,t=10){if(e.length===0)return"";let r=e.slice(-t),o=Math.min(...r),n=Math.max(...r)-o||1;return r.map(a=>{let s=(a-o)/n,u=Math.floor(s*(Ze.length-1));return Ze[u]}).join("")}function _e(e,t){let r=Q(e).length,o=Math.max(0,t-r);return e+" ".repeat(o)}function Pt(e,t){if(!t)return S.horizontal.repeat(e);let r=` ${t} `,o=Q(r).length,i=e-o;if(i<4)return S.horizontal.repeat(e);let n=2,a=i-n;return S.horizontal.repeat(n)+r+S.horizontal.repeat(a)}function Qe(e,t,r){let o=e.state==="success"?X("\u2699",r.success):X("\u26A0",r.error),i=e.durationMs!==void 0?O(` [${B(e.durationMs)}]`):"",n="";e.type==="shouldRun"&&e.context?.skipped?n=O(" \u2192 workflow skipped"):e.type==="shouldRun"&&e.context?.result===!0?n=O(" \u2192 proceed"):e.type==="onBeforeStart"&&e.context?.skipped?n=O(" \u2192 workflow skipped"):e.type==="onAfterStep"&&e.context?.stepKey&&(n=O(` (${e.context.stepKey})`));let a=e.state==="error"&&e.error?O(` error: ${String(e.error)}`):"";return`${o} ${O(t)}${n}${i}${a}`}function Ht(e,t){let r=[];return e.shouldRun&&r.push(Qe(e.shouldRun,"shouldRun",t)),e.onBeforeStart&&r.push(Qe(e.onBeforeStart,"onBeforeStart",t)),r.length>0&&r.push(O("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),r}function le(){return{name:"ascii",supportsLive:!0,render(e,t){let r={...V,...t.colors},o=Math.max(t.terminalWidth??60,5),i=o-4,n=[],a=e.root.name??"workflow",s=ge(a);if(n.push(`${S.topLeft}${Pt(o-2,s)}${S.topRight}`),n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`),e.hooks){let c=Ht(e.hooks,r);for(let l of c)n.push(`${S.vertical} ${_e(l,i)}${S.vertical}`)}let u=Se(e.root.children,t,r,0,e.hooks);for(let c of u)n.push(`${S.vertical} ${_e(c,i)}${S.vertical}`);if(n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`),e.root.durationMs!==void 0&&t.showTimings){let c=e.root.state==="success"?"Completed":e.root.state==="aborted"?"Cancelled":"Failed",p=`${xe(c,e.root.state,r)} in ${B(e.root.durationMs)}`;n.push(`${S.vertical} ${_e(p,i)}${S.vertical}`),n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`)}return n.push(`${S.bottomLeft}${S.horizontal.repeat(o-2)}${S.bottomRight}`),n.join(`
2
+ `)}}}function Se(e,t,r,o,i){let n=[];for(let a of e)K(a)?n.push(Be(a,t,r,i)):j(a)?n.push(...zt(a,t,r,o,i)):F(a)?n.push(...Ut(a,t,r,o,i)):J(a)?n.push(...Kt(a,t,r,o,i)):ee(a)&&n.push(Ft(a,t,r));return n}function Be(e,t,r,o){let i=we(e.state,r),n=e.name??e.key??"step",a=t,s=a.showHeatmap&&a.heatmapData?a.heatmapData.heat.get(e.key??"")??a.heatmapData.heat.get(e.name??"")??a.heatmapData.heat.get(e.id):void 0,u;s!==void 0?u=Xe(n,s):u=xe(n,e.state,r);let c=`${i} ${u}`;if(t.showKeys&&e.key&&e.name&&(c+=O(` [key: ${e.key}]`)),e.input!==void 0){let p=typeof e.input=="string"?e.input:qe(e.input).slice(0,30);c+=O(` [in: ${p}${p.length>=30?"...":""}]`)}if(e.output!==void 0&&e.state==="success"){let p=typeof e.output=="string"?e.output:qe(e.output).slice(0,30);c+=O(` [out: ${p}${p.length>=30?"...":""}]`)}if(t.showTimings&&e.durationMs!==void 0){let p=B(e.durationMs),g=s!==void 0?Xe(`[${p}]`,s):O(`[${p}]`);c+=` ${g}`}if(a.showSparklines&&a.timingHistory){let p=a.timingHistory.get(e.key??"")??a.timingHistory.get(e.name??"")??a.timingHistory.get(e.id);p&&p.length>1&&(c+=` ${O(We(p))}`)}if(e.retryCount!==void 0&&e.retryCount>0&&(c+=O(` [${e.retryCount} ${e.retryCount===1?"retry":"retries"}]`)),e.timedOut){let p=e.timeoutMs!==void 0?` ${e.timeoutMs}ms`:"";c+=O(` [timeout${p}]`)}let l=e.key??e.id;if(o&&l&&o.onAfterStep.has(l)){let p=o.onAfterStep.get(l),g=p.state==="success"?X("\u2699",r.success):X("\u26A0",r.error),f=p.durationMs!==void 0?O(` ${B(p.durationMs)}`):"";c+=` ${g}${f}`}return c}function Ft(e,t,r){let o=e.streamState==="active"?X("\u27F3",r.running):e.streamState==="closed"?X("\u2713",r.success):X("\u2717",r.error),i=`stream:${e.namespace}`,n=xe(i,e.state,r),a=O(`[W:${e.writeCount} R:${e.readCount}]`),s=`${o} ${n} ${a}`;return t.showTimings&&e.durationMs!==void 0&&(s+=` ${O(`[${B(e.durationMs)}]`)}`),e.backpressureOccurred&&(s+=O(" [backpressure]")),e.streamState==="closed"&&(s+=O(` pos:${e.finalPosition}`)),s}function zt(e,t,r,o,i){let n=[],a=" ".repeat(o),s=we(e.state,r),u=e.name??"parallel",c=e.mode==="allSettled"?" (allSettled)":"";if(n.push(`${a}${S.teeRight}${S.teeDown}${S.horizontal} ${s} ${ge(u)}${c}`),e.children.length===0)n.push(`${a}${S.vertical} ${O("(operations not individually tracked)")}`),n.push(`${a}${S.vertical} ${O("(wrap each operation with step() to see individual steps)")}`);else for(let l=0;l<e.children.length;l++){let p=e.children[l],f=l===e.children.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`;if(K(p))n.push(`${f} ${Be(p,t,r,i)}`);else{let y=Se([p],t,r,o+1,i);for(let k of y)n.push(`${a}${S.vertical} ${k}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}function Ut(e,t,r,o,i){let n=[],a=" ".repeat(o),s=we(e.state,r),u=e.name??"race";if(n.push(`${a}${S.teeRight}\u26A1 ${s} ${ge(u)}`),e.children.length===0)n.push(`${a}${S.vertical} ${O("(operations not individually tracked)")}`),n.push(`${a}${S.vertical} ${O("(wrap each operation with step() to see individual steps)")}`);else for(let c=0;c<e.children.length;c++){let l=e.children[c],g=c===e.children.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`,y=e.winnerId&&l.id===e.winnerId?O(" (winner)"):"";if(K(l))n.push(`${g} ${Be(l,t,r,i)}${y}`);else{let k=Se([l],t,r,o+1,i);for(let $ of k)n.push(`${a}${S.vertical} ${$}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}function Kt(e,t,r,o,i){let n=[],a=" ".repeat(o),s=we(e.state,r),u=e.name??"decision",c=e.condition?O(` (${e.condition})`):"",l=e.decisionValue!==void 0?O(` = ${String(e.decisionValue)}`):"",p=e.branchTaken!==void 0?O(` \u2192 ${String(e.branchTaken)}`):"";n.push(`${a}${S.teeRight}${S.teeDown}${S.horizontal} ${s} ${ge(u)}${c}${l}${p}`);for(let g=0;g<e.branches.length;g++){let f=e.branches[g],k=g===e.branches.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`,$=f.taken?"\u2713":"\u2298",M=f.taken?r.success:r.skipped,N=X(`${$} ${f.label}`,M),I=f.condition?O(` (${f.condition})`):"";if(n.push(`${k} ${N}${I}`),f.children.length>0){let v=Se(f.children,t,r,o+1,i);for(let x of v)n.push(`${a}${S.vertical} ${x}`)}else f.taken||n.push(`${a}${S.vertical} ${O("(skipped)")}`)}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}import{ok as Vt,err as Gt}from"awaitly";function Ae(e){let t=[];for(let r of e)if(t.push(r),"children"in r&&Array.isArray(r.children)&&t.push(...Ae(r.children)),"branches"in r)for(let o of r.branches)t.push(...Ae(o.children));return t}function Re(e,t){if(e.length===0)return 0;let r=Math.floor(e.length*t);return e[Math.min(r,e.length-1)]}function be(e){return e<.2?"cold":e<.4?"cool":e<.6?"neutral":e<.8?"warm":e<.95?"hot":"critical"}function jt(){let e=new Map,t=new Map,r=new Map,o=new Map,i=[];function n(v){return v.stepKey??v.stepId??v.name??"unknown"}function a(v){let x=new Map;for(let m of v)switch(m.type){case"step_start":{let w=n(m);x.set(w,{retried:!1,timedOut:!1});break}case"step_retry":{let w=n(m),R=x.get(w);R&&(R.retried=!0);break}case"step_timeout":{let w=n(m),R=x.get(w);R&&(R.timedOut=!0);break}case"step_success":{let w=n(m),R=x.get(w),D=e.get(w)??[];D.push(m.durationMs),e.set(w,D);let E=t.get(w)??{retried:0,total:0};E.total++,R?.retried&&E.retried++,t.set(w,E);let T=o.get(w)??{timedOut:0,total:0};T.total++,R?.timedOut&&T.timedOut++,o.set(w,T);let P=r.get(w)??{errors:0,total:0};P.total++,r.set(w,P),x.delete(w);break}case"step_error":{let w=n(m),R=x.get(w),D=e.get(w)??[];D.push(m.durationMs),e.set(w,D);let E=t.get(w)??{retried:0,total:0};E.total++,R?.retried&&E.retried++,t.set(w,E);let T=o.get(w)??{timedOut:0,total:0};T.total++,R?.timedOut&&T.timedOut++,o.set(w,T);let P=r.get(w)??{errors:0,total:0};P.total++,P.errors++,r.set(w,P),x.delete(w);break}}}function s(v){a(v.events)}function u(v){i.push(v)}function c(v){i.length>0&&(a(i),i=[])}function l(v){let x=e.get(v);if(!x||x.length===0)return;let m=[...x].sort((U,_)=>U-_),R=m.reduce((U,_)=>U+_,0)/m.length,D=m.reduce((U,_)=>U+(_-R)**2,0)/m.length,E=t.get(v)??{retried:0,total:1},T=r.get(v)??{errors:0,total:1},P=o.get(v)??{timedOut:0,total:1};return{nodeId:v,avgDurationMs:R,minDurationMs:m[0],maxDurationMs:m[m.length-1],stdDevMs:Math.sqrt(D),samples:m.length,retryRate:E.total>0?E.retried/E.total:0,timeoutRate:P.total>0?P.timedOut/P.total:0,errorRate:T.total>0?T.errors/T.total:0,percentiles:{p50:Re(m,.5),p90:Re(m,.9),p95:Re(m,.95),p99:Re(m,.99)}}}function p(v){return l(v)}function g(v,x="duration"){let m=new Map,w=Ae(v.root.children),R=[];for(let _ of w){let re=("key"in _?_.key:void 0)??_.id??_.name,ne=l(re);if(ne){let oe;switch(x){case"duration":oe=ne.avgDurationMs;break;case"retryRate":oe=ne.retryRate;break;case"errorRate":oe=ne.errorRate;break}R.push({id:_.id,value:oe})}}if(R.length===0)return{heat:m,metric:x,stats:{min:0,max:0,mean:0,threshold:0}};let D=R.map(_=>_.value),E=Math.min(...D),T=Math.max(...D),P=D.reduce((_,re)=>_+re,0)/D.length,U=T-E||1;for(let{id:_,value:re}of R)m.set(_,(re-E)/U);return{heat:m,metric:x,stats:{min:E,max:T,mean:P,threshold:P+(T-P)*.5}}}function f(){let v=new Map;for(let x of e.keys()){let m=l(x);m&&v.set(x,m)}return v}function y(v=10){return[...f().values()].sort((m,w)=>w.avgDurationMs-m.avgDurationMs).slice(0,v)}function k(v=10){return[...f().values()].filter(m=>m.errorRate>0).sort((m,w)=>w.errorRate-m.errorRate).slice(0,v)}function $(v=10){return[...f().values()].filter(m=>m.retryRate>0).sort((m,w)=>w.retryRate-m.retryRate).slice(0,v)}function M(){return JSON.stringify({timingData:Object.fromEntries(e),retryData:Object.fromEntries(t),errorData:Object.fromEntries(r),timeoutData:Object.fromEntries(o)})}function N(v){let x=JSON.parse(v);e.clear(),t.clear(),r.clear(),o.clear();for(let[m,w]of Object.entries(x.timingData??{}))e.set(m,w);for(let[m,w]of Object.entries(x.retryData??{}))t.set(m,w);for(let[m,w]of Object.entries(x.errorData??{}))r.set(m,w);for(let[m,w]of Object.entries(x.timeoutData??{}))o.set(m,w)}function I(){e.clear(),t.clear(),r.clear(),o.clear(),i=[]}return{addRun:s,addEvent:u,finalizeRun:c,getNodePerformance:p,getHeatmap:g,getSlowestNodes:y,getErrorProneNodes:k,getRetryProneNodes:$,getAllPerformance:f,exportData:M,importData:N,clear:I}}function Yt(){return[" classDef pending fill:#f3f4f6,stroke:#9ca3af,stroke-width:2px,color:#374151"," classDef running fill:#fef3c7,stroke:#f59e0b,stroke-width:3px,color:#92400e"," classDef success fill:#d1fae5,stroke:#10b981,stroke-width:3px,color:#065f46"," classDef error fill:#fee2e2,stroke:#ef4444,stroke-width:3px,color:#991b1b"," classDef aborted fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#4b5563,stroke-dasharray: 5 5"," classDef cached fill:#dbeafe,stroke:#3b82f6,stroke-width:3px,color:#1e40af"," classDef skipped fill:#f9fafb,stroke:#d1d5db,stroke-width:2px,color:#6b7280,stroke-dasharray: 5 5"," classDef stream fill:#ede9fe,stroke:#8b5cf6,stroke-width:3px,color:#5b21b6"," classDef streamActive fill:#ddd6fe,stroke:#7c3aed,stroke-width:3px,color:#4c1d95"," classDef streamError fill:#fce7f3,stroke:#db2777,stroke-width:3px,color:#9d174d"]}function Jt(){return[" classDef heat_cold fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af"," classDef heat_cool fill:#ccfbf1,stroke:#14b8a6,stroke-width:2px,color:#0f766e"," classDef heat_neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#374151"," classDef heat_warm fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e"," classDef heat_hot fill:#fed7aa,stroke:#f97316,stroke-width:3px,color:#c2410c"," classDef heat_critical fill:#fecaca,stroke:#ef4444,stroke-width:3px,color:#b91c1c"]}function Xt(e){return`heat_${e}`}function qt(){return[" classDef hook_success fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e"," classDef hook_error fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d"]}function Zt(e){try{return Vt(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return Gt("STRINGIFY_ERROR")}}function et(e){let t=Zt(e);return t.ok?t.value:"[unserializable]"}function Qt(e,t,r){let o;if(e.shouldRun){let i="hook_shouldRun",n=e.shouldRun.state==="success"?"hook_success":"hook_error",a=e.shouldRun.state==="success"?"\u2699":"\u26A0",s=r.showTimings&&e.shouldRun.durationMs!==void 0?` ${B(e.shouldRun.durationMs)}`:"",u=e.shouldRun.context?.skipped?"\\nskipped workflow":e.shouldRun.context?.result===!0?"\\nproceed":"";t.push(` ${i}[["${a} shouldRun${u}${s}"]]:::${n}`),o=i}if(e.onBeforeStart){let i="hook_beforeStart",n=e.onBeforeStart.state==="success"?"hook_success":"hook_error",a=e.onBeforeStart.state==="success"?"\u2699":"\u26A0",s=r.showTimings&&e.onBeforeStart.durationMs!==void 0?` ${B(e.onBeforeStart.durationMs)}`:"",u=e.onBeforeStart.context?.skipped?"\\nskipped workflow":"";t.push(` ${i}[["${a} onBeforeStart${u}${s}"]]:::${n}`),o&&t.push(` ${o} --> ${i}`),o=i}return{lastHookId:o}}var tt=0,Ie=new Set,$e=new Set;function ue(e="node"){return`${e}_${++tt}`}function er(){tt=0,Ie.clear(),$e.clear()}function z(e){return e.replace(/"/g,"#quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;").trim()}function rt(e){return z(e).replace(/[{}[\]()]/g,"")}function ie(){return{name:"mermaid",supportsLive:!1,render(e,t){er();let r=[],o=t;r.push("flowchart TD");let i;e.hooks&&(i=Qt(e.hooks,r,t).lastHookId);let n="start";r.push(` ${n}(("\u25B6 Start"))`),i&&r.push(` ${i} --> ${n}`);let a=n;for(let u of e.root.children){let c=Ee(u,t,r,o,e.hooks);r.push(` ${a} --> ${c.entryId}`),a=c.exitId}if(["success","error","aborted"].includes(e.root.state)){let u="finish",c=e.root.state==="success"?"\u2713":e.root.state==="error"?"\u2717":"\u2298",l=e.root.state==="success"?"Done":e.root.state==="error"?"Failed":"Cancelled",p=`(("${c} ${l}"))`,g=e.root.state==="success"?":::success":e.root.state==="error"?":::error":":::aborted";r.push(` ${u}${p}${g}`),r.push(` ${a} --> ${u}`)}return r.push(""),r.push(...Yt()),o.showHeatmap&&r.push(...Jt()),e.hooks&&r.push(...qt()),r.join(`
3
+ `)}}}function Ee(e,t,r,o,i){if(K(e))return tr(e,t,r,o,i);if(j(e))return rr(e,t,r,o,i);if(F(e))return nr(e,t,r,o,i);if(J(e))return or(e,t,r,o,i);if(ee(e))return ir(e,t,r);let n=ue("unknown");return r.push(` ${n}["Unknown Node"]`),{entryId:n,exitId:n}}function tr(e,t,r,o,i){let n=t,a=n.showRetryEdges??!0,s=n.showErrorEdges??!0,u=n.showTimeoutEdges??!0,c=e.key?`step_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:ue("step");if($e.has(c)){let m=2;for(;$e.has(`${c}_${m}`);)m++;c=`${c}_${m}`}$e.add(c);let l=e.name??e.key??"Step",p=t.showKeys&&e.key&&e.name?`${l} [${e.key}]`:l,g=z(p),f=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"",y="";switch(e.state){case"success":y="\u2713 ";break;case"error":y="\u2717 ";break;case"cached":y="\u{1F4BE} ";break;case"running":y="\u23F3 ";break;case"skipped":y="\u2298 ";break}let k="";if(e.input!==void 0){let m=typeof e.input=="string"?z(e.input):z(et(e.input).slice(0,20));k+=`\\nin: ${m}`}if(e.output!==void 0&&e.state==="success"){let m=typeof e.output=="string"?z(e.output):z(et(e.output).slice(0,20));k+=`\\nout: ${m}`}let $="",M=e.key??e.id;if(i&&M&&i.onAfterStep.has(M)){let m=i.onAfterStep.get(M),w=m.state==="success"?"\u2699":"\u26A0",R=t.showTimings&&m.durationMs!==void 0?` ${B(m.durationMs)}`:"";$=`\\n${w} hook${R}`}let N=(y+g+k+$+f).trim(),I,v=o?.showHeatmap&&o.heatmapData?o.heatmapData.heat.get(e.key??"")??o.heatmapData.heat.get(e.name??"")??o.heatmapData.heat.get(e.id):void 0;if(v!==void 0){let m=be(v);I=Xt(m)}else I=e.state;let x;switch(e.state){case"error":x=`{{"${N}"}}`;break;case"cached":x=`[("${N}")]`;break;case"skipped":x=`["${N}"]`;break;default:x=`["${N}"]`}if(r.push(` ${c}${x}:::${I}`),a&&e.retryCount!==void 0&&e.retryCount>0){let m=`\u21BB ${e.retryCount} retr${e.retryCount===1?"y":"ies"}`;r.push(` ${c} -.->|"${m}"| ${c}`)}if(s&&e.state==="error"&&e.error!==void 0){let m=`ERR_${c}`,w=z(String(e.error)).slice(0,30);r.push(` ${m}{{"${w}"}}`),r.push(` ${c} -->|error| ${m}`),r.push(` style ${m} fill:#fee2e2,stroke:#dc2626`)}if(u&&e.timedOut){let m=`TO_${c}`,w=e.timeoutMs!==void 0?`${e.timeoutMs}ms`:"";r.push(` ${m}{{"\u23F1 Timeout ${w}"}}`),r.push(` ${c} -.->|timeout| ${m}`),r.push(` style ${m} fill:#fef3c7,stroke:#f59e0b`)}return{entryId:c,exitId:c}}function rr(e,t,r,o,i){let n=ue("parallel"),a=`${n}_fork`,s=`${n}_join`,u=rt(e.name??"Parallel"),c=e.mode==="allSettled"?" (allSettled)":"";if(e.children.length===0){let g=n,f=z(`${u}${c}`),y="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"";return r.push(` ${g}["${f}${k}\\n${y}"]:::${e.state}`),{entryId:g,exitId:g}}r.push(` subgraph ${n}["${u}${c}"]`),r.push(" direction TB"),r.push(` ${a}{"\u26A1 Fork"}`);let l=[];for(let g of e.children){let f=Ee(g,t,r,o,i);r.push(` ${a} --> ${f.entryId}`),l.push(f.exitId)}r.push(` ${s}{"\u2713 Join"}`);for(let g of l)r.push(` ${g} --> ${s}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:a,exitId:s}}function nr(e,t,r,o,i){let n=ue("race"),a=`${n}_start`,s=`${n}_end`,u=rt(e.name??"Race");if(e.children.length===0){let g=n,f=z(u),y="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"";return r.push(` ${g}["\u26A1 ${f}${k}\\n${y}"]:::${e.state}`),{entryId:g,exitId:g}}r.push(` subgraph ${n}["\u26A1 ${u}"]`),r.push(" direction TB"),r.push(` ${a}(("\u{1F3C1} Start"))`);let c=[],l;for(let g of e.children){let f=Ee(g,t,r,o,i),y=e.winnerId===g.id;r.push(` ${a} --> ${f.entryId}`),y&&(l=f.exitId),c.push({exitId:f.exitId,isWinner:y})}r.push(` ${s}(("\u2713 First"))`);for(let{exitId:g,isWinner:f}of c)f&&l?r.push(` ${g} ==>|\u{1F3C6} Winner| ${s}`):e.winnerId?r.push(` ${g} -. cancelled .-> ${s}`):r.push(` ${g} --> ${s}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:a,exitId:s}}function or(e,t,r,o,i){let n=e.key?`decision_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:ue("decision");if(Ie.has(n)){let g=2;for(;Ie.has(`${n}_${g}`);)g++;n=`${n}_${g}`}Ie.add(n);let a=z(e.condition??"condition"),s=e.decisionValue!==void 0?` = ${z(String(e.decisionValue)).slice(0,30)}`:"",u=`${a}${s}`.trim();r.push(` ${n}{"${u}"}`);let c=[],l,p=new Set;for(let g of e.branches){let f=`${n}_${g.label.replace(/[^a-zA-Z0-9]/g,"_")}`;if(p.has(f)){let N=2;for(;p.has(`${f}_${N}`);)N++;f=`${f}_${N}`}p.add(f);let y=z(g.label),k=g.taken?`${y} \u2713`:`${y} skipped`,$=g.taken?":::success":":::skipped";r.push(` ${f}["${k}"]${$}`);let M=g.condition?`|${z(g.condition).replace(/\|/g,"")}|`:"";if(r.push(` ${n} -->${M} ${f}`),g.children.length>0){let N=f;for(let I of g.children){let v=Ee(I,t,r,o,i);r.push(` ${N} --> ${v.entryId}`),N=v.exitId}c.push(N),g.taken&&(l=N)}else c.push(f),g.taken&&(l=f)}return l?{entryId:n,exitId:l}:{entryId:n,exitId:n}}function ir(e,t,r){let o=`stream_${e.namespace.replace(/[^a-zA-Z0-9]/g,"_")}_${ue("")}`,i=`W:${e.writeCount} R:${e.readCount}`,n="";switch(e.streamState){case"active":n="\u27F3 ";break;case"closed":n="\u2713 ";break;case"error":n="\u2717 ";break}let a=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"",s=e.backpressureOccurred?"\\nbackpressure":"",u=`${n}stream:${z(e.namespace)}\\n${i}${s}${a}`,c;return e.streamState==="error"?c="streamError":e.streamState==="active"?c="streamActive":c="stream",r.push(` ${o}{{"${u}"}}:::${c}`),{entryId:o,exitId:o}}var L={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeDown:"\u252C",teeUp:"\u2534",teeRight:"\u251C",teeLeft:"\u2524",cross:"\u253C",arrowDown:"\u25BC",arrowUp:"\u25B2"},ar={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},sr="\x1B[0m";function cr(e,t){let r=[],o=[];for(let i=0;i<t;i++)r.push(Array(e).fill(" ")),o.push(Array(e).fill(void 0));return{cells:r,colors:o,width:e,height:t}}function W(e,t,r,o,i){t>=0&&t<e.width&&r>=0&&r<e.height&&(e.cells[r][t]=o,i&&(e.colors[r][t]=i))}function it(e,t,r){return t>=0&&t<e.width&&r>=0&&r<e.height?e.cells[r][t]:" "}function dr(e,t,r,o,i){W(e,t,r,L.topLeft);for(let n=1;n<o-1;n++)W(e,t+n,r,L.horizontal);W(e,t+o-1,r,L.topRight);for(let n=1;n<i-1;n++)W(e,t,r+n,L.vertical),W(e,t+o-1,r+n,L.vertical);W(e,t,r+i-1,L.bottomLeft);for(let n=1;n<o-1;n++)W(e,t+n,r+i-1,L.horizontal);W(e,t+o-1,r+i-1,L.bottomRight)}function nt(e,t,r,o,i){let n=Q(o).split("");for(let a=0;a<n.length;a++)W(e,t+a,r,n[a],i)}function te(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let a=i;a<=n;a++){let s=it(e,t,a);s===L.horizontal?W(e,t,a,L.cross):(s===" "||s===L.vertical)&&W(e,t,a,L.vertical)}}function ot(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let a=i;a<=n;a++){let s=it(e,a,t);s===L.vertical?W(e,a,t,L.cross):(s===" "||s===L.horizontal)&&W(e,a,t,L.horizontal)}}function se(e,t,r){W(e,t,r,L.arrowDown)}function lr(e){let t=[];for(let r=0;r<e.height;r++){let o="";for(let i=0;i<e.width;i++){let n=e.colors[r][i],a=e.cells[r][i];n?o+=n+a+sr:o+=a}t.push(o.trimEnd())}for(;t.length>0&&t[t.length-1]==="";)t.pop();return t.join(`
4
+ `)}var q=11,Z=2,pe=2,Ne=3;function He(e,t){if(e.length<=t)return[e];let r=e.split(" "),o=[],i="";for(let n of r)i?i.length+1+n.length<=t?i+=" "+n:(o.push(i),i=n):i=n;if(i&&o.push(i),o.length===0)for(let n=0;n<e.length;n+=t)o.push(e.slice(n,n+t));return o}function at(e){switch(e){case"success":return"\u2713";case"error":return"\u2717";case"running":return"\u27F3";case"pending":return"\u25CB";case"aborted":case"skipped":return"\u2298";case"cached":return"\u21BA";default:return"\u25CB"}}function ur(e,t,r){let o=t.showStartEnd??!0,i=t,n=Math.floor(r/2),a=[],s=0;if(o){let c=Me("start","start",["\u25B6 Start"],"success",n,s);a.push(c),s=c.bottomY+pe}for(let c of e.root.children){let l=Te(c,n,s,r-4,t,i);a.push(l.node),s=l.bottomY+pe}if(o&&["success","error","aborted"].includes(e.root.state)){let c=e.root.state==="success"?"\u2713 Done":e.root.state==="error"?"\u2717 Failed":"\u2298 Cancelled",l=Me("end","end",[c],e.root.state,n,s);a.push(l),s=l.bottomY}return{nodes:a,totalHeight:s+2}}function Me(e,t,r,o,i,n){let a=Math.max(...r.map(l=>Q(l).length)),s=Math.max(q,a+Z*2),u=r.length+2,c=i-Math.floor(s/2);return{id:e,type:t,label:r,state:o,x:c,y:n,width:s,height:u,centerX:i,bottomY:n+u-1}}function Te(e,t,r,o,i,n){if(K(e))return pr(e,t,r,o,i,n);if(j(e)||F(e))return mr(e,t,r,o,i,n);if(J(e))return hr(e,t,r,o,i,n);if(ee(e))return fr(e,t,r,o,i,n);let a=Me(e.id,"step",["?"],e.state,t,r);return{node:a,bottomY:a.bottomY}}function pr(e,t,r,o,i,n){let a=e.name??e.key??"step",s=at(e.state),u=[],c=`${s} ${a}`;i.showKeys&&e.key&&e.name&&(c+=` [${e.key}]`);let l=Math.min(o-Z*2,40);if(u.push(...He(c,l)),i.showTimings&&e.durationMs!==void 0&&u.push(`[${B(e.durationMs)}]`),e.retryCount&&e.retryCount>0&&u.push(`${e.retryCount}x retry`),e.timedOut&&u.push("timeout"),n?.showSparklines&&n.timingHistory){let M=n.timingHistory.get(e.key??"")??n.timingHistory.get(e.name??"")??n.timingHistory.get(e.id);M&&M.length>1&&u.push(We(M,8))}let p=Math.max(...u.map(M=>Q(M).length)),g=Math.max(q,p+Z*2),f=u.length+2,y=t-Math.floor(g/2),k;if(n?.showHeatmap&&n.heatmapData){let M=e.key??e.name??e.id;k=n.heatmapData.heat.get(e.id)??n.heatmapData.heat.get(M)}let $={id:e.id,type:"step",label:u,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1,metadata:k!==void 0?{heat:k}:void 0};return{node:$,bottomY:$.bottomY}}function fr(e,t,r,o,i,n){let a=`stream:${e.namespace}`,s=e.streamState==="active"?"\u27F3":e.streamState==="closed"?"\u2713":"\u2717",u=[],c=`${s} ${a}`,l=Math.min(o-Z*2,40);u.push(...He(c,l)),u.push(`W:${e.writeCount} R:${e.readCount}`),i.showTimings&&e.durationMs!==void 0&&u.push(`[${B(e.durationMs)}]`),e.backpressureOccurred&&u.push("backpressure");let p=Math.max(...u.map($=>Q($).length)),g=Math.max(q,p+Z*2),f=u.length+2,y=t-Math.floor(g/2),k={id:e.id,type:"stream",label:u,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1,metadata:{streamState:e.streamState,backpressureOccurred:e.backpressureOccurred}};return{node:k,bottomY:k.bottomY}}function mr(e,t,r,o,i,n){let a=F(e),s=e.name??(a?"race":"parallel"),c=`${a?"\u26A1":"\u2AD8"} ${s}`;if(e.children.length===0){let w=[c,"(not tracked)"],R=Me(e.id,a?"race":"parallel",w,e.state,t,r);return{node:R,bottomY:R.bottomY}}let l=Math.floor((o-Ne*(e.children.length-1))/e.children.length),p=[];for(let w of e.children){let R=Pe(w,Math.max(l,q),i,n);p.push(R.width)}let g=p.reduce((w,R)=>w+R,0)+Ne*(e.children.length-1),f=g>o&&e.children.length>1,y=Math.max(q,c.length+Z*2),k=3,$=t-Math.floor(y/2),M=r;M+=k,M+=1,M+=1;let N=[];if(f)for(let w=0;w<e.children.length;w++){let R=e.children[w],D=Te(R,t,M,o,i,n);a&&F(e)&&e.winnerId===R.id&&(D.node.metadata={...D.node.metadata,isWinner:!0}),N.push(D.node),M=D.bottomY+pe}else{let w=t-Math.floor(g/2);for(let R=0;R<e.children.length;R++){let D=e.children[R],E=w+Math.floor(p[R]/2),T=Te(D,E,M,p[R],i,n);a&&F(e)&&e.winnerId===D.id&&(T.node.metadata={...T.node.metadata,isWinner:!0}),N.push(T.node),w+=p[R]+Ne}}let I=Math.max(...N.map(w=>w.bottomY)),x=!f&&N.length>1?I+2:I;return{node:{id:e.id,type:a?"race":"parallel",label:[c],state:e.state,x:$,y:r,width:y,height:k,centerX:t,bottomY:x,children:N,metadata:{verticalLayout:f}},bottomY:x}}function hr(e,t,r,o,i,n){let a=e.name??"decision",s=e.condition?` (${e.condition.slice(0,20)})`:"",u=`\u25C7 ${a}${s}`,c=Math.min(o-Z*2,40),l=He(u,c),p=Math.max(...l.map(x=>Q(x).length)),g=Math.max(q,p+Z*2),f=l.length+2,y=t-Math.floor(g/2),k=e.branches.find(x=>x.taken),$=k&&k.children.length>0?k:e.branches.find(x=>x.children.length>0);if(!$||$.children.length===0){let x={id:e.id,type:"decision",label:l,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1};return{node:x,bottomY:x.bottomY}}let M=r+f+pe,N=[];for(let x of $.children){let m=Te(x,t,M,o,i,n);N.push(m.node),M=m.bottomY+pe}let I=N.length>0?N[N.length-1].bottomY:r+f-1;return{node:{id:e.id,type:"decision",label:l,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:I,children:N},bottomY:I}}function Pe(e,t,r,o){if(K(e)){let i=e.name??e.key??"step",n=at(e.state),a=1;r.showTimings&&e.durationMs!==void 0&&a++,e.retryCount&&e.retryCount>0&&a++,e.timedOut&&a++,o?.showSparklines&&(o.timingHistory?.has(e.key??"")||o.timingHistory?.has(e.name??"")||o.timingHistory?.has(e.id))&&a++;let s=`${n} ${i}`;r.showKeys&&e.key&&e.name&&(s+=` [${e.key}]`);let u=Math.min(t,Math.max(q,s.length+Z*2)),c=a+2;return{width:u,height:c}}if(j(e)||F(e)){if(e.children.length===0)return{width:q+4,height:4};let i=Math.floor(t/e.children.length),n=0,a=0;for(let s of e.children){let u=Pe(s,i,r,o);n+=u.width,a=Math.max(a,u.height)}return n+=Ne*(e.children.length-1),{width:Math.max(n,q),height:5+a+2}}if(J(e)){let i=e.branches.find(a=>a.taken),n=0;if(i)for(let a of i.children){let s=Pe(a,t,r,o);n+=s.height+pe}return{width:Math.min(t,30),height:3+n}}if(ee(e)){let i=`stream:${e.namespace}`,n=2;r.showTimings&&e.durationMs!==void 0&&n++,e.backpressureOccurred&&n++;let a=Math.min(t,Math.max(q,i.length+Z*2+4)),s=n+2;return{width:a,height:s}}return{width:q,height:3}}function gr(e,t,r){let o={...V,...r.colors};for(let i=0;i<t.length;i++){let n=t[i],a=i===t.length-1;if(Oe(e,n,o),!a){let s=t[i+1],u=n.centerX,c=n.bottomY+1,l=s.centerX,p=s.y-1;te(e,u,c,p-1),se(e,l,p)}}}function Oe(e,t,r){let o=t.type!=="start",i=t.type!=="end"&&(!t.children||t.children.length===0);dr(e,t.x,t.y,t.width,t.height),o&&W(e,t.centerX,t.y,L.teeUp),(i||t.children&&t.children.length>0)&&W(e,t.centerX,t.y+t.height-1,L.teeDown);let n=t.width-Z*2,a=kr(t,r);for(let s=0;s<t.label.length;s++){let u=t.label[s],c=t.x+1+Math.floor((n-Q(u).length)/2),l=t.y+1+s;nt(e,c,l,u,a)}t.metadata?.isWinner&&nt(e,t.x+t.width-2,t.y,"\u{1F3C6}"),t.children&&t.children.length>0&&(t.type==="parallel"||t.type==="race"?wr(e,t,r):br(e,t,r))}function wr(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=t.centerX;if(t.metadata?.verticalLayout===!0){let s=o[0];te(e,n,i,s.y-2),se(e,s.centerX,s.y-1);for(let u=0;u<o.length;u++){let c=o[u];if(Oe(e,c,r),u<o.length-1){let l=o[u+1];te(e,c.centerX,c.bottomY+1,l.y-2),se(e,l.centerX,l.y-1)}}return}if(o.length===1)te(e,n,i,o[0].y-2),se(e,o[0].centerX,o[0].y-1);else{let s=o.map(l=>l.centerX),u=Math.min(...s),c=Math.max(...s);te(e,n,i,i+1),ot(e,i+1,u,c),W(e,n,i+1,L.teeUp);for(let l of o){let p=l.centerX;p===u?W(e,p,i+1,L.topLeft):p===c?W(e,p,i+1,L.topRight):p!==n&&W(e,p,i+1,L.teeDown),te(e,p,i+2,l.y-2),se(e,p,l.y-1)}}for(let s of o)Oe(e,s,r);if(o.length>1){let s=o.map(f=>f.bottomY),u=Math.max(...s),c=u+1,l=o.map(f=>f.centerX),p=Math.min(...l),g=Math.max(...l);for(let f of o)f.bottomY<u&&te(e,f.centerX,f.bottomY+1,c-1);ot(e,c,p,g);for(let f of o){let y=f.centerX;y===p?W(e,y,c,L.bottomLeft):y===g?W(e,y,c,L.bottomRight):W(e,y,c,L.teeUp)}W(e,t.centerX,c,L.teeDown),W(e,t.centerX,c+1,L.vertical)}}function br(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=o[0];te(e,t.centerX,i,n.y-2),se(e,n.centerX,n.y-1);for(let a=0;a<o.length;a++){let s=o[a];if(Oe(e,s,r),a<o.length-1){let u=o[a+1];te(e,s.centerX,s.bottomY+1,u.y-2),se(e,u.centerX,u.y-1)}}}var yr={active:"\x1B[36m",closed:"\x1B[32m",error:"\x1B[31m"};function kr(e,t){if(e.metadata?.heat!==void 0){let r=be(e.metadata.heat);return ar[r]||void 0}return e.type==="stream"&&e.metadata?.streamState?yr[e.metadata.streamState]||void 0:t[e.state]||void 0}function fe(){return{name:"flowchart",supportsLive:!1,render(e,t){let r=t.terminalWidth??80,{nodes:o,totalHeight:i}=ur(e,t,r),n=cr(r,i);return gr(n,o,t),lr(n)}}}function vr(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function xr(e){let t=[];function r(o){for(let i of o)if(K(i))t.push(i);else if(Ge(i))r(i.children);else if(j(i)||F(i))r(i.children);else if(J(i))for(let n of i.branches)n.taken&&r(n.children)}return r(e),t}function Sr(e){let t={id:e.id,name:e.name??e.key??e.id,state:e.state};return e.key&&(t.key=e.key),e.durationMs!==void 0&&(t.durationMs=e.durationMs),e.startTs!==void 0&&(t.startTs=e.startTs),e.endTs!==void 0&&(t.endTs=e.endTs),e.retryCount!==void 0&&e.retryCount>0&&(t.retryCount=e.retryCount),e.timedOut&&(t.timedOut=!0,e.timeoutMs!==void 0&&(t.timeoutMs=e.timeoutMs)),e.error!==void 0&&(t.error=typeof e.error=="string"?e.error:String(e.error)),t}function Rr(e){let t=0,r=0,o=0,i=0,n=0,a;for(let s of e)s.state==="success"&&t++,s.state==="error"&&r++,s.state==="cached"&&o++,s.state==="skipped"&&i++,s.retryCount!==void 0&&(n+=s.retryCount),s.durationMs!==void 0&&(!a||s.durationMs>a.durationMs)&&(a={name:s.name??s.key??s.id,durationMs:s.durationMs});return{totalSteps:e.length,successCount:t,errorCount:r,cacheHits:o,skippedCount:i,totalRetries:n,slowestStep:a}}function Ir(e){let t={};if(e.shouldRun&&(t.shouldRun={result:e.shouldRun.context?.result,durationMs:e.shouldRun.durationMs},e.shouldRun.error!==void 0&&e.shouldRun.error!==null&&(t.shouldRun.error=String(e.shouldRun.error))),e.onBeforeStart&&(t.onBeforeStart={durationMs:e.onBeforeStart.durationMs},e.onBeforeStart.error!==void 0&&e.onBeforeStart.error!==null&&(t.onBeforeStart.error=String(e.onBeforeStart.error))),e.onAfterStep.size>0){t.onAfterStep=[];for(let[r,o]of e.onAfterStep){let i={stepKey:r};o.durationMs!==void 0&&(i.durationMs=o.durationMs),o.error!==void 0&&o.error!==null&&(i.error=String(o.error)),t.onAfterStep.push(i)}}return t}function $r(e,t){let r=e.root,o=xr(r.children),i=t.includeDiagram??!0,n=t.stripAnsiColors??!0,a={workflow:{id:r.workflowId,name:r.name,state:r.state,durationMs:r.durationMs,startedAt:r.startTs,completedAt:r.endTs},steps:o.map(Sr),summary:Rr(o)};if(e.hooks){let s=Ir(e.hooks);Object.keys(s).length>0&&(a.hooks=s)}if(i){let c=((t.diagramFormat??"ascii")==="flowchart"?fe():le()).render(e,t);n&&(c=vr(c)),a.diagram=c}return a}function De(){return{name:"logger",supportsLive:!1,render(e,t){let o=$r(e,t);return JSON.stringify(o)}}}function st(e){let t={bg:"#ffffff",bgSecondary:"#f8f9fa",text:"#212529",textMuted:"#6c757d",border:"#dee2e6",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#e9ecef",nodeRunning:"#fff3cd",nodeSuccess:"#d1e7dd",nodeError:"#f8d7da",nodeAborted:"#e9ecef",nodeCached:"#cfe2ff",nodeSkipped:"#f8f9fa",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},r={bg:"#212529",bgSecondary:"#343a40",text:"#f8f9fa",textMuted:"#adb5bd",border:"#495057",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#495057",nodeRunning:"#664d03",nodeSuccess:"#0f5132",nodeError:"#842029",nodeAborted:"#495057",nodeCached:"#084298",nodeSkipped:"#343a40",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},o=n=>`
5
+ --bg: ${n.bg};
6
+ --bg-secondary: ${n.bgSecondary};
7
+ --text: ${n.text};
8
+ --text-muted: ${n.textMuted};
9
+ --border: ${n.border};
10
+ --primary: ${n.primary};
11
+ --success: ${n.success};
12
+ --error: ${n.error};
13
+ --warning: ${n.warning};
14
+ --info: ${n.info};
15
+ --muted: ${n.muted};
16
+ --node-pending: ${n.nodePending};
17
+ --node-running: ${n.nodeRunning};
18
+ --node-success: ${n.nodeSuccess};
19
+ --node-error: ${n.nodeError};
20
+ --node-aborted: ${n.nodeAborted};
21
+ --node-cached: ${n.nodeCached};
22
+ --node-skipped: ${n.nodeSkipped};
23
+ --heat-cold: ${n.heatCold};
24
+ --heat-cool: ${n.heatCool};
25
+ --heat-neutral: ${n.heatNeutral};
26
+ --heat-warm: ${n.heatWarm};
27
+ --heat-hot: ${n.heatHot};
28
+ --heat-critical: ${n.heatCritical};
29
+ `,i;return e==="auto"?i=`
30
+ :root {
31
+ ${o(t)}
32
+ }
33
+ @media (prefers-color-scheme: dark) {
34
+ :root {
35
+ ${o(r)}
36
+ }
37
+ }
38
+ `:e==="dark"?i=`
39
+ :root {
40
+ ${o(r)}
41
+ }
42
+ `:i=`
43
+ :root {
44
+ ${o(t)}
45
+ }
46
+ `,`
47
+ ${i}
48
+
49
+ * {
50
+ box-sizing: border-box;
51
+ margin: 0;
52
+ padding: 0;
53
+ }
54
+
55
+ body {
56
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
57
+ background-color: var(--bg);
58
+ color: var(--text);
59
+ line-height: 1.5;
60
+ }
61
+
62
+ .workflow-visualizer {
63
+ display: flex;
64
+ flex-direction: column;
65
+ height: 100vh;
66
+ overflow: hidden;
67
+ }
68
+
69
+ /* Header */
70
+ .wv-header {
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: space-between;
74
+ padding: 12px 20px;
75
+ background-color: var(--bg-secondary);
76
+ border-bottom: 1px solid var(--border);
77
+ }
78
+
79
+ .wv-header h1 {
80
+ font-size: 1.25rem;
81
+ font-weight: 600;
82
+ }
83
+
84
+ .wv-controls {
85
+ display: flex;
86
+ gap: 8px;
87
+ align-items: center;
88
+ }
89
+
90
+ .wv-btn {
91
+ display: inline-flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ padding: 6px 12px;
95
+ font-size: 0.875rem;
96
+ font-weight: 500;
97
+ border: 1px solid var(--border);
98
+ border-radius: 6px;
99
+ background-color: var(--bg);
100
+ color: var(--text);
101
+ cursor: pointer;
102
+ transition: all 0.15s ease;
103
+ }
104
+
105
+ .wv-btn:hover {
106
+ background-color: var(--bg-secondary);
107
+ }
108
+
109
+ .wv-btn:disabled {
110
+ opacity: 0.5;
111
+ cursor: not-allowed;
112
+ background-color: var(--bg-secondary);
113
+ color: var(--text-muted);
114
+ }
115
+
116
+ .wv-btn--primary {
117
+ background-color: var(--primary);
118
+ border-color: var(--primary);
119
+ color: white;
120
+ }
121
+
122
+ .wv-btn--primary:hover {
123
+ opacity: 0.9;
124
+ }
125
+
126
+ .wv-btn--icon {
127
+ padding: 6px;
128
+ min-width: 32px;
129
+ }
130
+
131
+ /* Main content area */
132
+ .wv-main {
133
+ display: flex;
134
+ flex: 1;
135
+ overflow: hidden;
136
+ }
137
+
138
+ /* Diagram container */
139
+ .wv-diagram {
140
+ flex: 1;
141
+ position: relative;
142
+ overflow: hidden;
143
+ background-color: var(--bg);
144
+ background-image:
145
+ radial-gradient(circle, var(--border) 1px, transparent 1px);
146
+ background-size: 20px 20px;
147
+ }
148
+
149
+ .wv-diagram svg {
150
+ width: 100%;
151
+ height: 100%;
152
+ }
153
+
154
+ /* SVG Node styles */
155
+ .wv-node {
156
+ cursor: pointer;
157
+ transition: filter 0.15s ease;
158
+ }
159
+
160
+ .wv-node:hover {
161
+ filter: brightness(1.1) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
162
+ }
163
+
164
+ .wv-node rect,
165
+ .wv-node circle {
166
+ stroke: var(--border);
167
+ stroke-width: 2;
168
+ transition: all 0.2s ease;
169
+ }
170
+
171
+ .wv-node:hover rect,
172
+ .wv-node:hover circle {
173
+ stroke-width: 3;
174
+ }
175
+
176
+ .wv-node--pending rect { fill: var(--node-pending); }
177
+ .wv-node--running rect { fill: var(--node-running); stroke: var(--warning); }
178
+ .wv-node--success rect { fill: var(--node-success); stroke: var(--success); }
179
+ .wv-node--error rect { fill: var(--node-error); stroke: var(--error); }
180
+ .wv-node--aborted rect { fill: var(--node-aborted); }
181
+ .wv-node--cached rect { fill: var(--node-cached); stroke: var(--info); }
182
+ .wv-node--skipped rect { fill: var(--node-skipped); opacity: 0.6; }
183
+
184
+ .wv-node--selected rect {
185
+ stroke: var(--primary);
186
+ stroke-width: 3;
187
+ }
188
+
189
+ .wv-node text {
190
+ fill: var(--text);
191
+ font-size: 12px;
192
+ font-weight: 500;
193
+ dominant-baseline: middle;
194
+ text-anchor: middle;
195
+ }
196
+
197
+ .wv-node .wv-node-timing {
198
+ fill: var(--text-muted);
199
+ font-size: 10px;
200
+ }
201
+
202
+ /* Edge styles */
203
+ .wv-edge {
204
+ fill: none;
205
+ stroke: var(--border);
206
+ stroke-width: 2;
207
+ }
208
+
209
+ .wv-edge--active {
210
+ stroke: var(--success);
211
+ stroke-width: 2.5;
212
+ }
213
+
214
+ .wv-edge-arrow {
215
+ fill: var(--border);
216
+ }
217
+
218
+ /* Parallel/Race container */
219
+ .wv-container {
220
+ fill: transparent;
221
+ stroke: var(--border);
222
+ stroke-dasharray: 5 3;
223
+ }
224
+
225
+ .wv-container--parallel { stroke: var(--info); }
226
+ .wv-container--race { stroke: var(--warning); }
227
+
228
+ .wv-container-label {
229
+ fill: var(--text-muted);
230
+ font-size: 10px;
231
+ font-weight: 600;
232
+ text-transform: uppercase;
233
+ letter-spacing: 0.5px;
234
+ }
235
+
236
+ /* Heatmap overlay */
237
+ .wv-node--heat-cold rect { fill: var(--heat-cold) !important; opacity: 0.7; }
238
+ .wv-node--heat-cool rect { fill: var(--heat-cool) !important; opacity: 0.7; }
239
+ .wv-node--heat-neutral rect { fill: var(--heat-neutral) !important; opacity: 0.7; }
240
+ .wv-node--heat-warm rect { fill: var(--heat-warm) !important; opacity: 0.7; }
241
+ .wv-node--heat-hot rect { fill: var(--heat-hot) !important; opacity: 0.7; }
242
+ .wv-node--heat-critical rect { fill: var(--heat-critical) !important; opacity: 0.85; }
243
+
244
+ /* Timeline scrubber */
245
+ .wv-timeline {
246
+ height: 80px;
247
+ padding: 12px 20px;
248
+ background-color: var(--bg-secondary);
249
+ border-top: 1px solid var(--border);
250
+ }
251
+
252
+ .wv-timeline-track {
253
+ position: relative;
254
+ height: 24px;
255
+ background-color: var(--bg);
256
+ border-radius: 4px;
257
+ overflow: hidden;
258
+ }
259
+
260
+ .wv-timeline-progress {
261
+ position: absolute;
262
+ top: 0;
263
+ left: 0;
264
+ height: 100%;
265
+ background-color: var(--primary);
266
+ opacity: 0.3;
267
+ transition: width 0.1s ease;
268
+ }
269
+
270
+ .wv-timeline-marker {
271
+ position: absolute;
272
+ top: 0;
273
+ width: 3px;
274
+ height: 100%;
275
+ background-color: var(--primary);
276
+ cursor: ew-resize;
277
+ }
278
+
279
+ .wv-timeline-events {
280
+ display: flex;
281
+ gap: 2px;
282
+ height: 100%;
283
+ align-items: center;
284
+ padding: 4px;
285
+ }
286
+
287
+ .wv-timeline-event {
288
+ width: 4px;
289
+ height: 16px;
290
+ border-radius: 2px;
291
+ background-color: var(--muted);
292
+ }
293
+
294
+ .wv-timeline-event--success { background-color: var(--success); }
295
+ .wv-timeline-event--error { background-color: var(--error); }
296
+ .wv-timeline-event--running { background-color: var(--warning); }
297
+
298
+ .wv-timeline-controls {
299
+ display: flex;
300
+ gap: 8px;
301
+ margin-top: 8px;
302
+ align-items: center;
303
+ }
304
+
305
+ .wv-timeline-time {
306
+ font-size: 0.75rem;
307
+ color: var(--text-muted);
308
+ font-family: monospace;
309
+ }
310
+
311
+ /* Inspector panel */
312
+ .wv-inspector {
313
+ width: 320px;
314
+ background-color: var(--bg-secondary);
315
+ border-left: 1px solid var(--border);
316
+ overflow-y: auto;
317
+ transition: width 0.2s ease;
318
+ }
319
+
320
+ .wv-inspector--collapsed {
321
+ width: 0;
322
+ }
323
+
324
+ .wv-inspector-header {
325
+ display: flex;
326
+ align-items: center;
327
+ justify-content: space-between;
328
+ padding: 12px 16px;
329
+ border-bottom: 1px solid var(--border);
330
+ }
331
+
332
+ .wv-inspector-header h2 {
333
+ font-size: 0.875rem;
334
+ font-weight: 600;
335
+ }
336
+
337
+ .wv-inspector-content {
338
+ padding: 16px;
339
+ }
340
+
341
+ .wv-inspector-section {
342
+ margin-bottom: 20px;
343
+ }
344
+
345
+ .wv-inspector-section h3 {
346
+ font-size: 0.75rem;
347
+ font-weight: 600;
348
+ text-transform: uppercase;
349
+ letter-spacing: 0.5px;
350
+ color: var(--text-muted);
351
+ margin-bottom: 8px;
352
+ }
353
+
354
+ .wv-inspector-row {
355
+ display: flex;
356
+ justify-content: space-between;
357
+ padding: 4px 0;
358
+ font-size: 0.875rem;
359
+ }
360
+
361
+ .wv-inspector-label {
362
+ color: var(--text-muted);
363
+ }
364
+
365
+ .wv-inspector-value {
366
+ font-weight: 500;
367
+ font-family: monospace;
368
+ }
369
+
370
+ .wv-inspector-value--success { color: var(--success); }
371
+ .wv-inspector-value--error { color: var(--error); }
372
+ .wv-inspector-value--running { color: var(--warning); }
373
+
374
+ /* Status badge */
375
+ .wv-badge {
376
+ display: inline-flex;
377
+ align-items: center;
378
+ padding: 2px 8px;
379
+ font-size: 0.75rem;
380
+ font-weight: 500;
381
+ border-radius: 4px;
382
+ text-transform: capitalize;
383
+ }
384
+
385
+ .wv-badge--pending { background-color: var(--node-pending); }
386
+ .wv-badge--running { background-color: var(--node-running); color: #664d03; }
387
+ .wv-badge--success { background-color: var(--node-success); color: #0f5132; }
388
+ .wv-badge--error { background-color: var(--node-error); color: #842029; }
389
+ .wv-badge--cached { background-color: var(--node-cached); color: #084298; }
390
+
391
+ /* Live indicator */
392
+ .wv-live {
393
+ display: flex;
394
+ align-items: center;
395
+ gap: 6px;
396
+ padding: 4px 10px;
397
+ background-color: var(--error);
398
+ color: white;
399
+ font-size: 0.75rem;
400
+ font-weight: 600;
401
+ border-radius: 4px;
402
+ }
403
+
404
+ .wv-live-dot {
405
+ width: 8px;
406
+ height: 8px;
407
+ background-color: white;
408
+ border-radius: 50%;
409
+ animation: wv-pulse 1.5s infinite;
410
+ }
411
+
412
+ @keyframes wv-pulse {
413
+ 0%, 100% { opacity: 1; }
414
+ 50% { opacity: 0.5; }
415
+ }
416
+
417
+ /* Performance stats */
418
+ .wv-perf-bar {
419
+ height: 8px;
420
+ background-color: var(--bg);
421
+ border-radius: 4px;
422
+ overflow: hidden;
423
+ margin-top: 4px;
424
+ }
425
+
426
+ .wv-perf-bar-fill {
427
+ height: 100%;
428
+ border-radius: 4px;
429
+ transition: width 0.3s ease;
430
+ }
431
+
432
+ .wv-perf-bar-fill--cold { background-color: var(--heat-cold); }
433
+ .wv-perf-bar-fill--cool { background-color: var(--heat-cool); }
434
+ .wv-perf-bar-fill--neutral { background-color: var(--heat-neutral); }
435
+ .wv-perf-bar-fill--warm { background-color: var(--heat-warm); }
436
+ .wv-perf-bar-fill--hot { background-color: var(--heat-hot); }
437
+ .wv-perf-bar-fill--critical { background-color: var(--heat-critical); }
438
+
439
+ /* Tooltip */
440
+ .wv-tooltip {
441
+ position: fixed;
442
+ padding: 8px 12px;
443
+ background-color: var(--text);
444
+ color: var(--bg);
445
+ font-size: 0.75rem;
446
+ border-radius: 4px;
447
+ pointer-events: none;
448
+ z-index: 1000;
449
+ max-width: 300px;
450
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
451
+ }
452
+
453
+ /* Loading state */
454
+ .wv-loading {
455
+ display: flex;
456
+ align-items: center;
457
+ justify-content: center;
458
+ height: 100%;
459
+ color: var(--text-muted);
460
+ }
461
+
462
+ .wv-spinner {
463
+ width: 24px;
464
+ height: 24px;
465
+ border: 3px solid var(--border);
466
+ border-top-color: var(--primary);
467
+ border-radius: 50%;
468
+ animation: wv-spin 1s linear infinite;
469
+ margin-right: 8px;
470
+ }
471
+
472
+ @keyframes wv-spin {
473
+ to { transform: rotate(360deg); }
474
+ }
475
+
476
+ /* Empty state */
477
+ .wv-empty {
478
+ display: flex;
479
+ flex-direction: column;
480
+ align-items: center;
481
+ justify-content: center;
482
+ height: 100%;
483
+ color: var(--text-muted);
484
+ text-align: center;
485
+ padding: 40px;
486
+ }
487
+
488
+ .wv-empty svg {
489
+ width: 64px;
490
+ height: 64px;
491
+ margin-bottom: 16px;
492
+ opacity: 0.5;
493
+ }
494
+
495
+ /* Modal */
496
+ .wv-modal {
497
+ position: fixed;
498
+ top: 0;
499
+ left: 0;
500
+ right: 0;
501
+ bottom: 0;
502
+ background-color: rgba(0, 0, 0, 0.5);
503
+ display: flex;
504
+ align-items: center;
505
+ justify-content: center;
506
+ z-index: 1000;
507
+ }
508
+
509
+ .wv-modal-content {
510
+ background-color: var(--bg);
511
+ border-radius: 8px;
512
+ width: 90%;
513
+ max-width: 600px;
514
+ max-height: 90vh;
515
+ display: flex;
516
+ flex-direction: column;
517
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
518
+ }
519
+
520
+ .wv-modal-header {
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: space-between;
524
+ padding: 16px 20px;
525
+ border-bottom: 1px solid var(--border);
526
+ }
527
+
528
+ .wv-modal-header h2 {
529
+ font-size: 1.125rem;
530
+ font-weight: 600;
531
+ margin: 0;
532
+ }
533
+
534
+ .wv-modal-body {
535
+ padding: 20px;
536
+ overflow-y: auto;
537
+ flex: 1;
538
+ }
539
+
540
+ .wv-modal-body p {
541
+ margin: 0 0 12px 0;
542
+ font-size: 0.875rem;
543
+ color: var(--text-muted);
544
+ }
545
+
546
+ .wv-modal-body code {
547
+ background-color: var(--bg-secondary);
548
+ padding: 2px 6px;
549
+ border-radius: 4px;
550
+ font-size: 0.875rem;
551
+ font-family: monospace;
552
+ }
553
+
554
+ .wv-textarea {
555
+ width: 100%;
556
+ padding: 12px;
557
+ font-family: monospace;
558
+ font-size: 0.875rem;
559
+ border: 1px solid var(--border);
560
+ border-radius: 6px;
561
+ background-color: var(--bg);
562
+ color: var(--text);
563
+ resize: vertical;
564
+ box-sizing: border-box;
565
+ }
566
+
567
+ .wv-textarea:focus {
568
+ outline: none;
569
+ border-color: var(--primary);
570
+ }
571
+
572
+ .wv-error {
573
+ margin-top: 12px;
574
+ padding: 12px;
575
+ background-color: var(--node-error);
576
+ color: #842029;
577
+ border-radius: 6px;
578
+ font-size: 0.875rem;
579
+ }
580
+
581
+ .wv-modal-footer {
582
+ display: flex;
583
+ gap: 8px;
584
+ justify-content: flex-end;
585
+ padding: 16px 20px;
586
+ border-top: 1px solid var(--border);
587
+ }
588
+
589
+ /* Responsive */
590
+ @media (max-width: 768px) {
591
+ .wv-inspector {
592
+ position: fixed;
593
+ right: 0;
594
+ top: 0;
595
+ bottom: 0;
596
+ z-index: 100;
597
+ box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);
598
+ }
599
+
600
+ .wv-timeline {
601
+ height: auto;
602
+ }
603
+
604
+ .wv-modal-content {
605
+ width: 95%;
606
+ max-height: 95vh;
607
+ }
608
+ }
609
+ `}function ct(e){return`
610
+ (function() {
611
+ 'use strict';
612
+
613
+ // State
614
+ let selectedNodeId = null;
615
+ let transform = { x: 0, y: 0, scale: 1 };
616
+ let isDragging = false;
617
+ let dragStart = { x: 0, y: 0 };
618
+ let ws = null;
619
+ let snapshots = [];
620
+ let currentSnapshotIndex = -1;
621
+ let isPlaying = false;
622
+ let playbackSpeed = 1;
623
+ let heatmapEnabled = false;
624
+ let heatmapMetric = 'duration';
625
+
626
+ // DOM elements
627
+ const diagram = document.getElementById('diagram');
628
+ const svg = diagram?.querySelector('svg');
629
+ const inspector = document.getElementById('inspector');
630
+ const timeline = document.getElementById('timeline');
631
+
632
+ // Initialize
633
+ document.addEventListener('DOMContentLoaded', init);
634
+
635
+ function init() {
636
+ ${e.interactive?"setupInteractivity(); setupLoadJSON();":""}
637
+ // WebSocket must be initialized before time-travel and heatmap checks
638
+ ${e.wsUrl?`setupWebSocket('${e.wsUrl}');`:""}
639
+ ${e.timeTravel?"setupTimeTravel(); initializeTimeTravelFromData();":""}
640
+ ${e.heatmap?"setupHeatmap();":""}
641
+ setupKeyboardShortcuts();
642
+ }
643
+
644
+ // Load JSON functionality
645
+ function setupLoadJSON() {
646
+ const loadBtn = document.getElementById('load-json-btn');
647
+ const modal = document.getElementById('load-json-modal');
648
+ const closeBtn = document.getElementById('load-json-close');
649
+ const cancelBtn = document.getElementById('load-json-cancel');
650
+ const submitBtn = document.getElementById('load-json-submit');
651
+ const input = document.getElementById('load-json-input');
652
+ const errorDiv = document.getElementById('load-json-error');
653
+
654
+ if (!loadBtn || !modal) return;
655
+
656
+ loadBtn.addEventListener('click', () => {
657
+ modal.style.display = 'flex';
658
+ if (input) {
659
+ input.value = '';
660
+ input.focus();
661
+ }
662
+ if (errorDiv) errorDiv.style.display = 'none';
663
+ });
664
+
665
+ const closeModal = () => {
666
+ modal.style.display = 'none';
667
+ if (errorDiv) errorDiv.style.display = 'none';
668
+ };
669
+
670
+ closeBtn?.addEventListener('click', closeModal);
671
+ cancelBtn?.addEventListener('click', closeModal);
672
+ modal.addEventListener('click', (e) => {
673
+ if (e.target === modal) closeModal();
674
+ });
675
+
676
+ submitBtn?.addEventListener('click', () => {
677
+ if (!input) return;
678
+
679
+ try {
680
+ const jsonText = input.value.trim();
681
+ if (!jsonText) {
682
+ showError('Please paste JSON data');
683
+ return;
684
+ }
685
+
686
+ const ir = JSON.parse(jsonText);
687
+
688
+ // Validate IR structure
689
+ if (!ir || !ir.root || !ir.root.type || ir.root.type !== 'workflow') {
690
+ showError('Invalid workflow IR. Expected object with root.type === "workflow"');
691
+ return;
692
+ }
693
+
694
+ // Update global data
695
+ window.__WORKFLOW_IR__ = ir;
696
+ const newData = buildWorkflowDataFromIR(ir);
697
+ window.__WORKFLOW_DATA__ = newData;
698
+
699
+ // Save to sessionStorage for full rebuild on reload
700
+ try {
701
+ sessionStorage.setItem('workflow_ir', JSON.stringify(ir));
702
+ } catch (storageErr) {
703
+ console.warn('Failed to save IR to sessionStorage:', storageErr);
704
+ }
705
+
706
+ // Rebuild the diagram (updates node states in-place)
707
+ rebuildDiagram(ir);
708
+
709
+ // Update inspector if node is selected
710
+ if (selectedNodeId) {
711
+ updateInspector(selectedNodeId);
712
+ }
713
+
714
+ closeModal();
715
+
716
+ // Offer full rebuild via reload if structure changed significantly
717
+ console.log('IR loaded. Node states updated. Reload page for full layout rebuild with new structure.');
718
+ } catch (e) {
719
+ showError('Invalid JSON: ' + e.message);
720
+ }
721
+ });
722
+
723
+ function showError(message) {
724
+ if (errorDiv) {
725
+ errorDiv.textContent = message;
726
+ errorDiv.style.display = 'block';
727
+ }
728
+ }
729
+ }
730
+
731
+ function buildWorkflowDataFromIR(ir) {
732
+ const nodes = {};
733
+
734
+ function collectNodes(flowNodes) {
735
+ for (const node of flowNodes || []) {
736
+ nodes[node.id] = {
737
+ id: node.id,
738
+ name: node.name,
739
+ type: node.type,
740
+ state: node.state,
741
+ key: node.key,
742
+ durationMs: node.durationMs,
743
+ startTs: node.startTs,
744
+ error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
745
+ retryCount: node.retryCount,
746
+ input: node.input,
747
+ output: node.output,
748
+ ...(node.type === 'stream' && {
749
+ namespace: node.namespace,
750
+ writeCount: node.writeCount,
751
+ readCount: node.readCount,
752
+ finalPosition: node.finalPosition,
753
+ streamState: node.streamState,
754
+ backpressureOccurred: node.backpressureOccurred,
755
+ }),
756
+ ...(node.type === 'decision' && {
757
+ condition: node.condition,
758
+ decisionValue: node.decisionValue,
759
+ branchTaken: node.branchTaken,
760
+ branches: node.branches,
761
+ }),
762
+ };
763
+
764
+ if (node.children) {
765
+ collectNodes(node.children);
766
+ }
767
+ if (node.branches) {
768
+ for (const branch of node.branches) {
769
+ collectNodes(branch.children);
770
+ }
771
+ }
772
+ }
773
+ }
774
+
775
+ collectNodes(ir.root.children);
776
+ const hooks = ir.hooks
777
+ ? {
778
+ ...ir.hooks,
779
+ onAfterStep:
780
+ ir.hooks.onAfterStep instanceof Map
781
+ ? Object.fromEntries(ir.hooks.onAfterStep)
782
+ : ir.hooks.onAfterStep,
783
+ }
784
+ : undefined;
785
+ return { nodes, hooks };
786
+ }
787
+
788
+ function rebuildDiagram(ir) {
789
+ // Update workflow data and node states
790
+ const newData = buildWorkflowDataFromIR(ir);
791
+ window.__WORKFLOW_DATA__ = newData;
792
+ window.__WORKFLOW_IR__ = ir;
793
+
794
+ // Update existing node states in SVG
795
+ renderIR(ir);
796
+
797
+ // Note: Full diagram rebuild (new nodes, layout changes) requires regenerating the HTML
798
+ // For now, we update node states. Users can save the IR and regenerate HTML for full rebuild.
799
+ console.log('Workflow IR loaded. Node states updated. For full diagram rebuild, regenerate HTML with the new IR.');
800
+ }
801
+
802
+ function initializeTimeTravelFromData() {
803
+ // For static HTML (no WebSocket), time travel doesn't work since we only have one state
804
+ // Initialize with empty snapshots and disable controls
805
+ if (!ws) {
806
+ snapshots = [];
807
+ currentSnapshotIndex = -1;
808
+ updateTimelineUI();
809
+
810
+ // Disable time travel controls for static HTML
811
+ const playBtn = document.getElementById('tt-play');
812
+ const pauseBtn = document.getElementById('tt-pause');
813
+ const prevBtn = document.getElementById('tt-prev');
814
+ const nextBtn = document.getElementById('tt-next');
815
+ const slider = document.getElementById('tt-slider');
816
+
817
+ [playBtn, pauseBtn, prevBtn, nextBtn, slider].forEach(btn => {
818
+ if (btn) {
819
+ btn.disabled = true;
820
+ btn.title = 'Time travel requires a live WebSocket connection';
821
+ }
822
+ });
823
+ }
824
+ }
825
+
826
+ // Interactivity
827
+ function setupInteractivity() {
828
+ if (!diagram || !svg) return;
829
+
830
+ // Zoom with mouse wheel
831
+ diagram.addEventListener('wheel', (e) => {
832
+ e.preventDefault();
833
+ const delta = e.deltaY > 0 ? 0.9 : 1.1;
834
+ const rect = diagram.getBoundingClientRect();
835
+ const x = e.clientX - rect.left;
836
+ const y = e.clientY - rect.top;
837
+
838
+ // Zoom towards cursor position
839
+ transform.scale *= delta;
840
+ transform.scale = Math.max(0.1, Math.min(5, transform.scale));
841
+ transform.x = x - (x - transform.x) * delta;
842
+ transform.y = y - (y - transform.y) * delta;
843
+
844
+ applyTransform();
845
+ });
846
+
847
+ // Pan with drag
848
+ diagram.addEventListener('mousedown', (e) => {
849
+ if (e.target === diagram || e.target === svg) {
850
+ isDragging = true;
851
+ dragStart = { x: e.clientX - transform.x, y: e.clientY - transform.y };
852
+ diagram.style.cursor = 'grabbing';
853
+ }
854
+ });
855
+
856
+ document.addEventListener('mousemove', (e) => {
857
+ if (!isDragging) return;
858
+ transform.x = e.clientX - dragStart.x;
859
+ transform.y = e.clientY - dragStart.y;
860
+ applyTransform();
861
+ });
862
+
863
+ document.addEventListener('mouseup', () => {
864
+ isDragging = false;
865
+ if (diagram) diagram.style.cursor = 'grab';
866
+ });
867
+
868
+ // Node selection - handle clicks on nodes and their children (rect, text, etc.)
869
+ document.querySelectorAll('.wv-node').forEach((node) => {
870
+ node.addEventListener('click', (e) => {
871
+ e.stopPropagation();
872
+ const nodeId = node.dataset.nodeId;
873
+ if (nodeId) {
874
+ selectNode(nodeId);
875
+ }
876
+ });
877
+ });
878
+
879
+ // Also handle clicks directly on child elements (rect, text) that bubble up
880
+ if (svg) {
881
+ svg.addEventListener('click', (e) => {
882
+ // Find the closest .wv-node parent
883
+ let target = e.target;
884
+ while (target && target !== svg) {
885
+ if (target.classList && target.classList.contains('wv-node')) {
886
+ const nodeId = target.dataset?.nodeId;
887
+ if (nodeId) {
888
+ e.stopPropagation();
889
+ selectNode(nodeId);
890
+ return;
891
+ }
892
+ }
893
+ target = target.parentElement;
894
+ }
895
+ });
896
+ }
897
+
898
+ // Deselect on background click
899
+ diagram.addEventListener('click', (e) => {
900
+ if (e.target === diagram || e.target === svg) {
901
+ selectNode(null);
902
+ }
903
+ });
904
+
905
+ // Zoom buttons
906
+ document.getElementById('zoom-in')?.addEventListener('click', () => zoom(1.2));
907
+ document.getElementById('zoom-out')?.addEventListener('click', () => zoom(0.8));
908
+ document.getElementById('zoom-reset')?.addEventListener('click', resetZoom);
909
+
910
+ // Set initial cursor
911
+ diagram.style.cursor = 'grab';
912
+ }
913
+
914
+ function applyTransform() {
915
+ if (!svg) return;
916
+ const g = svg.querySelector('g.wv-root');
917
+ if (g) {
918
+ g.setAttribute('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.scale + ')');
919
+ }
920
+ }
921
+
922
+ function zoom(factor) {
923
+ if (!diagram) return;
924
+ const rect = diagram.getBoundingClientRect();
925
+ const centerX = rect.width / 2;
926
+ const centerY = rect.height / 2;
927
+
928
+ transform.scale *= factor;
929
+ transform.scale = Math.max(0.1, Math.min(5, transform.scale));
930
+ transform.x = centerX - (centerX - transform.x) * factor;
931
+ transform.y = centerY - (centerY - transform.y) * factor;
932
+
933
+ applyTransform();
934
+ }
935
+
936
+ function resetZoom() {
937
+ transform = { x: 0, y: 0, scale: 1 };
938
+ applyTransform();
939
+ }
940
+
941
+ function selectNode(nodeId) {
942
+ // Remove previous selection
943
+ document.querySelectorAll('.wv-node--selected').forEach((n) => {
944
+ n.classList.remove('wv-node--selected');
945
+ });
946
+
947
+ selectedNodeId = nodeId;
948
+
949
+ if (nodeId) {
950
+ const node = document.querySelector('[data-node-id="' + nodeId + '"]');
951
+ if (node) {
952
+ node.classList.add('wv-node--selected');
953
+ updateInspector(nodeId);
954
+ }
955
+ } else {
956
+ clearInspector();
957
+ }
958
+ }
959
+
960
+ function updateInspector(nodeId) {
961
+ const content = document.getElementById('inspector-content');
962
+ if (!content) return;
963
+
964
+ const nodeData = window.__WORKFLOW_DATA__?.nodes?.[nodeId];
965
+ if (!nodeData) {
966
+ // Clear and add empty message using safe DOM methods
967
+ while (content.firstChild) content.removeChild(content.firstChild);
968
+ const p = document.createElement('p');
969
+ p.className = 'wv-empty';
970
+ p.textContent = 'No data available';
971
+ content.appendChild(p);
972
+ return;
973
+ }
974
+
975
+ renderInspectorContent(content, nodeData);
976
+ }
977
+
978
+ function renderInspectorContent(container, node) {
979
+ // Clear container using safe DOM method
980
+ while (container.firstChild) container.removeChild(container.firstChild);
981
+
982
+ // Node Info section
983
+ const infoSection = createSection('Node Info');
984
+ infoSection.appendChild(createRow('Name', node.name || node.id));
985
+ infoSection.appendChild(createRow('Type', node.type));
986
+
987
+ // State badge
988
+ const stateRow = document.createElement('div');
989
+ stateRow.className = 'wv-inspector-row';
990
+ const stateLabel = document.createElement('span');
991
+ stateLabel.className = 'wv-inspector-label';
992
+ stateLabel.textContent = 'State';
993
+ const stateBadge = document.createElement('span');
994
+ stateBadge.className = 'wv-badge wv-badge--' + node.state;
995
+ stateBadge.textContent = node.state;
996
+ stateRow.appendChild(stateLabel);
997
+ stateRow.appendChild(stateBadge);
998
+ infoSection.appendChild(stateRow);
999
+
1000
+ if (node.key) {
1001
+ infoSection.appendChild(createRow('Key', node.key));
1002
+ }
1003
+ container.appendChild(infoSection);
1004
+
1005
+ // Timing section
1006
+ if (node.durationMs !== undefined) {
1007
+ const timingSection = createSection('Timing');
1008
+ timingSection.appendChild(createRow('Duration', formatDuration(node.durationMs)));
1009
+ if (node.startTs !== undefined) {
1010
+ timingSection.appendChild(createRow('Started', new Date(node.startTs).toLocaleTimeString()));
1011
+ }
1012
+ container.appendChild(timingSection);
1013
+ }
1014
+
1015
+ // Retries section
1016
+ if (node.retryCount !== undefined && node.retryCount > 0) {
1017
+ const retrySection = createSection('Retries');
1018
+ retrySection.appendChild(createRow('Retry Count', String(node.retryCount)));
1019
+ container.appendChild(retrySection);
1020
+ }
1021
+
1022
+ // Input/Output section
1023
+ if (node.input !== undefined || node.output !== undefined) {
1024
+ const ioSection = createSection('Input / Output');
1025
+ if (node.input !== undefined) {
1026
+ const inputPre = document.createElement('pre');
1027
+ inputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
1028
+ inputPre.textContent = typeof node.input === 'string' ? node.input : safeStringify(node.input);
1029
+ ioSection.appendChild(createRow('Input', ''));
1030
+ ioSection.appendChild(inputPre);
1031
+ }
1032
+ if (node.output !== undefined) {
1033
+ const outputPre = document.createElement('pre');
1034
+ outputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
1035
+ outputPre.textContent = typeof node.output === 'string' ? node.output : safeStringify(node.output);
1036
+ ioSection.appendChild(createRow('Output', ''));
1037
+ ioSection.appendChild(outputPre);
1038
+ }
1039
+ container.appendChild(ioSection);
1040
+ }
1041
+
1042
+ // Hook timing (onAfterStep)
1043
+ const hookKey = node.key || node.id;
1044
+ const hookExec = window.__WORKFLOW_DATA__?.hooks?.onAfterStep?.[hookKey];
1045
+ if (hookExec && (hookExec.durationMs !== undefined || hookExec.ts !== undefined)) {
1046
+ const hookSection = createSection('Hook (onAfterStep)');
1047
+ if (hookExec.durationMs !== undefined) {
1048
+ hookSection.appendChild(createRow('Duration', formatDuration(hookExec.durationMs)));
1049
+ }
1050
+ if (hookExec.ts !== undefined) {
1051
+ hookSection.appendChild(createRow('At', new Date(hookExec.ts).toLocaleTimeString()));
1052
+ }
1053
+ container.appendChild(hookSection);
1054
+ }
1055
+
1056
+ // Error section (preserve falsy errors: 0, "", false)
1057
+ if (node.error !== undefined && node.error !== null) {
1058
+ const errorSection = createSection('Error');
1059
+ const pre = document.createElement('pre');
1060
+ pre.style.cssText = 'font-size:11px;overflow:auto;max-height:150px;background:var(--bg);padding:8px;border-radius:4px;';
1061
+ pre.textContent = String(node.error);
1062
+ errorSection.appendChild(pre);
1063
+ container.appendChild(errorSection);
1064
+ }
1065
+ }
1066
+
1067
+ function createSection(title) {
1068
+ const section = document.createElement('div');
1069
+ section.className = 'wv-inspector-section';
1070
+ const h3 = document.createElement('h3');
1071
+ h3.textContent = title;
1072
+ section.appendChild(h3);
1073
+ return section;
1074
+ }
1075
+
1076
+ function createRow(label, value) {
1077
+ const row = document.createElement('div');
1078
+ row.className = 'wv-inspector-row';
1079
+ const labelSpan = document.createElement('span');
1080
+ labelSpan.className = 'wv-inspector-label';
1081
+ labelSpan.textContent = label;
1082
+ const valueSpan = document.createElement('span');
1083
+ valueSpan.className = 'wv-inspector-value';
1084
+ valueSpan.textContent = value;
1085
+ row.appendChild(labelSpan);
1086
+ row.appendChild(valueSpan);
1087
+ return row;
1088
+ }
1089
+
1090
+ function clearInspector() {
1091
+ const content = document.getElementById('inspector-content');
1092
+ if (content) {
1093
+ while (content.firstChild) content.removeChild(content.firstChild);
1094
+ const p = document.createElement('p');
1095
+ p.className = 'wv-empty';
1096
+ p.textContent = 'Select a node to inspect';
1097
+ content.appendChild(p);
1098
+ }
1099
+ }
1100
+
1101
+ // Time Travel
1102
+ function setupTimeTravel() {
1103
+ const playBtn = document.getElementById('tt-play');
1104
+ const pauseBtn = document.getElementById('tt-pause');
1105
+ const prevBtn = document.getElementById('tt-prev');
1106
+ const nextBtn = document.getElementById('tt-next');
1107
+ const speedSelect = document.getElementById('tt-speed');
1108
+ const slider = document.getElementById('tt-slider');
1109
+
1110
+ playBtn?.addEventListener('click', play);
1111
+ pauseBtn?.addEventListener('click', pause);
1112
+ prevBtn?.addEventListener('click', stepBackward);
1113
+ nextBtn?.addEventListener('click', stepForward);
1114
+ speedSelect?.addEventListener('change', (e) => {
1115
+ playbackSpeed = parseFloat(e.target.value);
1116
+ });
1117
+ slider?.addEventListener('input', (e) => {
1118
+ seek(parseInt(e.target.value, 10));
1119
+ });
1120
+ }
1121
+
1122
+ function play() {
1123
+ if (snapshots.length === 0) {
1124
+ console.warn('[Visualizer] No snapshots available for time travel. Time travel requires a live WebSocket connection.');
1125
+ return;
1126
+ }
1127
+ isPlaying = true;
1128
+ updatePlaybackUI();
1129
+ playNext();
1130
+ }
1131
+
1132
+ function pause() {
1133
+ isPlaying = false;
1134
+ updatePlaybackUI();
1135
+ }
1136
+
1137
+ function playNext() {
1138
+ if (!isPlaying) return;
1139
+ if (currentSnapshotIndex < snapshots.length - 1) {
1140
+ const current = snapshots[currentSnapshotIndex];
1141
+ const next = snapshots[currentSnapshotIndex + 1];
1142
+ const delay = (next.timestamp - current.timestamp) / playbackSpeed;
1143
+
1144
+ setTimeout(() => {
1145
+ stepForward();
1146
+ playNext();
1147
+ }, Math.max(16, delay));
1148
+ } else {
1149
+ pause();
1150
+ }
1151
+ }
1152
+
1153
+ function stepForward() {
1154
+ if (snapshots.length === 0) {
1155
+ console.warn('[Visualizer] No snapshots available for time travel.');
1156
+ return;
1157
+ }
1158
+ if (currentSnapshotIndex < snapshots.length - 1) {
1159
+ seek(currentSnapshotIndex + 1);
1160
+ }
1161
+ }
1162
+
1163
+ function stepBackward() {
1164
+ if (snapshots.length === 0) {
1165
+ console.warn('[Visualizer] No snapshots available for time travel.');
1166
+ return;
1167
+ }
1168
+ if (currentSnapshotIndex > 0) {
1169
+ seek(currentSnapshotIndex - 1);
1170
+ }
1171
+ }
1172
+
1173
+ function seek(index) {
1174
+ if (index < 0 || index >= snapshots.length) return;
1175
+ currentSnapshotIndex = index;
1176
+ updateTimelineUI();
1177
+
1178
+ // Request IR update from server or use cached
1179
+ if (ws && ws.readyState === WebSocket.OPEN) {
1180
+ ws.send(JSON.stringify({ type: 'time_travel_seek', payload: { index } }));
1181
+ } else if (snapshots[index]?.ir) {
1182
+ renderIR(snapshots[index].ir);
1183
+ }
1184
+ }
1185
+
1186
+ function updatePlaybackUI() {
1187
+ const playBtn = document.getElementById('tt-play');
1188
+ const pauseBtn = document.getElementById('tt-pause');
1189
+
1190
+ if (playBtn) playBtn.style.display = isPlaying ? 'none' : 'inline-flex';
1191
+ if (pauseBtn) pauseBtn.style.display = isPlaying ? 'inline-flex' : 'none';
1192
+ }
1193
+
1194
+ function updateTimelineUI() {
1195
+ const slider = document.getElementById('tt-slider');
1196
+ const timeDisplay = document.getElementById('tt-time');
1197
+
1198
+ if (slider) {
1199
+ slider.max = String(Math.max(0, snapshots.length - 1));
1200
+ slider.value = String(Math.max(0, currentSnapshotIndex));
1201
+ }
1202
+
1203
+ if (timeDisplay) {
1204
+ timeDisplay.textContent = (currentSnapshotIndex + 1) + ' / ' + snapshots.length;
1205
+ }
1206
+ }
1207
+
1208
+ // WebSocket
1209
+ function setupWebSocket(url) {
1210
+ ws = new WebSocket(url);
1211
+
1212
+ ws.onopen = () => {
1213
+ console.log('[Visualizer] Connected to server');
1214
+ showLiveIndicator(true);
1215
+ ${e.timeTravel?"if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'request_snapshots' }));":""}
1216
+ };
1217
+
1218
+ ws.onclose = () => {
1219
+ console.log('[Visualizer] Disconnected from server');
1220
+ showLiveIndicator(false);
1221
+ // Attempt reconnect after 2 seconds
1222
+ setTimeout(() => setupWebSocket(url), 2000);
1223
+ };
1224
+
1225
+ ws.onmessage = (event) => {
1226
+ try {
1227
+ const msg = JSON.parse(event.data);
1228
+ handleServerMessage(msg);
1229
+ } catch (e) {
1230
+ console.error('[Visualizer] Failed to parse message:', e);
1231
+ }
1232
+ };
1233
+
1234
+ ws.onerror = (error) => {
1235
+ console.error('[Visualizer] WebSocket error:', error);
1236
+ };
1237
+ }
1238
+
1239
+ function handleServerMessage(msg) {
1240
+ switch (msg.type) {
1241
+ case 'ir_update':
1242
+ renderIR(msg.payload);
1243
+ break;
1244
+ case 'snapshot':
1245
+ snapshots.push(msg.payload);
1246
+ currentSnapshotIndex = snapshots.length - 1;
1247
+ updateTimelineUI();
1248
+ break;
1249
+ case 'snapshots_list':
1250
+ snapshots = msg.payload;
1251
+ currentSnapshotIndex = snapshots.length - 1;
1252
+ updateTimelineUI();
1253
+ break;
1254
+ case 'performance_data':
1255
+ window.__PERFORMANCE_DATA__ = msg.payload;
1256
+ if (heatmapEnabled) applyHeatmap();
1257
+ break;
1258
+ case 'workflow_complete':
1259
+ showLiveIndicator(false);
1260
+ break;
1261
+ case 'time_travel_state':
1262
+ currentSnapshotIndex = msg.payload.currentIndex;
1263
+ isPlaying = msg.payload.isPlaying;
1264
+ playbackSpeed = msg.payload.playbackSpeed;
1265
+ updateTimelineUI();
1266
+ updatePlaybackUI();
1267
+ break;
1268
+ }
1269
+ }
1270
+
1271
+ function showLiveIndicator(show) {
1272
+ const indicator = document.getElementById('live-indicator');
1273
+ if (indicator) {
1274
+ indicator.style.display = show ? 'flex' : 'none';
1275
+ }
1276
+ }
1277
+
1278
+ // Heatmap
1279
+ function setupHeatmap() {
1280
+ const toggle = document.getElementById('heatmap-toggle');
1281
+ const metricSelect = document.getElementById('heatmap-metric');
1282
+
1283
+ // For static HTML (no WebSocket), disable heatmap controls
1284
+ if (!ws) {
1285
+ if (toggle) {
1286
+ toggle.disabled = true;
1287
+ toggle.title = 'Heatmap requires a live WebSocket connection with performance data';
1288
+ }
1289
+ if (metricSelect) {
1290
+ metricSelect.disabled = true;
1291
+ metricSelect.title = 'Heatmap requires a live WebSocket connection with performance data';
1292
+ }
1293
+ return;
1294
+ }
1295
+
1296
+ toggle?.addEventListener('click', () => {
1297
+ heatmapEnabled = !heatmapEnabled;
1298
+ toggle.classList.toggle('wv-btn--primary', heatmapEnabled);
1299
+ if (ws && ws.readyState === 1) {
1300
+ ws.send(JSON.stringify({ type: 'toggle_heatmap', payload: { enabled: heatmapEnabled } }));
1301
+ }
1302
+ if (heatmapEnabled) {
1303
+ applyHeatmap();
1304
+ } else {
1305
+ removeHeatmap();
1306
+ }
1307
+ });
1308
+
1309
+ metricSelect?.addEventListener('change', (e) => {
1310
+ heatmapMetric = e.target.value;
1311
+ if (ws && ws.readyState === 1) {
1312
+ ws.send(JSON.stringify({ type: 'set_heatmap_metric', payload: { metric: heatmapMetric } }));
1313
+ }
1314
+ if (heatmapEnabled) applyHeatmap();
1315
+ });
1316
+ }
1317
+
1318
+ function applyHeatmap() {
1319
+ const perfData = window.__PERFORMANCE_DATA__;
1320
+ if (!perfData) return;
1321
+
1322
+ const heat = perfData.heat;
1323
+ document.querySelectorAll('.wv-node').forEach((node) => {
1324
+ const nodeId = node.dataset.nodeId;
1325
+ const value = heat && (typeof heat.get === 'function' ? heat.get(nodeId) : heat[nodeId]);
1326
+
1327
+ // Remove existing heat classes
1328
+ node.classList.remove(
1329
+ 'wv-node--heat-cold',
1330
+ 'wv-node--heat-cool',
1331
+ 'wv-node--heat-neutral',
1332
+ 'wv-node--heat-warm',
1333
+ 'wv-node--heat-hot',
1334
+ 'wv-node--heat-critical'
1335
+ );
1336
+
1337
+ if (value !== undefined) {
1338
+ const level = getHeatLevel(value);
1339
+ node.classList.add('wv-node--heat-' + level);
1340
+ }
1341
+ });
1342
+ }
1343
+
1344
+ function removeHeatmap() {
1345
+ document.querySelectorAll('.wv-node').forEach((node) => {
1346
+ node.classList.remove(
1347
+ 'wv-node--heat-cold',
1348
+ 'wv-node--heat-cool',
1349
+ 'wv-node--heat-neutral',
1350
+ 'wv-node--heat-warm',
1351
+ 'wv-node--heat-hot',
1352
+ 'wv-node--heat-critical'
1353
+ );
1354
+ });
1355
+ }
1356
+
1357
+ function getHeatLevel(heat) {
1358
+ if (heat < 0.2) return 'cold';
1359
+ if (heat < 0.4) return 'cool';
1360
+ if (heat < 0.6) return 'neutral';
1361
+ if (heat < 0.8) return 'warm';
1362
+ if (heat < 0.95) return 'hot';
1363
+ return 'critical';
1364
+ }
1365
+
1366
+ // Keyboard shortcuts
1367
+ function setupKeyboardShortcuts() {
1368
+ document.addEventListener('keydown', (e) => {
1369
+ // Don't trigger shortcuts when typing in inputs
1370
+ if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
1371
+
1372
+ switch (e.key) {
1373
+ case ' ':
1374
+ e.preventDefault();
1375
+ isPlaying ? pause() : play();
1376
+ break;
1377
+ case 'ArrowLeft':
1378
+ e.preventDefault();
1379
+ stepBackward();
1380
+ break;
1381
+ case 'ArrowRight':
1382
+ e.preventDefault();
1383
+ stepForward();
1384
+ break;
1385
+ case '0':
1386
+ resetZoom();
1387
+ break;
1388
+ case '+':
1389
+ case '=':
1390
+ zoom(1.2);
1391
+ break;
1392
+ case '-':
1393
+ zoom(0.8);
1394
+ break;
1395
+ case 'h':
1396
+ ${e.heatmap?"document.getElementById('heatmap-toggle')?.click();":""}
1397
+ break;
1398
+ case 'Escape':
1399
+ selectNode(null);
1400
+ break;
1401
+ }
1402
+ });
1403
+ }
1404
+
1405
+ // Render functions
1406
+ function renderIR(ir) {
1407
+ window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(ir);
1408
+
1409
+ // Update SVG node states
1410
+ document.querySelectorAll('.wv-node').forEach((node) => {
1411
+ const nodeId = node.dataset.nodeId;
1412
+ const nodeData = window.__WORKFLOW_DATA__.nodes[nodeId];
1413
+ if (nodeData) {
1414
+ // Update only state class so heatmap (wv-node--heat-*) and other classes are preserved
1415
+ node.className = node.className.replace(/wv-node--(success|error|running|cached|skipped|pending|aborted)/g, '').replace(/\\s+/g, ' ').trim();
1416
+ node.classList.add('wv-node', 'wv-node--' + nodeData.state);
1417
+
1418
+ // Update timing text if present
1419
+ const timing = node.querySelector('.wv-node-timing');
1420
+ if (timing && nodeData.durationMs !== undefined) {
1421
+ timing.textContent = formatDuration(nodeData.durationMs);
1422
+ }
1423
+ }
1424
+ });
1425
+
1426
+ // Re-apply selection so wv-node--selected is not lost after class updates
1427
+ if (selectedNodeId) {
1428
+ selectNode(selectedNodeId);
1429
+ }
1430
+ }
1431
+
1432
+ function flattenNodes(nodes) {
1433
+ const result = [];
1434
+ for (const node of nodes) {
1435
+ result.push(node);
1436
+ if (node.children) {
1437
+ result.push(...flattenNodes(node.children));
1438
+ }
1439
+ if (node.branches) {
1440
+ for (const branch of node.branches) {
1441
+ result.push(...flattenNodes(branch.children));
1442
+ }
1443
+ }
1444
+ }
1445
+ return result;
1446
+ }
1447
+
1448
+ // Utilities
1449
+ function safeStringify(val) {
1450
+ const seen = new WeakSet();
1451
+ try {
1452
+ return JSON.stringify(val, function(key, value) {
1453
+ if (typeof value === 'bigint') return value.toString();
1454
+ if (typeof value === 'object' && value !== null) {
1455
+ if (seen.has(value)) return '[Circular]';
1456
+ seen.add(value);
1457
+ }
1458
+ return value;
1459
+ }, 2);
1460
+ } catch (e) {
1461
+ return String(val);
1462
+ }
1463
+ }
1464
+
1465
+ function formatDuration(ms) {
1466
+ if (ms < 1000) return Math.round(ms) + 'ms';
1467
+ if (ms < 60000) {
1468
+ const s = (ms / 1000).toFixed(1).replace(/\\.0$/, '');
1469
+ return s + 's';
1470
+ }
1471
+ let min = Math.floor(ms / 60000);
1472
+ let sec = Math.round((ms % 60000) / 1000);
1473
+ if (sec >= 60) { min += 1; sec = 0; }
1474
+ if (sec === 0) return min + 'm';
1475
+ return min + 'm ' + sec + 's';
1476
+ }
1477
+ })();
1478
+ `}var ae=160,me=50,Fe=40,Er=30,H=20;function Nr(e,t="TB",r){let o=t==="TB"||t==="BT",i=t==="RL"||t==="BT",n=[],a=H,s=H,u=0,c=0;for(let g of e){let f=ze(g,a,s,o,r);n.push(f.node),o?(s+=f.height+Er,u=Math.max(u,f.width),c=s):(a+=f.width+Fe,c=Math.max(c,f.height),u=a)}let l=u+H,p=c+H;if(i)for(let g of n)lt(g,l,p,o);return{nodes:n,width:l,height:p}}function lt(e,t,r,o){if(o?e.y=r-e.y-e.height:e.x=t-e.x-e.width,e.children)for(let i of e.children)lt(i,t,r,o)}function ze(e,t,r,o,i){if(K(e)){let n=e.name??e.key??"step",a=i?.showKeys&&e.key&&e.name?`${n} [key: ${e.key}]`:n;return{node:{id:e.id,name:a,type:"step",state:e.state,x:t,y:r,width:ae,height:me,durationMs:e.durationMs},width:ae,height:me}}if(ee(e)){let n=e.streamState==="active"?`stream:${e.namespace} \u27F3`:e.streamState==="error"?`stream:${e.namespace} \u2717`:`stream:${e.namespace} \u2713`;return{node:{id:e.id,name:n,type:"stream",state:e.state,x:t,y:r,width:ae,height:me,durationMs:e.durationMs},width:ae,height:me}}if(j(e)||F(e)){let n=j(e)?"parallel":"race",a=e.name??n,s=[],u=t+H,c=r+H+20,l=0,p=0;for(let y of e.children){let k=ze(y,u,c,!0,i);s.push(k.node),u+=k.width+Fe,p=Math.max(p,k.height)}l=u-t-H;let g=Math.max(l+H,ae+H*2),f=p+H*2+20;return{node:{id:e.id,name:a,type:n,state:e.state,x:t,y:r,width:g,height:f,durationMs:e.durationMs,children:s,containerType:n,containerLabel:n==="parallel"?"PARALLEL":"RACE"},width:g,height:f}}if(J(e)){let n=e.name??"decision",a=[],s=t+H,u=r+H+20,c=0;for(let g of e.branches)for(let f of g.children){let y=ze(f,s,u,!0,i);a.push(y.node),s+=y.width+Fe,c=Math.max(c,y.height)}let l=Math.max(s-t,ae+H*2),p=c+H*2+20;return{node:{id:e.id,name:n,type:"decision",state:e.state,x:t,y:r,width:l,height:p,durationMs:e.durationMs,children:a,containerType:"decision",containerLabel:"DECISION"},width:l,height:p}}return{node:{id:e.id,name:e.name??"unknown",type:e.type,state:e.state,x:t,y:r,width:ae,height:me},width:ae,height:me}}function ut(e,t){return e.containerType?Tr(e,t):Mr(e,t)}function Mr(e,t){let o=t&&e.durationMs!==void 0?B(e.durationMs):"";return`
1479
+ <g class="wv-node wv-node--${e.state}" data-node-id="${ft(e.id)}" transform="translate(${e.x}, ${e.y})">
1480
+ <rect width="${e.width}" height="${e.height}" rx="8" ry="8" />
1481
+ <text x="${e.width/2}" y="${e.height/2-(o?4:0)}">${Ke(Dr(e.name,e.name.includes("[key:")?40:20))}</text>
1482
+ ${o?`<text class="wv-node-timing" x="${e.width/2}" y="${e.height/2+12}">${o}</text>`:""}
1483
+ </g>
1484
+ `}function Tr(e,t){let o=e.children?.map(i=>ut(i,t)).join(`
1485
+ `)??"";return`
1486
+ <g class="wv-container wv-container--${e.containerType}" data-node-id="${ft(e.id)}" transform="translate(${e.x}, ${e.y})">
1487
+ <rect width="${e.width}" height="${e.height}" rx="12" ry="12" />
1488
+ <text class="wv-container-label" x="${H}" y="16">${e.containerLabel}</text>
1489
+ <g transform="translate(${-e.x}, ${-e.y})">
1490
+ ${o}
1491
+ </g>
1492
+ </g>
1493
+ `}function Ue(e,t){for(let r of e){if(r.id===t)return r;if("children"in r&&r.children){let o=Ue(r.children,t);if(o)return o}if("branches"in r&&r.branches)for(let o of r.branches){let i=Ue(o.children,t);if(i)return i}}}function Or(e,t){let r=[];function o(n,a){if(Math.abs(n.y-a.y)<n.height){let u=n.x+n.width,c=n.y+n.height/2,l=a.x,p=a.y+a.height/2;r.push(`
1494
+ <path class="wv-edge" d="M ${u} ${c} L ${l-8} ${p}" />
1495
+ <polygon class="wv-edge-arrow" points="${l-8},${p-4} ${l-8},${p+4} ${l},${p}" />
1496
+ `)}else{let u=n.x+n.width/2,c=n.y+n.height,l=a.x+a.width/2,p=a.y;r.push(`
1497
+ <path class="wv-edge" d="M ${u} ${c} L ${l} ${p-8}" />
1498
+ <polygon class="wv-edge-arrow" points="${l-4},${p-8} ${l+4},${p-8} ${l},${p}" />
1499
+ `)}}function i(n){for(let a=0;a<n.length-1;a++)o(n[a],n[a+1]);for(let a of n)if(a.children&&a.children.length>0)if(a.containerType==="decision"){let s=Ue(t.root.children,a.id);if(s&&s.type==="decision"&&s.branches){let u=0;for(let c of s.branches){let l=c.children.length;l>0&&o(a,a.children[u]);for(let p=0;p<l-1;p++)o(a.children[u+p],a.children[u+p+1]);u+=l}}}else if(a.containerType==="parallel"||a.containerType==="race")for(let s of a.children)s.children&&s.children.length>0&&i([s]);else i(a.children)}return i(e),r.join(`
1500
+ `)}function pt(e,t){let r=Nr(e.root.children,t.layout,t),o=Math.max(r.width,400),i=Math.max(r.height,300),n=r.nodes.map(l=>ut(l,t.showTimings)).join(`
1501
+ `),a=Or(r.nodes,e),s=e.root.name??"Workflow",u=st(t.theme),c=ct({wsUrl:t.wsUrl,interactive:t.interactive,timeTravel:t.timeTravel,heatmap:t.heatmap});return`<!DOCTYPE html>
1502
+ <html lang="en">
1503
+ <head>
1504
+ <meta charset="UTF-8">
1505
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1506
+ <title>${Ke(s)} - Workflow Visualizer</title>
1507
+ <style>${u}</style>
1508
+ </head>
1509
+ <body>
1510
+ <div class="workflow-visualizer">
1511
+ <header class="wv-header">
1512
+ <h1>${Ke(s)}</h1>
1513
+ <div class="wv-controls">
1514
+ ${t.interactive?`
1515
+ <button id="load-json-btn" class="wv-btn" title="Load workflow state from JSON">Load JSON</button>
1516
+ `:""}
1517
+ ${t.wsUrl?'<div id="live-indicator" class="wv-live" style="display:none"><span class="wv-live-dot"></span>LIVE</div>':""}
1518
+ ${t.heatmap&&t.wsUrl?`
1519
+ <button id="heatmap-toggle" class="wv-btn">Heatmap</button>
1520
+ <select id="heatmap-metric" class="wv-btn">
1521
+ <option value="duration">Duration</option>
1522
+ <option value="retryRate">Retry Rate</option>
1523
+ <option value="errorRate">Error Rate</option>
1524
+ </select>
1525
+ `:""}
1526
+ ${t.interactive?`
1527
+ <button id="zoom-out" class="wv-btn wv-btn--icon" title="Zoom out (-)">\u2212</button>
1528
+ <button id="zoom-reset" class="wv-btn wv-btn--icon" title="Reset zoom (0)">\u27F2</button>
1529
+ <button id="zoom-in" class="wv-btn wv-btn--icon" title="Zoom in (+)">+</button>
1530
+ `:""}
1531
+ </div>
1532
+ </header>
1533
+
1534
+ <div class="wv-main">
1535
+ <div id="diagram" class="wv-diagram">
1536
+ <svg viewBox="0 0 ${o} ${i}" preserveAspectRatio="xMidYMid meet">
1537
+ <g class="wv-root">
1538
+ ${a}
1539
+ ${n}
1540
+ </g>
1541
+ </svg>
1542
+ </div>
1543
+
1544
+ ${t.interactive?`
1545
+ <aside id="inspector" class="wv-inspector">
1546
+ <div class="wv-inspector-header">
1547
+ <h2>Inspector</h2>
1548
+ </div>
1549
+ <div id="inspector-content" class="wv-inspector-content">
1550
+ <p class="wv-empty">Select a node to inspect</p>
1551
+ </div>
1552
+ </aside>
1553
+ `:""}
1554
+ </div>
1555
+
1556
+ ${t.timeTravel?`
1557
+ <div id="timeline" class="wv-timeline">
1558
+ <div class="wv-timeline-track">
1559
+ <input type="range" id="tt-slider" min="0" max="0" value="0" style="width:100%">
1560
+ </div>
1561
+ <div class="wv-timeline-controls">
1562
+ <button id="tt-prev" class="wv-btn wv-btn--icon" title="Step backward (\u2190)">\u23EE</button>
1563
+ <button id="tt-play" class="wv-btn wv-btn--icon" title="Play (Space)">\u25B6</button>
1564
+ <button id="tt-pause" class="wv-btn wv-btn--icon" style="display:none" title="Pause (Space)">\u23F8</button>
1565
+ <button id="tt-next" class="wv-btn wv-btn--icon" title="Step forward (\u2192)">\u23ED</button>
1566
+ <select id="tt-speed" class="wv-btn">
1567
+ <option value="0.5">0.5x</option>
1568
+ <option value="1" selected>1x</option>
1569
+ <option value="2">2x</option>
1570
+ <option value="4">4x</option>
1571
+ <option value="10">10x</option>
1572
+ </select>
1573
+ <span id="tt-time" class="wv-timeline-time">0 / 0</span>
1574
+ </div>
1575
+ </div>
1576
+ `:""}
1577
+ </div>
1578
+
1579
+ ${t.interactive?`
1580
+ <div id="load-json-modal" class="wv-modal" style="display:none">
1581
+ <div class="wv-modal-content">
1582
+ <div class="wv-modal-header">
1583
+ <h2>Load Workflow State</h2>
1584
+ <button id="load-json-close" class="wv-btn wv-btn--icon" title="Close">\xD7</button>
1585
+ </div>
1586
+ <div class="wv-modal-body">
1587
+ <p>Paste the workflow IR JSON (from <code>viz.getIR()</code> or <code>viz.renderAs('json')</code>):</p>
1588
+ <textarea id="load-json-input" class="wv-textarea" rows="15" placeholder='{"root":{"type":"workflow","id":"...","children":[...]}}'></textarea>
1589
+ <div id="load-json-error" class="wv-error" style="display:none"></div>
1590
+ </div>
1591
+ <div class="wv-modal-footer">
1592
+ <button id="load-json-submit" class="wv-btn wv-btn--primary">Load</button>
1593
+ <button id="load-json-cancel" class="wv-btn">Cancel</button>
1594
+ </div>
1595
+ </div>
1596
+ </div>
1597
+ `:""}
1598
+
1599
+ <script>
1600
+ // Check if we have a saved IR in sessionStorage (from Load JSON)
1601
+ (function() {
1602
+ let initialIR = ${dt(Cr(e))};
1603
+ try {
1604
+ const savedIR = sessionStorage.getItem('workflow_ir');
1605
+ if (savedIR) {
1606
+ initialIR = JSON.parse(savedIR);
1607
+ sessionStorage.removeItem('workflow_ir'); // Clear after use
1608
+ }
1609
+ } catch (e) {
1610
+ console.warn('Failed to load saved IR:', e);
1611
+ }
1612
+
1613
+ const irObj = typeof initialIR === 'string' ? JSON.parse(initialIR) : initialIR;
1614
+ window.__WORKFLOW_IR__ = irObj;
1615
+
1616
+ // Build workflow data from IR (nodes include input/output; hooks serialized for inspector)
1617
+ function buildWorkflowDataFromIR(ir) {
1618
+ const nodes = {};
1619
+ function collectNodes(flowNodes) {
1620
+ for (const node of flowNodes || []) {
1621
+ nodes[node.id] = {
1622
+ id: node.id,
1623
+ name: node.name,
1624
+ type: node.type,
1625
+ state: node.state,
1626
+ key: node.key,
1627
+ durationMs: node.durationMs,
1628
+ startTs: node.startTs,
1629
+ error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
1630
+ retryCount: node.retryCount,
1631
+ input: node.input,
1632
+ output: node.output,
1633
+ ...(node.type === "stream" && {
1634
+ namespace: node.namespace,
1635
+ writeCount: node.writeCount,
1636
+ readCount: node.readCount,
1637
+ finalPosition: node.finalPosition,
1638
+ streamState: node.streamState,
1639
+ backpressureOccurred: node.backpressureOccurred,
1640
+ }),
1641
+ ...(node.type === "decision" && {
1642
+ condition: node.condition,
1643
+ decisionValue: node.decisionValue,
1644
+ branchTaken: node.branchTaken,
1645
+ branches: node.branches,
1646
+ }),
1647
+ };
1648
+ if (node.children) collectNodes(node.children);
1649
+ if (node.branches) {
1650
+ for (const branch of node.branches) {
1651
+ collectNodes(branch.children);
1652
+ }
1653
+ }
1654
+ }
1655
+ }
1656
+ collectNodes(ir.root.children);
1657
+ const hooks = ir.hooks
1658
+ ? {
1659
+ ...ir.hooks,
1660
+ onAfterStep:
1661
+ ir.hooks.onAfterStep instanceof Map
1662
+ ? Object.fromEntries(ir.hooks.onAfterStep)
1663
+ : ir.hooks.onAfterStep,
1664
+ }
1665
+ : undefined;
1666
+ return { nodes, hooks };
1667
+ }
1668
+
1669
+ window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(irObj);
1670
+
1671
+ ${t.heatmapData?`window.__PERFORMANCE_DATA__ = ${dt({heat:Object.fromEntries(t.heatmapData.heat),metric:t.heatmapData.metric,stats:t.heatmapData.stats})};`:""}
1672
+ })();
1673
+ </script>
1674
+ <script>${c}</script>
1675
+ </body>
1676
+ </html>`}function Ke(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function ft(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function Dr(e,t){return e.length<=t?e:e.slice(0,t-1)+"\u2026"}function Cr(e){if(!e.hooks)return e;let t=e.hooks.onAfterStep instanceof Map?Object.fromEntries(e.hooks.onAfterStep):e.hooks.onAfterStep;return{...e,hooks:{...e.hooks,onAfterStep:t}}}function dt(e){let t=new WeakSet;return JSON.stringify(e,(o,i)=>{if(typeof i=="bigint")return i.toString();if(o==="error"&&i!==void 0&&i!==null)return String(i);if(typeof i=="object"&&i!==null){if(t.has(i))return"[Circular]";t.add(i)}return i}).replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}var mt={interactive:!0,timeTravel:!0,heatmap:!0,animationDuration:200,theme:"auto",layout:"TB"};function Lr(){return{name:"html",supportsLive:!0,render(e,t){let r={...t,...mt,...t};return pt(e,r)}}}function _r(e,t={}){let r={showTimings:!0,showKeys:!1,colors:{pending:"#6c757d",running:"#ffc107",success:"#198754",error:"#dc3545",aborted:"#6c757d",cached:"#0dcaf0",skipped:"#adb5bd"},...mt,...t};return pt(e,r)}function je(e,t={}){let{condition:r,value:o,name:i,workflowId:n=crypto.randomUUID(),emit:a}=t,s=Date.now(),u,c=[];function l(g,f,y){c.push({label:g,condition:y,taken:f}),f&&(u=g),a?.({type:"decision_branch",workflowId:n,decisionId:e,branchLabel:g,condition:y,taken:f,ts:Date.now()})}function p(){let g=Date.now()-s;a?.({type:"decision_end",workflowId:n,decisionId:e,branchTaken:u,ts:Date.now(),durationMs:g})}return a?.({type:"decision_start",workflowId:n,decisionId:e,condition:r,decisionValue:o,name:i,ts:s}),{takeBranch:l,end:p,getBranchTaken:()=>u,getBranches:()=>[...c]}}function Wr(e,t,r={}){let o=je(e,{...r,condition:r.condition??String(t),value:r.value??t}),i=!1;return{...o,condition:t,then:()=>{i||(i=!0,o.takeBranch("if",!0),o.takeBranch("else",!1))},else:()=>{i||(i=!0,o.takeBranch("if",!1),o.takeBranch("else",!0))}}}function Br(e,t,r={}){let o=je(e,{...r,condition:r.condition??`switch(${String(t)})`,value:t});return{...o,value:t,case:(i,n)=>{o.takeBranch(`case '${i}'`,n,`value === '${i}'`)},default:i=>{o.takeBranch("default",i)}}}function Ar(e={}){let{maxSnapshots:t=1e3,autoRecord:r=!0,builderOptions:o={}}=e,i=he({...o,enableSnapshots:!0,maxSnapshots:t}),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},a=new Set,s=null;function u(){let E=v();for(let T of a)T(E)}function c(){n.snapshots=i.getSnapshots(),n.isRecording&&n.snapshots.length>0&&(n.currentIndex=n.snapshots.length-1)}function l(E){i.handleEvent(E),n.isRecording&&(c(),u())}function p(E){let T=i.getSnapshots();if(!(E<0||E>=T.length))return n.currentIndex=E,n.snapshots=T,u(),T[E].ir}function g(){return p(n.currentIndex+1)}function f(){return p(n.currentIndex-1)}function y(E=1){let T=i.getSnapshots();if(T.length===0)return;n.currentIndex===-1&&(n.currentIndex=0,n.snapshots=T),n.playbackSpeed=E,n.isPlaying=!0,u();let P=()=>{if(!n.isPlaying)return;let U=i.getSnapshots();if(n.currentIndex<U.length-1){let _=U[n.currentIndex],oe=(U[n.currentIndex+1].timestamp-_.timestamp)/n.playbackSpeed;s=setTimeout(()=>{g(),P()},Math.max(16,oe))}else k()};P()}function k(){n.isPlaying=!1,s&&(clearTimeout(s),s=null),u()}function $(){let E=i.getSnapshots();return n.currentIndex>=0&&n.currentIndex<E.length?E[n.currentIndex].ir:i.getIR()}function M(E){return i.getIRAt(E)}function N(){return i.getSnapshots()}function I(E){return i.getSnapshotAt(E)}function v(){return{snapshots:i.getSnapshots(),currentIndex:n.currentIndex,isPlaying:n.isPlaying,playbackSpeed:n.playbackSpeed,isRecording:n.isRecording}}function x(E){return a.add(E),()=>a.delete(E)}function m(){n.isRecording=!0,i.setSnapshotsEnabled(!0),c(),u()}function w(){n.isRecording=!1,i.setSnapshotsEnabled(!1),u()}function R(){k(),i.reset(),i.setSnapshotsEnabled(r),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},u()}function D(){return i}return{handleEvent:l,seek:p,stepForward:g,stepBackward:f,play:y,pause:k,getCurrentIR:$,getIRAt:M,getSnapshots:N,getSnapshotAt:I,getState:v,onStateChange:x,startRecording:m,stopRecording:w,reset:R,getBuilder:D}}import Pr from"pako";var Hr=typeof globalThis<"u"&&"Buffer"in globalThis&&typeof globalThis.Buffer=="function";function Fr(e){let t;if(Hr)t=globalThis.Buffer.from(e).toString("base64");else{let r="";for(let o=0;o<e.length;o++)r+=String.fromCharCode(e[o]);t=btoa(r)}return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Ce(e){let r=new TextEncoder().encode(e),o=Pr.deflate(r);return Fr(o)}var ht="https://kroki.io";function zr(e,t,r,o={}){let i=o.baseUrl??ht,n=Ce(r);return`${i}/${e}/${t}/${n}`}function ce(e,t="svg",r={}){let o=ie(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:V},n=o.render(e,i);return zr("mermaid",t,n,r)}function Ur(e,t={}){return ce(e,"svg",t)}function Kr(e,t={}){return ce(e,"png",t)}function jr(e={}){let t=e.baseUrl??ht;return{toUrl(r,o){return ce(r,o,{baseUrl:t})},toSvgUrl(r){return ce(r,"svg",{baseUrl:t})},toPngUrl(r){return ce(r,"png",{baseUrl:t})},toPdfUrl(r){return ce(r,"pdf",{baseUrl:t})},getBaseUrl(){return t}}}var gt="https://mermaid.ink";function wt(e){return`pako:${Ce(e)}`}function Vr(e){if("provider"in e){let t=e;return{theme:t.mermaidTheme,bgColor:t.background,scale:t.scale,fit:t.fit,width:t.width,height:t.height,paper:t.paper,imageType:"png"}}return e}function Gr(e,t){let r=[];return t.bgColor&&r.push(`bgColor=${encodeURIComponent(t.bgColor)}`),t.theme&&r.push(`theme=${t.theme}`),t.width!==void 0&&r.push(`width=${t.width}`),t.height!==void 0&&r.push(`height=${t.height}`),t.scale!==void 0&&(t.width!==void 0||t.height!==void 0)&&r.push(`scale=${t.scale}`),e==="img"&&t.imageType&&t.imageType!=="jpeg"&&r.push(`type=${t.imageType}`),e==="pdf"&&(t.fit&&r.push("fit"),t.paper&&!t.fit&&r.push(`paper=${t.paper}`),t.landscape&&!t.fit&&r.push("landscape")),r.length>0?`?${r.join("&")}`:""}function bt(e,t,r={}){let o=Vr(r),i=o.baseUrl??gt,n=wt(t),a=Gr(e,o);return`${i}/${e}/${n}${a}`}function G(e,t="svg",r={}){let o=ie(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:V},n=o.render(e,i);return bt(t,n,r)}function Yr(e,t={}){return G(e,"svg",t)}function Jr(e,t={}){return G(e,"img",{...t,imageType:"png"})}function Xr(e,t={}){return G(e,"img",{...t,imageType:"jpeg"})}function qr(e,t={}){return G(e,"img",{...t,imageType:"webp"})}function Zr(e,t={}){return G(e,"pdf",t)}function Qr(e={}){let t=e.baseUrl??gt;return{toUrl(r,o){return G(r,o,e)},toSvgUrl(r){return G(r,"svg",e)},toPngUrl(r){return G(r,"img",{...e,imageType:"png"})},toJpegUrl(r){return G(r,"img",{...e,imageType:"jpeg"})},toWebpUrl(r){return G(r,"img",{...e,imageType:"webp"})},toPdfUrl(r){return G(r,"pdf",e)},getBaseUrl(){return t},getOptions(){return{...e}}}}var ro=()=>{throw new Error("createLiveVisualizer is not available in browser. It requires Node.js process.stdout.")};function Ve(e={}){let{workflowName:t,detectParallel:r=!0,showTimings:o=!0,showKeys:i=!1,colors:n}=e,a=he({detectParallel:r}),s=new Set,u=le(),c=ie(),l=De(),p=fe(),g={showTimings:o,showKeys:i,terminalWidth:80,colors:{...V,...n}};function f(){if(s.size>0){let m=a.getIR();for(let w of s)w(m)}}function y(m){if(m.type==="scope_start"||m.type==="scope_end"){k(m);return}a.handleEvent(m),m.type,f()}function k(m){a.handleScopeEvent(m),f()}function $(m){a.handleDecisionEvent(m),f()}function M(){let m=a.getIR();return t&&!m.root.name&&(m.root.name=t),m}function N(){let m=M();return u.render(m,g)}function I(m){let w=M();switch(m){case"ascii":return u.render(w,g);case"mermaid":return c.render(w,g);case"json":{let R=w.hooks?{...w,hooks:{...w.hooks,onAfterStep:w.hooks.onAfterStep instanceof Map?Object.fromEntries(w.hooks.onAfterStep):w.hooks.onAfterStep??{}}}:w;return JSON.stringify(R,(E,T)=>typeof T=="bigint"?T.toString():T,2)}case"logger":return l.render(w,g);case"flowchart":return p.render(w,g);default:throw new Error(`Unknown format: ${m}`)}}function v(){a.reset(),f()}function x(m){return s.add(m),()=>s.delete(m)}return{handleEvent:y,handleScopeEvent:k,handleDecisionEvent:$,getIR:M,render:N,renderAs:I,reset:v,onUpdate:x}}function no(...e){return(t,r)=>{for(let o of e)o(t,r)}}function oo(e,t={}){let r=Ve(t);for(let o of e)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()}function io(e={}){let t=[];return{handleEvent:r=>{t.push(r)},handleDecisionEvent:r=>{t.push(r)},getEvents:()=>[...t],getWorkflowEvents:()=>t.filter(r=>!r.type.startsWith("decision_")),getDecisionEvents:()=>t.filter(r=>r.type.startsWith("decision_")),clear:()=>{t.length=0},visualize:()=>{let r=Ve(e);for(let o of t)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()},visualizeAs:r=>{let o=Ve(e);for(let i of t)i.type.startsWith("decision_")?o.handleDecisionEvent(i):o.handleEvent(i);return o.renderAs(r)}}}export{le as asciiRenderer,bt as buildMermaidInkUrl,no as combineEventHandlers,io as createEventCollector,he as createIRBuilder,ro as createLiveVisualizer,Qr as createMermaidInkGenerator,$t as createParallelDetector,jt as createPerformanceAnalyzer,Ar as createTimeTravelController,jr as createUrlGenerator,Ve as createVisualizer,V as defaultColorScheme,ve as detectParallelGroups,wt as encodeForMermaidInk,fe as flowchartRenderer,be as getHeatLevel,an as hasChildren,Lr as htmlRenderer,J as isDecisionNode,j as isParallelNode,F as isRaceNode,Ge as isSequenceNode,K as isStepNode,ee as isStreamNode,De as loggerRenderer,ie as mermaidRenderer,_r as renderToHTML,Kr as toKrokiPngUrl,Ur as toKrokiSvgUrl,ce as toKrokiUrl,Xr as toMermaidInkJpegUrl,Zr as toMermaidInkPdfUrl,Jr as toMermaidInkPngUrl,Yr as toMermaidInkSvgUrl,G as toMermaidInkUrl,qr as toMermaidInkWebpUrl,je as trackDecision,Wr as trackIf,Br as trackSwitch,oo as visualizeEvents};
1677
+ //# sourceMappingURL=index.browser.js.map