cli-jaw 1.6.14 → 1.6.16

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 (31) hide show
  1. package/dist/bin/postinstall.js +16 -6
  2. package/dist/bin/postinstall.js.map +1 -1
  3. package/package.json +1 -1
  4. package/public/assets/shark.svg +1 -0
  5. package/public/dist/assets/{employees-zxrU6ZV_.js → employees-V7lNStu1.js} +1 -1
  6. package/public/dist/assets/{index-D61icK-D.js → index-Cpe1jccL.js} +4 -4
  7. package/public/dist/assets/render-BoxeLlL9.js +25 -0
  8. package/public/dist/assets/settings-BcKp6ppP.js +1 -0
  9. package/public/dist/assets/{settings-Dl3RnWsB.js → settings-CBCg5Jhh.js} +1 -1
  10. package/public/dist/assets/skills-BuAXFNgp.js +1 -0
  11. package/public/dist/assets/{skills-DhiCSGws.js → skills-RbauGmBZ.js} +1 -1
  12. package/public/dist/assets/{slash-commands-B1k1vFJG.js → slash-commands-BgKxc49D.js} +1 -1
  13. package/public/dist/assets/slash-commands-DXGb_iGA.js +1 -0
  14. package/public/dist/assets/ui-KQ8_sSP8.js +131 -0
  15. package/public/dist/assets/ui-rD__Mvbs.js +1 -0
  16. package/public/dist/assets/vendor-icons-C6LXvgi0.js +1 -0
  17. package/public/dist/assets/{ws-CleMWrLF.js → ws-BtTpgocf.js} +1 -1
  18. package/public/dist/index.html +3 -3
  19. package/public/index.html +2 -2
  20. package/public/js/features/avatar.ts +5 -3
  21. package/public/js/icons.ts +10 -4
  22. package/public/js/ui.ts +87 -73
  23. package/public/js/virtual-scroll-bootstrap.ts +42 -0
  24. package/public/js/virtual-scroll.ts +140 -49
  25. package/public/dist/assets/render-CVr6a-dp.js +0 -25
  26. package/public/dist/assets/settings-BHIV4l1s.js +0 -1
  27. package/public/dist/assets/skills-JuDja1UC.js +0 -1
  28. package/public/dist/assets/slash-commands-DyLS0abr.js +0 -1
  29. package/public/dist/assets/ui-BXZhbE_1.js +0 -131
  30. package/public/dist/assets/ui-qR28iS0L.js +0 -1
  31. package/public/dist/assets/vendor-icons-BqxEYYco.js +0 -1
