cli-jaw 1.6.27 → 1.7.1

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.
@@ -0,0 +1,134 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-render-Bjnw0wQ6.css"])))=>i.map(i=>d[i]);
2
+ import{t as e}from"./state-O6NVkWcL.js";import{i as t,t as n}from"./api-DygAf_G_.js";import{Z as r}from"./vendor-mermaid-C2RBgdM6.js";import{c as i,h as a,i as o,l as s,n as c,o as l,r as u,s as d}from"./render-greWRQT7.js";import{a as f,i as p,r as m,t as ee}from"./idb-cache-DbK81tgv.js";function h(){let e=globalThis.crypto;if(typeof e?.randomUUID==`function`)return e.randomUUID();if(typeof e?.getRandomValues!=`function`)return`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)});let t=new Uint8Array(16);e.getRandomValues(t),t[6]=t[6]&15|64,t[8]=t[8]&63|128;let n=Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``);return`${n.slice(0,8)}-${n.slice(8,12)}-${n.slice(12,16)}-${n.slice(16,20)}-${n.slice(20)}`}var te=`agentName`,g=`CLI-JAW`,_=g;function ne(){return _}function re(e){_=(e||``).trim()||g,localStorage.setItem(te,_);let t=document.getElementById(`appNameInput`);t&&(t.value=_)}function ie(){_=localStorage.getItem(te)||g;let e=document.getElementById(`appNameInput`);e&&(e.value=_),document.getElementById(`appNameSave`)?.addEventListener(`click`,()=>{let e=document.getElementById(`appNameInput`);e&&re(e.value)}),document.getElementById(`appNameInput`)?.addEventListener(`keydown`,e=>{let t=e;t.key===`Enter`&&(t.preventDefault(),re(t.target.value),t.target.blur())})}var ae=`agentAvatar`,oe=`userAvatar`,se=d.shark,ce=d.user,le={agent:{emoji:se,imageUrl:``,updatedAt:null},user:{emoji:ce,imageUrl:``,updatedAt:null}},ue=!1;function v(e){return le[e]}function de(e){return e===`agent`?`agentAvatarPreview`:`userAvatarPreview`}function fe(e){return e===`agent`?`.agent-icon`:`.user-icon`}function y(e){let t=document.getElementById(de(e));if(t){t.innerHTML=b(e);let n=v(e).imageUrl?`image`:`emoji`;t.setAttribute(`data-avatar-kind`,n)}}function b(e){let t=v(e);return t.imageUrl?`<img class="avatar-image" src="${c(t.imageUrl)}" alt="" loading="lazy" decoding="async">`:t.emoji}function x(e){let t=b(e),n=v(e).imageUrl?`image`:`emoji`;document.querySelectorAll(fe(e)).forEach(e=>{e.innerHTML=t,e.setAttribute(`data-avatar-kind`,n)})}function S(e,t){t?.kind===`image`&&t.imageUrl?(v(e).imageUrl=t.imageUrl,v(e).updatedAt=t.updatedAt??Date.now()):(v(e).imageUrl=``,v(e).updatedAt=t?.updatedAt??null),y(e),x(e)}async function pe(){let e=await n(`/api/avatar`);e&&(S(`agent`,e.agent),S(`user`,e.user))}async function me(e,n){let r=await t(),i=new Headers(n.headers||{});return r&&i.set(`Authorization`,`Bearer ${r}`),fetch(e,{...n,headers:i})}async function he(e,t){let n=await me(`/api/avatar/${e}/upload`,{method:`POST`,headers:{"X-Filename":encodeURIComponent(t.name)},body:t}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`avatar upload failed (${n.status})`);S(e,r?.data||r)}async function ge(e){let t=await me(`/api/avatar/${e}/image`,{method:`DELETE`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||`avatar reset failed (${t.status})`);S(e,n?.data||n)}function _e(e){let t=e===`agent`?`agentAvatarUploadBtn`:`userAvatarUploadBtn`,n=e===`agent`?`agentAvatarResetBtn`:`userAvatarResetBtn`,r=e===`agent`?`agentAvatarFile`:`userAvatarFile`;document.getElementById(t)?.addEventListener(`click`,()=>{document.getElementById(r)?.click()}),document.getElementById(n)?.addEventListener(`click`,async()=>{try{await ge(e)}catch(e){console.warn(`[avatar:reset]`,e.message)}}),document.getElementById(r)?.addEventListener(`change`,async t=>{let n=t.target,r=n.files?.[0];if(r)try{await he(e,r)}catch(e){console.warn(`[avatar:upload]`,e.message)}finally{n.value=``}})}function ve(){return b(`agent`)}function ye(){return b(`user`)}async function be(){v(`agent`).emoji=localStorage.getItem(ae)||se,v(`user`).emoji=localStorage.getItem(oe)||ce,y(`agent`),y(`user`),ue||(ue=!0,_e(`agent`),_e(`user`)),await pe(),x(`agent`),x(`user`)}function C(e,t,n){let r=n.initialDeps??[],i,a=!0;function o(){let o;n.key&&n.debug?.call(n)&&(o=Date.now());let s=e();if(!(s.length!==r.length||s.some((e,t)=>r[t]!==e)))return i;r=s;let c;if(n.key&&n.debug?.call(n)&&(c=Date.now()),i=t(...s),n.key&&n.debug?.call(n)){let e=Math.round((Date.now()-o)*100)/100,t=Math.round((Date.now()-c)*100)/100,r=t/16,i=(e,t)=>{for(e=String(e);e.length<t;)e=` `+e;return e};console.info(`%c⏱ ${i(t,5)} /${i(e,5)} ms`,`
3
+ font-size: .6rem;
4
+ font-weight: bold;
5
+ color: hsl(${Math.max(0,Math.min(120-120*r,120))}deg 100% 31%);`,n?.key)}return n?.onChange&&!(a&&n.skipInitialOnChange)&&n.onChange(i),a=!1,i}return o.updateDeps=e=>{r=e},o}function xe(e,t){if(e===void 0)throw Error(`Unexpected undefined${t?`: ${t}`:``}`);return e}var Se=(e,t)=>Math.abs(e-t)<1.01,Ce=(e,t,n)=>{let r;return function(...i){e.clearTimeout(r),r=e.setTimeout(()=>t.apply(this,i),n)}},we=e=>{let{offsetWidth:t,offsetHeight:n}=e;return{width:t,height:n}},Te=e=>e,Ee=e=>{let t=Math.max(e.startIndex-e.overscan,0),n=Math.min(e.endIndex+e.overscan,e.count-1),r=[];for(let e=t;e<=n;e++)r.push(e);return r},De=(e,t)=>{let n=e.scrollElement;if(!n)return;let r=e.targetWindow;if(!r)return;let i=e=>{let{width:n,height:r}=e;t({width:Math.round(n),height:Math.round(r)})};if(i(we(n)),!r.ResizeObserver)return()=>{};let a=new r.ResizeObserver(t=>{let r=()=>{let e=t[0];if(e?.borderBoxSize){let t=e.borderBoxSize[0];if(t){i({width:t.inlineSize,height:t.blockSize});return}}i(we(n))};e.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(r):r()});return a.observe(n,{box:`border-box`}),()=>{a.unobserve(n)}},w={passive:!0},T=typeof window>`u`?!0:`onscrollend`in window,Oe=(e,t)=>{let n=e.scrollElement;if(!n)return;let r=e.targetWindow;if(!r)return;let i=0,a=e.options.useScrollendEvent&&T?()=>void 0:Ce(r,()=>{t(i,!1)},e.options.isScrollingResetDelay),o=r=>()=>{let{horizontal:o,isRtl:s}=e.options;i=o?n.scrollLeft*(s&&-1||1):n.scrollTop,a(),t(i,r)},s=o(!0),c=o(!1);n.addEventListener(`scroll`,s,w);let l=e.options.useScrollendEvent&&T;return l&&n.addEventListener(`scrollend`,c,w),()=>{n.removeEventListener(`scroll`,s),l&&n.removeEventListener(`scrollend`,c)}},ke=(e,t,n)=>{if(t?.borderBoxSize){let e=t.borderBoxSize[0];if(e)return Math.round(e[n.options.horizontal?`inlineSize`:`blockSize`])}return e[n.options.horizontal?`offsetWidth`:`offsetHeight`]},Ae=(e,{adjustments:t=0,behavior:n},r)=>{var i,a;let o=e+t;(a=(i=r.scrollElement)?.scrollTo)==null||a.call(i,{[r.options.horizontal?`left`:`top`]:o,behavior:n})},je=class{constructor(e){this.unsubs=[],this.scrollElement=null,this.targetWindow=null,this.isScrolling=!1,this.scrollState=null,this.measurementsCache=[],this.itemSizeCache=new Map,this.laneAssignments=new Map,this.pendingMeasuredCacheIndexes=[],this.prevLanes=void 0,this.lanesChangedFlag=!1,this.lanesSettling=!1,this.scrollRect=null,this.scrollOffset=null,this.scrollDirection=null,this.scrollAdjustments=0,this.elementsCache=new Map,this.now=()=>{var e;return((e=this.targetWindow?.performance)?.now)?.call(e)??Date.now()},this.observer=(()=>{let e=null,t=()=>e||(!this.targetWindow||!this.targetWindow.ResizeObserver?null:e=new this.targetWindow.ResizeObserver(e=>{e.forEach(e=>{let t=()=>{let t=e.target,n=this.indexFromElement(t);if(!t.isConnected){this.observer.unobserve(t);return}this.shouldMeasureDuringScroll(n)&&this.resizeItem(n,this.options.measureElement(t,e,this))};this.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(t):t()})}));return{disconnect:()=>{var n;(n=t())==null||n.disconnect(),e=null},observe:e=>t()?.observe(e,{box:`border-box`}),unobserve:e=>t()?.unobserve(e)}})(),this.range=null,this.setOptions=e=>{Object.entries(e).forEach(([t,n])=>{n===void 0&&delete e[t]}),this.options={debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:Te,rangeExtractor:Ee,onChange:()=>{},measureElement:ke,initialRect:{width:0,height:0},scrollMargin:0,gap:0,indexAttribute:`data-index`,initialMeasurementsCache:[],lanes:1,isScrollingResetDelay:150,enabled:!0,isRtl:!1,useScrollendEvent:!1,useAnimationFrameWithResizeObserver:!1,...e}},this.notify=e=>{var t,n;(n=(t=this.options).onChange)==null||n.call(t,this,e)},this.maybeNotify=C(()=>(this.calculateRange(),[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]),e=>{this.notify(e)},{key:!1,debug:()=>this.options.debug,initialDeps:[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]}),this.cleanup=()=>{this.unsubs.filter(Boolean).forEach(e=>e()),this.unsubs=[],this.observer.disconnect(),this.rafId!=null&&this.targetWindow&&(this.targetWindow.cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollState=null,this.scrollElement=null,this.targetWindow=null},this._didMount=()=>()=>{this.cleanup()},this._willUpdate=()=>{let e=this.options.enabled?this.options.getScrollElement():null;if(this.scrollElement!==e){if(this.cleanup(),!e){this.maybeNotify();return}this.scrollElement=e,this.scrollElement&&`ownerDocument`in this.scrollElement?this.targetWindow=this.scrollElement.ownerDocument.defaultView:this.targetWindow=this.scrollElement?.window??null,this.elementsCache.forEach(e=>{this.observer.observe(e)}),this.unsubs.push(this.options.observeElementRect(this,e=>{this.scrollRect=e,this.maybeNotify()})),this.unsubs.push(this.options.observeElementOffset(this,(e,t)=>{this.scrollAdjustments=0,this.scrollDirection=t?this.getScrollOffset()<e?`forward`:`backward`:null,this.scrollOffset=e,this.isScrolling=t,this.scrollState&&this.scheduleScrollReconcile(),this.maybeNotify()})),this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})}},this.rafId=null,this.getSize=()=>this.options.enabled?(this.scrollRect=this.scrollRect??this.options.initialRect,this.scrollRect[this.options.horizontal?`width`:`height`]):(this.scrollRect=null,0),this.getScrollOffset=()=>this.options.enabled?(this.scrollOffset=this.scrollOffset??(typeof this.options.initialOffset==`function`?this.options.initialOffset():this.options.initialOffset),this.scrollOffset):(this.scrollOffset=null,0),this.getFurthestMeasurement=(e,t)=>{let n=new Map,r=new Map;for(let i=t-1;i>=0;i--){let t=e[i];if(n.has(t.lane))continue;let a=r.get(t.lane);if(a==null||t.end>a.end?r.set(t.lane,t):t.end<a.end&&n.set(t.lane,!0),n.size===this.options.lanes)break}return r.size===this.options.lanes?Array.from(r.values()).sort((e,t)=>e.end===t.end?e.index-t.index:e.end-t.end)[0]:void 0},this.getMeasurementOptions=C(()=>[this.options.count,this.options.paddingStart,this.options.scrollMargin,this.options.getItemKey,this.options.enabled,this.options.lanes],(e,t,n,r,i,a)=>(this.prevLanes!==void 0&&this.prevLanes!==a&&(this.lanesChangedFlag=!0),this.prevLanes=a,this.pendingMeasuredCacheIndexes=[],{count:e,paddingStart:t,scrollMargin:n,getItemKey:r,enabled:i,lanes:a}),{key:!1}),this.getMeasurements=C(()=>[this.getMeasurementOptions(),this.itemSizeCache],({count:e,paddingStart:t,scrollMargin:n,getItemKey:r,enabled:i,lanes:a},o)=>{if(!i)return this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),[];if(this.laneAssignments.size>e)for(let t of this.laneAssignments.keys())t>=e&&this.laneAssignments.delete(t);this.lanesChangedFlag&&(this.lanesChangedFlag=!1,this.lanesSettling=!0,this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),this.pendingMeasuredCacheIndexes=[]),this.measurementsCache.length===0&&!this.lanesSettling&&(this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach(e=>{this.itemSizeCache.set(e.key,e.size)}));let s=this.lanesSettling?0:this.pendingMeasuredCacheIndexes.length>0?Math.min(...this.pendingMeasuredCacheIndexes):0;this.pendingMeasuredCacheIndexes=[],this.lanesSettling&&this.measurementsCache.length===e&&(this.lanesSettling=!1);let c=this.measurementsCache.slice(0,s),l=Array(a).fill(void 0);for(let e=0;e<s;e++){let t=c[e];t&&(l[t.lane]=e)}for(let i=s;i<e;i++){let e=r(i),a=this.laneAssignments.get(i),s,u;if(a!==void 0&&this.options.lanes>1){s=a;let e=l[s],r=e===void 0?void 0:c[e];u=r?r.end+this.options.gap:t+n}else{let e=this.options.lanes===1?c[i-1]:this.getFurthestMeasurement(c,i);u=e?e.end+this.options.gap:t+n,s=e?e.lane:i%this.options.lanes,this.options.lanes>1&&this.laneAssignments.set(i,s)}let d=o.get(e),f=typeof d==`number`?d:this.options.estimateSize(i),p=u+f;c[i]={index:i,start:u,size:f,end:p,key:e,lane:s},l[s]=i}return this.measurementsCache=c,c},{key:!1,debug:()=>this.options.debug}),this.calculateRange=C(()=>[this.getMeasurements(),this.getSize(),this.getScrollOffset(),this.options.lanes],(e,t,n,r)=>this.range=e.length>0&&t>0?Me({measurements:e,outerSize:t,scrollOffset:n,lanes:r}):null,{key:!1,debug:()=>this.options.debug}),this.getVirtualIndexes=C(()=>{let e=null,t=null,n=this.calculateRange();return n&&(e=n.startIndex,t=n.endIndex),this.maybeNotify.updateDeps([this.isScrolling,e,t]),[this.options.rangeExtractor,this.options.overscan,this.options.count,e,t]},(e,t,n,r,i)=>r===null||i===null?[]:e({startIndex:r,endIndex:i,overscan:t,count:n}),{key:!1,debug:()=>this.options.debug}),this.indexFromElement=e=>{let t=this.options.indexAttribute,n=e.getAttribute(t);return n?parseInt(n,10):(console.warn(`Missing attribute name '${t}={index}' on measured element.`),-1)},this.shouldMeasureDuringScroll=e=>{if(!this.scrollState||this.scrollState.behavior!==`smooth`)return!0;let t=this.scrollState.index??this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)?.index;if(t!==void 0&&this.range){let n=Math.max(this.options.overscan,Math.ceil((this.range.endIndex-this.range.startIndex)/2)),r=Math.max(0,t-n),i=Math.min(this.options.count-1,t+n);return e>=r&&e<=i}return!0},this.measureElement=e=>{if(!e){this.elementsCache.forEach((e,t)=>{e.isConnected||(this.observer.unobserve(e),this.elementsCache.delete(t))});return}let t=this.indexFromElement(e),n=this.options.getItemKey(t),r=this.elementsCache.get(n);r!==e&&(r&&this.observer.unobserve(r),this.observer.observe(e),this.elementsCache.set(n,e)),(!this.isScrolling||this.scrollState)&&this.shouldMeasureDuringScroll(t)&&this.resizeItem(t,this.options.measureElement(e,void 0,this))},this.resizeItem=(e,t)=>{let n=this.measurementsCache[e];if(!n)return;let r=t-(this.itemSizeCache.get(n.key)??n.size);r!==0&&(this.scrollState?.behavior!==`smooth`&&(this.shouldAdjustScrollPositionOnItemSizeChange===void 0?n.start<this.getScrollOffset()+this.scrollAdjustments:this.shouldAdjustScrollPositionOnItemSizeChange(n,r,this))&&this._scrollToOffset(this.getScrollOffset(),{adjustments:this.scrollAdjustments+=r,behavior:void 0}),this.pendingMeasuredCacheIndexes.push(n.index),this.itemSizeCache=new Map(this.itemSizeCache.set(n.key,t)),this.notify(!1))},this.getVirtualItems=C(()=>[this.getVirtualIndexes(),this.getMeasurements()],(e,t)=>{let n=[];for(let r=0,i=e.length;r<i;r++){let i=t[e[r]];n.push(i)}return n},{key:!1,debug:()=>this.options.debug}),this.getVirtualItemForOffset=e=>{let t=this.getMeasurements();if(t.length!==0)return xe(t[E(0,t.length-1,e=>xe(t[e]).start,e)])},this.getMaxScrollOffset=()=>{if(!this.scrollElement)return 0;if(`scrollHeight`in this.scrollElement)return this.options.horizontal?this.scrollElement.scrollWidth-this.scrollElement.clientWidth:this.scrollElement.scrollHeight-this.scrollElement.clientHeight;{let e=this.scrollElement.document.documentElement;return this.options.horizontal?e.scrollWidth-this.scrollElement.innerWidth:e.scrollHeight-this.scrollElement.innerHeight}},this.getOffsetForAlignment=(e,t,n=0)=>{if(!this.scrollElement)return 0;let r=this.getSize(),i=this.getScrollOffset();t===`auto`&&(t=e>=i+r?`end`:`start`),t===`center`?e+=(n-r)/2:t===`end`&&(e-=r);let a=this.getMaxScrollOffset();return Math.max(Math.min(a,e),0)},this.getOffsetForIndex=(e,t=`auto`)=>{e=Math.max(0,Math.min(e,this.options.count-1));let n=this.getSize(),r=this.getScrollOffset(),i=this.measurementsCache[e];if(!i)return;if(t===`auto`)if(i.end>=r+n-this.options.scrollPaddingEnd)t=`end`;else if(i.start<=r+this.options.scrollPaddingStart)t=`start`;else return[r,t];if(t===`end`&&e===this.options.count-1)return[this.getMaxScrollOffset(),t];let a=t===`end`?i.end+this.options.scrollPaddingEnd:i.start-this.options.scrollPaddingStart;return[this.getOffsetForAlignment(a,t,i.size),t]},this.scrollToOffset=(e,{align:t=`start`,behavior:n=`auto`}={})=>{let r=this.getOffsetForAlignment(e,t);this.scrollState={index:null,align:t,behavior:n,startedAt:this.now(),lastTargetOffset:r,stableFrames:0},this._scrollToOffset(r,{adjustments:void 0,behavior:n}),this.scheduleScrollReconcile()},this.scrollToIndex=(e,{align:t=`auto`,behavior:n=`auto`}={})=>{e=Math.max(0,Math.min(e,this.options.count-1));let r=this.getOffsetForIndex(e,t);if(!r)return;let[i,a]=r,o=this.now();this.scrollState={index:e,align:a,behavior:n,startedAt:o,lastTargetOffset:i,stableFrames:0},this._scrollToOffset(i,{adjustments:void 0,behavior:n}),this.scheduleScrollReconcile()},this.scrollBy=(e,{behavior:t=`auto`}={})=>{let n=this.getScrollOffset()+e;this.scrollState={index:null,align:`start`,behavior:t,startedAt:this.now(),lastTargetOffset:n,stableFrames:0},this._scrollToOffset(n,{adjustments:void 0,behavior:t}),this.scheduleScrollReconcile()},this.getTotalSize=()=>{let e=this.getMeasurements(),t;if(e.length===0)t=this.options.paddingStart;else if(this.options.lanes===1)t=e[e.length-1]?.end??0;else{let n=Array(this.options.lanes).fill(null),r=e.length-1;for(;r>=0&&n.some(e=>e===null);){let t=e[r];n[t.lane]===null&&(n[t.lane]=t.end),r--}t=Math.max(...n.filter(e=>e!==null))}return Math.max(t-this.options.scrollMargin+this.options.paddingEnd,0)},this._scrollToOffset=(e,{adjustments:t,behavior:n})=>{this.options.scrollToFn(e,{behavior:n,adjustments:t},this)},this.measure=()=>{this.itemSizeCache=new Map,this.laneAssignments=new Map,this.notify(!1)},this.setOptions(e)}scheduleScrollReconcile(){if(!this.targetWindow){this.scrollState=null;return}this.rafId??=this.targetWindow.requestAnimationFrame(()=>{this.rafId=null,this.reconcileScroll()})}reconcileScroll(){if(!this.scrollState||!this.scrollElement)return;if(this.now()-this.scrollState.startedAt>5e3){this.scrollState=null;return}let e=this.scrollState.index==null?void 0:this.getOffsetForIndex(this.scrollState.index,this.scrollState.align),t=e?e[0]:this.scrollState.lastTargetOffset,n=t!==this.scrollState.lastTargetOffset;if(!n&&Se(t,this.getScrollOffset())){if(this.scrollState.stableFrames++,this.scrollState.stableFrames>=1){this.scrollState=null;return}}else this.scrollState.stableFrames=0,n&&(this.scrollState.lastTargetOffset=t,this.scrollState.behavior=`auto`,this._scrollToOffset(t,{adjustments:void 0,behavior:`auto`}));this.scheduleScrollReconcile()}},E=(e,t,n,r)=>{for(;e<=t;){let i=(e+t)/2|0,a=n(i);if(a<r)e=i+1;else if(a>r)t=i-1;else return i}return e>0?e-1:0};function Me({measurements:e,outerSize:t,scrollOffset:n,lanes:r}){let i=e.length-1,a=t=>e[t].start;if(e.length<=r)return{startIndex:0,endIndex:i};let o=E(0,i,a,n),s=o;if(r===1)for(;s<i&&e[s].end<n+t;)s++;else if(r>1){let a=Array(r).fill(0);for(;s<i&&a.some(e=>e<n+t);){let t=e[s];a[t.lane]=t.end,s++}let c=Array(r).fill(n+t);for(;o>=0&&c.some(e=>e>=n);){let t=e[o];c[t.lane]=t.start,o--}o=Math.max(0,o-o%r),s=Math.min(i,s+(r-1-s%r))}return{startIndex:o,endIndex:s}}var D=80,Ne=5,Pe=class{items=[];container;innerEl;_active=!1;virtualizer=null;cleanupFn=null;mounted=new Map;itemGap=0;onLazyRender=null;onPostRender=null;constructor(e){this.container=document.getElementById(e),this.innerEl=document.createElement(`div`),this.innerEl.className=`vs-inner`}get active(){return this._active}get count(){return this.items.length}measureGap(){if(this.itemGap>0)return this.itemGap;let e=document.createElement(`div`);return e.className=`msg`,e.style.position=`absolute`,e.style.visibility=`hidden`,e.textContent=` `,this.innerEl.appendChild(e),this.itemGap=parseFloat(getComputedStyle(e).marginBottom)||0,e.remove(),this.itemGap}setItems(e,t){this.items=e,t?.autoActivate!==!1&&!this._active&&this.items.length>=80&&this.activate(t?.toBottom??!0)}seedMeasuredHeights(e,t){for(let n=0;n<t.length;n++){let r=e+n;this.items[r]&&(this.items[r].height=t[n])}}activateIfNeeded(e=!1){!this._active&&this.items.length>=80&&this.activate(e)}addItem(e,t){let n={id:e,html:t,height:D};if(this.items.push(n),!this._active&&this.items.length>=80){this.activate(!0);return}this._active&&this.virtualizer&&this.virtualizer.setOptions({...this.virtualizer.options,count:this.items.length})}appendLiveItem(e){if(!this._active)return;let t=e.outerHTML,n=h();this.items.push({id:n,html:t,height:D}),this.virtualizer&&this.virtualizer.setOptions({...this.virtualizer.options,count:this.items.length})}updateItemHtml(e,t){this.items[e]&&(this.items[e].html=t)}scrollToBottom(){this.container.scrollTop=this.container.scrollHeight}flushToDOM(){this._active&&(this.deactivate(),this.container.innerHTML=this.items.map(e=>e.html).join(``),this.items=[])}clear(){this.deactivate(),this.items=[],this.itemGap=0,this.onLazyRender=null,this.onPostRender=null}activate(e=!1){this._active=!0,this.container.querySelectorAll(`.msg`).forEach((e,t)=>{this.items[t]&&(this.items[t].height=e.getBoundingClientRect().height)}),this.container.classList.add(`vs-active`),this.container.replaceChildren(this.innerEl),this.measureGap(),this.virtualizer=new je({count:this.items.length,getScrollElement:()=>this.container,estimateSize:e=>this.items[e]?.height??D,overscan:Ne,gap:this.itemGap,useAnimationFrameWithResizeObserver:!0,onChange:()=>this.renderItems(),observeElementRect:De,observeElementOffset:Oe,scrollToFn:Ae,getItemKey:e=>this.items[e]?.id??e,indexAttribute:`data-vs-idx`}),this.cleanupFn=this.virtualizer._didMount(),this.virtualizer._willUpdate(),e&&this.items.length>0?(this.container.style.opacity=`0`,this.renderItems(),this.virtualizer.scrollToIndex(this.items.length-1,{align:`end`}),requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.container.style.opacity=``})})):this.renderItems()}deactivate(){this.cleanupFn&&=(this.cleanupFn(),null),this.virtualizer=null,this._active=!1,this.mounted.clear(),this.container.classList.remove(`vs-active`),this.container.innerHTML=``}renderItems(){if(!this.virtualizer)return;this.virtualizer._willUpdate();let e=this.virtualizer.getVirtualItems(),t=this.virtualizer.getTotalSize();this.innerEl.style.height=`${t}px`;let n=new Set(e.map(e=>e.index));for(let[e,t]of this.mounted)n.has(e)||(t.remove(),this.mounted.delete(e));let r=[];for(let t of e){let e=this.mounted.get(t.index);if(!e){let n=this.items[t.index];if(!n)continue;let i=document.createElement(`div`);if(i.innerHTML=n.html,e=i.firstElementChild,!e)continue;e.dataset.vsIdx=String(t.index),this.innerEl.appendChild(e),this.mounted.set(t.index,e),r.push(e)}e.style.transform=`translateY(${t.start}px)`}for(let e of r)this.virtualizer.measureElement(e);if(this.onLazyRender){let e=this.innerEl.querySelectorAll(`.lazy-pending`);e.length>0&&this.onLazyRender(Array.from(e))}this.onPostRender&&this.onPostRender(this.innerEl)}},O=null;function k(){return O||=new Pe(`chatMessages`),O}function Fe(e,t){t.registerCallbacks(),t.setItems(e,{autoActivate:!1}),t.activateIfNeeded(!0),t.scrollToBottom()}var Ie=2e3,Le=80;function Re(e){return{chunks:[],fullText:``,textDirty:!1,element:e,pendingRAF:null,isFinalized:!1,lastRenderTime:0}}function A(e){return e.textDirty&&=(e.fullText=e.chunks.join(``),!1),e.fullText}function ze(e,t){e.chunks.push(t),e.textDirty=!0,!e.pendingRAF&&!e.isFinalized&&(e.pendingRAF=requestAnimationFrame(()=>{if(e.pendingRAF=null,e.isFinalized)return;let t=performance.now(),n=A(e);n.length<Ie||t-e.lastRenderTime>Le?(e.element.innerHTML=o(n,!0)+`<span class="stream-cursor" aria-hidden="true"></span>`,e.lastRenderTime=t):e.pendingRAF=requestAnimationFrame(()=>{e.pendingRAF=null,!e.isFinalized&&(e.element.innerHTML=o(A(e),!0)+`<span class="stream-cursor" aria-hidden="true"></span>`,e.lastRenderTime=performance.now())})}))}function Be(e,t=!1){e.isFinalized=!0,e.pendingRAF&&=(cancelAnimationFrame(e.pendingRAF),null);let n=A(e);return t||(e.element.innerHTML=o(n)),n}var j=[`cdnjs.cloudflare.com`,`cdn.jsdelivr.net`,`unpkg.com`,`esm.sh`,`fonts.googleapis.com`,`fonts.gstatic.com`],Ve=[/\beval\s*\(/,/\bnew\s+Function\s*\(/,/\bdocument\.cookie\b/,/\bwindow\.opener\b/,/\bwindow\.top\b/,/\bparent\.postMessage\b(?!.*jaw-)/,/\blocation\.href\s*=/,/\bwindow\.location\b/,/\bsetTimeout\s*\(\s*["'`]/,/\bsetInterval\s*\(\s*["'`]/,/\.constructor\s*\.\s*constructor/,/\bdocument\.write\s*\(/,/\binsertAdjacentHTML\s*\(/,/\bimport\s*\(/],He=[];function Ue(e){let t=[];if(e.length>524288)return{valid:!1,reason:`Payload too large (>512KB)`,warnings:t};let n=/(?:src|href)\s*=\s*["']https?:\/\/([^/"']+)/gi,r;for(;(r=n.exec(e))!==null;){let e=r[1];if(!j.some(t=>e===t||e.endsWith(`.`+t)))return{valid:!1,reason:`Blocked domain: ${e}`,warnings:t}}let i=/url\s*\(\s*['"]?https?:\/\/([^)'"]+)/gi;for(;(r=i.exec(e))!==null;){let e=r[1].split(`/`)[0];j.some(t=>e===t||e.endsWith(`.`+t))||t.push(`CSS url() references external domain: ${e}`)}for(let n of Ve)if(n.test(e))return{valid:!1,reason:`Dangerous pattern: ${n.source}`,warnings:t};for(let n of He)n.test(e)&&t.push(`DOM sink detected: ${n.source}`);return{valid:!0,warnings:t}}function We(){let e=document.createElement(`button`);return e.className=`diagram-copy-btn`,e.type=`button`,e.ariaLabel=`Copy source`,e.title=`Copy`,e.innerHTML=d.copy,e}function Ge(){let e=document.createElement(`button`);return e.className=`diagram-save-btn`,e.type=`button`,e.ariaLabel=`Save as image`,e.title=`Save`,e.innerHTML=d.download,e}var Ke=[`cdnjs.cloudflare.com`,`cdn.jsdelivr.net`,`unpkg.com`,`esm.sh`,`fonts.googleapis.com`,`fonts.gstatic.com`],M=new Set,N=new Map,P=null;function qe(){if(P)return;let e=document.getElementById(`chatMessages`);e&&(P=new MutationObserver(e=>{if(M.size)for(let t of e)for(let e of t.removedNodes)e instanceof HTMLIFrameElement&&e.contentWindow&&(M.delete(e.contentWindow),N.delete(e.contentWindow)),e instanceof HTMLElement&&e.querySelectorAll(`iframe`).forEach(e=>{e.contentWindow&&(M.delete(e.contentWindow),N.delete(e.contentWindow))})}),P.observe(e,{childList:!0,subtree:!0}))}function Je(e){if(e.includes(`"importmap"`)||e.includes(`'importmap'`))return``;let t={},n=e.match(/(?:cdn\.jsdelivr\.net\/npm|unpkg\.com)\/three@([\d.]+)/);if(n){let r=n[1],i=e.includes(`unpkg.com/three@`)?`unpkg.com`:`cdn.jsdelivr.net/npm`;t.three=`https://${i}/three@${r}/${i===`unpkg.com`?`build/three.module.js`:`build/three.module.min.js`}`,t[`three/addons/`]=`https://${i}/three@${r}/examples/jsm/`}return Object.keys(t).length===0?``:`<script type="importmap">${JSON.stringify({imports:t})}<\/script>`}function Ye(e){let t=`'none'`;(e.includes(`cdn.jsdelivr.net/npm/us-atlas`)||e.includes(`cdn.jsdelivr.net/npm/world-atlas`)||e.includes(`cdn.jsdelivr.net/npm/datamaps`))&&(t=`https://cdn.jsdelivr.net`);let n=/Tone\.min\.js|tone@/.test(e)?`worker-src blob:;`:``,r=Ke.map(e=>`https://${e}`),i=r.join(` `),a=[`data:`,`blob:`,...r],o=[`'unsafe-inline'`,`https://fonts.googleapis.com`];/L\.(map|tileLayer|marker|geoJSON|polyline|polygon|circle)\(|leaflet[\w.@/-]*\.(js|css)|tile\.openstreetmap\.org/.test(e)&&(a.push(`https://a.tile.openstreetmap.org`,`https://b.tile.openstreetmap.org`,`https://c.tile.openstreetmap.org`),o.push(`https://cdnjs.cloudflare.com`,`https://cdn.jsdelivr.net`));let s=a.join(` `);return`<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline' ${i}; style-src ${o.join(` `)}; img-src ${s}; font-src https://fonts.gstatic.com; connect-src ${t}; ${n} base-uri 'none';">`}function Xe(){let e=!document.documentElement.hasAttribute(`data-theme`)||document.documentElement.getAttribute(`data-theme`)===`dark`,t=getComputedStyle(document.documentElement);return{isDark:e,tokens:{"--bg":t.getPropertyValue(`--bg`).trim(),"--surface":t.getPropertyValue(`--surface`).trim(),"--border":t.getPropertyValue(`--border`).trim(),"--text":t.getPropertyValue(`--text`).trim(),"--text-dim":t.getPropertyValue(`--text-dim`).trim(),"--accent":t.getPropertyValue(`--accent`).trim(),"--font-ui":t.getPropertyValue(`--font-ui`).trim(),"--font-mono":t.getPropertyValue(`--font-mono`).trim(),"--radius-sm":t.getPropertyValue(`--radius-sm`).trim(),"--radius-md":t.getPropertyValue(`--radius-md`).trim()}}}function Ze(e){return`
6
+ <script>
7
+ (function() {
8
+ var __nonce = '${e}';
9
+
10
+ window.addEventListener('message', function(e) {
11
+ if (e.source !== window.parent) return;
12
+ if (!e.data || typeof e.data !== 'object') return;
13
+
14
+ if (e.data.type === 'jaw-theme-update') {
15
+ window.__jawTheme = { isDark: !!e.data.isDark };
16
+ window.__jawTokens = e.data.tokens || {};
17
+ window.dispatchEvent(new CustomEvent('jaw-theme-change', { detail: window.__jawTheme }));
18
+ }
19
+ if (e.data.type === 'jaw-request-resize') {
20
+ postHeight();
21
+ }
22
+ if (e.data.type === 'jaw-request-screenshot') {
23
+ var canvas = document.querySelector('canvas');
24
+ if (canvas) {
25
+ try {
26
+ var dataUrl = canvas.toDataURL('image/png');
27
+ window.parent.postMessage({ type: 'jaw-screenshot', dataUrl: dataUrl, nonce: __nonce }, '*');
28
+ } catch(ex) { /* tainted canvas or other error */ }
29
+ }
30
+ }
31
+ });
32
+
33
+ function postHeight() {
34
+ var h = Math.max(
35
+ document.body.scrollHeight,
36
+ document.body.offsetHeight,
37
+ document.documentElement.scrollHeight
38
+ );
39
+ window.parent.postMessage({ type: 'jaw-diagram-resize', height: h, nonce: __nonce }, '*');
40
+ }
41
+
42
+ if (typeof ResizeObserver !== 'undefined') {
43
+ var ro = new ResizeObserver(function() {
44
+ clearTimeout(ro._t);
45
+ ro._t = setTimeout(postHeight, 50);
46
+ });
47
+ ro.observe(document.body);
48
+ }
49
+
50
+ window.addEventListener('load', function() {
51
+ postHeight();
52
+ // Deferred re-measure for async chart renders (Chart.js animation, CDN loading)
53
+ setTimeout(postHeight, 200);
54
+ setTimeout(postHeight, 800);
55
+ window.parent.postMessage({ type: 'jaw-widget-ready', nonce: __nonce }, '*');
56
+ });
57
+
58
+ var lastSend = 0;
59
+ window.sendPrompt = function(text) {
60
+ var now = Date.now();
61
+ if (now - lastSend < 3000) return;
62
+ lastSend = now;
63
+ window.parent.postMessage({ type: 'jaw-send-prompt', text: String(text).slice(0, 500), nonce: __nonce }, '*');
64
+ };
65
+
66
+ // Ctrl+C / Cmd+C: forward selected text to host for clipboard access
67
+ document.addEventListener('copy', function() {
68
+ var sel = window.getSelection();
69
+ if (sel && sel.toString().trim()) {
70
+ window.parent.postMessage({
71
+ type: 'jaw-copy-text',
72
+ text: sel.toString().slice(0, 512),
73
+ nonce: __nonce
74
+ }, '*');
75
+ }
76
+ });
77
+ })();
78
+ <\/script>`}var Qe=[[/\/p5\.js\/1\.11\.1[1-9]\//g,`/p5.js/1.11.10/`]];function $e(e){for(let[t,n]of Qe)e=e.replace(t,n);return e}function et(e){qe(),tt(),e=$e(e);let t=Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),n=Xe(),r=Ye(e),i=Je(e),a=Ze(t),o=`<!DOCTYPE html>
79
+ <html>
80
+ <head>
81
+ <meta charset="utf-8">
82
+ ${r}
83
+ ${i}
84
+ <style>
85
+ :root { ${Object.entries(n.tokens).map(([e,t])=>`${e}: ${t};`).join(`
86
+ `)} }
87
+ * { margin: 0; box-sizing: border-box; }
88
+ body {
89
+ font-family: var(--font-ui), system-ui, sans-serif;
90
+ color: var(--text);
91
+ background: transparent;
92
+ padding: 16px;
93
+ overflow: hidden;
94
+ }
95
+ </style>
96
+ </head>
97
+ <body>
98
+ <script>
99
+ window.__jawTheme = ${JSON.stringify({isDark:n.isDark})};
100
+ window.__jawTokens = ${JSON.stringify(n.tokens).replace(/<\//g,`<\\/`)};
101
+ <\/script>
102
+ ${a}
103
+ ${e}
104
+ </body>
105
+ </html>`,s=document.createElement(`iframe`);return s.sandbox.add(`allow-scripts`),s.srcdoc=o,s.style.cssText=`width: 100%; border: none; overflow: hidden; display: block;`,s.setAttribute(`aria-label`,`Interactive diagram widget`),{iframe:s,nonce:t}}function F(e){(e||document).querySelectorAll(`.diagram-widget-pending`).forEach(e=>{let t=e.dataset.diagramHtml;if(!t)return;let n;try{if(t.length>524288)throw Error(`Widget payload too large`);n=decodeURIComponent(escape(atob(t)))}catch{e.replaceWith(Object.assign(document.createElement(`div`),{className:`diagram-error`,textContent:`Failed to decode widget content`,role:`alert`}));return}let r=Ue(n);if(!r.valid){e.replaceWith(Object.assign(document.createElement(`div`),{className:`diagram-error`,textContent:`Widget blocked: ${r.reason}`,role:`alert`}));return}r.warnings.length&&console.warn(`[jaw-diagram] Widget warnings:`,r.warnings);let i=document.createElement(`div`);i.className=`diagram-container diagram-widget`,i.dataset.widgetHtml=t,i.appendChild(Ge()),i.appendChild(We());let{iframe:a,nonce:o}=et(n);i.appendChild(a),e.replaceWith(i);let s=!1;a.addEventListener(`load`,()=>{s?(a.contentWindow&&(M.delete(a.contentWindow),N.delete(a.contentWindow)),console.warn(`[jaw-diagram] iframe navigated — postMessage channel revoked`)):(s=!0,a.contentWindow&&(M.add(a.contentWindow),N.set(a.contentWindow,o),a.contentWindow.postMessage({type:`jaw-request-resize`},`*`),setTimeout(()=>a.contentWindow?.postMessage({type:`jaw-request-resize`},`*`),300),setTimeout(()=>a.contentWindow?.postMessage({type:`jaw-request-resize`},`*`),1e3)))});let c=Number(i.dataset.gen||`0`);i.dataset.gen=String(c);let l=!1,u=e=>{e.source===a.contentWindow&&e.data?.type===`jaw-widget-ready`&&e.data.nonce===o&&(l=!0,window.removeEventListener(`message`,u))};window.addEventListener(`message`,u),setTimeout(()=>{if(window.removeEventListener(`message`,u),Number(i.dataset.gen||`0`)===c&&!l&&i.isConnected){let e=a.contentWindow;e&&(M.delete(e),N.delete(e)),i.innerHTML=`<div class="diagram-error" role="alert">
106
+ Widget failed to load within 10 seconds.
107
+ </div>`,console.warn(`[jaw-diagram] Widget timeout — iframe deregistered`)}},1e4)})}var I=null;function tt(){if(I)return;let e=document.getElementById(`chatMessages`);e&&(I=new MutationObserver(t=>{for(let n of t)for(let t of n.addedNodes)if(t instanceof HTMLElement&&(t.classList?.contains(`diagram-widget-pending`)||t.querySelector?.(`.diagram-widget-pending`))){requestAnimationFrame(()=>F(t.parentElement||e));return}}),I.observe(e,{childList:!0}))}var L=new WeakMap;function nt(e,t){L.has(e)||(L.set(e,window.setTimeout(()=>L.delete(e),100)),document.querySelectorAll(`iframe`).forEach(n=>{n.contentWindow===e&&(n.style.height=`${Math.min(Math.max(t,60),2e3)}px`)}))}function rt(){document.querySelectorAll(`.diagram-widget`).forEach(e=>{let t=e.dataset.widgetHtml;if(!t)return;let n;try{n=decodeURIComponent(escape(atob(t)))}catch{return}let r=e.querySelector(`iframe`);r?.contentWindow&&(M.delete(r.contentWindow),N.delete(r.contentWindow));let i=e;i.dataset.gen=String((Number(i.dataset.gen||`0`)||0)+1);let{iframe:a,nonce:o}=et(n);e.innerHTML=``,e.appendChild(Ge()),e.appendChild(We()),e.appendChild(a);let s=!1;a.addEventListener(`load`,()=>{s?a.contentWindow&&(M.delete(a.contentWindow),N.delete(a.contentWindow)):(s=!0,a.contentWindow&&(M.add(a.contentWindow),N.set(a.contentWindow,o),a.contentWindow.postMessage({type:`jaw-request-resize`},`*`),setTimeout(()=>a.contentWindow?.postMessage({type:`jaw-request-resize`},`*`),300),setTimeout(()=>a.contentWindow?.postMessage({type:`jaw-request-resize`},`*`),1e3)))})})}var it=0;window.addEventListener(`message`,e=>{if(!e.data||typeof e.data!=`object`||!e.source||e.origin!==`null`||!M.has(e.source)||![...document.querySelectorAll(`iframe`)].find(t=>t.contentWindow===e.source)?.isConnected)return;let t=N.get(e.source);if(!(!t||e.data.nonce!==t))switch(e.data.type){case`jaw-diagram-resize`:{let t=Number(e.data.height);if(!Number.isFinite(t)||t<0)return;nt(e.source,t);break}case`jaw-send-prompt`:{let t=Date.now();if(t-it<3e3)return;it=t;let n=String(e.data.text||``).trim().slice(0,500);if(!n)return;let r=document.getElementById(`chatInput`);r&&(r.value=n,r.dispatchEvent(new Event(`input`,{bubbles:!0})),r.focus());break}case`jaw-copy-text`:{let t=String(e.data.text||``).trim().slice(0,512);if(!t)return;navigator.clipboard.writeText(t).catch(()=>{});break}case`jaw-screenshot`:{let t=String(e.data.dataUrl||``);if(!t.startsWith(`data:image/`)||t.length>5242880)return;fetch(t).then(e=>e.blob()).then(e=>{let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`widget-${Date.now()}.png`,n.click(),setTimeout(()=>URL.revokeObjectURL(t),1e3)}).catch(()=>{});break}case`jaw-widget-ready`:break}});function at(e){e.dataset.toolItemBound!==`1`&&(e.addEventListener(`click`,e=>{let t=e.target;if(!t)return;let n=t.closest(`.tool-item-toggle`);if(!n)return;let r=n.closest(`.tool-item`),i=r?.querySelector(`.tool-item-details`),a=n.querySelector(`.tool-item-chevron`);if(!r||!i)return;let o=i.classList.contains(`collapsed`);i.classList.toggle(`collapsed`,!o),r.classList.toggle(`expanded`,o),n.setAttribute(`aria-expanded`,o?`true`:`false`),a&&(a.innerHTML=o?d.chevronDown:d.chevronRight)}),e.dataset.toolItemBound=`1`)}function ot(){document.querySelectorAll(`.tool-activity-live`).forEach(e=>e.remove()),document.querySelectorAll(`.msg-system.tool-activity`).forEach(e=>e.remove())}function st(e){let t={};for(let n of e){let e=n.type===`thinking`?`${d.thinking} Thinking`:n.type===`search`?`${d.search} Search`:`${d.tool} Tool`;t[e]=(t[e]||0)+1}return Object.entries(t).map(([e,t])=>t>1?`${e}&times;${t}`:e).join(` + `)}function ct(e,t=120){let n=e.replace(/\s+/g,` `).trim();return n?n.length>t?`${n.slice(0,t-1)}…`:n:``}function lt(e){let t=(e.detail||``).trim();return t?t!==(e.label||``).trim():!1}function R(e){let t=`process-step-dot ${e.status}`,n=`process-step-badge ${e.type}`,r=e.type.toUpperCase(),i=c(e.label||e.icon||``),a=e.detail||``,o=`process-detail-${e.id}`,s=lt(e)?ct(a,e.type===`thinking`?120:100):``,l=s?`<span class="process-step-snippet">${c(s)}</span>`:``;return lt(e)?`<div class="process-step process-step-expandable" data-step-id="${e.id}" data-type="${e.type}">
108
+ <button class="process-step-toggle" aria-expanded="false" aria-controls="${o}">
109
+ <span class="${t}"></span>
110
+ <span class="${n}">${r}</span>
111
+ <span class="process-step-main">
112
+ <span class="process-step-label">${i}</span>
113
+ ${l}
114
+ </span>
115
+ <span class="process-step-chevron">${d.chevronRight}</span>
116
+ </button>
117
+ <div class="process-step-details collapsed" id="${o}">
118
+ <pre class="process-step-full">${c(a)}</pre>
119
+ </div>
120
+ </div>`:`<div class="process-step" data-step-id="${e.id}" data-type="${e.type}">
121
+ <span class="${t}"></span>
122
+ <span class="${n}">${r}</span>
123
+ <span class="process-step-label">${i}</span>
124
+ </div>`}function ut(e=``,t=!1){return`<div class="process-block${t?` collapsed`:``}">
125
+ <button class="process-summary" aria-expanded="${t?`false`:`true`}">
126
+ <span class="process-dot ${t?`done`:`running`}"></span>
127
+ <span class="process-summary-text">${e}</span>
128
+ <span class="process-duration"></span>
129
+ <span class="process-chevron">${t?d.chevronRight:d.chevronDown}</span>
130
+ </button>
131
+ <div class="process-details">
132
+ <div class="process-steps-inner"></div>
133
+ </div>
134
+ </div>`}function dt(e){let t=e.closest(`.process-step`),n=t?.querySelector(`.process-step-details`),r=e.querySelector(`.process-step-chevron`);if(!t||!n)return;let i=n.classList.contains(`collapsed`);n.classList.toggle(`collapsed`,!i),t.classList.toggle(`expanded`,i),e.setAttribute(`aria-expanded`,i?`true`:`false`),r&&(r.innerHTML=i?d.chevronDown:d.chevronRight)}function ft(e){e.dataset.processBlockBound!==`1`&&(e.addEventListener(`click`,e=>{let t=e.target;if(!t)return;let n=t.closest(`.process-step-toggle`);if(n){dt(n);return}let r=t.closest(`.process-summary`);if(r){let e=r.closest(`.process-block`);if(!e)return;let t=e.classList.contains(`collapsed`);e.classList.toggle(`collapsed`,!t),r.setAttribute(`aria-expanded`,t?`true`:`false`);let n=r.querySelector(`.process-chevron`);n&&(n.innerHTML=t?d.chevronDown:d.chevronRight)}}),e.dataset.processBlockBound=`1`)}function pt(e,t=!0){let n=ut(st(e),t),r=document.createElement(`div`);r.innerHTML=n;let i=r.querySelector(`.process-steps-inner`);i&&(i.innerHTML=e.map(R).join(``));let a=r.querySelector(`.process-dot`);if(a){let n=e.some(e=>e.status===`running`);a.classList.toggle(`running`,n&&!t),a.classList.toggle(`done`,!n||t)}return r.innerHTML}function z(e){let t=e.element.querySelector(`.process-summary-text`);t&&(t.innerHTML=st(e.steps));let n=e.steps.some(e=>e.status===`running`),r=e.element.querySelector(`.process-dot`);r&&(r.classList.toggle(`running`,n&&!e.collapsed),r.classList.toggle(`done`,!n||e.collapsed));let i=e.steps.length>0?Math.round((Date.now()-e.steps[0].startTime)/1e3):0,a=e.element.querySelector(`.process-duration`);a&&(a.textContent=i>0?`${i}s`:``)}function B(e){let t=document.createElement(`div`);t.innerHTML=ut(``,!1);let n=t.firstElementChild,r=e.querySelector(`.msg-content`);return r?r.before(n):e.appendChild(n),{element:n,steps:[],collapsed:!1}}function V(e,t){e.steps.push(t);let n=e.element.querySelector(`.process-steps-inner`);n&&n.insertAdjacentHTML(`beforeend`,R(t)),z(e)}function H(e,t,n){let r=e.steps.findIndex(e=>e.id===t);if(r===-1)return;e.steps[r]=n;let i=e.element.querySelector(`[data-step-id="${t}"]`);if(i){let e=document.createElement(`div`);e.innerHTML=R(n);let t=e.firstElementChild;t&&i.replaceWith(t)}z(e)}function mt(e,t,n){let r=e.steps.find(e=>e.id===t);if(!r)return;r.status=n;let i=e.element.querySelector(`[data-step-id="${t}"]`);if(i){let e=i.querySelector(`.process-step-dot`);e&&(e.classList.remove(`running`,`done`,`error`),e.classList.add(n))}z(e)}function U(e){e.collapsed=!0,e.element.classList.add(`collapsed`);let t=e.element.querySelector(`.process-summary`);t&&t.setAttribute(`aria-expanded`,`false`);let n=e.element.querySelector(`.process-chevron`);n&&(n.innerHTML=d.chevronRight);for(let t of e.steps)t.status===`running`&&(t.status=`done`);e.element.querySelectorAll(`.process-step-dot.running`).forEach(e=>{e.classList.remove(`running`),e.classList.add(`done`)}),z(e)}function W(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function ht(e){return ve()}function G(e){return e.map(e=>({id:h(),icon:e.icon?i(e.icon):d.tool,label:e.label||e.name||`tool`,type:e.toolType||`tool`,detail:e.detail||``,stepRef:e.stepRef||``,status:e.status||`done`,startTime:Date.now()}))}function gt(t){let n=document.getElementById(`statusBadge`),r=document.getElementById(`btnSend`);e.agentBusy=t===`running`,document.getElementById(`typingIndicator`)?.classList.toggle(`active`,e.agentBusy),t===`running`?(n&&(n.className=`status-badge status-running`,n.textContent=`running`),r&&(r.innerHTML=d.stop,r.title=a(`btn.stop`),r.classList.add(`stop-mode`)),vt()):(n&&(n.className=`status-badge status-idle`,n.textContent=`idle`),r&&(r.innerHTML=d.send,r.title=`Send`,r.classList.remove(`stop-mode`)),K(),_t(0))}function _t(e){let t=document.getElementById(`queueBadge`);if(!t){t=document.createElement(`span`),t.id=`queueBadge`,t.className=`queue-badge`;let e=document.getElementById(`btnSend`);e?.parentElement&&(e.parentElement.style.position=`relative`),e&&(e.style.position=`relative`,e.appendChild(t))}t.textContent=e>0?String(e):``,t.style.display=e>0?`flex`:`none`}function vt(){let e=document.getElementById(`chatMessages`);if(!e||e.querySelector(`.skeleton-msg`))return;q();let t=document.createElement(`div`);t.className=`skeleton-msg`,t.innerHTML=`<div class="skeleton-line"></div><div class="skeleton-line"></div><div class="skeleton-line"></div>`,e.appendChild(t),Q()}function K(){document.querySelectorAll(`.skeleton-msg`).forEach(e=>e.remove())}function q(){document.getElementById(`emptyState`)?.classList.remove(`visible`)}function J(){let e=document.getElementById(`chatMessages`);e&&e.children.length===0&&document.getElementById(`emptyState`)?.classList.add(`visible`)}function yt(e,t,n){let r=document.getElementById(`chatMessages`);if(!r)return;let i=k();q();let a=document.createElement(`div`);a.className=`msg msg-system`+(n?` msg-type-${n}`:``)+(t?` `+t:``),a.innerHTML=e,i.active?i.appendLiveItem(a):r.appendChild(a),Q()}function bt(){ot(),e.currentAgentDiv=null,e.currentProcessBlock=null}function xt(t){if(K(),(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=X(`agent`,``),e.currentProcessBlock=null),!e.currentProcessBlock){let t=e.currentAgentDiv.querySelector(`.agent-body`);t&&(e.currentProcessBlock=B(t))}if(e.currentProcessBlock){let n=t.status&&t.status!==`running`?t.status:s(t.icon);if(n===`done`||n===`error`){let r=t.stepRef,a=r?[...e.currentProcessBlock.steps].reverse().find(e=>e.status===`running`&&e.stepRef===r):[...e.currentProcessBlock.steps].reverse().find(e=>e.status===`running`&&e.label===t.label);if(a){t.detail&&!a.detail?(t.icon=i(t.icon),H(e.currentProcessBlock,a.id,{...t,id:a.id})):mt(e.currentProcessBlock,a.id,n),Q();return}let o=[...e.currentProcessBlock.steps].reverse().find(e=>e.status===`running`);if(o){t.detail&&!o.detail?(t.icon=i(t.icon),H(e.currentProcessBlock,o.id,{...t,id:o.id})):mt(e.currentProcessBlock,o.id,n),Q();return}}if(t.detail){let n=[...e.currentProcessBlock.steps].reverse().find(e=>e.status===`running`&&e.label===t.label&&e.type===t.type&&!e.detail);if(n){H(e.currentProcessBlock,n.id,t),Q();return}}t.icon=i(t.icon),V(e.currentProcessBlock,t)}Q()}var Y=null;function St(t){if(!t)return;K(),(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=X(`agent`,``),Y=null);let n=e.currentAgentDiv?.querySelector(`.msg-content`);n&&(Y||=Re(n),ze(Y,t)),Q()}var Ct=0;function wt(t,n){let r=Date.now();if(!e.currentAgentDiv&&r-Ct<500)return;ot(),K();let i=!!e.currentProcessBlock;e.currentProcessBlock&&=(U(e.currentProcessBlock),null);let a=n&&n.length>0;if(t||a){(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=X(`agent`,``));let r=e.currentAgentDiv?.querySelector(`.msg-content`),s=Y?Be(Y,!0):``,c=t||s;Y=null;let u=a&&!i?pt(G(n),!0):``;r&&(r.innerHTML=u+o(c)),r&&r.setAttribute(`data-raw`,l(c)),r&&F(r);let d=k();d.active&&e.currentAgentDiv&&e.currentAgentDiv.isConnected&&(d.appendLiveItem(e.currentAgentDiv),e.currentAgentDiv.remove()),c&&f({role:`assistant`,content:c,tool_log:n?JSON.stringify(n):null,timestamp:Date.now()}).catch(()=>{})}Y=null,e.currentAgentDiv=null,Ct=Date.now(),gt(`idle`),Mt()}function Tt(e){let t=e.match(/^\[(?:사용자가 파일 (\d+)개를 보냈습니다|User sent (\d+) files)\]/);if(t){let n=t[1]||t[2],r=e.match(/(?:사용자 메시지|User message): (.+)$/s);return`📎 [${n} files]${r?` `+r[1].trim():``}`}let n=e.match(/^\[(?:사용자가 파일을 보냈습니다|User sent a file): ([^\]]+)\]/);if(n){let t=n[1].split(`/`).pop()||n[1],r=e.match(/🎤\s*(.{0,80})/)?`🎤 [음성 메시지] `:``,i=e.match(/(?:사용자 메시지|User message): (.+)$/s);return`${r}📎 [${t}]${i?` `+i[1].trim():``}`}return e}function X(e,t,n){let r=document.getElementById(`chatMessages`),i=k();q(),K();let s=o(e===`user`?Tt(t):t),d=c(e===`user`?a(`msg.you`):ne()),f=document.createElement(`div`);e===`agent`?(f.className=`msg msg-agent`,f.innerHTML=`<div class="agent-icon" aria-hidden="true">${ht(n)}</div><div class="agent-body"><div class="msg-content">${s}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div>`):(f.className=`msg msg-${e}`,f.innerHTML=`<div class="user-body"><div class="msg-label">${d}</div><div class="msg-content">${s}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div><div class="user-icon" aria-hidden="true">${ye()}</div>`);let p=f.querySelector(`.msg-content`);p&&p.setAttribute(`data-raw`,l(t));let m=e===`agent`&&!t;return i.active&&!m?i.appendLiveItem(f):(r?.appendChild(f),F(f),!i.active&&!m&&r&&r.querySelectorAll(`.msg`).length>=80&&(r.querySelectorAll(`.msg`).forEach(e=>{i.addItem(h(),e.outerHTML)}),i.onPostRender=e=>{F(e),u(e)})),Q(e===`user`),f}var Et=null,Z=!0,Dt=!1,Ot=80;function kt(){if(Dt)return;let e=document.getElementById(`chatMessages`);e&&(Dt=!0,e.addEventListener(`scroll`,()=>{Z=e.scrollHeight-e.scrollTop-e.clientHeight<Ot},{passive:!0}))}function Q(e=!1){if(kt(),!e&&!Z)return;e&&(Z=!0);let t=k();if(t.active){t.scrollToBottom();return}Et||=requestAnimationFrame(()=>{Et=null;let e=document.getElementById(`chatMessages`);e&&(e.scrollTop=e.scrollHeight)})}function At(e,t){document.querySelectorAll(`.tab-btn`).forEach(e=>{e.classList.remove(`active`),e.setAttribute(`aria-selected`,`false`)}),document.querySelectorAll(`.tab-content`).forEach(e=>e.classList.remove(`active`)),document.getElementById({agents:`tabAgents`,settings:`tabSettings`,skills:`tabSkills`}[e])?.classList.add(`active`),t&&(t.classList.add(`active`),t.setAttribute(`aria-selected`,`true`)),e===`settings`&&r(()=>import(`./settings-DmZY7OMS.js`).then(e=>e.loadSettings()),__vite__mapDeps([0])),e===`agents`&&r(()=>import(`./employees-BqRBY-Bb.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0])),e===`skills`&&r(()=>import(`./skills-BOfkZh9T.js`).then(e=>e.loadSkills()),__vite__mapDeps([0]))}function jt(){document.getElementById(`tabSettings`)?.classList.contains(`active`)?r(()=>import(`./settings-DmZY7OMS.js`).then(e=>e.savePerCli()),__vite__mapDeps([0])):r(()=>import(`./settings-DmZY7OMS.js`).then(e=>e.updateSettings()),__vite__mapDeps([0]))}function $(e){let t=document.getElementById(`statMsgs`);t&&(t.textContent=a(`stat.messages`,{count:e}))}async function Mt(){let e=await n(`/api/messages`);e&&$(e.length)}function Nt(e){return e.map(e=>{let t=e.role===`assistant`?`agent`:e.role,n=l(t===`user`?Tt(e.content):e.content),r=c(t===`user`?a(`msg.you`):ne()),i=e.role===`assistant`?W(e.tool_log):[],s=i.length>0?pt(G(i),!0):``,u=n?o(n):``,d=t===`agent`?`<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true">${ht(e.cli)}</div><div class="agent-body">${s}<div class="msg-content" data-raw="${c(n)}">${u}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div></div>`:`<div class="msg msg-${t}"><div class="user-body"><div class="msg-label">${r}</div><div class="msg-content" data-raw="${c(n)}">${u}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div><div class="user-icon" aria-hidden="true">${ye()}</div></div>`;return{id:h(),html:d,height:80}})}function Pt(e){e.onLazyRender=t=>{for(let n of t){if(!n.classList.contains(`lazy-pending`))continue;let t=n.getAttribute(`data-raw`)||``;n.innerHTML=t?o(t):``,n.classList.remove(`lazy-pending`),F(n);let r=n.closest(`[data-vs-idx]`);if(r){let t=Number(r.dataset.vsIdx);e.updateItemHtml(t,r.outerHTML)}}},e.onPostRender=e=>{F(e),u(e)}}function Ft(e){return{registerCallbacks:()=>Pt(e),setItems:(t,n)=>e.setItems(t,n),activateIfNeeded:t=>e.activateIfNeeded(t),scrollToBottom:()=>e.scrollToBottom()}}async function It(){let e=k(),t=document.getElementById(`chatMessages`);try{let e=await n(`/api/settings`);e?.workingDir&&p(e.workingDir)}catch{}let r=await n(`/api/messages`);if(r!==null){e.clear(),t&&(t.innerHTML=``),r.length>=80?Fe(Nt(r),Ft(e)):r.forEach(e=>{let t=X(e.role===`assistant`?`agent`:e.role,e.content,e.cli);if(e.role===`assistant`){let n=W(e.tool_log);if(n.length>0){let e=t.querySelector(`.agent-body`);if(e){let t=B(e);for(let e of G(n))V(t,e);U(t)}}}}),ee(r.map(e=>({role:e.role,content:e.content,cli:e.cli??null,tool_log:e.tool_log??null,timestamp:Date.now()}))).catch(()=>{}),$(r.length),J();return}if(t&&t.children.length>0){J();return}let i=await m();i.length>0&&(i.length>=80?Fe(Nt(i),Ft(e)):i.forEach(e=>{let t=X(e.role===`assistant`?`agent`:e.role,e.content,e.cli);if(e.role===`assistant`&&e.tool_log){let n=W(e.tool_log);if(n.length>0){let e=t.querySelector(`.agent-body`);if(e){let t=B(e);for(let e of G(n))V(t,e);U(t)}}}}),yt(`${d.warning} 오프라인 모드 — 캐시된 메시지 표시 중`),$(i.length)),J()}function Lt(){let e=document.getElementById(`chatMessages`);e&&(ft(e),at(e),e.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`.tool-group-summary`);if(n){let e=n.closest(`.tool-group`),t=n.nextElementSibling;if(e&&t){let r=!e.classList.contains(`expanded`);e.classList.toggle(`expanded`),t.classList.toggle(`collapsed`),n.setAttribute(`aria-expanded`,r?`true`:`false`)}return}let r=t.closest(`.msg-copy`);if(!r)return;let i=r.closest(`.msg`)?.querySelector(`.msg-content`);if(!i)return;let a=i.getAttribute(`data-raw`)||i.innerText||i.textContent||``;navigator.clipboard.writeText(a).then(()=>{r.classList.add(`copied`),r.innerHTML=d.checkSimple,setTimeout(()=>{r.classList.remove(`copied`),r.textContent=``},600)}).catch(()=>{})}))}export{be as _,wt as a,It as c,gt as d,xt as f,k as g,rt as h,bt as i,Mt as l,_t as m,yt as n,jt as o,At as p,St as r,Lt as s,X as t,Q as u,ie as v};
@@ -0,0 +1 @@
1
+ import{c as e,d as t,i as n,m as r}from"./ui-CY4yns6t.js";export{n as cleanupToolActivity,e as loadMessages,t as setStatus,r as updateQueueBadge};
@@ -1,2 +1,2 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-render-Bjnw0wQ6.css"])))=>i.map(i=>d[i]);
2
- import{t as e}from"./state-O6NVkWcL.js";import{Z as t}from"./vendor-mermaid-C2RBgdM6.js";import{f as n,h as r,n as i,s as a,t as o}from"./render-ROX2ge5j.js";import{a as s,d as c,f as l,g as u,i as d,m as f,n as p,r as m,t as h}from"./ui-D39zHnDA.js";var g=[`P`,`A`,`B`,`C`],_=null;function v(e,t,n){let r=g.indexOf(n);if(r<0)return;let i=e.getBoundingClientRect(),a=t.offsetWidth||36,o=document.getElementById(`dot-${n}`);if(!o)return;let s=g[r+1],c=s?document.getElementById(`dot-${s}`):null;if(c){let e=o.getBoundingClientRect(),n=c.getBoundingClientRect(),r=(e.right+n.left)/2;t.style.left=r-i.left-a/2+`px`}else{let e=o.getBoundingClientRect();t.style.left=e.left-i.left+e.width/2-a/2+`px`}}var y={},b=``,x=0;function S(e){for(let e of Object.keys(y))delete y[e];for(let t of e)t.state===`running`&&t.phase&&(y[t.agentId]={phase:t.phase,phaseLabel:t.phaseLabel||``})}function C(t,n){let r=new Set([`IDLE`,`P`,`A`,`B`,`C`,`D`]).has(t)?t:`IDLE`;if(e.orcState=r,r===`IDLE`||r===`D`)document.body.removeAttribute(`data-orc-state`),document.body.style.removeProperty(`--orc-glow`);else{document.body.setAttribute(`data-orc-state`,r);let e=`--orc-glow-${r}`,t=getComputedStyle(document.documentElement).getPropertyValue(e).trim();document.body.style.setProperty(`--orc-glow`,t)}document.body.classList.add(`orc-pulse`),setTimeout(()=>document.body.classList.remove(`orc-pulse`),700);let i=document.getElementById(`orcStateBadge`);i&&(i.textContent={IDLE:``,P:`PLAN`,A:`AUDIT`,B:`BUILD`,C:`CHECK`,D:`DONE`}[r],i.style.display=r===`IDLE`?`none`:`inline-block`);let a=document.getElementById(`pabcRoadmap`),o=document.getElementById(`sharkRunner`),s=document.getElementById(`pabcBrand`);if(a&&o){if(!a.dataset.resizeObserved){a.dataset.resizeObserved=`1`,new ResizeObserver(()=>{_&&o.classList.contains(`running`)&&v(a,o,_)}).observe(a);let e=0;window.addEventListener(`resize`,()=>{cancelAnimationFrame(e),e=requestAnimationFrame(()=>{_&&o.classList.contains(`running`)&&v(a,o,_)})})}if(r===`IDLE`)a.classList.remove(`visible`,`shimmer-out`),o.classList.remove(`running`),_=null;else if(r===`D`){g.forEach(e=>{let t=document.getElementById(`dot-${e}`);t&&(t.className=`pabc-dot done`,t.setAttribute(`data-phase`,e))});for(let e=0;e<4;e++){let t=document.getElementById(`pabc-conn-${e}`);t&&(t.className=`pabc-connector done`)}o.classList.remove(`running`),_=null,a.classList.add(`shimmer-out`),setTimeout(()=>a.classList.remove(`visible`,`shimmer-out`),1e3)}else{a.classList.remove(`shimmer-out`),a.classList.add(`visible`),o.classList.add(`running`);let e=g.indexOf(r);g.forEach((t,n)=>{let r=document.getElementById(`dot-${t}`);r&&(r.className=`pabc-dot ${n<e?`done`:n===e?`active`:`future`}`,r.setAttribute(`data-phase`,t))});for(let t=0;t<4;t++){let n=document.getElementById(`pabc-conn-${t}`);n&&(n.className=`pabc-connector ${t<e?`done`:``}`)}_=r,requestAnimationFrame(()=>v(a,o,r))}s&&n&&(s.textContent=n)}}function w(){let g=`ws://${location.host}`;e.ws=new WebSocket(`${g}?lang=${n()}`),e.ws.onmessage=e=>{let n;try{n=JSON.parse(e.data)}catch{console.warn(`[ws] malformed message:`,e.data);return}if(!n||typeof n!=`object`||typeof n.type!=`string`){console.warn(`[ws] invalid message shape:`,n);return}if(n.type===`agent_status`)n.running===void 0?c(n.status||`idle`):c(n.running?`running`:`idle`),n.agentId&&n.phase&&(y[n.agentId]={phase:n.phase,phaseLabel:n.phaseLabel||``},t(()=>import(`./employees-lptr4zja.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0])));else if(n.type===`queue_update`)f(n.pending||0);else if(n.type===`worklog_created`)p(`${a.clipboard} Worklog: ${i(n.path||``)}`);else if(n.type===`round_start`){let e=n.agentPhases||n.subtasks||[],t=e.map(e=>i(e.agent||e.name||``)).join(`, `);p(r(`ws.roundStart`,{round:n.round||0,count:e.length,names:t}))}else if(n.type===`round_done`)n.action===`complete`?p(r(`ws.roundDone`,{round:n.round||0})):n.action===`next`?p(r(`ws.roundNext`,{round:n.round||0})):p(r(`ws.roundRetry`,{round:n.round||0}));else if(n.type===`agent_tool`){let e=n.toolType===`thinking`?`thinking`:n.toolType===`search`?`search`:`tool`;l({id:`step-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e,icon:n.icon||a.tool,label:n.label||``,detail:n.detail||``,stepRef:n.stepRef||``,status:n.status||`running`,startTime:Date.now()})}else if(n.type===`agent_output`)m(n.text||``);else if(n.type===`agent_retry`)p(r(`ws.retry`,{cli:i(n.cli||``),delay:n.delay||10}),`tool-activity`);else if(n.type===`agent_fallback`)p(r(`ws.fallback`,{from:i(n.from||``),to:i(n.to||``)}),`tool-activity`);else if(n.type===`agent_smoke`)p(`${a.warning} ${i(n.cli||`agent`)}: smoke response detected — auto-continuing`,`tool-activity`);else if(n.type===`agent_done`)s(n.text||``,n.toolLog);else if(n.type===`orchestrate_done`)s(n.text||``);else if(n.type===`clear`){o(),d(),u().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``),t(()=>import(`./idb-cache-C7z4qE00.js`).then(e=>e.clearCache()),[]).catch(()=>{})}else if(n.type===`session_reset`)p(`${a.refresh} Session reset — history preserved`,`tool-activity`);else if(n.type===`agent_added`||n.type===`agent_updated`||n.type===`agent_deleted`)t(()=>import(`./employees-lptr4zja.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0]));else if(n.type===`orc_state`){if(n.scope&&b&&n.scope!==b)return;C(typeof n.state==`string`?n.state:`IDLE`,n.title)}else n.type===`new_message`&&(n.source===`telegram`||n.source===`discord`)&&h(n.role===`assistant`?`agent`:n.role||`user`,n.content||``,n.cli)},e.ws.onopen=()=>{console.log(`[ws] connected`);let e=Date.now()-x<1e4;t(()=>import(`./ui-c57_qjIR.js`).then(async t=>{if(t.cleanupToolActivity(),!e)try{await t.loadMessages(),x=Date.now()}catch(e){console.error(`[ws] loadMessages failed`,e)}t.setStatus(`idle`)}),__vite__mapDeps([0])),fetch(`/api/orchestrate/snapshot`).then(e=>e.json()).then(e=>{b=String(e.orc.scope||``),C(e.orc.state),S(e.workers),f(e.runtime.queuePending),c(e.runtime.busy?`running`:`idle`),t(()=>import(`./employees-lptr4zja.js`).then(e=>{typeof e.renderEmployees==`function`&&e.renderEmployees()}),__vite__mapDeps([0]))}).catch(()=>{})},e.ws.onclose=()=>{console.log(`[ws] disconnected, reconnecting in 2s...`),t(()=>import(`./ui-c57_qjIR.js`).then(e=>e.cleanupToolActivity()),__vite__mapDeps([0])),c(`idle`),p(`${a.exec} 연결 끊김 — 재연결 중...`,`tool-activity`),setTimeout(w,2e3)}}function T(e){return y[e]||null}export{T as n,w as t};
2
+ import{t as e}from"./state-O6NVkWcL.js";import{Z as t}from"./vendor-mermaid-C2RBgdM6.js";import{f as n,h as r,n as i,s as a,t as o}from"./render-greWRQT7.js";import{a as s,d as c,f as l,g as u,i as d,m as f,n as p,r as m,t as h}from"./ui-CY4yns6t.js";var g=[`P`,`A`,`B`,`C`],_=null;function v(e,t,n){let r=g.indexOf(n);if(r<0)return;let i=e.getBoundingClientRect(),a=t.offsetWidth||36,o=document.getElementById(`dot-${n}`);if(!o)return;let s=g[r+1],c=s?document.getElementById(`dot-${s}`):null;if(c){let e=o.getBoundingClientRect(),n=c.getBoundingClientRect(),r=(e.right+n.left)/2;t.style.left=r-i.left-a/2+`px`}else{let e=o.getBoundingClientRect();t.style.left=e.left-i.left+e.width/2-a/2+`px`}}var y={},b=``,x=0;function S(e){for(let e of Object.keys(y))delete y[e];for(let t of e)t.state===`running`&&t.phase&&(y[t.agentId]={phase:t.phase,phaseLabel:t.phaseLabel||``})}function C(t,n){let r=new Set([`IDLE`,`P`,`A`,`B`,`C`,`D`]).has(t)?t:`IDLE`;if(e.orcState=r,r===`IDLE`||r===`D`)document.body.removeAttribute(`data-orc-state`),document.body.style.removeProperty(`--orc-glow`);else{document.body.setAttribute(`data-orc-state`,r);let e=`--orc-glow-${r}`,t=getComputedStyle(document.documentElement).getPropertyValue(e).trim();document.body.style.setProperty(`--orc-glow`,t)}document.body.classList.add(`orc-pulse`),setTimeout(()=>document.body.classList.remove(`orc-pulse`),700);let i=document.getElementById(`orcStateBadge`);i&&(i.textContent={IDLE:``,P:`PLAN`,A:`AUDIT`,B:`BUILD`,C:`CHECK`,D:`DONE`}[r],i.style.display=r===`IDLE`?`none`:`inline-block`);let a=document.getElementById(`pabcRoadmap`),o=document.getElementById(`sharkRunner`),s=document.getElementById(`pabcBrand`);if(a&&o){if(!a.dataset.resizeObserved){a.dataset.resizeObserved=`1`,new ResizeObserver(()=>{_&&o.classList.contains(`running`)&&v(a,o,_)}).observe(a);let e=0;window.addEventListener(`resize`,()=>{cancelAnimationFrame(e),e=requestAnimationFrame(()=>{_&&o.classList.contains(`running`)&&v(a,o,_)})})}if(r===`IDLE`)a.classList.remove(`visible`,`shimmer-out`),o.classList.remove(`running`),_=null;else if(r===`D`){g.forEach(e=>{let t=document.getElementById(`dot-${e}`);t&&(t.className=`pabc-dot done`,t.setAttribute(`data-phase`,e))});for(let e=0;e<4;e++){let t=document.getElementById(`pabc-conn-${e}`);t&&(t.className=`pabc-connector done`)}o.classList.remove(`running`),_=null,a.classList.add(`shimmer-out`),setTimeout(()=>a.classList.remove(`visible`,`shimmer-out`),1e3)}else{a.classList.remove(`shimmer-out`),a.classList.add(`visible`),o.classList.add(`running`);let e=g.indexOf(r);g.forEach((t,n)=>{let r=document.getElementById(`dot-${t}`);r&&(r.className=`pabc-dot ${n<e?`done`:n===e?`active`:`future`}`,r.setAttribute(`data-phase`,t))});for(let t=0;t<4;t++){let n=document.getElementById(`pabc-conn-${t}`);n&&(n.className=`pabc-connector ${t<e?`done`:``}`)}_=r,requestAnimationFrame(()=>v(a,o,r))}s&&n&&(s.textContent=n)}}function w(){let g=`ws://${location.host}`;e.ws=new WebSocket(`${g}?lang=${n()}`),e.ws.onmessage=e=>{let n;try{n=JSON.parse(e.data)}catch{console.warn(`[ws] malformed message:`,e.data);return}if(!n||typeof n!=`object`||typeof n.type!=`string`){console.warn(`[ws] invalid message shape:`,n);return}if(n.type===`agent_status`)n.running===void 0?c(n.status||`idle`):c(n.running?`running`:`idle`),n.agentId&&n.phase&&(y[n.agentId]={phase:n.phase,phaseLabel:n.phaseLabel||``},t(()=>import(`./employees-BqRBY-Bb.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0])));else if(n.type===`queue_update`)f(n.pending||0);else if(n.type===`worklog_created`)p(`${a.clipboard} Worklog: ${i(n.path||``)}`);else if(n.type===`round_start`){let e=n.agentPhases||n.subtasks||[],t=e.map(e=>i(e.agent||e.name||``)).join(`, `);p(r(`ws.roundStart`,{round:n.round||0,count:e.length,names:t}))}else if(n.type===`round_done`)n.action===`complete`?p(r(`ws.roundDone`,{round:n.round||0})):n.action===`next`?p(r(`ws.roundNext`,{round:n.round||0})):p(r(`ws.roundRetry`,{round:n.round||0}));else if(n.type===`agent_tool`){let e=n.toolType===`thinking`?`thinking`:n.toolType===`search`?`search`:`tool`;l({id:`step-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e,icon:n.icon||a.tool,label:n.label||``,detail:n.detail||``,stepRef:n.stepRef||``,status:n.status||`running`,startTime:Date.now()})}else if(n.type===`agent_output`)m(n.text||``);else if(n.type===`agent_retry`)p(r(`ws.retry`,{cli:i(n.cli||``),delay:n.delay||10}),`tool-activity`);else if(n.type===`agent_fallback`)p(r(`ws.fallback`,{from:i(n.from||``),to:i(n.to||``)}),`tool-activity`);else if(n.type===`agent_smoke`)p(`${a.warning} ${i(n.cli||`agent`)}: smoke response detected — auto-continuing`,`tool-activity`);else if(n.type===`agent_done`)s(n.text||``,n.toolLog);else if(n.type===`orchestrate_done`)s(n.text||``);else if(n.type===`clear`){o(),d(),u().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``),t(()=>import(`./idb-cache-C7z4qE00.js`).then(e=>e.clearCache()),[]).catch(()=>{})}else if(n.type===`session_reset`)p(`${a.refresh} Session reset — history preserved`,`tool-activity`);else if(n.type===`agent_added`||n.type===`agent_updated`||n.type===`agent_deleted`)t(()=>import(`./employees-BqRBY-Bb.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0]));else if(n.type===`orc_state`){if(n.scope&&b&&n.scope!==b)return;C(typeof n.state==`string`?n.state:`IDLE`,n.title)}else n.type===`new_message`&&(n.source===`telegram`||n.source===`discord`)&&h(n.role===`assistant`?`agent`:n.role||`user`,n.content||``,n.cli)},e.ws.onopen=()=>{console.log(`[ws] connected`);let e=Date.now()-x<1e4;t(()=>import(`./ui-KsH1DiJP.js`).then(async t=>{if(t.cleanupToolActivity(),!e)try{await t.loadMessages(),x=Date.now()}catch(e){console.error(`[ws] loadMessages failed`,e)}t.setStatus(`idle`)}),__vite__mapDeps([0])),fetch(`/api/orchestrate/snapshot`).then(e=>e.json()).then(e=>{b=String(e.orc.scope||``),C(e.orc.state),S(e.workers),f(e.runtime.queuePending),c(e.runtime.busy?`running`:`idle`),t(()=>import(`./employees-BqRBY-Bb.js`).then(e=>{typeof e.renderEmployees==`function`&&e.renderEmployees()}),__vite__mapDeps([0]))}).catch(()=>{})},e.ws.onclose=()=>{console.log(`[ws] disconnected, reconnecting in 2s...`),t(()=>import(`./ui-KsH1DiJP.js`).then(e=>e.cleanupToolActivity()),__vite__mapDeps([0])),c(`idle`),p(`${a.exec} 연결 끊김 — 재연결 중...`,`tool-activity`),setTimeout(w,2e3)}}function T(e){return y[e]||null}export{T as n,w as t};
@@ -25,9 +25,9 @@
25
25
  href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Outfit:wght@400;500;600;700&display=swap"
26
26
  rel="stylesheet">
27
27
  <!-- Vite handles module bundling in dev (HMR) and production (build) -->
28
- <script type="module" crossorigin src="/dist/assets/index-8LWemR8D.js"></script>
28
+ <script type="module" crossorigin src="/dist/assets/index-CZifLrLd.js"></script>
29
29
  <link rel="stylesheet" crossorigin href="/dist/assets/vendor-render-Bjnw0wQ6.css">
30
- <link rel="stylesheet" crossorigin href="/dist/assets/index-B4ZSYCSC.css">
30
+ <link rel="stylesheet" crossorigin href="/dist/assets/index-DzQ_i0rm.css">
31
31
  </head>
32
32
 
33
33
  <body>
package/public/js/ui.ts CHANGED
@@ -8,7 +8,7 @@ import { t } from './features/i18n.js';
8
8
  import { api } from './api.js';
9
9
  import { cacheMessages, getCachedMessages, appendCachedMessage, upsertMessage, setMessageScope, getScopedMessages } from './features/idb-cache.js';
10
10
  import { getVirtualScroll, VS_THRESHOLD, type VirtualItem } from './virtual-scroll.js';
11
- import { bootstrapVirtualHistory, BOOTSTRAP_SEED_COUNT, type VirtualHistoryBootstrapDeps } from './virtual-scroll-bootstrap.js';
11
+ import { bootstrapVirtualHistory, type VirtualHistoryBootstrapDeps } from './virtual-scroll-bootstrap.js';
12
12
  import { createStreamRenderer, appendChunk, finalizeStream, type StreamState } from './streaming-render.js';
13
13
  import { activateWidgets } from './diagram/iframe-renderer.js';
14
14
  import { renderLiveToolActivity, cleanupToolElements, bindToolItemInteractions, type ToolLogEntry } from './features/tool-ui.js';
@@ -282,13 +282,42 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
282
282
  loadStats();
283
283
  }
284
284
 
285
+ /** Convert server-stored prompts back to display format on reload.
286
+ * Handles: file uploads, multi-file, voice+file combos (ko + en patterns) */
287
+ function formatUserPrompt(text: string): string {
288
+ // Multi-file: "[사용자가 파일 3개를 보냈습니다]" or "[User sent 3 files]"
289
+ const multiMatch = text.match(/^\[(?:사용자가 파일 (\d+)개를 보냈습니다|User sent (\d+) files)\]/);
290
+ if (multiMatch) {
291
+ const count = multiMatch[1] || multiMatch[2];
292
+ const userMsgMatch = text.match(/(?:사용자 메시지|User message): (.+)$/s);
293
+ const userMsg = userMsgMatch ? ' ' + userMsgMatch[1].trim() : '';
294
+ return `📎 [${count} files]${userMsg}`;
295
+ }
296
+
297
+ // Single file: "[사용자가 파일을 보냈습니다: /path/to/file.md]"
298
+ const fileMatch = text.match(/^\[(?:사용자가 파일을 보냈습니다|User sent a file): ([^\]]+)\]/);
299
+ if (fileMatch) {
300
+ const fileName = fileMatch[1].split('/').pop() || fileMatch[1];
301
+ // Check if voice is also present (🎤 after file block)
302
+ const voiceMatch = text.match(/🎤\s*(.{0,80})/);
303
+ const voicePart = voiceMatch ? `🎤 [음성 메시지] ` : '';
304
+ const userMsgMatch = text.match(/(?:사용자 메시지|User message): (.+)$/s);
305
+ const userMsg = userMsgMatch ? ' ' + userMsgMatch[1].trim() : '';
306
+ return `${voicePart}📎 [${fileName}]${userMsg}`;
307
+ }
308
+
309
+ return text;
310
+ }
311
+
285
312
  export function addMessage(role: string, text: string, cli?: string | null): HTMLDivElement {
286
313
  const container = document.getElementById('chatMessages');
287
314
  const vs = getVirtualScroll();
288
315
  hideEmptyState();
289
316
  removeSkeleton();
290
317
 
291
- const rendered = renderMarkdown(text);
318
+ // For user messages: convert file-upload prompts to clean display format
319
+ const displayText = role === 'user' ? formatUserPrompt(text) : text;
320
+ const rendered = renderMarkdown(displayText);
292
321
  const label = escapeHtml(role === 'user' ? t('msg.you') : getAppName());
293
322
 
294
323
  const div = document.createElement('div');
@@ -413,20 +442,20 @@ export async function loadStats(): Promise<void> {
413
442
  // ── Virtual scroll bootstrap helpers ──
414
443
 
415
444
  function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
416
- const vsItems: VirtualItem[] = [];
417
- for (const m of msgs) {
445
+ return msgs.map((m) => {
418
446
  const role = m.role === 'assistant' ? 'agent' : m.role;
419
- const rawContent = stripOrchestration(m.content);
447
+ const rawContent = stripOrchestration(
448
+ role === 'user' ? formatUserPrompt(m.content) : m.content,
449
+ );
420
450
  const label = escapeHtml(role === 'user' ? t('msg.you') : getAppName());
421
451
  const tools = m.role === 'assistant' ? parseToolLog(m.tool_log) : [];
422
452
  const toolHtml = tools.length > 0 ? buildProcessBlockHtml(toProcessSteps(tools), true) : '';
423
- const skeletonContent = '<div class="skeleton-line"></div><div class="skeleton-line"></div>';
453
+ const rendered = rawContent ? renderMarkdown(rawContent) : '';
424
454
  const html = role === 'agent'
425
- ? `<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true">${getAgentIcon(m.cli)}</div><div class="agent-body">${toolHtml}<div class="msg-content lazy-pending" data-raw="${escapeHtml(rawContent)}">${skeletonContent}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div></div>`
426
- : `<div class="msg msg-${role}"><div class="user-body"><div class="msg-label">${label}</div><div class="msg-content lazy-pending" data-raw="${escapeHtml(rawContent)}">${skeletonContent}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div><div class="user-icon" aria-hidden="true">${getUserAvatarMarkup()}</div></div>`;
427
- vsItems.push({ id: generateId(), html, height: 80 });
428
- }
429
- return vsItems;
455
+ ? `<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true">${getAgentIcon(m.cli)}</div><div class="agent-body">${toolHtml}<div class="msg-content" data-raw="${escapeHtml(rawContent)}">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div></div>`
456
+ : `<div class="msg msg-${role}"><div class="user-body"><div class="msg-label">${label}</div><div class="msg-content" data-raw="${escapeHtml(rawContent)}">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div><div class="user-icon" aria-hidden="true">${getUserAvatarMarkup()}</div></div>`;
457
+ return { id: generateId(), html, height: 80 };
458
+ });
430
459
  }
431
460
 
432
461
  function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>): void {
@@ -450,42 +479,12 @@ function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>)
450
479
  };
451
480
  }
452
481
 
453
- function measureTailWindow(
454
- chatEl: HTMLElement,
455
- items: VirtualItem[],
456
- seedCount: number,
457
- ): number[] {
458
- const start = Math.max(0, items.length - seedCount);
459
- const slice = items.slice(start);
460
- if (slice.length === 0) return [];
461
-
462
- // Render tail items temporarily into empty chatEl, measure, then clear
463
- const fragment = document.createDocumentFragment();
464
- for (const item of slice) {
465
- const wrapper = document.createElement('div');
466
- wrapper.innerHTML = item.html;
467
- const el = wrapper.firstElementChild;
468
- if (el) fragment.appendChild(el);
469
- }
470
- chatEl.appendChild(fragment);
471
- const heights: number[] = [];
472
- const children = chatEl.children;
473
- for (let i = 0; i < children.length; i++) {
474
- heights.push(children[i].getBoundingClientRect().height);
475
- }
476
- chatEl.innerHTML = '';
477
- return heights;
478
- }
479
-
480
482
  function makeBootstrapDeps(
481
483
  vs: ReturnType<typeof getVirtualScroll>,
482
- chatEl: HTMLElement,
483
484
  ): VirtualHistoryBootstrapDeps {
484
485
  return {
485
486
  registerCallbacks: () => registerVirtualScrollCallbacks(vs),
486
- measureTailWindow: (items, seedCount) => measureTailWindow(chatEl, items, seedCount),
487
487
  setItems: (items, opts) => vs.setItems(items, opts),
488
- seedMeasuredHeights: (start, h) => vs.seedMeasuredHeights(start, h),
489
488
  activateIfNeeded: (toBottom) => vs.activateIfNeeded(toBottom),
490
489
  scrollToBottom: () => vs.scrollToBottom(),
491
490
  };
@@ -510,7 +509,7 @@ export async function loadMessages(): Promise<void> {
510
509
 
511
510
  if (msgs.length >= VS_THRESHOLD) {
512
511
  const vsItems = buildVirtualHistoryItems(msgs);
513
- bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs, chatEl!));
512
+ bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs));
514
513
  } else {
515
514
  msgs.forEach(m => {
516
515
  const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content, m.cli);
@@ -546,7 +545,7 @@ export async function loadMessages(): Promise<void> {
546
545
  if (cached.length > 0) {
547
546
  if (cached.length >= VS_THRESHOLD) {
548
547
  const vsItems = buildVirtualHistoryItems(cached as MessageItem[]);
549
- bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs, chatEl!));
548
+ bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs));
550
549
  } else {
551
550
  cached.forEach(m => {
552
551
  const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content, m.cli);
@@ -1,28 +1,22 @@
1
1
  /**
2
2
  * Pure-logic bootstrap orchestrator for virtual scroll.
3
- * No DOM imports safe to import in Node test environment.
3
+ * Simplified: tanstack virtual-core measures heights automatically.
4
4
  */
5
- import type { VirtualItem, LazyRenderCallback } from './virtual-scroll.js';
6
-
7
- export const BOOTSTRAP_SEED_COUNT = 20;
5
+ import type { VirtualItem } from './virtual-scroll.js';
8
6
 
9
7
  export interface VirtualHistoryBootstrapDeps {
10
8
  registerCallbacks: () => void;
11
- measureTailWindow: (items: VirtualItem[], seedCount: number) => number[];
12
9
  setItems: (items: VirtualItem[], options?: { autoActivate?: boolean; toBottom?: boolean }) => void;
13
- seedMeasuredHeights: (startIndex: number, heights: number[]) => void;
14
10
  activateIfNeeded: (toBottom: boolean) => void;
15
11
  scrollToBottom: () => void;
16
12
  }
17
13
 
18
14
  /**
19
- * Orchestrates virtual scroll bootstrap in correct order:
15
+ * Orchestrates virtual scroll bootstrap:
20
16
  * 1. registerCallbacks (onLazyRender, onPostRender)
21
- * 2. setItems with autoActivate:false (load all items without triggering activate)
22
- * 3. measureTailWindow (measure last N items for accurate initial heights)
23
- * 4. seedMeasuredHeights (feed measured heights back)
24
- * 5. activateIfNeeded (switch to VS mode with accurate bottom heights)
25
- * 6. scrollToBottom
17
+ * 2. setItems (with autoActivate=false to prevent premature activation)
18
+ * 3. activateIfNeeded tanstack measures on mount via ResizeObserver
19
+ * 4. scrollToBottom
26
20
  */
27
21
  export function bootstrapVirtualHistory(
28
22
  items: VirtualItem[],
@@ -30,13 +24,6 @@ export function bootstrapVirtualHistory(
30
24
  ): void {
31
25
  deps.registerCallbacks();
32
26
  deps.setItems(items, { autoActivate: false });
33
-
34
- const seedStart = Math.max(0, items.length - BOOTSTRAP_SEED_COUNT);
35
- const heights = deps.measureTailWindow(items, BOOTSTRAP_SEED_COUNT);
36
- if (heights.length > 0) {
37
- deps.seedMeasuredHeights(seedStart, heights);
38
- }
39
-
40
27
  deps.activateIfNeeded(true);
41
28
  deps.scrollToBottom();
42
29
  }