@@ -0,0 +1,131 @@
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-BoxeLlL9.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 v(){return _}function ne(e){_=(e||``).trim()||g,localStorage.setItem(te,_);let t=document.getElementById(`appNameInput`);t&&(t.value=_)}function re(){_=localStorage.getItem(te)||g;let e=document.getElementById(`appNameInput`);e&&(e.value=_),document.getElementById(`appNameSave`)?.addEventListener(`click`,()=>{let e=document.getElementById(`appNameInput`);e&&ne(e.value)}),document.getElementById(`appNameInput`)?.addEventListener(`keydown`,e=>{let t=e;t.key===`Enter`&&(t.preventDefault(),ne(t.target.value),t.target.blur())})}var ie=`agentAvatar`,ae=`userAvatar`,oe=d.shark,se=d.user,ce={agent:{emoji:oe,imageUrl:``,updatedAt:null},user:{emoji:se,imageUrl:``,updatedAt:null}},le=!1;function y(e){return ce[e]}function ue(e){return e===`agent`?`agentAvatarPreview`:`userAvatarPreview`}function de(e){return e===`agent`?`.agent-icon`:`.user-icon`}function b(e){let t=document.getElementById(ue(e));if(t){t.innerHTML=x(e);let n=y(e).imageUrl?`image`:`emoji`;t.setAttribute(`data-avatar-kind`,n)}}function x(e){let t=y(e);return t.imageUrl?`<img class="avatar-image" src="${c(t.imageUrl)}" alt="" loading="lazy" decoding="async">`:t.emoji}function S(e){let t=x(e),n=y(e).imageUrl?`image`:`emoji`;document.querySelectorAll(de(e)).forEach(e=>{e.innerHTML=t,e.setAttribute(`data-avatar-kind`,n)})}function C(e,t){t?.kind===`image`&&t.imageUrl?(y(e).imageUrl=t.imageUrl,y(e).updatedAt=t.updatedAt??Date.now()):(y(e).imageUrl=``,y(e).updatedAt=t?.updatedAt??null),b(e),S(e)}async function fe(){let e=await n(`/api/avatar`);e&&(C(`agent`,e.agent),C(`user`,e.user))}async function w(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 pe(e,t){let n=await w(`/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})`);C(e,r?.data||r)}async function me(e){let t=await w(`/api/avatar/${e}/image`,{method:`DELETE`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||`avatar reset failed (${t.status})`);C(e,n?.data||n)}function he(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 me(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 pe(e,r)}catch(e){console.warn(`[avatar:upload]`,e.message)}finally{n.value=``}})}function ge(){return x(`agent`)}function _e(){return x(`user`)}async function ve(){y(`agent`).emoji=localStorage.getItem(ie)||oe,y(`user`).emoji=localStorage.getItem(ae)||se,b(`agent`),b(`user`),le||(le=!0,he(`agent`),he(`user`)),await fe(),S(`agent`),S(`user`)}var ye=5,T=80,be=class{items=[];container;spacerTop;spacerBottom;viewport;_active=!1;_totalHeight=0;rafId=null;firstVisible=-1;lastVisible=-1;prefixHeights=[0];prefixDirtyFrom=0;itemSpacing=0;onLazyRender=null;onPostRender=null;constructor(e){this.container=document.getElementById(e),this.spacerTop=document.createElement(`div`),this.spacerTop.className=`vs-spacer-top`,this.spacerBottom=document.createElement(`div`),this.spacerBottom.className=`vs-spacer-bottom`,this.viewport=document.createElement(`div`),this.viewport.className=`vs-viewport`}get active(){return this._active}get count(){return this.items.length}markPrefixDirty(e){this.prefixDirtyFrom=Math.min(this.prefixDirtyFrom,Math.max(0,e))}rebuildPrefixHeights(){let e=this.items.length;this.prefixHeights.length!==e+1&&(this.prefixHeights=Array(e+1).fill(0),this.prefixDirtyFrom=0);for(let t=this.prefixDirtyFrom;t<e;t++)this.prefixHeights[t+1]=this.prefixHeights[t]+this.items[t].height;this.prefixDirtyFrom=e}offsetForIndex(e){return this.rebuildPrefixHeights(),this.prefixHeights[Math.max(0,Math.min(e,this.items.length))]}effectiveOffset(e){return this.offsetForIndex(e)+e*this.itemSpacing}totalEffectiveHeight(){let e=this.items.length;return e===0?0:this.offsetForIndex(e)+(e-1)*this.itemSpacing}indexForOffset(e){this.rebuildPrefixHeights();let t=this.items.length;if(t===0)return 0;let n=0,r=t-1;for(;n<r;){let t=n+r+1>>1;this.prefixHeights[t]+t*this.itemSpacing<=e?n=t:r=t-1}return n}refreshLayoutMetrics(){let e=this.viewport.querySelector(`.msg`);e&&(this.itemSpacing=parseFloat(getComputedStyle(e).marginBottom)||0)}flushToDOM(){this._active&&(this.container.classList.remove(`vs-active`),this.container.removeEventListener(`scroll`,this.scrollHandler),this.rafId&&=(cancelAnimationFrame(this.rafId),null),this.container.innerHTML=this.items.map(e=>e.html).join(``),this._active=!1,this.firstVisible=-1,this.lastVisible=-1,this.items=[],this._totalHeight=0,this.prefixHeights=[0],this.prefixDirtyFrom=0,this.itemSpacing=0)}setItems(e,t){this.items=e,this._totalHeight=e.reduce((e,t)=>e+t.height,0),this.prefixHeights=Array(e.length+1).fill(0),this.prefixDirtyFrom=0,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,i=this.items[r];if(!i)continue;let a=i.height,o=t[n];a!==o&&(i.height=o,this._totalHeight+=o-a,this.markPrefixDirty(r))}}activateIfNeeded(e=!1){!this._active&&this.items.length>=80&&this.activate(e)}addItem(e,t){let n={id:e,html:t,height:T};this.items.push(n),this._totalHeight+=T,this.markPrefixDirty(this.items.length-1),!this._active&&this.items.length>=80&&this.activate(!0),this._active&&this.scheduleRender()}appendLiveItem(e){if(!this._active)return;let t=e.outerHTML,n={id:h(),html:t,height:T};this.items.push(n),this._totalHeight+=T,this.markPrefixDirty(this.items.length-1),this.scrollToBottom()}updateItemHtml(e,t){this.items[e]&&(this.items[e].html=t)}scrollHandler=()=>this.scheduleRender();activate(e=!1){this._active=!0,this._totalHeight=0,this.container.querySelectorAll(`.msg`).forEach((e,t)=>{this.items[t]&&(this.items[t].height=e.getBoundingClientRect().height)});for(let e of this.items)this._totalHeight+=e.height;if(this.prefixHeights=Array(this.items.length+1).fill(0),this.prefixDirtyFrom=0,this.container.classList.add(`vs-active`),this.container.replaceChildren(this.spacerTop,this.viewport,this.spacerBottom),this.container.addEventListener(`scroll`,this.scrollHandler,{passive:!0}),e){let e=this.totalEffectiveHeight();this.spacerTop.style.height=`${e}px`,this.spacerBottom.style.height=`0px`,this.container.scrollTop=this.container.scrollHeight,this.firstVisible=-1,this.lastVisible=-1}this.render()}scheduleRender(){this.rafId||=requestAnimationFrame(()=>{this.rafId=null,this.render()})}render(){let e=this.container.scrollTop,t=this.container.clientHeight,n=this.indexForOffset(e),r=Math.max(0,n-ye),i=n;for(let r=n;r<this.items.length&&(i=r,!(this.effectiveOffset(r+1)>e+t));r++);let a=Math.min(this.items.length-1,i+ye);if(r===this.firstVisible&&a===this.lastVisible){this.refreshLayoutMetrics();let e=this.effectiveOffset(r),t=this.effectiveOffset(this.items.length)-this.effectiveOffset(a+1);this.spacerTop.style.height=`${e}px`,this.spacerBottom.style.height=`${t}px`;return}this.firstVisible=r,this.lastVisible=a;let o=new Map;for(let e of Array.from(this.viewport.children)){let t=Number(e.dataset.vsIdx);isNaN(t)||o.set(t,e)}for(let[e,t]of o)(e<r||e>a)&&(t.remove(),o.delete(e));let s=[];for(let e=r;e<=a;e++){let t=o.get(e);if(t)s.push(t);else{let t=this.items[e],n=document.createElement(`div`);n.innerHTML=t.html;let r=n.firstElementChild;r&&(r.dataset.vsIdx=String(e),s.push(r))}}let c=this.viewport.firstChild;for(let e of s)e===c?c=c.nextSibling:this.viewport.insertBefore(e,c);this.refreshLayoutMetrics();let l=this.effectiveOffset(r),u=this.effectiveOffset(this.items.length)-this.effectiveOffset(a+1);if(this.spacerTop.style.height=`${l}px`,this.spacerBottom.style.height=`${u}px`,this.onLazyRender){let e=this.viewport.querySelectorAll(`.lazy-pending`);e.length>0&&this.onLazyRender(Array.from(e))}this.onPostRender&&this.onPostRender(this.viewport),this.remeasureVisible()}remeasureVisible(){let e=this.container.scrollHeight-this.container.scrollTop-this.container.clientHeight<80,t=[];this.viewport.querySelectorAll(`[data-vs-idx]`).forEach(e=>{let n=Number(e.dataset.vsIdx);this.items[n]&&t.push({idx:n,newH:e.getBoundingClientRect().height})});let n=!1;for(let{idx:e,newH:r}of t){let t=this.items[e].height;t!==r&&(this.items[e].height=r,this._totalHeight+=r-t,this.markPrefixDirty(e),n=!0)}n&&e&&this.scrollToBottom()}scrollToBottom(){this.rafId&&=(cancelAnimationFrame(this.rafId),null);let e=this.totalEffectiveHeight();this.spacerTop.style.height=`${e}px`,this.spacerBottom.style.height=`0px`,this.container.scrollTop=this.container.scrollHeight,this.firstVisible=-1,this.lastVisible=-1,this.render()}clear(){this.items=[],this._totalHeight=0,this.prefixHeights=[0],this.prefixDirtyFrom=0,this.itemSpacing=0,this._active&&(this.container.classList.remove(`vs-active`),this.container.removeEventListener(`scroll`,this.scrollHandler),this.viewport.innerHTML=``,this.spacerTop.style.height=`0`,this.spacerBottom.style.height=`0`,this.container.innerHTML=``),this._active=!1,this.firstVisible=-1,this.lastVisible=-1,this.onLazyRender=null,this.onPostRender=null,this.rafId&&=(cancelAnimationFrame(this.rafId),null)}},xe=null;function E(){return xe||=new be(`chatMessages`),xe}function D(e,t){t.registerCallbacks(),t.setItems(e,{autoActivate:!1});let n=Math.max(0,e.length-20),r=t.measureTailWindow(e,20);r.length>0&&t.seedMeasuredHeights(n,r),t.activateIfNeeded(!0),t.scrollToBottom()}var Se=2e3,Ce=80;function we(e){return{chunks:[],fullText:``,textDirty:!1,element:e,pendingRAF:null,isFinalized:!1,lastRenderTime:0}}function O(e){return e.textDirty&&=(e.fullText=e.chunks.join(``),!1),e.fullText}function Te(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=O(e);n.length<Se||t-e.lastRenderTime>Ce?(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(O(e),!0)+`<span class="stream-cursor" aria-hidden="true"></span>`,e.lastRenderTime=performance.now())})}))}function Ee(e,t=!1){e.isFinalized=!0,e.pendingRAF&&=(cancelAnimationFrame(e.pendingRAF),null);let n=O(e);return t||(e.element.innerHTML=o(n)),n}var k=[`cdnjs.cloudflare.com`,`cdn.jsdelivr.net`,`unpkg.com`,`esm.sh`,`fonts.googleapis.com`,`fonts.gstatic.com`],De=[/\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*\(/],Oe=[];function ke(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(!k.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];k.some(t=>e===t||e.endsWith(`.`+t))||t.push(`CSS url() references external domain: ${e}`)}for(let n of De)if(n.test(e))return{valid:!1,reason:`Dangerous pattern: ${n.source}`,warnings:t};for(let n of Oe)n.test(e)&&t.push(`DOM sink detected: ${n.source}`);return{valid:!0,warnings:t}}function A(){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 j(){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 Ae=[`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 je(){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 Me(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 Ne(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=Ae.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 Pe(){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 Fe(e){return`
3
+ <script>
4
+ (function() {
5
+ var __nonce = '${e}';
6
+
7
+ window.addEventListener('message', function(e) {
8
+ if (e.source !== window.parent) return;
9
+ if (!e.data || typeof e.data !== 'object') return;
10
+
11
+ if (e.data.type === 'jaw-theme-update') {
12
+ window.__jawTheme = { isDark: !!e.data.isDark };
13
+ window.__jawTokens = e.data.tokens || {};
14
+ window.dispatchEvent(new CustomEvent('jaw-theme-change', { detail: window.__jawTheme }));
15
+ }
16
+ if (e.data.type === 'jaw-request-resize') {
17
+ postHeight();
18
+ }
19
+ if (e.data.type === 'jaw-request-screenshot') {
20
+ var canvas = document.querySelector('canvas');
21
+ if (canvas) {
22
+ try {
23
+ var dataUrl = canvas.toDataURL('image/png');
24
+ window.parent.postMessage({ type: 'jaw-screenshot', dataUrl: dataUrl, nonce: __nonce }, '*');
25
+ } catch(ex) { /* tainted canvas or other error */ }
26
+ }
27
+ }
28
+ });
29
+
30
+ function postHeight() {
31
+ var h = Math.max(
32
+ document.body.scrollHeight,
33
+ document.body.offsetHeight,
34
+ document.documentElement.scrollHeight
35
+ );
36
+ window.parent.postMessage({ type: 'jaw-diagram-resize', height: h, nonce: __nonce }, '*');
37
+ }
38
+
39
+ if (typeof ResizeObserver !== 'undefined') {
40
+ var ro = new ResizeObserver(function() {
41
+ clearTimeout(ro._t);
42
+ ro._t = setTimeout(postHeight, 50);
43
+ });
44
+ ro.observe(document.body);
45
+ }
46
+
47
+ window.addEventListener('load', function() {
48
+ postHeight();
49
+ // Deferred re-measure for async chart renders (Chart.js animation, CDN loading)
50
+ setTimeout(postHeight, 200);
51
+ setTimeout(postHeight, 800);
52
+ window.parent.postMessage({ type: 'jaw-widget-ready', nonce: __nonce }, '*');
53
+ });
54
+
55
+ var lastSend = 0;
56
+ window.sendPrompt = function(text) {
57
+ var now = Date.now();
58
+ if (now - lastSend < 3000) return;
59
+ lastSend = now;
60
+ window.parent.postMessage({ type: 'jaw-send-prompt', text: String(text).slice(0, 500), nonce: __nonce }, '*');
61
+ };
62
+
63
+ // Ctrl+C / Cmd+C: forward selected text to host for clipboard access
64
+ document.addEventListener('copy', function() {
65
+ var sel = window.getSelection();
66
+ if (sel && sel.toString().trim()) {
67
+ window.parent.postMessage({
68
+ type: 'jaw-copy-text',
69
+ text: sel.toString().slice(0, 512),
70
+ nonce: __nonce
71
+ }, '*');
72
+ }
73
+ });
74
+ })();
75
+ <\/script>`}var Ie=[[/\/p5\.js\/1\.11\.1[1-9]\//g,`/p5.js/1.11.10/`]];function Le(e){for(let[t,n]of Ie)e=e.replace(t,n);return e}function Re(e){je(),ze(),e=Le(e);let t=Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),n=Pe(),r=Ne(e),i=Me(e),a=Fe(t),o=`<!DOCTYPE html>
76
+ <html>
77
+ <head>
78
+ <meta charset="utf-8">
79
+ ${r}
80
+ ${i}
81
+ <style>
82
+ :root { ${Object.entries(n.tokens).map(([e,t])=>`${e}: ${t};`).join(`
83
+ `)} }
84
+ * { margin: 0; box-sizing: border-box; }
85
+ body {
86
+ font-family: var(--font-ui), system-ui, sans-serif;
87
+ color: var(--text);
88
+ background: transparent;
89
+ padding: 16px;
90
+ overflow: hidden;
91
+ }
92
+ </style>
93
+ </head>
94
+ <body>
95
+ <script>
96
+ window.__jawTheme = ${JSON.stringify({isDark:n.isDark})};
97
+ window.__jawTokens = ${JSON.stringify(n.tokens).replace(/<\//g,`<\\/`)};
98
+ <\/script>
99
+ ${a}
100
+ ${e}
101
+ </body>
102
+ </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=ke(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(j()),i.appendChild(A());let{iframe:a,nonce:o}=Re(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">
103
+ Widget failed to load within 10 seconds.
104
+ </div>`,console.warn(`[jaw-diagram] Widget timeout — iframe deregistered`)}},1e4)})}var I=null;function ze(){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 Be(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 Ve(){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}=Re(n);e.innerHTML=``,e.appendChild(j()),e.appendChild(A()),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 He=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;Be(e.source,t);break}case`jaw-send-prompt`:{let t=Date.now();if(t-He<3e3)return;He=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 Ue(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 R(){document.querySelectorAll(`.tool-activity-live`).forEach(e=>e.remove()),document.querySelectorAll(`.msg-system.tool-activity`).forEach(e=>e.remove())}function We(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 Ge(e,t=120){let n=e.replace(/\s+/g,` `).trim();return n?n.length>t?`${n.slice(0,t-1)}…`:n:``}function Ke(e){let t=(e.detail||``).trim();return t?t!==(e.label||``).trim():!1}function z(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=Ke(e)?Ge(a,e.type===`thinking`?120:100):``,l=s?`<span class="process-step-snippet">${c(s)}</span>`:``;return Ke(e)?`<div class="process-step process-step-expandable" data-step-id="${e.id}" data-type="${e.type}">
105
+ <button class="process-step-toggle" aria-expanded="false" aria-controls="${o}">
106
+ <span class="${t}"></span>
107
+ <span class="${n}">${r}</span>
108
+ <span class="process-step-main">
109
+ <span class="process-step-label">${i}</span>
110
+ ${l}
111
+ </span>
112
+ <span class="process-step-chevron">${d.chevronRight}</span>
113
+ </button>
114
+ <div class="process-step-details collapsed" id="${o}">
115
+ <pre class="process-step-full">${c(a)}</pre>
116
+ </div>
117
+ </div>`:`<div class="process-step" data-step-id="${e.id}" data-type="${e.type}">
118
+ <span class="${t}"></span>
119
+ <span class="${n}">${r}</span>
120
+ <span class="process-step-label">${i}</span>
121
+ </div>`}function qe(e=``,t=!1){return`<div class="process-block${t?` collapsed`:``}">
122
+ <button class="process-summary" aria-expanded="${t?`false`:`true`}">
123
+ <span class="process-dot ${t?`done`:`running`}"></span>
124
+ <span class="process-summary-text">${e}</span>
125
+ <span class="process-duration"></span>
126
+ <span class="process-chevron">${t?d.chevronRight:d.chevronDown}</span>
127
+ </button>
128
+ <div class="process-details">
129
+ <div class="process-steps-inner"></div>
130
+ </div>
131
+ </div>`}function Je(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 Ye(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){Je(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 Xe(e,t=!0){let n=qe(We(e),t),r=document.createElement(`div`);r.innerHTML=n;let i=r.querySelector(`.process-steps-inner`);i&&(i.innerHTML=e.map(z).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 B(e){let t=e.element.querySelector(`.process-summary-text`);t&&(t.innerHTML=We(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 V(e){let t=document.createElement(`div`);t.innerHTML=qe(``,!1);let n=t.firstElementChild,r=e.querySelector(`.msg-content`);return r?r.before(n):e.appendChild(n),{element:n,steps:[],collapsed:!1}}function H(e,t){e.steps.push(t);let n=e.element.querySelector(`.process-steps-inner`);n&&n.insertAdjacentHTML(`beforeend`,z(t)),B(e)}function U(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=z(n);let t=e.firstElementChild;t&&i.replaceWith(t)}B(e)}function Ze(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))}B(e)}function W(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`)}),B(e)}function G(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function Qe(e){return ge()}function K(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 $e(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`)),tt()):(n&&(n.className=`status-badge status-idle`,n.textContent=`idle`),r&&(r.innerHTML=d.send,r.title=`Send`,r.classList.remove(`stop-mode`)),q(),et(0))}function et(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 tt(){let e=document.getElementById(`chatMessages`);if(!e||e.querySelector(`.skeleton-msg`))return;J();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 q(){document.querySelectorAll(`.skeleton-msg`).forEach(e=>e.remove())}function J(){document.getElementById(`emptyState`)?.classList.remove(`visible`)}function Y(){let e=document.getElementById(`chatMessages`);e&&e.children.length===0&&document.getElementById(`emptyState`)?.classList.add(`visible`)}function nt(e,t,n){let r=document.getElementById(`chatMessages`);if(!r)return;let i=E();J();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 rt(){R(),e.currentAgentDiv=null,e.currentProcessBlock=null}function it(t){if(q(),(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=Z(`agent`,``),e.currentProcessBlock=null),!e.currentProcessBlock){let t=e.currentAgentDiv.querySelector(`.agent-body`);t&&(e.currentProcessBlock=V(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),U(e.currentProcessBlock,a.id,{...t,id:a.id})):Ze(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),U(e.currentProcessBlock,o.id,{...t,id:o.id})):Ze(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){U(e.currentProcessBlock,n.id,t),Q();return}}t.icon=i(t.icon),H(e.currentProcessBlock,t)}Q()}var X=null;function at(t){if(!t)return;q(),(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=Z(`agent`,``),X=null);let n=e.currentAgentDiv?.querySelector(`.msg-content`);n&&(X||=we(n),Te(X,t)),Q()}var ot=0;function st(t,n){let r=Date.now();if(!e.currentAgentDiv&&r-ot<500)return;R(),q();let i=!!e.currentProcessBlock;e.currentProcessBlock&&=(W(e.currentProcessBlock),null);let a=n&&n.length>0;if(t||a){(!e.currentAgentDiv||!e.currentAgentDiv.isConnected)&&(e.currentAgentDiv=Z(`agent`,``));let r=e.currentAgentDiv?.querySelector(`.msg-content`),s=X?Ee(X,!0):``,c=t||s;X=null;let u=a&&!i?Xe(K(n),!0):``;r&&(r.innerHTML=u+o(c)),r&&r.setAttribute(`data-raw`,l(c)),r&&F(r);let d=E();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(()=>{})}X=null,e.currentAgentDiv=null,ot=Date.now(),$e(`idle`),dt()}function Z(e,t,n){let r=document.getElementById(`chatMessages`),i=E();J(),q();let s=o(t),d=c(e===`user`?a(`msg.you`):v()),f=document.createElement(`div`);e===`agent`?(f.className=`msg msg-agent`,f.innerHTML=`<div class="agent-icon" aria-hidden="true">${Qe(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">${_e()}</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(),f}var ct=null;function Q(){let e=E();if(e.active){e.scrollToBottom();return}ct||=requestAnimationFrame(()=>{ct=null;let e=document.getElementById(`chatMessages`);e&&(e.scrollTop=e.scrollHeight)})}function lt(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-BcKp6ppP.js`).then(e=>e.loadSettings()),__vite__mapDeps([0])),e===`agents`&&r(()=>import(`./employees-V7lNStu1.js`).then(e=>e.loadEmployees()),__vite__mapDeps([0])),e===`skills`&&r(()=>import(`./skills-BuAXFNgp.js`).then(e=>e.loadSkills()),__vite__mapDeps([0]))}function ut(){document.getElementById(`tabSettings`)?.classList.contains(`active`)?r(()=>import(`./settings-BcKp6ppP.js`).then(e=>e.savePerCli()),__vite__mapDeps([0])):r(()=>import(`./settings-BcKp6ppP.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 dt(){let e=await n(`/api/messages`);e&&$(e.length)}function ft(e){let t=[];for(let n of e){let e=n.role===`assistant`?`agent`:n.role,r=l(n.content),i=c(e===`user`?a(`msg.you`):v()),o=n.role===`assistant`?G(n.tool_log):[],s=o.length>0?Xe(K(o),!0):``,u=`<div class="skeleton-line"></div><div class="skeleton-line"></div>`,d=e===`agent`?`<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true">${Qe(n.cli)}</div><div class="agent-body">${s}<div class="msg-content lazy-pending" data-raw="${c(r)}">${u}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div></div>`:`<div class="msg msg-${e}"><div class="user-body"><div class="msg-label">${i}</div><div class="msg-content lazy-pending" data-raw="${c(r)}">${u}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div><div class="user-icon" aria-hidden="true">${_e()}</div></div>`;t.push({id:h(),html:d,height:80})}return t}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 mt(e,t,n){let r=Math.max(0,t.length-n),i=t.slice(r);if(i.length===0)return[];let a=document.createDocumentFragment();for(let e of i){let t=document.createElement(`div`);t.innerHTML=e.html;let n=t.firstElementChild;n&&a.appendChild(n)}e.appendChild(a);let o=[],s=e.children;for(let e=0;e<s.length;e++)o.push(s[e].getBoundingClientRect().height);return e.innerHTML=``,o}function ht(e,t){return{registerCallbacks:()=>pt(e),measureTailWindow:(e,n)=>mt(t,e,n),setItems:(t,n)=>e.setItems(t,n),seedMeasuredHeights:(t,n)=>e.seedMeasuredHeights(t,n),activateIfNeeded:t=>e.activateIfNeeded(t),scrollToBottom:()=>e.scrollToBottom()}}async function gt(){let e=E(),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?D(ft(r),ht(e,t)):r.forEach(e=>{let t=Z(e.role===`assistant`?`agent`:e.role,e.content,e.cli);if(e.role===`assistant`){let n=G(e.tool_log);if(n.length>0){let e=t.querySelector(`.agent-body`);if(e){let t=V(e);for(let e of K(n))H(t,e);W(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),Y();return}if(t&&t.children.length>0){Y();return}let i=await m();i.length>0&&(i.length>=80?D(ft(i),ht(e,t)):i.forEach(e=>{let t=Z(e.role===`assistant`?`agent`:e.role,e.content,e.cli);if(e.role===`assistant`&&e.tool_log){let n=G(e.tool_log);if(n.length>0){let e=t.querySelector(`.agent-body`);if(e){let t=V(e);for(let e of K(n))H(t,e);W(t)}}}}),nt(`${d.warning} 오프라인 모드 — 캐시된 메시지 표시 중`),$(i.length)),Y()}function _t(){let e=document.getElementById(`chatMessages`);e&&(Ye(e),Ue(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{ve as _,st as a,gt as c,$e as d,it as f,E as g,Ve as h,rt as i,dt as l,et as m,nt as n,ut as o,lt as p,at as r,_t as s,Z as t,Q as u,re as v};
@@ -0,0 +1 @@
1
+ import{c as e,d as t,i as n,m as r}from"./ui-KQ8_sSP8.js";export{n as cleanupToolActivity,e as loadMessages,t as setStatus,r as updateQueueBadge};
@@ -0,0 +1 @@
1
+ var e={xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`};function t(t,n={}){let r=(`size`in t?t.size:t.width)??e.width,i=(`size`in t?t.size:t.height)??e.height,a=t.aliases?.map(e=>`lucide-${e}`)??[],o=[`lucide`,`lucide-${t.name}`,...a];return n.className&&o.push(n.className),[`svg`,{...e,...`color`in n&&{stroke:n.color},...`size`in n&&n.size&&{width:n.size.toString(10),height:n.size.toString(10)},...`width`in n&&n.width&&{width:n.width.toString(10)},...`height`in n&&n.height&&{height:n.height.toString(10)},...`strokeWidth`in n&&n.strokeWidth&&{"stroke-width":n.strokeWidth.toString(10)},class:o.join(` `),viewBox:`0 0 ${r} ${i}`,...`attributes`in n&&n.attributes},t.node.map(([e,t])=>[e,n.absoluteStrokeWidth?{"vector-effect":`non-scaling-stroke`,...t}:t])]}var n=([e,t,r=[]])=>`<${e} ${Object.entries(t).map(([e,t])=>`${e}="${t}"`).join(` `)}>${r?.map(e=>n(e)).join(``)}</${e}>`;function r(e,r={}){return n(t(e,r))}var i={name:`arrow-left`,size:24,node:[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]},a={name:`arrow-right`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]},o={name:`bot`,size:24,node:[[`path`,{d:`M12 8V4H8`,key:`hb8ula`}],[`rect`,{width:`16`,height:`12`,x:`4`,y:`8`,rx:`2`,key:`enze0r`}],[`path`,{d:`M2 14h2`,key:`vft8re`}],[`path`,{d:`M20 14h2`,key:`4cs60a`}],[`path`,{d:`M15 13v2`,key:`1xurst`}],[`path`,{d:`M9 13v2`,key:`rq6x2g`}]]},s={name:`brain`,size:24,node:[[`path`,{d:`M12 18V5`,key:`adv99a`}],[`path`,{d:`M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4`,key:`1e3is1`}],[`path`,{d:`M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5`,key:`1gqd8o`}],[`path`,{d:`M17.997 5.125a4 4 0 0 1 2.526 5.77`,key:`iwvgf7`}],[`path`,{d:`M18 18a4 4 0 0 0 2-7.464`,key:`efp6ie`}],[`path`,{d:`M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517`,key:`1gq6am`}],[`path`,{d:`M6 18a4 4 0 0 1-2-7.464`,key:`k1g0md`}],[`path`,{d:`M6.003 5.125a4 4 0 0 0-2.526 5.77`,key:`q97ue3`}]]},c={name:`chart-bar`,size:24,node:[[`path`,{d:`M3 3v16a2 2 0 0 0 2 2h16`,key:`c24i48`}],[`path`,{d:`M7 16h8`,key:`srdodz`}],[`path`,{d:`M7 11h12`,key:`127s9w`}],[`path`,{d:`M7 6h3`,key:`w9rmul`}]],aliases:[`bar-chart-horizontal`]},l={name:`check`,size:24,node:[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]},u={name:`chevron-down`,size:24,node:[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]},d={name:`chevron-left`,size:24,node:[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]},f={name:`chevron-right`,size:24,node:[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]},p={name:`circle-check`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]],aliases:[`check-circle-2`]},m={name:`circle-user-round`,size:24,node:[[`path`,{d:`M17.925 20.056a6 6 0 0 0-11.851.001`,key:`z69sun`}],[`circle`,{cx:`12`,cy:`11`,r:`4`,key:`1gt34v`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]],aliases:[`user-circle-2`]},h={name:`circle-x`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]],aliases:[`x-circle`]},g={name:`clipboard-list`,size:24,node:[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`,key:`116196`}],[`path`,{d:`M12 11h4`,key:`1jrz19`}],[`path`,{d:`M12 16h4`,key:`n85exb`}],[`path`,{d:`M8 11h.01`,key:`1dfujw`}],[`path`,{d:`M8 16h.01`,key:`18s6g9`}]]},_={name:`copy`,size:24,node:[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]},v={name:`download`,size:24,node:[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]},y={name:`file-text`,size:24,node:[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 9H8`,key:`b1mrlr`}],[`path`,{d:`M16 13H8`,key:`t4e002`}],[`path`,{d:`M16 17H8`,key:`z1uh3a`}]]},b={name:`folder-open`,size:24,node:[[`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`,key:`usdka0`}]]},x={name:`gamepad-2`,size:24,node:[[`line`,{x1:`6`,x2:`10`,y1:`11`,y2:`11`,key:`1gktln`}],[`line`,{x1:`8`,x2:`8`,y1:`9`,y2:`13`,key:`qnk9ow`}],[`line`,{x1:`15`,x2:`15.01`,y1:`12`,y2:`12`,key:`krot7o`}],[`line`,{x1:`18`,x2:`18.01`,y1:`10`,y2:`10`,key:`1lcuu1`}],[`path`,{d:`M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z`,key:`mfqc10`}]]},S={name:`globe`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20`,key:`13o1zl`}],[`path`,{d:`M2 12h20`,key:`9i4pu4`}]]},C={name:`hand-metal`,size:24,node:[[`path`,{d:`M18 12.5V10a2 2 0 0 0-2-2a2 2 0 0 0-2 2v1.4`,key:`wc6myp`}],[`path`,{d:`M14 11V9a2 2 0 1 0-4 0v2`,key:`94qvcw`}],[`path`,{d:`M10 10.5V5a2 2 0 1 0-4 0v9`,key:`m1ah89`}],[`path`,{d:`m7 15-1.76-1.76a2 2 0 0 0-2.83 2.82l3.6 3.6C7.5 21.14 9.2 22 12 22h2a8 8 0 0 0 8-8V7a2 2 0 1 0-4 0v5`,key:`t1skq1`}]]},w={name:`heart-pulse`,size:24,node:[[`path`,{d:`M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5`,key:`mvr1a0`}],[`path`,{d:`M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27`,key:`auskq0`}]]},T={name:`hourglass`,size:24,node:[[`path`,{d:`M5 22h14`,key:`ehvnwv`}],[`path`,{d:`M5 2h14`,key:`pdyrp9`}],[`path`,{d:`M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22`,key:`1d314k`}],[`path`,{d:`M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2`,key:`1vvvr6`}]]},E={name:`house`,size:24,node:[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]],aliases:[`home`]},D={name:`key-round`,size:24,node:[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]]},O={name:`lightbulb`,size:24,node:[[`path`,{d:`M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5`,key:`1gvzjb`}],[`path`,{d:`M9 18h6`,key:`x1upvd`}],[`path`,{d:`M10 22h4`,key:`ceow96`}]]},k={name:`link`,size:24,node:[[`path`,{d:`M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71`,key:`1cjeqo`}],[`path`,{d:`M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71`,key:`19qd67`}]]},A={name:`lock-open`,size:24,node:[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 9.9-1`,key:`1mm8w8`}]],aliases:[`unlock`]},j={name:`lock`,size:24,node:[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]},M={name:`message-square`,size:24,node:[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}]]},N={name:`mic`,size:24,node:[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M19 10v2a7 7 0 0 1-14 0v-2`,key:`1vc78b`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`13`,rx:`3`,key:`s6n7sd`}]]},P={name:`notebook-pen`,size:24,node:[[`path`,{d:`M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4`,key:`re6nr2`}],[`path`,{d:`M2 6h4`,key:`aawbzj`}],[`path`,{d:`M2 10h4`,key:`l0bgd4`}],[`path`,{d:`M2 14h4`,key:`1gsvsf`}],[`path`,{d:`M2 18h4`,key:`1bu2t1`}],[`path`,{d:`M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z`,key:`pqwjuv`}]]},F={name:`package`,size:24,node:[[`path`,{d:`M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z`,key:`1a0edw`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}],[`polyline`,{points:`3.29 7 12 12 20.71 7`,key:`ousv84`}],[`path`,{d:`m7.5 4.27 9 5.15`,key:`1c824w`}]]},I={name:`palette`,size:24,node:[[`path`,{d:`M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z`,key:`e79jfc`}],[`circle`,{cx:`13.5`,cy:`6.5`,r:`.5`,fill:`currentColor`,key:`1okk4w`}],[`circle`,{cx:`17.5`,cy:`10.5`,r:`.5`,fill:`currentColor`,key:`f64h9f`}],[`circle`,{cx:`6.5`,cy:`12.5`,r:`.5`,fill:`currentColor`,key:`qy21gx`}],[`circle`,{cx:`8.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`fotxhn`}]]},L={name:`paperclip`,size:24,node:[[`path`,{d:`m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551`,key:`1miecu`}]]},R={name:`pencil`,size:24,node:[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}]]},z={name:`radio`,size:24,node:[[`path`,{d:`M16.247 7.761a6 6 0 0 1 0 8.478`,key:`1fwjs5`}],[`path`,{d:`M19.075 4.933a10 10 0 0 1 0 14.134`,key:`ehdyv1`}],[`path`,{d:`M4.925 19.067a10 10 0 0 1 0-14.134`,key:`1q22gi`}],[`path`,{d:`M7.753 16.239a6 6 0 0 1 0-8.478`,key:`r2q7qm`}],[`circle`,{cx:`12`,cy:`12`,r:`2`,key:`1c9p78`}]]},B={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]},V={name:`save`,size:24,node:[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]]},H={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]},U={name:`send`,size:24,node:[[`path`,{d:`M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z`,key:`1ffxy3`}],[`path`,{d:`m21.854 2.147-10.94 10.939`,key:`12cjpa`}]]},W={name:`settings`,size:24,node:[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]},G={name:`skip-forward`,size:24,node:[[`path`,{d:`M21 4v16`,key:`7j8fe9`}],[`path`,{d:`M6.029 4.285A2 2 0 0 0 3 6v12a2 2 0 0 0 3.029 1.715l9.997-5.998a2 2 0 0 0 .003-3.432z`,key:`zs4d6`}]]},K={name:`square`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]},q={name:`trash-2`,size:24,node:[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]},J={name:`triangle-alert`,size:24,node:[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]],aliases:[`alert-triangle`]},Y={name:`wrench`,size:24,node:[[`path`,{d:`M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z`,key:`1ngwbx`}]]},X={name:`x`,size:24,node:[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]},Z={name:`zap`,size:24,node:[[`path`,{d:`M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z`,key:`1xq2db`}]]};export{S as A,f as B,k as C,T as D,E,_ as F,s as G,u as H,g as I,i as J,o as K,h as L,b as M,y as N,w as O,v as P,m as R,A as S,D as T,l as U,d as V,c as W,r as Y,F as _,q as a,M as b,W as c,V as d,B as f,I as g,L as h,J as i,x as j,C as k,U as l,R as m,X as n,K as o,z as p,a as q,Y as r,G as s,Z as t,H as u,P as v,O as w,j as x,N as y,p as z};
@@ -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-CVr6a-dp.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-BXZhbE_1.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-zxrU6ZV_.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-zxrU6ZV_.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-qR28iS0L.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-zxrU6ZV_.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-qR28iS0L.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-BoxeLlL9.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-KQ8_sSP8.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-V7lNStu1.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-V7lNStu1.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-rD__Mvbs.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-V7lNStu1.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-rD__Mvbs.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,7 +25,7 @@
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-D61icK-D.js"></script>
28
+ <script type="module" crossorigin src="/dist/assets/index-Cpe1jccL.js"></script>
29
29
  <link rel="stylesheet" crossorigin href="/dist/assets/vendor-render-Bjnw0wQ6.css">
30
30
  <link rel="stylesheet" crossorigin href="/dist/assets/index-DVTRbkJF.css">
31
31
  </head>
@@ -90,7 +90,7 @@
90
90
  <div class="section-title" style="margin-top:12px" data-i18n="sidebar.avatar">아바타</div>
91
91
  <div class="avatar-row">
92
92
  <div class="avatar-card">
93
- <div class="avatar-preview agent-icon" id="agentAvatarPreview" aria-hidden="true">🦈</div>
93
+ <div class="avatar-preview agent-icon" id="agentAvatarPreview" data-icon="shark" aria-hidden="true"></div>
94
94
  <span class="avatar-card-label">Agent</span>
95
95
  <div class="avatar-card-actions">
96
96
  <button class="avatar-action-btn" id="agentAvatarUploadBtn" title="Upload image">
@@ -103,7 +103,7 @@
103
103
  <input type="file" id="agentAvatarFile" hidden accept="image/png,image/jpeg,image/webp,image/gif">
104
104
  </div>
105
105
  <div class="avatar-card">
106
- <div class="avatar-preview user-icon" id="userAvatarPreview" aria-hidden="true">👤</div>
106
+ <div class="avatar-preview user-icon" id="userAvatarPreview" data-icon="user" aria-hidden="true"></div>
107
107
  <span class="avatar-card-label">User</span>
108
108
  <div class="avatar-card-actions">
109
109
  <button class="avatar-action-btn" id="userAvatarUploadBtn" title="Upload image">
package/public/index.html CHANGED
@@ -96,7 +96,7 @@
96
96
  <div class="section-title" style="margin-top:12px" data-i18n="sidebar.avatar">아바타</div>
97
97
  <div class="avatar-row">
98
98
  <div class="avatar-card">
99
- <div class="avatar-preview agent-icon" id="agentAvatarPreview" aria-hidden="true">🦈</div>
99
+ <div class="avatar-preview agent-icon" id="agentAvatarPreview" data-icon="shark" aria-hidden="true"></div>
100
100
  <span class="avatar-card-label">Agent</span>
101
101
  <div class="avatar-card-actions">
102
102
  <button class="avatar-action-btn" id="agentAvatarUploadBtn" title="Upload image">
@@ -109,7 +109,7 @@
109
109
  <input type="file" id="agentAvatarFile" hidden accept="image/png,image/jpeg,image/webp,image/gif">
110
110
  </div>
111
111
  <div class="avatar-card">
112
- <div class="avatar-preview user-icon" id="userAvatarPreview" aria-hidden="true">👤</div>
112
+ <div class="avatar-preview user-icon" id="userAvatarPreview" data-icon="user" aria-hidden="true"></div>
113
113
  <span class="avatar-card-label">User</span>
114
114
  <div class="avatar-card-actions">
115
115
  <button class="avatar-action-btn" id="userAvatarUploadBtn" title="Upload image">
@@ -1,5 +1,6 @@
1
1
  import { escapeHtml } from '../render.js';
2
2
  import { api, getAuthToken } from '../api.js';
3
+ import { ICONS } from '../icons.js';
3
4
 
4
5
  type AvatarRole = 'agent' | 'user';
5
6
  type AvatarServerEntry = {
@@ -16,8 +17,8 @@ type AvatarState = {
16
17
 
17
18
  const AGENT_KEY = 'agentAvatar';
18
19
  const USER_KEY = 'userAvatar';
19
- const DEFAULT_AGENT = '🦈';
20
- const DEFAULT_USER = '👤';
20
+ const DEFAULT_AGENT = ICONS.shark;
21
+ const DEFAULT_USER = ICONS.user;
21
22
 
22
23
  const avatarState: Record<AvatarRole, AvatarState> = {
23
24
  agent: { emoji: DEFAULT_AGENT, imageUrl: '', updatedAt: null },
@@ -56,7 +57,8 @@ function avatarMarkup(role: AvatarRole): string {
56
57
  if (current.imageUrl) {
57
58
  return `<img class="avatar-image" src="${escapeHtml(current.imageUrl)}" alt="" loading="lazy" decoding="async">`;
58
59
  }
59
- return escapeHtml(current.emoji);
60
+ // Default icons are Lucide SVG strings — render as-is
61
+ return current.emoji;
60
62
  }
61
63
 
62
64
  function applyAvatar(role: AvatarRole): void {
@@ -29,6 +29,7 @@ import {
29
29
  Package,
30
30
  ClipboardList,
31
31
  Bot,
32
+ CircleUserRound,
32
33
  Palette,
33
34
  Link,
34
35
  HandMetal,
@@ -54,6 +55,9 @@ import {
54
55
  Download,
55
56
  } from '@lucide/icons';
56
57
 
58
+ // ── Inline SVG assets (embedded to avoid ?raw import issues in Node.js tests) ──
59
+ const sharkSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12c0 0 2-4 6-4 1 0 2 .5 3 1l3-6c0 0 1 5 3 7 1.5 1.5 5 2 5 2s-1 4-5 4c-1 0-2-.3-3-.8L12 18c0 0-2-1-4-1-4 0-6-5-6-5z"/><circle cx="17" cy="11" r="0.5" fill="currentColor" stroke="none"/><path d="M7 12l1 2"/><path d="M9.5 12l1 2"/></svg>';
60
+
57
61
  // ── Size presets ──
58
62
  const S = 14; // inline / small
59
63
  const M = 16; // default UI
@@ -62,8 +66,7 @@ function luc(data: Parameters<typeof buildLucideSvg>[0], size = M): string {
62
66
  return buildLucideSvg(data, { size });
63
67
  }
64
68
 
65
- // ── Shark mascot (🦈 emoji — brand identity) ──
66
- const SHARK_SVG = '🦈';
69
+ // ── Default avatar icons (Lucide-based, no emoji literals) ──
67
70
 
68
71
  // ── Icon registry ──
69
72
  // Keys match the semantic role, NOT the old emoji codepoint.
@@ -101,8 +104,9 @@ export const ICONS = {
101
104
  link: luc(Link),
102
105
  salute: luc(HandMetal),
103
106
 
104
- // Mascot
105
- shark: SHARK_SVG,
107
+ // Avatar defaults
108
+ shark: sharkSvg,
109
+ user: luc(CircleUserRound),
106
110
 
107
111
  // HTML template icons
108
112
  paperclip: luc(Paperclip),
@@ -165,6 +169,7 @@ const iconMap: Partial<Record<IconName, (s: number) => string>> = {
165
169
  palette: (s) => luc(Palette, s),
166
170
  link: (s) => luc(Link, s),
167
171
  salute: (s) => luc(HandMetal, s),
172
+ user: (s) => luc(CircleUserRound, s),
168
173
  paperclip: (s) => luc(Paperclip, s),
169
174
  save: (s) => luc(Save, s),
170
175
  gamepad: (s) => luc(Gamepad2, s),
@@ -197,6 +202,7 @@ const EMOJI_TO_ICON: Record<string, IconName> = {
197
202
  '⚠️': 'warning',
198
203
  '💡': 'lightbulb',
199
204
  '🦈': 'shark',
205
+ '👤': 'user',
200
206
  '💭': 'thinking',
201
207
  '🔍': 'search',
202
208
  '🌐': 'web',
package/public/js/ui.ts CHANGED
@@ -7,7 +7,8 @@ import { getAgentAvatarMarkup, getUserAvatarMarkup } from './features/avatar.js'
7
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
- import { getVirtualScroll, VS_THRESHOLD } from './virtual-scroll.js';
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
12
  import { createStreamRenderer, appendChunk, finalizeStream, type StreamState } from './streaming-render.js';
12
13
  import { activateWidgets } from './diagram/iframe-renderer.js';
13
14
  import { renderLiveToolActivity, cleanupToolElements, bindToolItemInteractions, type ToolLogEntry } from './features/tool-ui.js';
@@ -385,6 +386,87 @@ export async function loadStats(): Promise<void> {
385
386
  updateStatMsgs(msgs.length);
386
387
  }
387
388
 
389
+ // ── Virtual scroll bootstrap helpers ──
390
+
391
+ function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
392
+ const vsItems: VirtualItem[] = [];
393
+ for (const m of msgs) {
394
+ const role = m.role === 'assistant' ? 'agent' : m.role;
395
+ const rawContent = stripOrchestration(m.content);
396
+ const label = escapeHtml(role === 'user' ? t('msg.you') : getAppName());
397
+ const tools = m.role === 'assistant' ? parseToolLog(m.tool_log) : [];
398
+ const toolHtml = tools.length > 0 ? buildProcessBlockHtml(toProcessSteps(tools), true) : '';
399
+ const skeletonContent = '<div class="skeleton-line"></div><div class="skeleton-line"></div>';
400
+ const html = role === 'agent'
401
+ ? `<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>`
402
+ : `<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>`;
403
+ vsItems.push({ id: generateId(), html, height: 80 });
404
+ }
405
+ return vsItems;
406
+ }
407
+
408
+ function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>): void {
409
+ vs.onLazyRender = (targets: HTMLElement[]) => {
410
+ for (const el of targets) {
411
+ if (!el.classList.contains('lazy-pending')) continue;
412
+ const raw = el.getAttribute('data-raw') || '';
413
+ el.innerHTML = raw ? renderMarkdown(raw) : '';
414
+ el.classList.remove('lazy-pending');
415
+ activateWidgets(el);
416
+ const msgEl = el.closest('[data-vs-idx]') as HTMLElement | null;
417
+ if (msgEl) {
418
+ const idx = Number(msgEl.dataset.vsIdx);
419
+ vs.updateItemHtml(idx, msgEl.outerHTML);
420
+ }
421
+ }
422
+ };
423
+ vs.onPostRender = (viewport: HTMLElement) => {
424
+ activateWidgets(viewport);
425
+ linkifyFilePaths(viewport);
426
+ };
427
+ }
428
+
429
+ function measureTailWindow(
430
+ chatEl: HTMLElement,
431
+ items: VirtualItem[],
432
+ seedCount: number,
433
+ ): number[] {
434
+ const start = Math.max(0, items.length - seedCount);
435
+ const slice = items.slice(start);
436
+ if (slice.length === 0) return [];
437
+
438
+ // Render tail items temporarily into empty chatEl, measure, then clear
439
+ const fragment = document.createDocumentFragment();
440
+ for (const item of slice) {
441
+ const wrapper = document.createElement('div');
442
+ wrapper.innerHTML = item.html;
443
+ const el = wrapper.firstElementChild;
444
+ if (el) fragment.appendChild(el);
445
+ }
446
+ chatEl.appendChild(fragment);
447
+ const heights: number[] = [];
448
+ const children = chatEl.children;
449
+ for (let i = 0; i < children.length; i++) {
450
+ heights.push(children[i].getBoundingClientRect().height);
451
+ }
452
+ chatEl.innerHTML = '';
453
+ return heights;
454
+ }
455
+
456
+ function makeBootstrapDeps(
457
+ vs: ReturnType<typeof getVirtualScroll>,
458
+ chatEl: HTMLElement,
459
+ ): VirtualHistoryBootstrapDeps {
460
+ return {
461
+ registerCallbacks: () => registerVirtualScrollCallbacks(vs),
462
+ measureTailWindow: (items, seedCount) => measureTailWindow(chatEl, items, seedCount),
463
+ setItems: (items, opts) => vs.setItems(items, opts),
464
+ seedMeasuredHeights: (start, h) => vs.seedMeasuredHeights(start, h),
465
+ activateIfNeeded: (toBottom) => vs.activateIfNeeded(toBottom),
466
+ scrollToBottom: () => vs.scrollToBottom(),
467
+ };
468
+ }
469
+
388
470
  export async function loadMessages(): Promise<void> {
389
471
  const vs = getVirtualScroll();
390
472
  const chatEl = document.getElementById('chatMessages');
@@ -403,47 +485,8 @@ export async function loadMessages(): Promise<void> {
403
485
  if (chatEl) chatEl.innerHTML = '';
404
486
 
405
487
  if (msgs.length >= VS_THRESHOLD) {
406
- // RC5 fix: register callbacks BEFORE feeding items so activate() has them
407
- vs.onLazyRender = (targets: HTMLElement[]) => {
408
- for (const el of targets) {
409
- if (!el.classList.contains('lazy-pending')) continue;
410
- const raw = el.getAttribute('data-raw') || '';
411
- el.innerHTML = raw ? renderMarkdown(raw) : '';
412
- el.classList.remove('lazy-pending');
413
- activateWidgets(el);
414
-
415
- // Persist rendered HTML back into VS cache
416
- const msgEl = el.closest('[data-vs-idx]') as HTMLElement | null;
417
- if (msgEl) {
418
- const idx = Number(msgEl.dataset.vsIdx);
419
- vs.updateItemHtml(idx, msgEl.outerHTML);
420
- }
421
- }
422
- };
423
-
424
- // Activate widgets + file path linkification on all VS-rendered items
425
- vs.onPostRender = (viewport: HTMLElement) => {
426
- activateWidgets(viewport);
427
- linkifyFilePaths(viewport);
428
- };
429
-
430
- // Bulk-load all items at once — avoids mid-loop activate (RC5 fix)
431
- const vsItems: import('./virtual-scroll.js').VirtualItem[] = [];
432
- for (const m of msgs) {
433
- const role = m.role === 'assistant' ? 'agent' : m.role;
434
- const rawContent = stripOrchestration(m.content);
435
- const label = escapeHtml(role === 'user' ? t('msg.you') : getAppName());
436
- const tools = m.role === 'assistant' ? parseToolLog(m.tool_log) : [];
437
- const toolHtml = tools.length > 0 ? buildProcessBlockHtml(toProcessSteps(tools), true) : '';
438
- const skeletonContent = '<div class="skeleton-line"></div><div class="skeleton-line"></div>';
439
- const html = role === 'agent'
440
- ? `<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>`
441
- : `<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>`;
442
- vsItems.push({ id: generateId(), html, height: 80 });
443
- }
444
- vs.setItems(vsItems);
445
-
446
- vs.scrollToBottom();
488
+ const vsItems = buildVirtualHistoryItems(msgs);
489
+ bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs, chatEl!));
447
490
  } else {
448
491
  msgs.forEach(m => {
449
492
  const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content, m.cli);
@@ -478,37 +521,8 @@ export async function loadMessages(): Promise<void> {
478
521
  const cached = await getScopedMessages();
479
522
  if (cached.length > 0) {
480
523
  if (cached.length >= VS_THRESHOLD) {
481
- for (const m of cached) {
482
- const role = m.role === 'assistant' ? 'agent' : m.role;
483
- const rawContent = stripOrchestration(m.content);
484
- const label = escapeHtml(role === 'user' ? t('msg.you') : getAppName());
485
- const tools = m.role === 'assistant' && m.tool_log ? parseToolLog(m.tool_log) : [];
486
- const toolHtml = tools.length > 0 ? buildProcessBlockHtml(toProcessSteps(tools), true) : '';
487
- const skeletonContent = '<div class="skeleton-line"></div><div class="skeleton-line"></div>';
488
- const html = role === 'agent'
489
- ? `<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>`
490
- : `<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>`;
491
- vs.addItem(generateId(), html);
492
- }
493
- vs.onLazyRender = (targets: HTMLElement[]) => {
494
- for (const el of targets) {
495
- if (!el.classList.contains('lazy-pending')) continue;
496
- const raw = el.getAttribute('data-raw') || '';
497
- el.innerHTML = raw ? renderMarkdown(raw) : '';
498
- el.classList.remove('lazy-pending');
499
- activateWidgets(el);
500
- const msgEl = el.closest('[data-vs-idx]') as HTMLElement | null;
501
- if (msgEl) {
502
- const idx = Number(msgEl.dataset.vsIdx);
503
- vs.updateItemHtml(idx, msgEl.outerHTML);
504
- }
505
- }
506
- };
507
- vs.onPostRender = (viewport: HTMLElement) => {
508
- activateWidgets(viewport);
509
- linkifyFilePaths(viewport);
510
- };
511
- vs.scrollToBottom();
524
+ const vsItems = buildVirtualHistoryItems(cached as MessageItem[]);
525
+ bootstrapVirtualHistory(vsItems, makeBootstrapDeps(vs, chatEl!));
512
526
  } else {
513
527
  cached.forEach(m => {
514
528
  const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content, m.cli);