sliccy 1.64.2 → 1.64.3

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.
package/README.md CHANGED
@@ -11,7 +11,7 @@ If this scares, confuses, or excites you, keep reading.
11
11
 
12
12
  # slicc — Self-Licking Ice Cream Cone
13
13
 
14
- [![69% Vibe_Coded](https://img.shields.io/badge/69%25-Vibe_Coded-ff69b4?style=for-the-badge&logo=claude&logoColor=white)](https://github.com/ai-ecoverse/vibe-coded-badge-action)
14
+ [![68% Vibe_Coded](https://img.shields.io/badge/68%25-Vibe_Coded-ff69b4?style=for-the-badge&logo=claude&logoColor=white)](https://github.com/ai-ecoverse/vibe-coded-badge-action)
15
15
 
16
16
  [![npm](https://img.shields.io/npm/v/sliccy)](https://www.npmjs.com/package/sliccy)
17
17
 
@@ -239,7 +239,7 @@ ${t.includes(`<slicc-editor`)?`<script src="/slicc-editor.js"><\/script>`:``}
239
239
  ${t.includes(`<slicc-diff`)?`<script src="/slicc-diff.js"><\/script>`:``}
240
240
  <script src="/lucide-icons.js"><\/script>
241
241
  </head>
242
- <body class="sprinkle-inline">${t}</body></html>`;if(li)return mi(e,r,n);let i=document.createElement(`iframe`);i.setAttribute(`sandbox`,`allow-scripts allow-same-origin`),i.style.cssText=`width:100%;border:none;overflow:hidden;display:block;`,i.srcdoc=r,e.appendChild(i);let a=e=>{if(e.source!==i.contentWindow)return;let t=e.data;t?.type&&(t.type===`inline-sprinkle-lick`?n(t.action,t.data):t.type===`inline-sprinkle-height`&&(i.style.height=t.height+`px`))};return window.addEventListener(`message`,a),{dispose(){window.removeEventListener(`message`,a),i.remove()}}}function fi(e,t){let n=e.querySelectorAll(`pre > code.language-shtml`);if(n.length===0)return[];let r=[];for(let e of n){let n=e.parentElement,i=e.textContent??``,a=document.createElement(`div`);a.className=`msg__inline-sprinkle`,n.replaceWith(a),r.push(di(a,i,t))}return r}function pi(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function mi(e,t,n){let r=document.createElement(`iframe`);r.src=chrome.runtime.getURL(`sprinkle-sandbox.html`),r.style.cssText=`width:100%;border:none;overflow:hidden;display:block;`,e.appendChild(r);let i=e=>{if(e.source!==r.contentWindow)return;let t=e.data;t?.type&&(t.type===`inline-sprinkle-lick`?n(t.action,t.data):t.type===`inline-sprinkle-height`&&(r.style.height=t.height+`px`))};return window.addEventListener(`message`,i),r.addEventListener(`load`,()=>{r.contentWindow?.postMessage({type:`inline-sprinkle-render`,srcdoc:t},`*`)},{once:!0}),{dispose(){window.removeEventListener(`message`,i),r.remove()}}}var hi=n(`tool-ui-renderer`),gi=typeof chrome<`u`&&!!chrome?.runtime?.id,_i=class{container;iframe=null;inlineSprinkle=null;messageHandler=null;requestId;nonce;constructor(e,t){this.container=e,this.requestId=t,this.nonce=crypto.randomUUID()}async render(e){gi?await this.renderInSandbox(e):this.renderWithInlineSprinkle(e)}async renderInSandbox(e){let t=document.createElement(`iframe`);t.src=chrome.runtime.getURL(`tool-ui-sandbox.html`),t.style.cssText=`width: 100%; border: none; min-height: 60px;`,this.iframe=t,await new Promise((e,n)=>{let r=setTimeout(()=>{hi.error(`Tool UI iframe load timed out`),t.remove(),this.iframe=null,n(Error(`tool-ui sandbox iframe load timed out`))},5e3);t.addEventListener(`load`,()=>{clearTimeout(r),e()},{once:!0}),t.addEventListener(`error`,()=>{clearTimeout(r),t.remove(),this.iframe=null,n(Error(`tool-ui sandbox iframe failed to load`))},{once:!0}),this.container.appendChild(t)}),this.messageHandler=e=>{if(e.source!==t.contentWindow)return;let n=e.data;if(n?.type){if(n.nonce!==this.nonce){hi.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(hi.info(`Tool UI action received`,{id:n.id,action:n.action}),v.handleAction(n.id,{action:n.action,data:n.data})):n.type===`tool-ui-rendered`&&n.id===this.requestId?n.height&&this.iframe&&(this.iframe.style.height=`${Math.max(60,n.height)}px`):n.type===`tool-ui-resize`&&n.id===this.requestId&&n.height&&this.iframe&&(this.iframe.style.height=`${Math.max(60,n.height)}px`)}},window.addEventListener(`message`,this.messageHandler);let{collectThemeCSS:n}=await r(async()=>{let{collectThemeCSS:e}=await import(`./sprinkle-renderer-CRPARJ9i.js`);return{collectThemeCSS:e}},[]),i=n();t.contentWindow.postMessage({type:`tool-ui-render`,id:this.requestId,nonce:this.nonce,html:e,themeCSS:i},`*`)}renderWithInlineSprinkle(e){let t=document.createElement(`div`);t.className=`msg__inline-sprinkle`,this.container.appendChild(t),this.inlineSprinkle=di(t,e,(e,t)=>{hi.info(`Tool UI action (inline sprinkle)`,{id:this.requestId,action:e}),v.handleAction(this.requestId,{action:e,data:t})})}dispose(){this.messageHandler&&=(window.removeEventListener(`message`,this.messageHandler),null),this.iframe&&=(this.iframe.remove(),null),this.inlineSprinkle&&=(this.inlineSprinkle.dispose(),null)}},vi=new Map;function yi(e,t,n){let r=vi.get(t);r&&r.dispose();let i=new _i(e,t);return vi.set(t,i),i.render(n).catch(e=>{hi.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function bi(e){let t=vi.get(e);t&&(t.dispose(),vi.delete(e))}var xi=n(`chat-panel`);function Si(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var Ci={bash:`$`,browser:`B`,read_file:`R`,write_file:`W`,edit_file:`E`,javascript:`JS`,delegate_to_scoop:`D`,send_message:`M`,schedule_task:`T`,list_scoops:`LS`,list_tasks:`LT`,register_scoop:`RS`,update_global_memory:`GM`};function wi(e){return Ci[e]??`?`}function Ti(e){return e.role===`assistant`?Gr(e.content):Wr(e.content)}var Ei=class{container;messagesEl;messagesInner;inputArea;textarea;sendBtn;stopBtn;micBtn;voiceInput=null;voiceMode=!1;keydownListener=null;messages=[];agent=null;unsubscribe=null;isStreaming=!1;currentStreamId=null;sessionStore;sessionId;readOnly=!1;terminalOutputCallback=null;currentScoopName=null;autoScrollAttached=!0;lastScrollTop=0;jumpPill;onDeleteQueuedMessage=null;pendingDeltaText=``;streamingRafId=null;inlineSprinkles=new Map;onInlineSprinkleLick;modelSelectorEl;handoffsEl;pendingHandoffs=[];onAcceptPendingHandoff=null;onDismissPendingHandoff=null;onModelChange;constructor(e){this.container=e,this.sessionStore=new Zr,this.sessionId=`default`,this.render()}setAgent(e){this.unsubscribe?.(),this.agent=e,this.unsubscribe=e.onEvent(e=>this.handleAgentEvent(e))}onTerminalOutput(e){this.terminalOutputCallback=e}setDeleteQueuedMessageCallback(e){this.onDeleteQueuedMessage=e}async initSession(e){await this.sessionStore.init(),this.sessionId=e??`default`;let t=await this.sessionStore.load(this.sessionId);t&&t.messages.length>0&&(this.messages=t.messages.map(e=>({...e,isStreaming:!1})),this.renderMessages())}async clearSession(){this.messages=[],this.renderMessages(),await this.sessionStore.delete(this.sessionId)}async deleteSessionById(e){await this.sessionStore.delete(e)}async switchToContext(e,t,n){await this.persistSessionAsync(),this.setStreamingState(!1),this.currentStreamId=null,this.cancelPendingDelta(),this.sessionId=e,this.currentScoopName=n??null,this.setReadOnly(t);let r=await this.sessionStore.load(this.sessionId);r&&r.messages.length>0?this.messages=r.messages.map(e=>({...e,isStreaming:!1})):this.messages=[],this.renderMessages()}setReadOnly(e){this.readOnly=e,this.inputArea&&(this.inputArea.style.display=e?`none`:``)}async persistSessionAsync(){try{await this.sessionStore.saveMessages(this.sessionId,this.messages)}catch{}}setProcessing(e){e?this.setStreamingState(!0):this.setStreamingState(!1)}addSystemMessage(e){let t={id:Si(),role:`assistant`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t),this.persistSession()}addLickMessage(e,t,n){let r={id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:n};this.messages.push(r),this.appendMessageEl(r),this.persistSession()}getMessages(){return[...this.messages]}loadMessages(e){this.messages=e.map(e=>({...e,isStreaming:!1})),this.renderMessages(),this.persistSession(),this.renderModelSelector()}clear(){this.messages=[],this.renderMessages(),this.renderModelSelector()}setPendingHandoffs(e){this.pendingHandoffs=[...e],this.renderPendingHandoffs()}setPendingHandoffActions(e){this.onAcceptPendingHandoff=e.onAccept,this.onDismissPendingHandoff=e.onDismiss,this.renderPendingHandoffs()}addUserMessage(e){let t={id:Si(),role:`user`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}deleteQueuedMessage(e){let t=this.messages.findIndex(t=>t.id===e);if(t===-1)return;this.messages.splice(t,1);let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);n&&n.remove(),this.persistSession(),this.onDeleteQueuedMessage?.(e)}render(){this.container.innerHTML=``,this.container.classList.add(`chat`),this.messagesEl=document.createElement(`div`),this.messagesEl.className=`chat__messages`,this.messagesInner=document.createElement(`div`),this.messagesInner.className=`chat__messages-inner`,this.messagesEl.appendChild(this.messagesInner),this.handoffsEl=document.createElement(`div`),this.handoffsEl.className=`chat__handoffs`,this.handoffsEl.hidden=!0,this.messagesEl.appendChild(this.handoffsEl),this.container.appendChild(this.messagesEl),this.renderPendingHandoffs(),this.messagesEl.addEventListener(`scroll`,()=>{let{scrollTop:e,scrollHeight:t,clientHeight:n}=this.messagesEl;t-e-n<=250?(this.autoScrollAttached=!0,this.hideJumpPill()):e<this.lastScrollTop&&(this.autoScrollAttached=!1),this.lastScrollTop=e},{passive:!0}),this.inputArea=document.createElement(`div`);let e=this.inputArea;e.className=`chat__input-area`;let t=document.createElement(`div`);t.className=`chat__input-area-inner`,this.textarea=document.createElement(`textarea`),this.textarea.className=`chat__textarea`,this.textarea.placeholder=`What shall we build?`,this.textarea.rows=1,this.sendBtn=document.createElement(`button`),this.sendBtn.className=`chat__send-btn`,this.sendBtn.innerHTML=`<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1.25C5.167 1.25 1.25 5.167 1.25 10s3.917 8.75 8.75 8.75 8.75-3.918 8.75-8.75S14.833 1.25 10 1.25zm3.527 8.284a.75.75 0 0 1-1.06 0L10.75 7.82v6.172a.75.75 0 0 1-1.5 0V7.812L7.527 9.534a.75.75 0 1 1-1.06-1.06l2.998-2.998a.75.75 0 0 1 1.06-.001l3.002 2.998a.75.75 0 0 1 0 1.061z"/></svg>`,this.sendBtn.dataset.tooltip=`Send message`,this.sendBtn.dataset.tooltipPos=`top`,this.stopBtn=document.createElement(`button`),this.stopBtn.className=`chat__stop-btn`,this.stopBtn.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M13.75 4H6.25A2.25 2.25 0 0 0 4 6.25v7.5A2.25 2.25 0 0 0 6.25 16h7.5A2.25 2.25 0 0 0 16 13.75v-7.5A2.25 2.25 0 0 0 13.75 4z"/></svg>`,this.stopBtn.dataset.tooltip=`Stop generation`,this.stopBtn.style.display=`none`,this.micBtn=document.createElement(`button`),this.micBtn.className=`chat__mic-btn`;let n=`http://www.w3.org/2000/svg`,r=document.createElementNS(n,`svg`);r.setAttribute(`width`,`16`),r.setAttribute(`height`,`16`),r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,`2`),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`stroke-linejoin`,`round`);let i=document.createElementNS(n,`path`);i.setAttribute(`d`,`M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z`);let a=document.createElementNS(n,`path`);a.setAttribute(`d`,`M19 10v2a7 7 0 0 1-14 0v-2`);let o=document.createElementNS(n,`line`);o.setAttribute(`x1`,`12`),o.setAttribute(`y1`,`19`),o.setAttribute(`x2`,`12`),o.setAttribute(`y2`,`23`);let s=document.createElementNS(n,`line`);s.setAttribute(`x1`,`8`),s.setAttribute(`y1`,`23`),s.setAttribute(`x2`,`16`),s.setAttribute(`y2`,`23`),r.append(i,a,o,s),this.micBtn.appendChild(r),this.micBtn.dataset.tooltip=`Voice (Ctrl+Shift+V)`;let c=document.createElement(`div`);c.className=`chat__input-wrapper`,c.appendChild(this.textarea);let l=document.createElement(`div`);l.className=`chat__action-bar`;let u=document.createElement(`div`);u.className=`chat__action-bar-left`,u.appendChild(this.micBtn),l.appendChild(u),this.modelSelectorEl=document.createElement(`div`),this.modelSelectorEl.className=`chat__model-selector`,this.renderModelSelector(),l.appendChild(this.modelSelectorEl);let d=document.createElement(`div`);d.className=`chat__action-bar-right`,d.appendChild(this.sendBtn),d.appendChild(this.stopBtn),l.appendChild(d),c.appendChild(l),t.appendChild(c),e.appendChild(t),this.container.appendChild(e),this.jumpPill=document.createElement(`button`),this.jumpPill.className=`chat__jump-pill`,this.jumpPill.textContent=`↓ New activity`,this.jumpPill.addEventListener(`click`,()=>{this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}),this.container.appendChild(this.jumpPill),this.textarea.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),this.sendMessage())}),this.textarea.addEventListener(`input`,()=>{this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`}),this.sendBtn.addEventListener(`click`,()=>this.sendMessage()),this.stopBtn.addEventListener(`click`,()=>{this.agent?.stop();for(let e of this.messages)e.queued&&(e.queued=!1,this.updateMessageEl(e.id));this.setStreamingState(!1)}),this.voiceInput=new ti({onTranscript:(e,t)=>{this.textarea.value=e,this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`},onStateChange:e=>{e===`error`?(this.voiceMode=!1,this.micBtn.classList.remove(`chat__mic-btn--active`,`chat__mic-btn--listening`)):this.voiceMode?e===`listening`&&this.micBtn.classList.add(`chat__mic-btn--listening`):this.micBtn.classList.toggle(`chat__mic-btn--listening`,e===`listening`)},onError:e=>{xi.debug(`Voice input error`,{error:e}),!(this.voiceMode&&e.includes(`No speech detected`))&&this.addSystemMessage(e)},autoSend:!0,onAutoSend:e=>{this.textarea.value=e,this.sendMessage()},onAutoDisable:()=>{this.voiceMode=!1,this.micBtn.classList.remove(`chat__mic-btn--active`,`chat__mic-btn--listening`),this.addSystemMessage(`Voice mode disabled after 2 minutes of inactivity.`)},lang:ri()}),this.micBtn.addEventListener(`click`,()=>{this.toggleVoiceMode()}),this.keydownListener=e=>{e.shiftKey&&(e.ctrlKey||e.metaKey)&&e.key===`V`&&(e.preventDefault(),this.toggleVoiceMode())},document.addEventListener(`keydown`,this.keydownListener)}renderPendingHandoffs(){if(!this.handoffsEl)return;if(this.pendingHandoffs.length===0){this.handoffsEl.hidden=!0,this.handoffsEl.innerHTML=``;return}let e=this.pendingHandoffs.length===1?`1 pending handoff`:`${this.pendingHandoffs.length} pending handoffs`;this.handoffsEl.hidden=!1,this.handoffsEl.innerHTML=`
242
+ <body class="sprinkle-inline">${t}</body></html>`;if(li)return mi(e,r,n);let i=document.createElement(`iframe`);i.setAttribute(`sandbox`,`allow-scripts allow-same-origin`),i.style.cssText=`width:100%;border:none;overflow:hidden;display:block;`,i.srcdoc=r,e.appendChild(i);let a=e=>{if(e.source!==i.contentWindow)return;let t=e.data;t?.type&&(t.type===`inline-sprinkle-lick`?n(t.action,t.data):t.type===`inline-sprinkle-height`&&(i.style.height=t.height+`px`))};return window.addEventListener(`message`,a),{dispose(){window.removeEventListener(`message`,a),i.remove()}}}function fi(e,t){let n=e.querySelectorAll(`pre > code.language-shtml`);if(n.length===0)return[];let r=[];for(let e of n){let n=e.parentElement,i=e.textContent??``,a=document.createElement(`div`);a.className=`msg__inline-sprinkle`,n.replaceWith(a),r.push(di(a,i,t))}return r}function pi(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function mi(e,t,n){let r=document.createElement(`iframe`);r.src=chrome.runtime.getURL(`sprinkle-sandbox.html`),r.style.cssText=`width:100%;border:none;overflow:hidden;display:block;`,e.appendChild(r);let i=e=>{if(e.source!==r.contentWindow)return;let t=e.data;t?.type&&(t.type===`inline-sprinkle-lick`?n(t.action,t.data):t.type===`inline-sprinkle-height`&&(r.style.height=t.height+`px`))};return window.addEventListener(`message`,i),r.addEventListener(`load`,()=>{r.contentWindow?.postMessage({type:`inline-sprinkle-render`,srcdoc:t},`*`)},{once:!0}),{dispose(){window.removeEventListener(`message`,i),r.remove()}}}var hi=n(`tool-ui-renderer`),gi=typeof chrome<`u`&&!!chrome?.runtime?.id,_i=class{container;iframe=null;inlineSprinkle=null;messageHandler=null;requestId;nonce;constructor(e,t){this.container=e,this.requestId=t,this.nonce=crypto.randomUUID()}async render(e){gi?await this.renderInSandbox(e):this.renderWithInlineSprinkle(e)}async renderInSandbox(e){let t=document.createElement(`iframe`);t.src=chrome.runtime.getURL(`tool-ui-sandbox.html`),t.style.cssText=`width: 100%; border: none; min-height: 60px;`,this.iframe=t,await new Promise((e,n)=>{let r=setTimeout(()=>{hi.error(`Tool UI iframe load timed out`),t.remove(),this.iframe=null,n(Error(`tool-ui sandbox iframe load timed out`))},5e3);t.addEventListener(`load`,()=>{clearTimeout(r),e()},{once:!0}),t.addEventListener(`error`,()=>{clearTimeout(r),t.remove(),this.iframe=null,n(Error(`tool-ui sandbox iframe failed to load`))},{once:!0}),this.container.appendChild(t)}),this.messageHandler=e=>{if(e.source!==t.contentWindow)return;let n=e.data;if(n?.type){if(n.nonce!==this.nonce){hi.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(hi.info(`Tool UI action received`,{id:n.id,action:n.action}),v.handleAction(n.id,{action:n.action,data:n.data})):n.type===`tool-ui-rendered`&&n.id===this.requestId?n.height&&this.iframe&&(this.iframe.style.height=`${Math.max(60,n.height)}px`):n.type===`tool-ui-resize`&&n.id===this.requestId&&n.height&&this.iframe&&(this.iframe.style.height=`${Math.max(60,n.height)}px`)}},window.addEventListener(`message`,this.messageHandler);let{collectThemeCSS:n}=await r(async()=>{let{collectThemeCSS:e}=await import(`./sprinkle-renderer-CJ4wOw20.js`);return{collectThemeCSS:e}},[]),i=n();t.contentWindow.postMessage({type:`tool-ui-render`,id:this.requestId,nonce:this.nonce,html:e,themeCSS:i},`*`)}renderWithInlineSprinkle(e){let t=document.createElement(`div`);t.className=`msg__inline-sprinkle`,this.container.appendChild(t),this.inlineSprinkle=di(t,e,(e,t)=>{hi.info(`Tool UI action (inline sprinkle)`,{id:this.requestId,action:e}),v.handleAction(this.requestId,{action:e,data:t})})}dispose(){this.messageHandler&&=(window.removeEventListener(`message`,this.messageHandler),null),this.iframe&&=(this.iframe.remove(),null),this.inlineSprinkle&&=(this.inlineSprinkle.dispose(),null)}},vi=new Map;function yi(e,t,n){let r=vi.get(t);r&&r.dispose();let i=new _i(e,t);return vi.set(t,i),i.render(n).catch(e=>{hi.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function bi(e){let t=vi.get(e);t&&(t.dispose(),vi.delete(e))}var xi=n(`chat-panel`);function Si(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var Ci={bash:`$`,browser:`B`,read_file:`R`,write_file:`W`,edit_file:`E`,javascript:`JS`,delegate_to_scoop:`D`,send_message:`M`,schedule_task:`T`,list_scoops:`LS`,list_tasks:`LT`,register_scoop:`RS`,update_global_memory:`GM`};function wi(e){return Ci[e]??`?`}function Ti(e){return e.role===`assistant`?Gr(e.content):Wr(e.content)}var Ei=class{container;messagesEl;messagesInner;inputArea;textarea;sendBtn;stopBtn;micBtn;voiceInput=null;voiceMode=!1;keydownListener=null;messages=[];agent=null;unsubscribe=null;isStreaming=!1;currentStreamId=null;sessionStore;sessionId;readOnly=!1;terminalOutputCallback=null;currentScoopName=null;autoScrollAttached=!0;lastScrollTop=0;jumpPill;onDeleteQueuedMessage=null;pendingDeltaText=``;streamingRafId=null;inlineSprinkles=new Map;onInlineSprinkleLick;modelSelectorEl;handoffsEl;pendingHandoffs=[];onAcceptPendingHandoff=null;onDismissPendingHandoff=null;onModelChange;constructor(e){this.container=e,this.sessionStore=new Zr,this.sessionId=`default`,this.render()}setAgent(e){this.unsubscribe?.(),this.agent=e,this.unsubscribe=e.onEvent(e=>this.handleAgentEvent(e))}onTerminalOutput(e){this.terminalOutputCallback=e}setDeleteQueuedMessageCallback(e){this.onDeleteQueuedMessage=e}async initSession(e){await this.sessionStore.init(),this.sessionId=e??`default`;let t=await this.sessionStore.load(this.sessionId);t&&t.messages.length>0&&(this.messages=t.messages.map(e=>({...e,isStreaming:!1})),this.renderMessages())}async clearSession(){this.messages=[],this.renderMessages(),await this.sessionStore.delete(this.sessionId)}async deleteSessionById(e){await this.sessionStore.delete(e)}async switchToContext(e,t,n){await this.persistSessionAsync(),this.setStreamingState(!1),this.currentStreamId=null,this.cancelPendingDelta(),this.sessionId=e,this.currentScoopName=n??null,this.setReadOnly(t);let r=await this.sessionStore.load(this.sessionId);r&&r.messages.length>0?this.messages=r.messages.map(e=>({...e,isStreaming:!1})):this.messages=[],this.renderMessages()}setReadOnly(e){this.readOnly=e,this.inputArea&&(this.inputArea.style.display=e?`none`:``)}async persistSessionAsync(){try{await this.sessionStore.saveMessages(this.sessionId,this.messages)}catch{}}setProcessing(e){e?this.setStreamingState(!0):this.setStreamingState(!1)}addSystemMessage(e){let t={id:Si(),role:`assistant`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t),this.persistSession()}addLickMessage(e,t,n){let r={id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:n};this.messages.push(r),this.appendMessageEl(r),this.persistSession()}getMessages(){return[...this.messages]}loadMessages(e){this.messages=e.map(e=>({...e,isStreaming:!1})),this.renderMessages(),this.persistSession(),this.renderModelSelector()}clear(){this.messages=[],this.renderMessages(),this.renderModelSelector()}setPendingHandoffs(e){this.pendingHandoffs=[...e],this.renderPendingHandoffs()}setPendingHandoffActions(e){this.onAcceptPendingHandoff=e.onAccept,this.onDismissPendingHandoff=e.onDismiss,this.renderPendingHandoffs()}addUserMessage(e){let t={id:Si(),role:`user`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}deleteQueuedMessage(e){let t=this.messages.findIndex(t=>t.id===e);if(t===-1)return;this.messages.splice(t,1);let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);n&&n.remove(),this.persistSession(),this.onDeleteQueuedMessage?.(e)}render(){this.container.innerHTML=``,this.container.classList.add(`chat`),this.messagesEl=document.createElement(`div`),this.messagesEl.className=`chat__messages`,this.messagesInner=document.createElement(`div`),this.messagesInner.className=`chat__messages-inner`,this.messagesEl.appendChild(this.messagesInner),this.handoffsEl=document.createElement(`div`),this.handoffsEl.className=`chat__handoffs`,this.handoffsEl.hidden=!0,this.messagesEl.appendChild(this.handoffsEl),this.container.appendChild(this.messagesEl),this.renderPendingHandoffs(),this.messagesEl.addEventListener(`scroll`,()=>{let{scrollTop:e,scrollHeight:t,clientHeight:n}=this.messagesEl;t-e-n<=250?(this.autoScrollAttached=!0,this.hideJumpPill()):e<this.lastScrollTop&&(this.autoScrollAttached=!1),this.lastScrollTop=e},{passive:!0}),this.inputArea=document.createElement(`div`);let e=this.inputArea;e.className=`chat__input-area`;let t=document.createElement(`div`);t.className=`chat__input-area-inner`,this.textarea=document.createElement(`textarea`),this.textarea.className=`chat__textarea`,this.textarea.placeholder=`What shall we build?`,this.textarea.rows=1,this.sendBtn=document.createElement(`button`),this.sendBtn.className=`chat__send-btn`,this.sendBtn.innerHTML=`<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1.25C5.167 1.25 1.25 5.167 1.25 10s3.917 8.75 8.75 8.75 8.75-3.918 8.75-8.75S14.833 1.25 10 1.25zm3.527 8.284a.75.75 0 0 1-1.06 0L10.75 7.82v6.172a.75.75 0 0 1-1.5 0V7.812L7.527 9.534a.75.75 0 1 1-1.06-1.06l2.998-2.998a.75.75 0 0 1 1.06-.001l3.002 2.998a.75.75 0 0 1 0 1.061z"/></svg>`,this.sendBtn.dataset.tooltip=`Send message`,this.sendBtn.dataset.tooltipPos=`top`,this.stopBtn=document.createElement(`button`),this.stopBtn.className=`chat__stop-btn`,this.stopBtn.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M13.75 4H6.25A2.25 2.25 0 0 0 4 6.25v7.5A2.25 2.25 0 0 0 6.25 16h7.5A2.25 2.25 0 0 0 16 13.75v-7.5A2.25 2.25 0 0 0 13.75 4z"/></svg>`,this.stopBtn.dataset.tooltip=`Stop generation`,this.stopBtn.style.display=`none`,this.micBtn=document.createElement(`button`),this.micBtn.className=`chat__mic-btn`;let n=`http://www.w3.org/2000/svg`,r=document.createElementNS(n,`svg`);r.setAttribute(`width`,`16`),r.setAttribute(`height`,`16`),r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,`2`),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`stroke-linejoin`,`round`);let i=document.createElementNS(n,`path`);i.setAttribute(`d`,`M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z`);let a=document.createElementNS(n,`path`);a.setAttribute(`d`,`M19 10v2a7 7 0 0 1-14 0v-2`);let o=document.createElementNS(n,`line`);o.setAttribute(`x1`,`12`),o.setAttribute(`y1`,`19`),o.setAttribute(`x2`,`12`),o.setAttribute(`y2`,`23`);let s=document.createElementNS(n,`line`);s.setAttribute(`x1`,`8`),s.setAttribute(`y1`,`23`),s.setAttribute(`x2`,`16`),s.setAttribute(`y2`,`23`),r.append(i,a,o,s),this.micBtn.appendChild(r),this.micBtn.dataset.tooltip=`Voice (Ctrl+Shift+V)`;let c=document.createElement(`div`);c.className=`chat__input-wrapper`,c.appendChild(this.textarea);let l=document.createElement(`div`);l.className=`chat__action-bar`;let u=document.createElement(`div`);u.className=`chat__action-bar-left`,u.appendChild(this.micBtn),l.appendChild(u),this.modelSelectorEl=document.createElement(`div`),this.modelSelectorEl.className=`chat__model-selector`,this.renderModelSelector(),l.appendChild(this.modelSelectorEl);let d=document.createElement(`div`);d.className=`chat__action-bar-right`,d.appendChild(this.sendBtn),d.appendChild(this.stopBtn),l.appendChild(d),c.appendChild(l),t.appendChild(c),e.appendChild(t),this.container.appendChild(e),this.jumpPill=document.createElement(`button`),this.jumpPill.className=`chat__jump-pill`,this.jumpPill.textContent=`↓ New activity`,this.jumpPill.addEventListener(`click`,()=>{this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}),this.container.appendChild(this.jumpPill),this.textarea.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),this.sendMessage())}),this.textarea.addEventListener(`input`,()=>{this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`}),this.sendBtn.addEventListener(`click`,()=>this.sendMessage()),this.stopBtn.addEventListener(`click`,()=>{this.agent?.stop();for(let e of this.messages)e.queued&&(e.queued=!1,this.updateMessageEl(e.id));this.setStreamingState(!1)}),this.voiceInput=new ti({onTranscript:(e,t)=>{this.textarea.value=e,this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`},onStateChange:e=>{e===`error`?(this.voiceMode=!1,this.micBtn.classList.remove(`chat__mic-btn--active`,`chat__mic-btn--listening`)):this.voiceMode?e===`listening`&&this.micBtn.classList.add(`chat__mic-btn--listening`):this.micBtn.classList.toggle(`chat__mic-btn--listening`,e===`listening`)},onError:e=>{xi.debug(`Voice input error`,{error:e}),!(this.voiceMode&&e.includes(`No speech detected`))&&this.addSystemMessage(e)},autoSend:!0,onAutoSend:e=>{this.textarea.value=e,this.sendMessage()},onAutoDisable:()=>{this.voiceMode=!1,this.micBtn.classList.remove(`chat__mic-btn--active`,`chat__mic-btn--listening`),this.addSystemMessage(`Voice mode disabled after 2 minutes of inactivity.`)},lang:ri()}),this.micBtn.addEventListener(`click`,()=>{this.toggleVoiceMode()}),this.keydownListener=e=>{e.shiftKey&&(e.ctrlKey||e.metaKey)&&e.key===`V`&&(e.preventDefault(),this.toggleVoiceMode())},document.addEventListener(`keydown`,this.keydownListener)}renderPendingHandoffs(){if(!this.handoffsEl)return;if(this.pendingHandoffs.length===0){this.handoffsEl.hidden=!0,this.handoffsEl.innerHTML=``;return}let e=this.pendingHandoffs.length===1?`1 pending handoff`:`${this.pendingHandoffs.length} pending handoffs`;this.handoffsEl.hidden=!1,this.handoffsEl.innerHTML=`
243
243
  <div class="chat__handoffs-inner">
244
244
  <div class="chat__handoffs-header">${jr(e)}</div>
245
245
  ${this.pendingHandoffs.map(e=>this.renderPendingHandoffCard(e)).join(``)}
@@ -13107,7 +13107,7 @@ ${t}
13107
13107
  ... (truncated)`:n,a={id:`scoop-done-${e}-${Date.now()}`,chatJid:r.jid,senderId:t.folder,senderName:t.assistantLabel,content:`[@${t.assistantLabel} completed]:\n${i}`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-notify`};Q.info(`Routing scoop completion to cone`,{scoop:t.folder,responseLength:n.length}),this.handleMessage(a).catch(e=>{let n=e instanceof Error?e.message:String(e);Q.error(`Failed to route scoop completion to cone`,{scoop:t.folder,error:n}),this.callbacks.onError(r.jid,`Scoop ${t.folder} completed but notification failed: ${n}`)})}}}},onToolStart:(t,n)=>{this.callbacks.onToolStart?.(e,t,n)},onToolEnd:(t,n,r)=>{this.callbacks.onToolEnd?.(e,t,n,r)},onToolUI:(t,n,r)=>{this.callbacks.onToolUI?.(e,t,n,r)},onToolUIDone:t=>{this.callbacks.onToolUIDone?.(e,t)},onSendMessage:(t,n)=>{this.callbacks.onSendMessage(e,`${n?`[${n}] `:``}${t}`)},getScoops:()=>this.getScoops(),getScoopTabState:t.isCone?e=>this.tabs.get(e):void 0,onFeedScoop:t.isCone?(e,n)=>this.delegateToScoop(e,n,t.assistantLabel):void 0,onScoopScoop:t.isCone?async e=>{let t={...e,jid:`scoop_${e.folder}_${Date.now()}`};return await this.registerScoop(t),t}:void 0,onDropScoop:t.isCone?async e=>{await this.unregisterScoop(e)}:void 0,getGlobalMemory:()=>this.getGlobalMemory(),setGlobalMemory:t.isCone?e=>this.setGlobalMemory(e):void 0,getBrowserAPI:()=>this.callbacks.getBrowserAPI()},r,this.sessionStore??void 0,this.sharedFs??void 0);this.contexts.set(e,i),this.tabs.set(e,{jid:e,contextId:n,status:`initializing`,lastActivity:new Date().toISOString()}),await i.init();let a=this.tabs.get(e);a&&a.status===`initializing`&&(a.status=`ready`,this.tabs.set(e,a),this.callbacks.onStatusChange(e,`ready`));let o=this.scoops.get(e);o&&!o.isCone&&this.startIdleTimer(e),Q.info(`Scoop context created`,{jid:e,contextId:n})}async destroyScoopTab(e){this.clearIdleTimer(e);let t=this.contexts.get(e);t&&(t.dispose(),this.contexts.delete(e),this.tabs.delete(e),Q.info(`Scoop context destroyed`,{jid:e}))}isProcessing(e){return this.tabs.get(e)?.status===`processing`}getScoopContext(e){return this.contexts.get(e)}async clearQueuedMessages(e){let t=this.messageQueues.get(e);if(t&&t.length>0){for(let e of t)await Le(e.id);this.messageQueues.set(e,[])}}async deleteQueuedMessage(e,t){let n=this.messageQueues.get(e);if(n){let e=n.findIndex(e=>e.id===t);e!==-1&&n.splice(e,1)}await Le(t)}async getMessagesForScoop(e){return De(e)}async waitForTabReady(e,t=1e4){let n=Date.now();for(;Date.now()-n<t;){let t=this.tabs.get(e);if(!t)return!1;if(t.status===`ready`||t.status===`processing`)return!0;if(t.status===`error`)return!1;await new Promise(e=>setTimeout(e,100))}return Q.warn(`Timed out waiting for tab to become ready`,{jid:e}),!1}async sendPrompt(e,t,n,r){let i=this.contexts.get(e);i||=(await this.createScoopTab(e),this.contexts.get(e));let a=this.tabs.get(e);if(a?.status===`initializing`){if(Q.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){Q.error(`Context did not become ready in time, dropping prompt`,{jid:e});return}i=this.contexts.get(e),a=this.tabs.get(e)}if(!i){Q.error(`Context not found after creation`,{jid:e});return}this.clearIdleTimer(e),this.scoopResponseBuffer.delete(e),a&&(a.status=`processing`,a.lastActivity=new Date().toISOString(),this.tabs.set(e,a),this.callbacks.onStatusChange(e,`processing`)),Q.debug(`Prompt sent to scoop`,{jid:e,textLength:t.length}),await i.prompt(t)}async processScoopQueue(e){let t=this.messageQueues.get(e);if(!t||t.length===0){Q.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){Q.debug(`processScoopQueue: tab not ready`,{jid:e,status:n?.status??`no-tab`});return}let r=this.scoops.get(e),i=r?.assistantLabel??e,a=this.lastAgentTimestamp.get(e)??``,o=await Oe(e,a,i);if(Q.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:a,dbMessageCount:o.length,queueLength:t.length}),o.length===0){Q.debug(`processScoopQueue: no messages from DB, clearing queue`,{jid:e}),this.messageQueues.set(e,[]);return}let s=o.map(e=>`[${new Date(e.timestamp).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hour12:!0})}] ${e.senderName}: ${e.content}`).join(`
13108
13108
  `);this.messageQueues.set(e,[]);let c=o[o.length-1];this.lastAgentTimestamp.set(e,c.timestamp),await R(`lastAgentTs_${e}`,c.timestamp),await this.sendPrompt(e,s,c.senderId,c.senderName)}startMessageLoop(){this.pollInterval||=window.setInterval(()=>{for(let e of this.scoops.keys())this.tabs.get(e)?.status===`ready`&&this.processScoopQueue(e).catch(t=>{let n=t instanceof Error?t.message:String(t);Q.error(`Message queue processing failed`,{jid:e,error:n}),this.callbacks.onError(e,`Queue processing failed: ${n}`)})},2e3)}stopMessageLoop(){this.pollInterval&&=(clearInterval(this.pollInterval),null)}updateModel(){for(let e of this.contexts.values())e.updateModel();Q.info(`Model updated on all active contexts`,{contextCount:this.contexts.size})}async reloadAllSkills(){let e=[];for(let[t,n]of this.contexts){let r=this.tabs.get(t);(r?.status===`ready`||r?.status===`processing`)&&e.push(n.reloadSkills().catch(e=>{Q.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),Q.info(`Skills reloaded across all contexts`,{count:e.length})}stopScoop(e){let t=this.contexts.get(e);t&&t.stop()}buildScoopCost(e,t){let n=t.getAgentMessages().filter(e=>e.role===`assistant`);if(n.length===0)return null;let r={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},i=new Map;for(let e of n)r.input+=e.usage.input,r.output+=e.usage.output,r.cacheRead+=e.usage.cacheRead,r.cacheWrite+=e.usage.cacheWrite,r.totalTokens+=e.usage.totalTokens,r.cost.input+=e.usage.cost.input,r.cost.output+=e.usage.cost.output,r.cost.cacheRead+=e.usage.cost.cacheRead,r.cost.cacheWrite+=e.usage.cost.cacheWrite,r.cost.total+=e.usage.cost.total,i.set(e.model,(i.get(e.model)??0)+1);let a=``,o=0;for(let[e,t]of i)t>o&&(a=e,o=t);return{name:e.assistantLabel,type:e.isCone?`cone`:`scoop`,model:a,usage:r,turns:n.length}}snapshotScoopCost(e){let t=this.scoops.get(e),n=this.contexts.get(e);if(!t||!n)return;let r=this.buildScoopCost(t,n);r&&this.droppedScoopCosts.push(r)}getSessionCosts(){let e=[];for(let t of this.scoops.values()){let n=this.contexts.get(t.jid);if(!n)continue;let r=this.buildScoopCost(t,n);r&&e.push(r)}return e.push(...this.droppedScoopCosts),e}startIdleTimer(e){if(this.clearIdleTimer(e),this.tabs.get(e)?.status===`processing`)return;let t=setTimeout(()=>{this.idleTimers.delete(e);let t=this.scoops.get(e);if(!t||t.isCone||this.tabs.get(e)?.status!==`ready`)return;let n=Array.from(this.scoops.values()).find(e=>e.isCone);if(!n)return;let r={id:`scoop-idle-${e}-${Date.now()}`,chatJid:n.jid,senderId:t.folder,senderName:t.assistantLabel,content:`[@${t.assistantLabel} idle]: Scoop "${t.name}" has been ready for 2 minutes without receiving any work. This is expected if the scoop is waiting for webhooks or cron tasks. If you intended to delegate work, use feed_scoop to send a prompt.`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-idle`};Q.info(`Scoop idle timeout`,{jid:e,scoop:t.folder}),this.handleMessage(r).catch(t=>{let n=t instanceof Error?t.message:String(t);Q.error(`Failed to send idle notification`,{jid:e,error:n})})},ib);this.idleTimers.set(e,t)}clearIdleTimer(e){let t=this.idleTimers.get(e);t&&(clearTimeout(t),this.idleTimers.delete(e))}async shutdown(){this.stopMessageLoop();for(let e of this.idleTimers.keys())this.clearIdleTimer(e);this.scheduler?.stop(),this.scheduler=null;for(let e of this.contexts.keys())await this.destroyScoopTab(e);Q.info(`Orchestrator shutdown`)}};n(`heartbeat`);var ob=n(`tray-follower`);function sb(e){let t=new URL(e);return t.searchParams.set(`json`,`true`),t.toString()}async function cb(e){let t=sb(e.joinUrl),n=await hb(await(e.fetchImpl??fetch)(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:e.controllerId,runtime:e.runtime})}));return ob.info(`Follower tray attach response`,{trayId:n.trayId,action:n.result.action,code:n.result.code,participantCount:n.participantCount}),lb(n)}function lb(e){let t={trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,action:e.result.action,code:e.result.code,iceServers:e.iceServers};return e.result.action===`wait`?{...t,retryAfterMs:e.result.retryAfterMs}:e.result.action===`signal`?{...t,bootstrap:e.result.bootstrap}:e.result.action===`fail`?{...t,error:e.result.error}:t}async function ub(e){return mb(await gb(e,{action:`poll`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,cursor:e.cursor}))}async function db(e){return mb(await gb(e,{action:`answer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,answer:e.answer}))}async function fb(e){return mb(await gb(e,{action:`ice-candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:e.candidate}))}async function pb(e){return mb(await gb(e,{action:`retry`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,runtime:e.runtime}))}function mb(e){return{trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,bootstrap:e.bootstrap,events:e.events}}async function hb(e){let t=null,n=null;try{t=await e.text(),n=JSON.parse(t)}catch{}if(!_b(n)){let n=t?t.slice(0,200):`(empty)`;throw ob.warn(`Tray follower attach returned an invalid response`,{status:e.status,body:n}),Error(`Tray follower attach returned an invalid response (${e.status}): ${n}`)}return n}async function gb(e,t){let n=sb(e.joinUrl),r=await(e.fetchImpl??fetch)(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),i=await r.json().catch(()=>null);if(!vb(i))throw Error(`Tray follower bootstrap returned an invalid response (${r.status})`);return i}function _b(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.trayId!=`string`||typeof t.controllerId!=`string`||t.role!==`follower`||typeof t.participantCount!=`number`)return!1;let n=t.result;if(!n||typeof n!=`object`)return!1;let r=n;return r.action===`wait`?(r.code===`LEADER_NOT_ELECTED`||r.code===`LEADER_NOT_CONNECTED`)&&typeof r.retryAfterMs==`number`:r.action===`signal`?r.code===`LEADER_CONNECTED`&&yb(r.bootstrap):r.action===`fail`?(r.code===`INVALID_JOIN_CAPABILITY`||r.code===`TRAY_EXPIRED`)&&typeof r.error==`string`:!1}function vb(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.trayId==`string`&&typeof t.controllerId==`string`&&t.role===`follower`&&typeof t.participantCount==`number`&&yb(t.bootstrap)&&Array.isArray(t.events)}function yb(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.controllerId==`string`&&typeof t.bootstrapId==`string`&&typeof t.attempt==`number`&&typeof t.state==`string`&&typeof t.expiresAt==`string`&&typeof t.cursor==`number`&&typeof t.maxRetries==`number`&&typeof t.retriesRemaining==`number`}var bb=n(`tray-webrtc`),xb=`tray-control`,Sb=250,Cb=class{peerConnectionFactory;dataChannelLabel;peers=new Map;iceServers;constructor(e){this.options=e,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>Eb(this.iceServers)),this.dataChannelLabel=e.dataChannelLabel??xb}setIceServers(e){this.iceServers=e}async handleControlMessage(e){e.type===`follower.join_requested`?(e.iceServers&&!this.iceServers&&(this.iceServers=e.iceServers),await this.handleJoinRequested(e)):e.type===`bootstrap.answer`?await this.peers.get(e.bootstrapId)?.peer.setRemoteDescription(e.answer):e.type===`bootstrap.ice_candidate`&&await this.peers.get(e.bootstrapId)?.peer.addIceCandidate(e.candidate)}getPeers(){return Array.from(this.peers.values()).map(({state:e})=>({...e}))}getChannel(e){return this.peers.get(e)?.channel??null}stop(){for(let e of this.peers.values())e.peer.close();this.peers.clear()}async handleJoinRequested(e){this.closeControllerPeers(e.controllerId);let t=this.peerConnectionFactory(),n={controllerId:e.controllerId,bootstrapId:e.bootstrapId,attempt:e.attempt,state:`connecting`,connectedAt:null,runtime:e.runtime},r=t.createDataChannel(this.dataChannelLabel);this.peers.set(e.bootstrapId,{state:n,peer:t,channel:r}),t.addEventListener(`icecandidate`,({candidate:t})=>{let n=Ob(t);n&&this.options.sendControlMessage({type:`bootstrap.ice_candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:n})}),t.addEventListener(`connectionstatechange`,()=>{let n=this.peers.get(e.bootstrapId);n&&(n.state.state===`connected`?(t.connectionState===`disconnected`||t.connectionState===`failed`)&&(bb.warn(`Leader peer connection state changed post-connect`,{bootstrapId:e.bootstrapId,state:t.connectionState}),this.options.onPeerDisconnected?.(e.bootstrapId,`Peer connection ${t.connectionState}`)):t.connectionState===`failed`&&this.failPeer(e,`Leader peer connection failed before the data channel opened`))}),r.addEventListener(`open`,()=>{let t=this.peers.get(e.bootstrapId);!t||t.state.state===`connected`||(t.state.state=`connected`,t.state.connectedAt=new Date().toISOString(),this.options.onPeerConnected?.({...t.state},t.channel))}),r.addEventListener(`close`,()=>{let t=this.peers.get(e.bootstrapId);t&&(t.state.state===`connected`?(bb.warn(`Leader data channel closed post-connect`,{bootstrapId:e.bootstrapId}),this.options.onPeerDisconnected?.(e.bootstrapId,`Data channel closed`)):this.failPeer(e,`Leader data channel closed before opening`))}),r.addEventListener(`error`,()=>{let t=this.peers.get(e.bootstrapId);t&&(t.state.state===`connected`?(bb.warn(`Leader data channel error post-connect`,{bootstrapId:e.bootstrapId}),this.options.onPeerDisconnected?.(e.bootstrapId,`Data channel error`)):this.failPeer(e,`Leader data channel failed before opening`))});try{let n=await t.createOffer();await t.setLocalDescription(n),this.options.sendControlMessage({type:`bootstrap.offer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,offer:Db(t.localDescription??n,`offer`)})}catch(t){this.failPeer(e,t instanceof Error?t.message:String(t))}}closeControllerPeers(e){for(let[t,n]of this.peers.entries())n.state.controllerId===e&&(n.peer.close(),this.peers.delete(t))}failPeer(e,t){let n=this.peers.get(e.bootstrapId);if(n){n.peer.close(),this.peers.delete(e.bootstrapId);try{this.options.sendControlMessage({type:`bootstrap.failed`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,code:`WEBRTC_BOOTSTRAP_FAILED`,message:t,retryable:!0,retryAfterMs:1e3})}catch(e){bb.warn(`Failed to report tray bootstrap failure`,{error:e instanceof Error?e.message:String(e)})}}}},wb=class{fetchImpl;peerConnectionFactory;controllerIdFactory;sleep;pollIntervalMs;iceServers;activePeer=null;stopped=!1;constructor(e){this.options=e,this.fetchImpl=e.fetchImpl??fetch,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>Eb(this.iceServers)),this.controllerIdFactory=e.controllerIdFactory??(()=>crypto.randomUUID()),this.sleep=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),this.pollIntervalMs=e.pollIntervalMs??Sb}async start(){this.stopped=!1;let e=this.controllerIdFactory(),t=Date.now();p({state:`connecting`,joinUrl:this.options.joinUrl,trayId:null,error:null,lastPingTime:null,reconnectAttempts:0,attachAttempts:0,lastAttachCode:null,connectingSince:t,lastError:null}),bb.info(`Follower tray join starting`,{joinUrl:this.options.joinUrl});let n=0;for(;;){kb(this.stopped),n++;let t;try{t=await cb({joinUrl:this.options.joinUrl,controllerId:e,runtime:this.options.runtime,fetchImpl:this.fetchImpl})}catch(e){let t=e instanceof Error?e.message:String(e);throw p({...h(),attachAttempts:n,lastError:t}),e}if(p({...h(),attachAttempts:n,lastAttachCode:t.code}),t.action===`wait`){let e=t.retryAfterMs??1e3;bb.info(`Follower tray attach waiting`,{attempt:n,code:t.code,retryAfterMs:e}),n%10==0&&bb.warn(`Follower tray attach still waiting after ${n} attempts`,{attempt:n,code:t.code,retryAfterMs:e}),await this.sleep(e);continue}if(t.action===`fail`||!t.bootstrap){let e=t.error??`Tray follower attach failed (${t.code})`;throw p({state:`error`,joinUrl:this.options.joinUrl,trayId:null,error:e,lastPingTime:null,reconnectAttempts:0,attachAttempts:n,lastAttachCode:t.code,connectingSince:null,lastError:e}),bb.warn(`Follower tray attach failed`,{error:e}),Error(e)}t.iceServers&&(this.iceServers=t.iceServers);try{let r=await this.completeBootstrap(t.trayId,e,t.bootstrap);return p({state:`connected`,joinUrl:this.options.joinUrl,trayId:r.trayId,error:null,lastPingTime:null,reconnectAttempts:0,attachAttempts:n,lastAttachCode:t.code,connectingSince:null,lastError:null}),bb.info(`Follower tray connected`,{trayId:r.trayId,controllerId:e}),r}catch(e){let r=e instanceof Error?e.message:String(e);throw p({state:`error`,joinUrl:this.options.joinUrl,trayId:t.trayId,error:r,lastPingTime:null,reconnectAttempts:0,attachAttempts:n,lastAttachCode:t.code,connectingSince:null,lastError:r}),bb.warn(`Follower tray bootstrap failed`,{error:r}),e}}}stop(){this.stopped=!0,this.activePeer?.peer.close(),this.activePeer?.channel?.close(),this.activePeer=null,p({state:`inactive`,joinUrl:null,trayId:null,error:null,lastPingTime:null,reconnectAttempts:0,attachAttempts:0,lastAttachCode:null,connectingSince:null,lastError:null})}async completeBootstrap(e,t,n){let r=n,i=0;for(this.activePeer=this.createFollowerPeer(t,r.bootstrapId);;){if(kb(this.stopped),this.activePeer.open&&this.activePeer.channel)return{trayId:e,controllerId:t,bootstrapId:r.bootstrapId,channel:this.activePeer.channel};if(this.activePeer.openError)throw Error(this.activePeer.openError);let n=await ub({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,cursor:i,fetchImpl:this.fetchImpl});r=n.bootstrap,i=r.cursor;try{for(let e of n.events)if(e.type===`bootstrap.offer`){await this.activePeer.peer.setRemoteDescription(e.offer);let n=await this.activePeer.peer.createAnswer();await this.activePeer.peer.setLocalDescription(n),await db({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,answer:Db(this.activePeer.peer.localDescription??n,`answer`),fetchImpl:this.fetchImpl})}else if(e.type===`bootstrap.ice_candidate`)await this.activePeer.peer.addIceCandidate(e.candidate);else if(e.type===`bootstrap.failed`)throw Error(e.failure.message)}catch(e){if(r.failure?.retryable&&r.retriesRemaining>0){r=(await pb({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,runtime:this.options.runtime,fetchImpl:this.fetchImpl})).bootstrap,i=0,this.activePeer.peer.close(),this.activePeer=this.createFollowerPeer(t,r.bootstrapId);continue}throw e}this.activePeer.open||await this.sleep(this.pollIntervalMs)}}createFollowerPeer(e,t){let n=this.peerConnectionFactory(),r={peer:n,channel:null,open:!1,openError:null};return n.addEventListener(`connectionstatechange`,()=>{r.open&&(n.connectionState===`disconnected`||n.connectionState===`failed`)&&(bb.warn(`Follower peer connection state changed post-connect`,{bootstrapId:t,state:n.connectionState}),this.options.onDisconnected?.(`Peer connection ${n.connectionState}`))}),n.addEventListener(`datachannel`,({channel:e})=>{r.channel=e,e.addEventListener(`open`,()=>{r.open=!0}),e.addEventListener(`close`,()=>{r.open?(bb.warn(`Follower data channel closed post-connect`,{bootstrapId:t}),this.options.onDisconnected?.(`Data channel closed`)):r.openError=`Follower data channel closed before opening`}),e.addEventListener(`error`,()=>{r.open?(bb.warn(`Follower data channel error post-connect`,{bootstrapId:t}),this.options.onDisconnected?.(`Data channel error`)):r.openError=`Follower data channel failed before opening`})}),n.addEventListener(`icecandidate`,({candidate:n})=>{let r=Ob(n);r&&fb({joinUrl:this.options.joinUrl,controllerId:e,bootstrapId:t,candidate:r,fetchImpl:this.fetchImpl}).catch(e=>{bb.warn(`Failed to send follower ICE candidate`,{error:e instanceof Error?e.message:String(e)})})}),r}};function Tb(e,t){let n=t.baseDelayMs??1e3,r=t.backoffMultiplier??2,i=t.maxDelayMs??3e4,a=t.maxAttempts??10,o=t.sleep??e.sleep??(e=>new Promise(t=>setTimeout(t,e))),s=!1,c=!1,l=null,u={cancel(){s=!0,c=!1,l?.stop(),l=null},get reconnecting(){return c}},d=()=>{let t=new wb({...e,sleep:o,onDisconnected:e=>{s||(bb.warn(`Follower disconnected, starting reconnect loop`,{reason:e}),f(e))}});return l=t,{manager:t,connectionPromise:t.start()}},f=async u=>{if(s||c)return;c=!0,l?.stop(),l=null;let f=0,m=n,g=u??`Unknown disconnect`;for(;!s&&f<a&&(f++,t.onReconnecting?.(f),p({...h(),state:`reconnecting`,error:null,reconnectAttempts:f}),bb.info(`Reconnect attempt`,{attempt:f,delay:m}),await o(m),!s);){let n=null;try{let r=d();n=r.manager;let i=await r.connectionPromise;if(s){n.stop();break}c=!1,p({...h(),state:`connected`,joinUrl:e.joinUrl,trayId:i.trayId,error:null,lastPingTime:null,reconnectAttempts:0,connectingSince:null,lastError:null}),bb.info(`Reconnect successful`,{attempt:f,trayId:i.trayId}),t.onConnected(i);return}catch(e){g=e instanceof Error?e.message:String(e),bb.warn(`Reconnect attempt failed`,{attempt:f,error:g}),n?.stop(),l=null}m=Math.min(m*r,i)}s||(c=!1,p({...h(),state:`error`,error:`Reconnect failed after ${f} attempts: ${g}`,reconnectAttempts:f}),bb.warn(`Reconnect gave up`,{attempts:f,lastError:g}),t.onGaveUp?.(g))},{connectionPromise:m}=d();return m.then(e=>{s||t.onConnected(e)}).catch(e=>{s||bb.warn(`Initial follower connection failed`,{error:e instanceof Error?e.message:String(e)})}),u}function Eb(e){if(typeof RTCPeerConnection>`u`)throw Error(`RTCPeerConnection is not available in this runtime`);let t=e?.length?{iceServers:e}:void 0;return new RTCPeerConnection(t)}function Db(e,t){if(!e||e.type!==t||typeof e.sdp!=`string`)throw Error(`Expected a local ${t} description before signaling`);return{type:e.type,sdp:e.sdp}}function Ob(e){if(!e||typeof e!=`object`)return null;let t=e;return typeof t.candidate==`string`?{candidate:t.candidate,sdpMid:typeof t.sdpMid==`string`?t.sdpMid:null,sdpMLineIndex:typeof t.sdpMLineIndex==`number`?t.sdpMLineIndex:null,usernameFragment:typeof t.usernameFragment==`string`?t.usernameFragment:null}:null}function kb(e){if(e)throw Error(`Tray follower stopped before WebRTC bootstrap completed`)}var Ab=64*1024;async function jb(e,t){try{switch(t.op){case`readFile`:return await Mb(e,t.path,t.encoding);case`writeFile`:return[await Nb(e,t.path,t.content,t.encoding)];case`stat`:return[await Pb(e,t.path)];case`readDir`:return[await Fb(e,t.path)];case`mkdir`:return[await Ib(e,t.path,t.recursive)];case`rm`:return[await Lb(e,t.path,t.recursive)];case`exists`:return[await Rb(e,t.path)];case`walk`:return[await zb(e,t.path)];default:return[{ok:!1,error:`Unknown fs operation: ${t.op}`}]}}catch(e){return[Vb(e)]}}async function Mb(e,t,n){return(n??`utf-8`)===`utf-8`?Bb(await e.readFile(t,{encoding:`utf-8`}),`utf-8`):Bb(Hb(await e.readFile(t,{encoding:`binary`})),`base64`)}async function Nb(e,t,n,r){if(r===`base64`){let r=Ub(n);await e.writeFile(t,r)}else await e.writeFile(t,n);return{ok:!0,data:{type:`void`}}}async function Pb(e,t){return{ok:!0,data:{type:`stat`,stat:await e.stat(t)}}}async function Fb(e,t){return{ok:!0,data:{type:`dirEntries`,entries:await e.readDir(t)}}}async function Ib(e,t,n){return await e.mkdir(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function Lb(e,t,n){return await e.rm(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function Rb(e,t){return{ok:!0,data:{type:`exists`,exists:await e.exists(t)}}}async function zb(e,t){let n=[];for await(let r of e.walk(t))n.push(r);return{ok:!0,data:{type:`paths`,paths:n}}}function Bb(e,t){if(e.length<=Ab)return[{ok:!0,data:{type:`file`,content:e,encoding:t}}];let n=Math.ceil(e.length/Ab),r=[];for(let i=0;i<n;i++){let a=i*Ab,o=e.slice(a,a+Ab);r.push({ok:!0,data:{type:`file`,content:o,encoding:t},chunkIndex:i,totalChunks:n})}return r}function Vb(e){return e instanceof Error&&`code`in e?{ok:!1,error:e.message,code:e.code}:{ok:!1,error:e instanceof Error?e.message:String(e)}}function Hb(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function Ub(e){let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}var Wb=class{runtimes=new Map;dirty=!1;setTargets(e,t){this.runtimes.set(e,t),this.dirty=!0}removeRuntime(e){this.runtimes.delete(e)&&(this.dirty=!0)}getEntries(){this.dirty=!1;let e=[];for(let[t,n]of this.runtimes)for(let r of n)e.push({targetId:`${t}:${r.targetId}`,localTargetId:r.targetId,runtimeId:t,title:r.title,url:r.url,isLocal:!1});return e}hasChanged(){return this.dirty}getRuntimeIds(){return[...this.runtimes.keys()]}},Gb=n(`data-channel-keepalive`),Kb=class{sendPing;onDead;intervalMs;maxMissed;timer=null;missedPongs=0;awaitingPong=!1;stopped=!1;constructor(e){this.sendPing=e.sendPing,this.onDead=e.onDead,this.intervalMs=e.intervalMs??1e4,this.maxMissed=e.maxMissed??3}start(){this.timer||this.stopped||(this.timer=setInterval(()=>this.tick(),this.intervalMs))}stop(){this.stopped=!0,this.timer&&=(clearInterval(this.timer),null)}receivePong(){this.awaitingPong=!1,this.missedPongs=0}receivePing(){this.missedPongs=0,this.awaitingPong=!1}get missed(){return this.missedPongs}tick(){if(!this.stopped){if(this.awaitingPong&&(this.missedPongs++,Gb.debug(`Missed pong`,{missedPongs:this.missedPongs,maxMissed:this.maxMissed}),this.missedPongs>=this.maxMissed)){Gb.warn(`Channel declared dead`,{missedPongs:this.missedPongs}),this.stop(),this.onDead();return}this.awaitingPong=!0,this.sendPing()}}},qb=n(`tray-leader-sync`);function Jb(e){return e?e.includes(`standalone`)?`standalone`:e.includes(`extension`)?`extension`:e.includes(`electron`)?`electron`:`unknown`:`unknown`}var Yb=class{followers=new Map;registry=new Wb;runtimeToBootstrap=new Map;pendingCDPRoutes=new Map;cdpChunkBuffers=new Map;remoteTransports=new Map;pendingTabOpenRoutes=new Map;tabOpenResolvers=new Map;pendingFsRoutes=new Map;fsResolvers=new Map;constructor(e){this.options=e}addFollower(e,t,n){this.removeFollower(e);let r=ge(t),i=r.onMessage(t=>{this.handleFollowerMessage(e,t)}),a=new Kb({sendPing:()=>r.send({type:`ping`}),onDead:()=>{qb.warn(`Follower keepalive dead, removing follower`,{bootstrapId:e}),this.removeFollower(e),this.options.onFollowerDead?.(e)}});a.start(),this.followers.set(e,{bootstrapId:e,sync:r,unsubscribe:i,keepalive:a,runtime:n?.runtime,connectedAt:n?.connectedAt,lastActivity:Date.now(),floatType:Jb(n?.runtime)}),qb.info(`Follower added to sync`,{bootstrapId:e,followerCount:this.followers.size}),this.sendSnapshotToFollower(e);let o=this.getConnectedEntries();o.length>0&&r.send({type:`targets.registry`,targets:o})}removeFollower(e){let t=this.followers.get(e);if(t){t.keepalive.stop(),t.unsubscribe(),t.sync.close(),this.followers.delete(e);for(let[t,n]of this.runtimeToBootstrap)if(n===e){this.cleanupRemoteTransports(t),this.registry.removeRuntime(t),this.runtimeToBootstrap.delete(t);break}this.registry.hasChanged()&&this.broadcastTargetRegistry(),qb.info(`Follower removed from sync`,{bootstrapId:e,followerCount:this.followers.size})}}broadcastEvent(e){if(this.followers.size===0)return;let t={type:`agent_event`,event:e,scoopJid:this.options.getScoopJid()};for(let e of this.followers.values())e.sync.send(t)}broadcastUserMessage(e,t){if(this.followers.size===0)return;let n={type:`user_message_echo`,text:e,messageId:t,scoopJid:this.options.getScoopJid()};for(let e of this.followers.values())e.sync.send(n)}broadcastStatus(e){if(this.followers.size===0)return;let t={type:`status`,scoopStatus:e};for(let e of this.followers.values())e.sync.send(t)}sendSnapshotToFollower(e){let t=this.followers.get(e);if(!t)return;let n=this.options.getMessages(),r=this.options.getScoopJid();me(t.sync,n,r),qb.debug(`Snapshot sent to follower`,{bootstrapId:e,messageCount:n.length})}handleFollowerMessage(e,t){switch(t.type){case`user_message`:qb.info(`Follower user message received`,{bootstrapId:e,messageId:t.messageId}),this.options.onFollowerMessage(t.text,t.messageId);break;case`abort`:qb.info(`Follower abort received`,{bootstrapId:e}),this.options.onFollowerAbort();break;case`request_snapshot`:qb.info(`Follower snapshot request received`,{bootstrapId:e}),this.sendSnapshotToFollower(e);break;case`targets.advertise`:qb.info(`Follower targets advertised`,{bootstrapId:e,runtimeId:t.runtimeId,targetCount:t.targets.length});for(let e of[...this.remoteTransports.keys()]){let n=e.substring(0,e.indexOf(`:`));n!==`leader`&&!this.runtimeToBootstrap.has(n)&&n!==t.runtimeId&&(this.remoteTransports.get(e)?.disconnect(),this.remoteTransports.delete(e),qb.debug(`Cleaned up orphaned remote transport on advertise`,{key:e}))}this.runtimeToBootstrap.set(t.runtimeId,e),this.registry.setTargets(t.runtimeId,t.targets),this.broadcastTargetRegistry();break;case`cdp.request`:{let{requestId:n,targetRuntimeId:r,localTargetId:i,method:a,params:o,sessionId:s}=t;r===`leader`?this.executeLocalCDP(n,i,a,o,s,e):this.forwardCDPRequest(n,r,i,a,o,s,e);break}case`cdp.response`:this.handleCDPResponse(t);break;case`cdp.event`:this.handleCDPEvent(e,t.method,t.params,t.sessionId);break;case`tab.open`:{let{requestId:n,targetRuntimeId:r,url:i}=t;r===`leader`?this.executeLocalTabOpen(n,i,e):this.forwardTabOpen(n,r,i,e);break}case`tab.opened`:this.handleTabOpenResponse(t.requestId,t.targetId);break;case`tab.open.error`:this.handleTabOpenError(t.requestId,t.error);break;case`fs.request`:{let{requestId:n,targetRuntimeId:r,request:i}=t;r===`leader`?this.executeLocalFs(n,i,e):this.forwardFsRequest(n,r,i,e);break}case`fs.response`:this.handleFsResponse(t.requestId,t.response);break;case`ping`:{let t=this.followers.get(e);t&&(t.keepalive.receivePing(),t.lastActivity=Date.now(),t.sync.send({type:`pong`}));break}case`pong`:{let t=this.followers.get(e);t&&(t.keepalive.receivePong(),t.lastActivity=Date.now());break}}}setLocalTargets(e){this.registry.setTargets(`leader`,e),this.registry.hasChanged()&&this.broadcastTargetRegistry()}broadcastTargetRegistry(){if(this.followers.size===0)return;let e={type:`targets.registry`,targets:this.getConnectedEntries()};for(let t of this.followers.values())t.sync.send(e)}getTargets(){return this.getConnectedEntries()}getConnectedEntries(){return this.registry.getEntries().filter(e=>{if(e.runtimeId===`leader`)return!0;let t=this.runtimeToBootstrap.get(e.runtimeId);return t?this.followers.has(t):!1})}createRemoteTransport(e,t){let n=new ve({sendCDPRequest:(n,r,i,a)=>{let o=this.runtimeToBootstrap.get(e),s=o?this.followers.get(o):void 0;if(!s){this.remoteTransports.get(`${e}:${t}`)?.handleResponse(n,void 0,`Target runtime "${e}" not connected`);return}this.pendingCDPRoutes.set(n,{requesterBootstrapId:`__leader__`,requestId:n}),s.sync.send({type:`cdp.request`,requestId:n,localTargetId:t,method:r,params:i,sessionId:a})}});return this.remoteTransports.set(`${e}:${t}`,n),n}removeRemoteTransport(e,t){let n=`${e}:${t}`,r=this.remoteTransports.get(n);r&&(r.disconnect(),this.remoteTransports.delete(n))}cleanupRemoteTransports(e){let t=`${e}:`;for(let e of[...this.remoteTransports.keys()])e.startsWith(t)&&(this.remoteTransports.get(e)?.disconnect(),this.remoteTransports.delete(e),qb.debug(`Cleaned up stale remote transport`,{key:e}))}getConnectedFollowers(){return[...this.runtimeToBootstrap.entries()].map(([e,t])=>{let n=this.followers.get(t);return{runtimeId:e,runtime:n?.runtime,connectedAt:n?.connectedAt,lastActivity:n?.lastActivity,floatType:n?.floatType}})}getBestFollowerForTeleport(){let e=[];for(let[t,n]of this.runtimeToBootstrap){let r=this.followers.get(n);r&&e.push({runtimeId:t,bootstrapId:n,floatType:r.floatType,lastActivity:r.lastActivity})}if(e.length===0)return null;let t=e.filter(e=>e.floatType===`standalone`),n=t.length>0?t:e;return n.sort((e,t)=>t.lastActivity-e.lastActivity),n[0]}get hasFollowers(){return this.followers.size>0}stop(){for(let e of[...this.followers.keys()])this.removeFollower(e)}async executeLocalCDP(e,t,n,r,i,a){let o=this.followers.get(a);if(!o)return;let s=this.options.browserTransport;if(!s){o.sync.send({type:`cdp.response`,requestId:e,error:`Leader has no browser transport`});return}try{let t=await s.send(n,r,i);xe(o.sync,e,t)}catch(t){o.sync.send({type:`cdp.response`,requestId:e,error:t instanceof Error?t.message:String(t)})}}forwardCDPRequest(e,t,n,r,i,a,o){let s=this.runtimeToBootstrap.get(t),c=s?this.followers.get(s):void 0,l=this.followers.get(o);if(!c){l&&l.sync.send({type:`cdp.response`,requestId:e,error:`Target runtime "${t}" not connected`});return}this.pendingCDPRoutes.set(e,{requesterBootstrapId:o,requestId:e}),c.sync.send({type:`cdp.request`,requestId:e,localTargetId:n,method:r,params:i,sessionId:a})}handleCDPResponse(e){let{requestId:t,result:n,error:r,chunkData:i,chunkIndex:a,totalChunks:o}=e,s=this.pendingCDPRoutes.get(t);if(!s)return;let c=pe(this.cdpChunkBuffers,e);if(!c)return;if(this.pendingCDPRoutes.delete(t),s.requesterBootstrapId===`__leader__`){for(let e of this.remoteTransports.values())e.handleResponse(t,c.result,c.error);return}let l=this.followers.get(s.requesterBootstrapId);l&&xe(l.sync,t,c.result,c.error)}handleCDPEvent(e,t,n,r){let i;for(let[t,n]of this.runtimeToBootstrap)if(n===e){i=t;break}if(!i)return;let a=`${i}:`;for(let[e,r]of this.remoteTransports)e.startsWith(a)&&r.handleEvent(t,n)}openRemoteTab(e,t){let n=this.runtimeToBootstrap.get(e),r=n?this.followers.get(n):void 0;if(!r)return Promise.reject(Error(`Target runtime "${e}" not connected`));let i=`tab-open-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return new Promise((e,n)=>{this.tabOpenResolvers.set(i,{resolve:e,reject:n}),this.pendingTabOpenRoutes.set(i,{requesterBootstrapId:`__leader__`,requestId:i}),r.sync.send({type:`tab.open`,requestId:i,url:t})})}async executeLocalTabOpen(e,t,n){let r=this.followers.get(n);if(!r)return;let i=this.options.browserTransport;if(!i){r.sync.send({type:`tab.open.error`,requestId:e,error:`Leader has no browser transport`});return}try{let n=(await i.send(`Target.createTarget`,{url:t,background:!0})).targetId;r.sync.send({type:`tab.opened`,requestId:e,targetId:`leader:${n}`})}catch(t){r.sync.send({type:`tab.open.error`,requestId:e,error:t instanceof Error?t.message:String(t)})}}forwardTabOpen(e,t,n,r){let i=this.runtimeToBootstrap.get(t),a=i?this.followers.get(i):void 0,o=this.followers.get(r);if(!a){o&&o.sync.send({type:`tab.open.error`,requestId:e,error:`Target runtime "${t}" not connected`});return}this.pendingTabOpenRoutes.set(e,{requesterBootstrapId:r,requestId:e}),a.sync.send({type:`tab.open`,requestId:e,url:n})}handleTabOpenResponse(e,t){let n=this.pendingTabOpenRoutes.get(e);if(!n)return;if(this.pendingTabOpenRoutes.delete(e),n.requesterBootstrapId===`__leader__`){let n=this.tabOpenResolvers.get(e);n&&(this.tabOpenResolvers.delete(e),n.resolve(t));return}let r=this.followers.get(n.requesterBootstrapId);r&&r.sync.send({type:`tab.opened`,requestId:e,targetId:t})}handleTabOpenError(e,t){let n=this.pendingTabOpenRoutes.get(e);if(!n)return;if(this.pendingTabOpenRoutes.delete(e),n.requesterBootstrapId===`__leader__`){let n=this.tabOpenResolvers.get(e);n&&(this.tabOpenResolvers.delete(e),n.reject(Error(t)));return}let r=this.followers.get(n.requesterBootstrapId);r&&r.sync.send({type:`tab.open.error`,requestId:e,error:t})}async executeLocalFs(e,t,n){let r=this.followers.get(n);if(!r)return;let i=this.options.vfs;if(!i){r.sync.send({type:`fs.response`,requestId:e,response:{ok:!1,error:`Leader has no VFS`}});return}let a=await jb(i,t);for(let t of a)r.sync.send({type:`fs.response`,requestId:e,response:t})}forwardFsRequest(e,t,n,r){let i=this.runtimeToBootstrap.get(t),a=i?this.followers.get(i):void 0,o=this.followers.get(r);if(!a){o&&o.sync.send({type:`fs.response`,requestId:e,response:{ok:!1,error:`Target runtime "${t}" not connected`}});return}this.pendingFsRoutes.set(e,{requesterBootstrapId:r,requestId:e,chunks:[],totalChunks:1}),a.sync.send({type:`fs.request`,requestId:e,request:n})}handleFsResponse(e,t){let n=this.pendingFsRoutes.get(e);if(!n){let n=this.fsResolvers.get(e);if(n){n.responses.push(t);let r=t.ok&&t.totalChunks||1;n.responses.length>=r&&(this.fsResolvers.delete(e),n.resolve(n.responses))}return}if(n.requesterBootstrapId===`__leader__`){let n=this.fsResolvers.get(e);if(n){n.responses.push(t);let r=t.ok&&t.totalChunks||1;n.responses.length>=r&&(this.fsResolvers.delete(e),this.pendingFsRoutes.delete(e),n.resolve(n.responses))}return}let r=this.followers.get(n.requesterBootstrapId);r&&r.sync.send({type:`fs.response`,requestId:e,response:t}),n.chunks.push(t),n.totalChunks=t.ok&&t.totalChunks||1,n.chunks.length>=n.totalChunks&&this.pendingFsRoutes.delete(e)}sendFsRequest(e,t){if(e===`leader`){let e=this.options.vfs;return e?jb(e,t):Promise.resolve([{ok:!1,error:`Leader has no VFS`}])}let n=this.runtimeToBootstrap.get(e),r=n?this.followers.get(n):void 0;if(!r)return Promise.resolve([{ok:!1,error:`Target runtime "${e}" not connected`}]);let i=`fs-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return new Promise((e,n)=>{this.fsResolvers.set(i,{resolve:e,reject:n,responses:[]}),this.pendingFsRoutes.set(i,{requesterBootstrapId:`__leader__`,requestId:i,chunks:[],totalChunks:1}),r.sync.send({type:`fs.request`,requestId:i,request:t})})}},Xb=n(`tray-follower-sync`),Zb=class{sync;eventListeners=new Set;unsubscribe;keepalive;latestSnapshot=null;sentMessageIds=new Set;targetEntries=[];remoteTransports=new Map;cdpChunkBuffers=new Map;snapshotChunkBuffer=null;remoteCDPSessions=new Set;cdpEventCleanups=[];tabOpenResolvers=new Map;fsResolvers=new Map;constructor(e,t={}){this.options=t,this.sync=be(e),this.unsubscribe=this.sync.onMessage(e=>{this.handleLeaderMessage(e)}),this.keepalive=new Kb({sendPing:()=>this.sync.send({type:`ping`}),onDead:()=>{Xb.warn(`Leader keepalive dead, cleaning up`),this.handleDisconnect(`Keepalive timeout — leader not responding`),this.options.onDead?.()}}),this.keepalive.start(),e.addEventListener(`close`,()=>{Xb.warn(`Data channel closed`),this.handleDisconnect(`Data channel closed`)}),e.addEventListener(`error`,()=>{Xb.warn(`Data channel error`),this.handleDisconnect(`Data channel error`)})}sendMessage(e,t){let n=t??`follower-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;this.sentMessageIds.add(n),this.sync.send({type:`user_message`,text:e,messageId:n}),Xb.info(`Sent user message to leader`,{messageId:n})}onEvent(e){return this.eventListeners.add(e),()=>this.eventListeners.delete(e)}stop(){this.sync.send({type:`abort`}),Xb.info(`Sent abort to leader`)}requestSnapshot(){this.sync.send({type:`request_snapshot`})}getLatestSnapshot(){return this.latestSnapshot}close(){this.keepalive.stop(),this.unsubscribe(),this.sync.close(),this.eventListeners.clear(),this.cleanupCDPEventForwarding(),Xb.info(`Follower sync closed`)}advertiseTargets(e,t){this.sync.send({type:`targets.advertise`,targets:e,runtimeId:t})}getTargets(){return this.targetEntries}disconnected=!1;handleDisconnect(e){this.disconnected||(this.disconnected=!0,p({...h(),state:`error`,error:e}),this.emitEvent({type:`error`,error:`Connection to leader lost: ${e}`}),this.keepalive.stop(),this.cleanupCDPEventForwarding(),this.unsubscribe(),this.sync.close(),this.options.onDisconnect?.(e))}handleLeaderMessage(e){switch(e.type){case`snapshot`:Xb.info(`Snapshot received from leader`,{messageCount:e.messages.length,scoopJid:e.scoopJid}),this.snapshotChunkBuffer=null,this.latestSnapshot={messages:e.messages,scoopJid:e.scoopJid},this.options.onSnapshot?.(e.messages,e.scoopJid);break;case`snapshot_chunk`:{let t=ye(this.snapshotChunkBuffer,e);this.snapshotChunkBuffer=t.buffer,t.result&&(Xb.info(`Chunked snapshot reassembled from leader`,{messageCount:t.result.messages.length,scoopJid:t.result.scoopJid}),this.latestSnapshot=t.result,this.options.onSnapshot?.(t.result.messages,t.result.scoopJid));break}case`agent_event`:this.emitEvent(e.event);break;case`user_message_echo`:if(this.sentMessageIds.has(e.messageId)){this.sentMessageIds.delete(e.messageId),Xb.debug(`Skipping own message echo`,{messageId:e.messageId});break}Xb.info(`User message echo received`,{messageId:e.messageId,scoopJid:e.scoopJid}),this.options.onUserMessage?.(e.text,e.messageId,e.scoopJid);break;case`status`:this.options.onStatus?.(e.scoopStatus);break;case`error`:Xb.warn(`Error from leader`,{error:e.error}),this.emitEvent({type:`error`,error:e.error});break;case`targets.registry`:Xb.info(`Target registry received from leader`,{targetCount:e.targets.length}),this.targetEntries=e.targets,this.options.onTargetsUpdated?.(this.targetEntries);break;case`cdp.request`:{let{requestId:t,localTargetId:n,method:r,params:i,sessionId:a}=e;this.executeLocalCDP(t,n,r,i,a);break}case`cdp.response`:this.routeCDPResponse(e);break;case`cdp.event`:for(let t of this.remoteTransports.values())t.handleEvent(e.method,e.params);break;case`tab.open`:this.executeLocalTabOpen(e.requestId,e.url);break;case`tab.opened`:{let t=this.tabOpenResolvers.get(e.requestId);t&&(this.tabOpenResolvers.delete(e.requestId),t.resolve(e.targetId));break}case`tab.open.error`:{let t=this.tabOpenResolvers.get(e.requestId);t&&(this.tabOpenResolvers.delete(e.requestId),t.reject(Error(e.error)));break}case`fs.request`:this.executeLocalFs(e.requestId,e.request);break;case`fs.response`:this.routeFsResponse(e.requestId,e.response);break;case`ping`:this.keepalive.receivePing(),this.sync.send({type:`pong`});break;case`pong`:this.keepalive.receivePong(),u(Date.now());break}}emitEvent(e){for(let t of this.eventListeners)try{t(e)}catch(t){Xb.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}}createRemoteTransport(e,t){let n=new ve({sendCDPRequest:(n,r,i,a)=>{this.sync.send({type:`cdp.request`,requestId:n,targetRuntimeId:e,localTargetId:t,method:r,params:i,sessionId:a})}});return this.remoteTransports.set(`${e}:${t}`,n),n}removeRemoteTransport(e,t){let n=`${e}:${t}`,r=this.remoteTransports.get(n);r&&(r.disconnect(),this.remoteTransports.delete(n))}openRemoteTab(e,t){let n=`tab-open-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return new Promise((r,i)=>{this.tabOpenResolvers.set(n,{resolve:r,reject:i}),this.sync.send({type:`tab.open`,requestId:n,targetRuntimeId:e,url:t})})}async executeLocalTabOpen(e,t){let n=this.options.browserTransport;if(!n){this.sync.send({type:`tab.open.error`,requestId:e,error:`Follower has no browser transport`});return}try{let r=(await n.send(`Target.createTarget`,{url:t,background:!0})).targetId;this.sync.send({type:`tab.opened`,requestId:e,targetId:r}),this.options.onTargetsChanged?.()}catch(t){this.sync.send({type:`tab.open.error`,requestId:e,error:t instanceof Error?t.message:String(t)})}}async executeLocalCDP(e,t,n,r,i){let a=this.options.browserTransport;if(!a){this.sync.send({type:`cdp.response`,requestId:e,error:`Follower has no browser transport`});return}try{let t=await a.send(n,r,i);if(n===`Target.attachToTarget`&&t.sessionId){let e=t.sessionId;this.remoteCDPSessions.add(e),this.setupCDPEventForwarding(a,e),Xb.debug(`Tracking remote CDP session`,{remoteSessionId:e})}n===`Target.detachFromTarget`&&i&&this.remoteCDPSessions.has(i)&&(this.remoteCDPSessions.delete(i),Xb.debug(`Removed remote CDP session on detach`,{sessionId:i})),xe(this.sync,e,t)}catch(t){this.sync.send({type:`cdp.response`,requestId:e,error:t instanceof Error?t.message:String(t)})}}setupCDPEventForwarding(e,t){for(let n of[`Page.frameNavigated`,`Page.loadEventFired`,`Page.domContentEventFired`,`Network.responseReceived`,`Network.loadingFinished`,`Network.requestWillBeSent`]){let r=e=>{if(e.sessionId!==t||!this.remoteCDPSessions.has(t))return;let{sessionId:r,...i}=e;this.sync.send({type:`cdp.event`,method:n,params:i,sessionId:t})};e.on(n,r),this.cdpEventCleanups.push(()=>e.off(n,r))}}cleanupCDPEventForwarding(){for(let e of this.cdpEventCleanups)e();this.cdpEventCleanups.length=0,this.remoteCDPSessions.clear()}routeCDPResponse(e){let t=pe(this.cdpChunkBuffers,e);if(t)for(let n of this.remoteTransports.values())n.handleResponse(e.requestId,t.result,t.error)}async executeLocalFs(e,t){let n=this.options.vfs;if(!n){this.sync.send({type:`fs.response`,requestId:e,response:{ok:!1,error:`Follower has no VFS`}});return}let r=await jb(n,t);for(let t of r)this.sync.send({type:`fs.response`,requestId:e,response:t})}routeFsResponse(e,t){let n=this.fsResolvers.get(e);if(!n)return;n.responses.push(t);let r=t.ok&&t.totalChunks||1;n.responses.length>=r&&(this.fsResolvers.delete(e),n.resolve(n.responses))}sendFsRequest(e,t){let n=`fs-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return new Promise((r,i)=>{this.fsResolvers.set(n,{resolve:r,reject:i,responses:[]}),this.sync.send({type:`fs.request`,requestId:n,targetRuntimeId:e,request:t})})}};function Qb(e,t){if(t)return`extension`;try{return tx(new URL(e))?`electron-overlay`:`standalone`}catch{return`standalone`}}function $b(e,t){return e===`electron-overlay`||e===`standalone`&&t}function ex(e){try{let t=new URL(e).searchParams.get(`tab`);return t&&Ji(t)?t:Ki}catch{return Ki}}function tx(e){return e.pathname===`/electron`||e.pathname===`/electron/`||e.searchParams.get(`runtime`)===`electron-overlay`}function nx(e){let t=new URL(e);return`${t.protocol===`https:`?`wss:`:`ws:`}//${t.host}/licks-ws`}function rx(e,t){return`${new URL(e).origin}/webhooks/${t}`}function ix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function ax(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`slicc-electron-overlay:set-tab`}var ox=[`/shared/sprinkles`];async function sx(e){let t=new Map;for(let n of ox)await e.exists(n)&&await cx(e,n,t);return await cx(e,`/`,t),t}async function cx(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.shtml`))continue;let t=lx(r);if(!n.has(t)){let i;try{i=await e.readFile(r,{encoding:`utf-8`})??``}catch{i=``}n.set(t,{name:t,path:r,title:ux(i,t),autoOpen:dx(i)})}}}function lx(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function ux(e,t){let n=e.match(/data-sprinkle-title=["']([^"']+)["']/);if(n)return n[1];let r=e.match(/<title>([^<]+)<\/title>/i);return r?r[1].trim():t}function dx(e){return/data-sprinkle-autoopen\b/.test(e)}var fx=n(`sprinkle-manager`),px=`slicc-open-sprinkles`,mx=class{fs;bridge;callbacks;availableSprinkles=new Map;watcherUnsub;openSprinkles=new Map;constructor(e,t,n,r){this.fs=e,this.bridge=new Nh(e,t,e=>this.close(e),r),this.callbacks=n}async restoreOpenSprinkles(){try{let e=localStorage.getItem(px);if(!e){for(let e of this.availableSprinkles.values())if(e.autoOpen)try{await this.open(e.name)}catch{fx.warn(`Failed to auto-open sprinkle`,{name:e.name})}return}let t=JSON.parse(e);for(let e of t)try{await this.open(e)}catch{fx.warn(`Failed to restore sprinkle`,{name:e})}}catch{}}persistOpenSprinkles(){try{localStorage.setItem(px,JSON.stringify([...this.openSprinkles.keys()]))}catch{}}async openNewAutoOpenSprinkles(){await this.refresh();for(let e of this.availableSprinkles.values())if(e.autoOpen&&!this.openSprinkles.has(e.name))try{await this.open(e.name),fx.info(`Auto-opened new sprinkle after install`,{name:e.name})}catch{fx.warn(`Failed to auto-open new sprinkle`,{name:e.name})}}async refresh(){this.availableSprinkles=await sx(this.fs),fx.info(`Discovered sprinkles`,{count:this.availableSprinkles.size})}async open(e,t){if(this.openSprinkles.has(e)){fx.info(`Sprinkle already open`,{name:e});return}let n=this.availableSprinkles.get(e);if(n||=(await this.refresh(),this.availableSprinkles.get(e)),!n)throw Error(`Sprinkle not found: ${e}`);let r=await this.fs.readFile(n.path,{encoding:`utf-8`}),i=document.createElement(`div`);i.className=`sprinkle-panel`,i.style.cssText=`width: 100%; height: 100%; display: flex; flex-direction: column; overflow: hidden;`,i.dataset.sprinkle=e,this.openSprinkles.set(e,{renderer:null,container:i}),this.callbacks.addSprinkle(e,n.title,i,t);let a=new oi(i,this.bridge.createAPI(e));await a.render(r,e),this.openSprinkles.get(e).renderer=a,this.persistOpenSprinkles(),Bv(e),fx.info(`Sprinkle opened`,{name:e,title:n.title})}close(e){let t=this.openSprinkles.get(e);t&&(t.renderer?.dispose(),t.container.remove(),this.bridge.removeSprinkle(e),this.openSprinkles.delete(e),this.callbacks.removeSprinkle(e),this.persistOpenSprinkles(),fx.info(`Sprinkle closed`,{name:e}))}available(){return Array.from(this.availableSprinkles.values())}opened(){return Array.from(this.openSprinkles.keys())}setupWatcher(e){this.watcherUnsub=e.watch(`/workspace`,e=>e.endsWith(`.shtml`),()=>void this.refresh())}dispose(){this.watcherUnsub?.()}sendToSprinkle(e,t){let n=this.openSprinkles.get(e);if(!n){fx.warn(`Cannot send to closed sprinkle`,{name:e});return}this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t)}};function hx(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch{return e}}function gx(e){let t=[],{payload:n}=e;if(n.title&&t.push(`# ${n.title}`),t.push(`A new handoff was accepted from ${hx(e.sourceUrl)}.`),t.push(`## Instruction`),t.push(n.instruction),n.urls&&n.urls.length>0){t.push(`## URLs`);for(let e of n.urls)t.push(`- ${e}`)}if(n.context&&(t.push(`## Context`),t.push(n.context)),n.acceptanceCriteria&&n.acceptanceCriteria.length>0){t.push(`## Acceptance Criteria`);for(let e of n.acceptanceCriteria)t.push(`- ${e}`)}return n.notes&&(t.push(`## Notes`),t.push(n.notes)),t.join(`
13109
13109
 
13110
- `)}function _x(e,t){return e.receivedAt.localeCompare(t.receivedAt)}var vx=class{onPendingHandoffsChange;pendingByHandoffId=new Map;constructor(e){this.onPendingHandoffsChange=e.onPendingHandoffsChange}injectHandoff(e,t=`local`){let n=`injected-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.pendingByHandoffId.set(n,{handoffId:n,sourceUrl:t,payload:e,receivedAt:new Date().toISOString()}),this.emitChange(),n}clearHandoff(e){let t=this.pendingByHandoffId.get(e)??null;return this.pendingByHandoffId.delete(e),t&&this.emitChange(),{handoff:t,targetIds:[]}}emitChange(){this.onPendingHandoffsChange?.([...this.pendingByHandoffId.values()].sort(_x))}},$=n(`main`),yx=`slicc-pending-mount`,bx=`pendingMount`;async function xx(e){let t=await new Promise((e,t)=>{let n=indexedDB.open(yx,1);n.onupgradeneeded=()=>n.result.createObjectStore(`handles`),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),n=t.transaction(`handles`,`readwrite`);n.objectStore(`handles`).put(e,bx),await new Promise(e=>n.oncomplete=()=>e()),t.close()}async function Sx(e){let t;try{t=await new Promise((e,t)=>{let n=indexedDB.open(yx,1);n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}catch{return}let n=t.transaction(`handles`,`readwrite`),r=await new Promise(e=>{let t=n.objectStore(`handles`).get(bx);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)});if(r){n.objectStore(`handles`).delete(bx),await new Promise(e=>n.oncomplete=()=>e());let t=`/mnt/${r.name}`;await e.mount(t,r),$.info(`Mounted folder from welcome onboarding`,{name:r.name,path:t})}t.close()}function Cx(){let e=document.createElement(`div`);e.className=`skill-drop-overlay`;let t=document.createElement(`div`);t.className=`skill-drop-overlay__card`;let n=document.createElement(`div`);n.className=`skill-drop-overlay__title`,t.appendChild(n);let r=document.createElement(`div`);return r.className=`skill-drop-overlay__desc`,t.appendChild(r),e.appendChild(t),document.body.appendChild(e),{show(t,i){n.textContent=t,r.textContent=i,e.classList.add(`skill-drop-overlay--visible`)},hide(){e.classList.remove(`skill-drop-overlay--visible`)}}}function wx(){let e=document.createElement(`div`);return e.className=`skill-drop-toast-container`,document.body.appendChild(e),(t,n)=>{let r=document.createElement(`div`);r.className=`skill-drop-toast skill-drop-toast--${n}`,r.textContent=t,e.appendChild(r),requestAnimationFrame(()=>r.classList.add(`skill-drop-toast--visible`)),window.setTimeout(()=>{r.classList.remove(`skill-drop-toast--visible`),window.setTimeout(()=>r.remove(),180)},4200)}}function Tx(e,t,n){let r=Cx(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ga(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ga(e.dataTransfer)&&(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`),a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragleave`,()=>{i!==0&&(i=Math.max(0,i-1),i===0&&!a&&r.hide())}),window.addEventListener(`dragend`,o),window.addEventListener(`blur`,o),window.addEventListener(`drop`,async s=>{let c=_a(s.dataTransfer);if(!c){o();return}if(s.preventDefault(),i=0,a){r.hide(),t(`Another .skill installation is already in progress.`,`error`);return}a=!0,r.show(`Installing skill…`,c.name);try{let r=await de(e,c);await n(),t(`Installed "${r.skillName}" to ${r.destinationPath} (${r.fileCount} files). Run "skill install ${r.skillName}" to apply it.`,`success`)}catch(e){t(`Failed to install dropped skill: ${e instanceof Error?e.message:String(e)}`,`error`)}finally{a=!1,r.hide()}})}async function Ex(e){let{OffscreenClient:t}=await r(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-BMlTH2Sh.js`);return{OffscreenClient:e}},__vite__mapDeps([24,17])),{VirtualFS:n}=await r(async()=>{let{VirtualFS:e}=await import(`./fs-CjCas3-3.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([22,4,17])),i=new $i(e,!0);window.__slicc_debug_tabs=e=>i.setDebugTabs(e),await i.panels.chat.initSession(`session-cone`);let a=null,o=await n.create({dbName:`slicc-fs`});i.panels.fileBrowser.setFs(o),$.info(`File browser wired to shared VFS (local IndexedDB)`);let s=new BroadcastChannel(`preview-vfs`);s.onmessage=e=>{if(e.data?.type!==`preview-vfs-read`)return;let{id:t,path:n,asText:r}=e.data;(async()=>{try{let e=r?`utf-8`:`binary`,i=await o.readFile(n,{encoding:e});s.postMessage({type:`preview-vfs-response`,id:t,content:i})}catch(e){let r=e instanceof Error?e.message:String(e);r.includes(`ENOENT`)||$.error(`Preview VFS read failed`,{path:n,error:r}),s.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},Tx(o,wx(),async()=>{await i.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await r(async()=>{let{WasmShell:e}=await import(`./shell-BWdwGyuc.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await r(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-Dln7uDXr.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([25,4,1,17])),{fetchSecretEnvVars:a}=await r(async()=>{let{fetchSecretEnvVars:e}=await import(`./secret-env-CzfRNoJA.js`);return{fetchSecretEnvVars:e}},[]),s=new t;await s.connect();let c=new n(s),l=await a(),u=new e({fs:o,browserAPI:c,env:Object.keys(l).length>0?l:void 0});await i.panels.terminal.mountShell(u),$.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){$.warn(`Failed to mount shell to terminal`,e)}{let{registerSessionCostsProvider:e}=await r(async()=>{let{registerSessionCostsProvider:e}=await import(`./cost-command-DhUP8Ozj.js`).then(e=>e.t);return{registerSessionCostsProvider:e}},__vite__mapDeps([26,4]));e(()=>new Promise(e=>{chrome.runtime.sendMessage({source:`panel`,payload:{type:`get-session-costs`}},t=>{if(chrome.runtime.lastError||!t?.ok){e([]);return}e(t.costs??[])})}))}let l,u=new Set,d=e=>{i.setPendingHandoffCount(e.length),i.panels.chat.setPendingHandoffs(e)},f=async e=>{a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid),i.setScoopSwitcherSelected?.(e.jid),i.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=e.isCone?void 0:e.name;await i.panels.chat.switchToContext(t,!e.isCone,n),l.isProcessing(e.jid)&&i.panels.chat.setProcessing(!0)};l=new t({onStatusChange:(e,t)=>{i.panels.scoops.updateScoopStatus(e,t),i.updateScoopSwitcherStatus?.(e,t),a?.jid===e&&(i.setAgentProcessing(t===`processing`),t===`processing`?i.panels.chat.setProcessing(!0):t===`ready`&&i.panels.chat.setProcessing(!1))},onScoopCreated:e=>{i.panels.scoops.refreshScoops(),i.refreshScoopSwitcher?.(),a||(a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid))},onScoopListUpdate:()=>{let e=new Set(l.getScoops().map(e=>e.folder));for(let t of u)e.has(t)||i.panels.chat.deleteSessionById(`session-${t}`);if(u=e,i.panels.scoops.refreshScoops(),i.refreshScoopSwitcher?.(),!a){let e=l.getScoops().find(e=>e.isCone);e&&(a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid))}},onIncomingMessage:(e,t)=>{if(a?.jid===e){let e=t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content;i.panels.chat.addUserMessage(e)}},onPendingHandoffsChange:d,onReady:async()=>{try{$.info(`Offscreen engine ready, scoop count:`,l.getScoops().length),window.localStorage.getItem(`slicc.trayJoinUrl`)&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`refresh-tray-runtime`}}).catch(()=>{});let e=a??l.getScoops().find(e=>e.isCone)??l.getScoops()[0];e&&(a=e,l.selectedScoopJid=e.jid,await f(e))}catch(e){$.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),l.setLocalFS(o);let p=l.createAgentHandle();i.panels.chat.setAgent(p),i.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=l.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await f(t),i.setActiveTab(`chat`),p.sendMessage(gx(e),`handoff-${e.handoffId}`),l.acceptPendingHandoff(e.handoffId)},onDismiss:e=>{l.dismissPendingHandoff(e.handoffId)}}),l.requestPendingHandoffs(),i.panels.scoops.setOrchestrator(l),i.panels.memory.setOrchestrator(l),i.setScoopSwitcherOrchestrator?.(l),i.onScoopSelect=f,i.onModelChange=e=>{localStorage.setItem(`selected-model`,e),l.updateModel()},i.onClearChat=async()=>{let e=l.getScoops();for(let t of e){let e=t.isCone?`session-cone`:`session-${t.folder}`;await i.panels.chat.deleteSessionById(e)}l.clearAllMessages()},i.onClearFilesystem=async()=>{l.clearFilesystem()},i.panels.chat.onInlineSprinkleLick=(e,t)=>{l.sendSprinkleLick(`inline`,{action:e,data:t})};let m=new mx(o,async e=>{if(e.type===`sprinkle`){if(e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&o.writeFile(`/shared/.welcomed`,`1`).catch(e=>$.warn(`Failed to persist welcome completion marker`,e)),n===`shortcut-migrate`&&m.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&Sx(o).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await xx(t),m.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),m.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}return}l.sendSprinkleLick(e.sprinkleName,e.body,e.targetScoop)}},{addSprinkle:(e,t,n,r)=>i.addSprinkle(e,t,n,r),removeSprinkle:e=>i.removeSprinkle(e)},()=>{let e=l.getScoops().find(e=>e.isCone);e&&l.stopScoop(e.jid)});if(window.__slicc_sprinkleManager=m,window.__slicc_reloadSkills=()=>(chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}}),Promise.resolve()),l.setSprinkleOpHandler(e=>{let{id:t,op:n,name:r,data:i}=e;console.log(`[main-ext] sprinkle-op handler called`,{id:t,op:n,name:r}),(async()=>{try{let e;switch(n){case`list`:await m.refresh(),e=m.available();break;case`opened`:e=m.opened();break;case`refresh`:await m.refresh(),e=m.available().length;break;case`open`:await m.open(r),e=!0;break;case`close`:m.close(r),e=!0;break;case`send`:m.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await m.openNewAutoOpenSprinkles(),e=!0;break}console.log(`[main-ext] sprinkle-op response sending`,{id:t,op:n,result:typeof e}),chrome.runtime.sendMessage({source:`panel`,payload:{type:`sprinkle-op-response`,id:t,result:e}}).catch(()=>{})}catch(e){chrome.runtime.sendMessage({source:`panel`,payload:{type:`sprinkle-op-response`,id:t,error:e instanceof Error?e.message:String(e)}}).catch(()=>{})}})()}),await m.refresh(),i.onSprinkleClose=e=>m.close(e),i.getAvailableSprinkles=()=>{let e=new Set(m.opened());return m.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},i.onOpenSprinkle=(e,t)=>m.open(e,t),i.updateAddButtons(),await m.restoreOpenSprinkles(),!await o.exists(`/shared/.welcomed`)&&localStorage.getItem(`slicc-welcomed`)&&(await o.writeFile(`/shared/.welcomed`,`1`).catch(()=>{}),localStorage.removeItem(`slicc-welcomed`)),!await o.exists(`/shared/.welcomed`)&&!c(window.localStorage)&&m.available().some(e=>e.name===`welcome`))try{await m.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}$.info(`SprinkleManager initialized (extension mode)`),l.requestState(),$.info(`Extension UI connected to offscreen agent engine`),Lv().catch(()=>{})}function Dx(){if(typeof chrome<`u`&&chrome?.runtime?.id)return;let e=new Blob([`
13110
+ `)}function _x(e,t){return e.receivedAt.localeCompare(t.receivedAt)}var vx=class{onPendingHandoffsChange;pendingByHandoffId=new Map;constructor(e){this.onPendingHandoffsChange=e.onPendingHandoffsChange}injectHandoff(e,t=`local`){let n=`injected-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.pendingByHandoffId.set(n,{handoffId:n,sourceUrl:t,payload:e,receivedAt:new Date().toISOString()}),this.emitChange(),n}clearHandoff(e){let t=this.pendingByHandoffId.get(e)??null;return this.pendingByHandoffId.delete(e),t&&this.emitChange(),{handoff:t,targetIds:[]}}emitChange(){this.onPendingHandoffsChange?.([...this.pendingByHandoffId.values()].sort(_x))}},$=n(`main`),yx=`slicc-pending-mount`,bx=`pendingMount`;async function xx(e){let t=await new Promise((e,t)=>{let n=indexedDB.open(yx,1);n.onupgradeneeded=()=>n.result.createObjectStore(`handles`),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),n=t.transaction(`handles`,`readwrite`);n.objectStore(`handles`).put(e,bx),await new Promise(e=>n.oncomplete=()=>e()),t.close()}async function Sx(e){let t;try{t=await new Promise((e,t)=>{let n=indexedDB.open(yx,1);n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}catch{return}let n=t.transaction(`handles`,`readwrite`),r=await new Promise(e=>{let t=n.objectStore(`handles`).get(bx);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)});if(r){n.objectStore(`handles`).delete(bx),await new Promise(e=>n.oncomplete=()=>e());let t=`/mnt/${r.name}`;await e.mount(t,r),$.info(`Mounted folder from welcome onboarding`,{name:r.name,path:t})}t.close()}function Cx(){let e=document.createElement(`div`);e.className=`skill-drop-overlay`;let t=document.createElement(`div`);t.className=`skill-drop-overlay__card`;let n=document.createElement(`div`);n.className=`skill-drop-overlay__title`,t.appendChild(n);let r=document.createElement(`div`);return r.className=`skill-drop-overlay__desc`,t.appendChild(r),e.appendChild(t),document.body.appendChild(e),{show(t,i){n.textContent=t,r.textContent=i,e.classList.add(`skill-drop-overlay--visible`)},hide(){e.classList.remove(`skill-drop-overlay--visible`)}}}function wx(){let e=document.createElement(`div`);return e.className=`skill-drop-toast-container`,document.body.appendChild(e),(t,n)=>{let r=document.createElement(`div`);r.className=`skill-drop-toast skill-drop-toast--${n}`,r.textContent=t,e.appendChild(r),requestAnimationFrame(()=>r.classList.add(`skill-drop-toast--visible`)),window.setTimeout(()=>{r.classList.remove(`skill-drop-toast--visible`),window.setTimeout(()=>r.remove(),180)},4200)}}function Tx(e,t,n){let r=Cx(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ga(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ga(e.dataTransfer)&&(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`),a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragleave`,()=>{i!==0&&(i=Math.max(0,i-1),i===0&&!a&&r.hide())}),window.addEventListener(`dragend`,o),window.addEventListener(`blur`,o),window.addEventListener(`drop`,async s=>{let c=_a(s.dataTransfer);if(!c){o();return}if(s.preventDefault(),i=0,a){r.hide(),t(`Another .skill installation is already in progress.`,`error`);return}a=!0,r.show(`Installing skill…`,c.name);try{let r=await de(e,c);await n(),t(`Installed "${r.skillName}" to ${r.destinationPath} (${r.fileCount} files). Run "skill install ${r.skillName}" to apply it.`,`success`)}catch(e){t(`Failed to install dropped skill: ${e instanceof Error?e.message:String(e)}`,`error`)}finally{a=!1,r.hide()}})}async function Ex(e){let{OffscreenClient:t}=await r(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-BMlTH2Sh.js`);return{OffscreenClient:e}},__vite__mapDeps([24,17])),{VirtualFS:n}=await r(async()=>{let{VirtualFS:e}=await import(`./fs-CjCas3-3.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([22,4,17])),i=new $i(e,!0);window.__slicc_debug_tabs=e=>i.setDebugTabs(e),await i.panels.chat.initSession(`session-cone`);let a=null,o=await n.create({dbName:`slicc-fs`});i.panels.fileBrowser.setFs(o),$.info(`File browser wired to shared VFS (local IndexedDB)`);let s=new BroadcastChannel(`preview-vfs`);s.onmessage=e=>{if(e.data?.type!==`preview-vfs-read`)return;let{id:t,path:n,asText:r}=e.data;(async()=>{try{let e=r?`utf-8`:`binary`,i=await o.readFile(n,{encoding:e});s.postMessage({type:`preview-vfs-response`,id:t,content:i})}catch(e){let r=e instanceof Error?e.message:String(e);r.includes(`ENOENT`)||$.error(`Preview VFS read failed`,{path:n,error:r}),s.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},Tx(o,wx(),async()=>{await i.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await r(async()=>{let{WasmShell:e}=await import(`./shell-zRiJffsM.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await r(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-Dln7uDXr.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([25,4,1,17])),{fetchSecretEnvVars:a}=await r(async()=>{let{fetchSecretEnvVars:e}=await import(`./secret-env-B32GVtBN.js`);return{fetchSecretEnvVars:e}},[]),s=new t;await s.connect();let c=new n(s),l=await a(),u=new e({fs:o,browserAPI:c,env:Object.keys(l).length>0?l:void 0});await i.panels.terminal.mountShell(u),$.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){$.warn(`Failed to mount shell to terminal`,e)}{let{registerSessionCostsProvider:e}=await r(async()=>{let{registerSessionCostsProvider:e}=await import(`./cost-command-DhUP8Ozj.js`).then(e=>e.t);return{registerSessionCostsProvider:e}},__vite__mapDeps([26,4]));e(()=>new Promise(e=>{chrome.runtime.sendMessage({source:`panel`,payload:{type:`get-session-costs`}},t=>{if(chrome.runtime.lastError||!t?.ok){e([]);return}e(t.costs??[])})}))}let l,u=new Set,d=e=>{i.setPendingHandoffCount(e.length),i.panels.chat.setPendingHandoffs(e)},f=async e=>{a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid),i.setScoopSwitcherSelected?.(e.jid),i.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=e.isCone?void 0:e.name;await i.panels.chat.switchToContext(t,!e.isCone,n),l.isProcessing(e.jid)&&i.panels.chat.setProcessing(!0)};l=new t({onStatusChange:(e,t)=>{i.panels.scoops.updateScoopStatus(e,t),i.updateScoopSwitcherStatus?.(e,t),a?.jid===e&&(i.setAgentProcessing(t===`processing`),t===`processing`?i.panels.chat.setProcessing(!0):t===`ready`&&i.panels.chat.setProcessing(!1))},onScoopCreated:e=>{i.panels.scoops.refreshScoops(),i.refreshScoopSwitcher?.(),a||(a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid))},onScoopListUpdate:()=>{let e=new Set(l.getScoops().map(e=>e.folder));for(let t of u)e.has(t)||i.panels.chat.deleteSessionById(`session-${t}`);if(u=e,i.panels.scoops.refreshScoops(),i.refreshScoopSwitcher?.(),!a){let e=l.getScoops().find(e=>e.isCone);e&&(a=e,l.selectedScoopJid=e.jid,i.panels.memory.setSelectedScoop(e.jid))}},onIncomingMessage:(e,t)=>{if(a?.jid===e){let e=t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content;i.panels.chat.addUserMessage(e)}},onPendingHandoffsChange:d,onReady:async()=>{try{$.info(`Offscreen engine ready, scoop count:`,l.getScoops().length),window.localStorage.getItem(`slicc.trayJoinUrl`)&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`refresh-tray-runtime`}}).catch(()=>{});let e=a??l.getScoops().find(e=>e.isCone)??l.getScoops()[0];e&&(a=e,l.selectedScoopJid=e.jid,await f(e))}catch(e){$.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),l.setLocalFS(o);let p=l.createAgentHandle();i.panels.chat.setAgent(p),i.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=l.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await f(t),i.setActiveTab(`chat`),p.sendMessage(gx(e),`handoff-${e.handoffId}`),l.acceptPendingHandoff(e.handoffId)},onDismiss:e=>{l.dismissPendingHandoff(e.handoffId)}}),l.requestPendingHandoffs(),i.panels.scoops.setOrchestrator(l),i.panels.memory.setOrchestrator(l),i.setScoopSwitcherOrchestrator?.(l),i.onScoopSelect=f,i.onModelChange=e=>{localStorage.setItem(`selected-model`,e),l.updateModel()},i.onClearChat=async()=>{let e=l.getScoops();for(let t of e){let e=t.isCone?`session-cone`:`session-${t.folder}`;await i.panels.chat.deleteSessionById(e)}l.clearAllMessages()},i.onClearFilesystem=async()=>{l.clearFilesystem()},i.panels.chat.onInlineSprinkleLick=(e,t)=>{l.sendSprinkleLick(`inline`,{action:e,data:t})};let m=new mx(o,async e=>{if(e.type===`sprinkle`){if(e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&o.writeFile(`/shared/.welcomed`,`1`).catch(e=>$.warn(`Failed to persist welcome completion marker`,e)),n===`shortcut-migrate`&&m.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&Sx(o).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await xx(t),m.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),m.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}return}l.sendSprinkleLick(e.sprinkleName,e.body,e.targetScoop)}},{addSprinkle:(e,t,n,r)=>i.addSprinkle(e,t,n,r),removeSprinkle:e=>i.removeSprinkle(e)},()=>{let e=l.getScoops().find(e=>e.isCone);e&&l.stopScoop(e.jid)});if(window.__slicc_sprinkleManager=m,window.__slicc_reloadSkills=()=>(chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}}),Promise.resolve()),l.setSprinkleOpHandler(e=>{let{id:t,op:n,name:r,data:i}=e;console.log(`[main-ext] sprinkle-op handler called`,{id:t,op:n,name:r}),(async()=>{try{let e;switch(n){case`list`:await m.refresh(),e=m.available();break;case`opened`:e=m.opened();break;case`refresh`:await m.refresh(),e=m.available().length;break;case`open`:await m.open(r),e=!0;break;case`close`:m.close(r),e=!0;break;case`send`:m.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await m.openNewAutoOpenSprinkles(),e=!0;break}console.log(`[main-ext] sprinkle-op response sending`,{id:t,op:n,result:typeof e}),chrome.runtime.sendMessage({source:`panel`,payload:{type:`sprinkle-op-response`,id:t,result:e}}).catch(()=>{})}catch(e){chrome.runtime.sendMessage({source:`panel`,payload:{type:`sprinkle-op-response`,id:t,error:e instanceof Error?e.message:String(e)}}).catch(()=>{})}})()}),await m.refresh(),i.onSprinkleClose=e=>m.close(e),i.getAvailableSprinkles=()=>{let e=new Set(m.opened());return m.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},i.onOpenSprinkle=(e,t)=>m.open(e,t),i.updateAddButtons(),await m.restoreOpenSprinkles(),!await o.exists(`/shared/.welcomed`)&&localStorage.getItem(`slicc-welcomed`)&&(await o.writeFile(`/shared/.welcomed`,`1`).catch(()=>{}),localStorage.removeItem(`slicc-welcomed`)),!await o.exists(`/shared/.welcomed`)&&!c(window.localStorage)&&m.available().some(e=>e.name===`welcome`))try{await m.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}$.info(`SprinkleManager initialized (extension mode)`),l.requestState(),$.info(`Extension UI connected to offscreen agent engine`),Lv().catch(()=>{})}function Dx(){if(typeof chrome<`u`&&chrome?.runtime?.id)return;let e=new Blob([`
13111
13111
  let lastPong = Date.now();
13112
13112
  let frozen = false;
13113
13113
  setInterval(() => {
@@ -13135,4 +13135,4 @@ ${t}
13135
13135
  #app > .tab-content > .tab-content__panel {
13136
13136
  height: 100%;
13137
13137
  }
13138
- `,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&ax(e.data)&&u.setActiveTab(ex(`http://localhost/?tab=${e.data.tab??``}`))}),window.addEventListener(`keydown`,e=>{e.code===`Semicolon`&&(e.metaKey||e.ctrlKey)&&!e.shiftKey&&!e.altKey&&!e.repeat&&(e.preventDefault(),e.stopPropagation(),window.parent.postMessage({type:`slicc-electron-overlay:toggle`},`*`))},!0)}let f=wx();await u.panels.chat.initSession(`session-cone`),$.info(`Session initialized`);let p=new Se,m=e=>{u.setPendingHandoffCount(e.length),u.panels.chat.setPendingHandoffs(e)},h=new Set,_=e=>{$.debug(`Emit to UI`,{type:e.type,listenerCount:h.size});for(let t of h)try{t(e)}catch(t){$.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},v=null,y=new Map,b=new Map;function x(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function S(e){let t=b.get(e);return t||(t=[],b.set(e,t)),t}function C(e,t){let n=S(e),r=y.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${x()}`,y.set(e,r);let i=w.getScoops().find(t=>t.jid===e),a=i?.isCone?`cone`:i?.name??`unknown`,o={id:r,role:`assistant`,content:``,timestamp:Date.now(),toolCalls:[],isStreaming:!0,source:a,channel:t};return n.push(o),v?.jid===e&&_({type:`message_start`,messageId:r}),o}let w=new ab(u.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),v?.jid===e&&(_({type:`content_delta`,messageId:r.id,text:t}),n||_({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=S(e),n=y.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),v?.jid===e&&_({type:`content_done`,messageId:n}),y.delete(e)}},onSendMessage:(e,t)=>{$.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${x()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};w.handleMessage(r),S(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),v?.jid===e&&(_({type:`message_start`,messageId:n}),_({type:`content_delta`,messageId:n,text:t}),_({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(u.panels.scoops.updateScoopStatus(e,t),u.updateScoopSwitcherStatus?.(e,t),v?.jid===e){if(u.setAgentProcessing(t===`processing`),t===`processing`)u.panels.chat.setProcessing(!0);else if(t===`ready`){u.panels.chat.setProcessing(!1);let t=y.get(e)??`done-${e}-${x()}`;y.delete(e),_({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{$.error(`Scoop error`,{scoopJid:e,error:t}),v?.jid===e&&_({type:`error`,error:t})},getBrowserAPI:()=>p,onToolStart:(e,t,n)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let r=C(e);r.toolCalls||=[],r.toolCalls.push({id:x(),name:t,input:n}),v?.jid===e&&_({type:`tool_use_start`,messageId:r.id,toolName:t,toolInput:n})},onToolEnd:(e,t,n,r)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let i=S(e),a=y.get(e);if(a){let e=i.find(e=>e.id===a);if(e?.toolCalls){let i=[...e.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);i&&(i.result=n,i.isError=r)}}v?.jid===e&&a&&_({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=y.get(e);i?_({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):$.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=y.get(e);n&&_({type:`tool_ui_done`,messageId:n,requestId:t})},onIncomingMessage:(e,t)=>{let n={id:t.id,role:`user`,content:t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content,timestamp:new Date(t.timestamp).getTime(),source:t.channel===`delegation`?`delegation`:void 0,channel:t.channel};S(e).push(n),v?.jid===e&&(_({type:`message_start`,messageId:t.id}),_({type:`content_delta`,messageId:t.id,text:n.content}),_({type:`content_done`,messageId:t.id}))}});await w.init(),u.panels.scoops.setOrchestrator(w),u.panels.memory.setOrchestrator(w),u.setScoopSwitcherOrchestrator?.(w);let E=w.getSharedFS();if(E){u.panels.fileBrowser.setFs(E),$.info(`File browser wired to shared VFS`);let e=new BroadcastChannel(`preview-vfs`);e.onmessage=t=>{if(t.data?.type!==`preview-vfs-read`)return;let{id:n,path:r,asText:i}=t.data;(async()=>{try{let t=i?`utf-8`:`binary`,a=await E.readFile(r,{encoding:t});e.postMessage({type:`preview-vfs-response`,id:n,content:a})}catch(t){let i=t instanceof Error?t.message:String(t);i.includes(`ENOENT`)||$.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},Tx(E,(e,t)=>{t===`error`?$.warn(`Dropped skill install failed`,{message:e}):$.info(`Dropped skill installed`,{message:e}),f(e,t)},async()=>{await u.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await r(async()=>{let{WasmShell:e}=await import(`./shell-BWdwGyuc.js`);return{WasmShell:e}},[]),{fetchSecretEnvVars:t}=await r(async()=>{let{fetchSecretEnvVars:e}=await import(`./secret-env-CzfRNoJA.js`);return{fetchSecretEnvVars:e}},[]),n=await t(),i=new e({fs:E,browserAPI:p,env:Object.keys(n).length>0?n:void 0});await u.panels.terminal.mountShell(i),$.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await r(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-UyxqvRBs.js`);return{BshWatchdog:e}},__vite__mapDeps([27,17])),t=new e({browserAPI:p,scriptCatalog:i.getScriptCatalog(),fs:E});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),$.info(`BSH navigation watchdog started`)}catch(e){$.warn(`Failed to start BSH watchdog`,e)}}catch(e){$.warn(`Failed to mount shell to terminal`,e)}}let D=w.getScoops(),ee=D.some(e=>e.isCone);if(a)$.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!ee)v=await u.panels.scoops.createScoop(`Cone`,!0),$.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=D.find(t=>t.folder===e);t?(v=t,$.info(`Restored scoop from URL`,{folder:e})):v=D.find(e=>e.isCone)??D[0]}else v=D.find(e=>e.isCone)??D[0]}v&&u.panels.memory.setSelectedScoop(v.jid);let k=null,te=null,A={sendMessage(e,t){if(!v){_({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:v.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};S(v.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),k?.broadcastUserMessage(e,n.id),w.handleMessage(n),w.createScoopTab(v.jid)},onEvent(e){return h.add(e),()=>h.delete(e)},stop(){v&&(w.stopScoop(v.jid),w.clearQueuedMessages(v.jid).catch(e=>{$.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};u.panels.chat.setAgent(A),u.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=w.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await N(t),u.setActiveTab(`chat`),A.sendMessage(gx(e),`handoff-${e.handoffId}`);let n=te?.clearHandoff(e.handoffId);n&&await Promise.allSettled(n.targetIds.map(e=>p.closePage(e)))},onDismiss:async e=>{let t=te?.clearHandoff(e.handoffId);t&&await Promise.allSettled(t.targetIds.map(e=>p.closePage(e)))}}),u.panels.chat.setDeleteQueuedMessageCallback(e=>{if(v){w.deleteQueuedMessage(v.jid,e).catch(t=>{$.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=b.get(v.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),$.info(`Cone agent handle wired to chat UI`);let{getLickManager:ne}=await r(async()=>{let{getLickManager:e}=await import(`./lick-manager-CS6GCzeC.js`);return{getLickManager:e}},[]),ie=ne();await ie.init(),w.setLickManager(ie);let ae=e=>{let t=e.type===`webhook`,n=e.type===`sprinkle`,r=e.type===`fswatch`,i=e.type===`session-reload`,a=t?e.webhookName:n?e.sprinkleName:r?e.fswatchName:i?`session-reload`:e.cronName,o=t?e.webhookId:n?e.sprinkleName:r?e.fswatchId:i?`session-reload`:e.cronId,s=e.type;if($.debug(`Lick event`,{type:e.type,name:a,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&E?.writeFile(`/shared/.welcomed`,`1`).catch(e=>$.warn(`Failed to persist welcome marker`,e)),n===`shortcut-migrate`&&j?.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&E&&Sx(E).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(n&&e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){(async()=>{try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await xx(t),j?.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),j?.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}})();return}let c=w.getScoops(),l;if(l=e.targetScoop?c.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`):c.find(e=>e.isCone),l){let c=`${s}-${o}-${Date.now()}`,d=`[${t?`Webhook Event`:n?`Sprinkle Event`:r?`File Watch Event`:i?`Session Reload`:`Cron Event`}: ${a}]\n\`\`\`json\n${JSON.stringify(e.body,null,2)}\n\`\`\``,f={id:c,chatJid:l.jid,senderId:s,senderName:`${s}:${a}`,content:d,timestamp:e.timestamp,fromAssistant:!1,channel:s};S(l.jid).push({id:c,role:`user`,content:d,timestamp:Date.now(),source:`lick`,channel:s}),v?.jid===l.jid&&u.panels.chat.addLickMessage(c,d,s),$.info(`Routing lick to scoop`,{type:s,name:a,scoopJid:l.jid}),w.handleMessage(f)}else $.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};ie.setEventHandler(ae),E&&se().then(async e=>{if(e.length===0)return;let t=[];for(let{path:n,handle:r}of e)try{if(!(`queryPermission`in r)){t.push({path:n,dirName:r.name});continue}await r.queryPermission({mode:`readwrite`})===`granted`?(await E.mount(n,r),$.info(`Restored mount from previous session`,{path:n,name:r.name})):t.push({path:n,dirName:r.name})}catch{t.push({path:n,dirName:r.name})}t.length>0&&ae({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:t}})}).catch(e=>$.warn(`Failed to restore persisted mounts`,e)),u.panels.chat.onInlineSprinkleLick=(e,t)=>{ae({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let j=null;if(E){if(j=new mx(E,ae,{addSprinkle:(e,t,n,r)=>u.addSprinkle(e,t,n,r),removeSprinkle:e=>u.removeSprinkle(e)},()=>{let e=w.getScoops().find(e=>e.isCone);e&&(w.stopScoop(e.jid),w.clearQueuedMessages(e.jid).catch(e=>{$.error(`Failed to clear queued messages on sprinkle stopCone`,{error:e instanceof Error?e.message:String(e)})}))}),window.__slicc_sprinkleManager=j,window.__slicc_reloadSkills=()=>w.reloadAllSkills(),await j.refresh(),u.onSprinkleClose=e=>j.close(e),u.getAvailableSprinkles=()=>{let e=new Set(j.opened());return j.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},u.onOpenSprinkle=(e,t)=>j.open(e,t),u.updateAddButtons(),!await E.exists(`/shared/.welcomed`)&&localStorage.getItem(`slicc-welcomed`)&&(await E.writeFile(`/shared/.welcomed`,`1`).catch(()=>{}),localStorage.removeItem(`slicc-welcomed`)),!await E.exists(`/shared/.welcomed`)&&!a&&j.available().some(e=>e.name===`welcome`))try{await j.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}await j.restoreOpenSprinkles(),$.info(`SprinkleManager initialized`)}let M=()=>{let e=nx(window.location.href),t=new WebSocket(e);t.onopen=()=>{$.info(`Lick WebSocket connected`)},t.onmessage=async e=>{try{let n=JSON.parse(e.data);if(n.requestId){let e;try{switch(n.type){case`list_webhooks`:e={type:`response`,requestId:n.requestId,data:ie.listWebhooks()};break;case`create_webhook`:{let t=await ie.createWebhook(n.name||`default`,n.scoop,n.filter),r=Kp().session,i=r?.webhookUrl?ix(r.webhookUrl,t.id):rx(window.location.href,t.id);e={type:`response`,requestId:n.requestId,data:{...t,url:i}};break}case`delete_webhook`:e=await ie.deleteWebhook(n.id)?{type:`response`,requestId:n.requestId,data:{ok:!0}}:{type:`response`,requestId:n.requestId,data:{error:`Webhook not found`}};break;case`list_crontasks`:e={type:`response`,requestId:n.requestId,data:ie.listCronTasks()};break;case`create_crontask`:{if(!n.name)throw Error(`name is required`);if(!n.cron)throw Error(`cron is required`);let t=await ie.createCronTask(n.name,n.cron,n.scoop,n.filter);e={type:`response`,requestId:n.requestId,data:t};break}case`delete_crontask`:e=await ie.deleteCronTask(n.id)?{type:`response`,requestId:n.requestId,data:{ok:!0}}:{type:`response`,requestId:n.requestId,data:{error:`Cron task not found`}};break;case`tray_status`:{let t=Kp();e={type:`response`,requestId:n.requestId,data:{state:t.state,joinUrl:t.session?.joinUrl??null,workerBaseUrl:t.session?.workerBaseUrl??null,trayId:t.session?.trayId??null}};break}default:e={type:`response`,requestId:n.requestId,error:`Unknown request type: ${n.type}`}}}catch(t){e={type:`response`,requestId:n.requestId,error:t instanceof Error?t.message:String(t)}}t.send(JSON.stringify(e));return}n.type===`webhook_event`&&ie.handleWebhookEvent(n.webhookId,n.headers,n.body),n.type===`handoff_event`&&te&&te.injectHandoff(n.payload,n.sourceUrl)}catch(e){$.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{$.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(M,3e3)},t.onerror=e=>{$.error(`Lick WebSocket error`,{error:String(e)})}};M(),u.onModelChange=e=>{localStorage.setItem(`selected-model`,e),w.updateModel()},u.onClearChat=async()=>{await w.clearAllMessages(),b.clear()},u.onClearFilesystem=async()=>{await w.resetFilesystem()};let N=async e=>{$.info(`Scoop selected`,{jid:e.jid,name:e.name}),v=e,w.createScoopTab(e.jid),u.panels.memory.setSelectedScoop(e.jid),u.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=b.get(e.jid),r=e.isCone?void 0:e.name;if(n&&n.length>0)await u.panels.chat.switchToContext(t,!e.isCone,r),u.panels.chat.loadMessages(n);else if(await u.panels.chat.switchToContext(t,!e.isCone,r),u.panels.chat.getMessages().length===0){let t=await w.getMessagesForScoop(e.jid);for(let n of t){let t=n.channel===`webhook`||n.channel===`cron`,r=n.channel===`delegation`;if(t){let t={id:n.id,role:`user`,content:n.content,timestamp:new Date(n.timestamp).getTime(),source:`lick`,channel:n.channel};S(e.jid).push(t),u.panels.chat.addUserMessage(n.content)}else if(r){let t={id:n.id,role:`user`,content:`**[Instructions from sliccy]**\n\n${n.content}`,timestamp:new Date(n.timestamp).getTime(),source:`delegation`,channel:`delegation`};S(e.jid).push(t),u.panels.chat.addUserMessage(t.content)}else n.fromAssistant?(_({type:`message_start`,messageId:n.id}),_({type:`content_delta`,messageId:n.id,text:n.content}),_({type:`content_done`,messageId:n.id})):u.panels.chat.addUserMessage(n.content)}}e.isCone&&w.isProcessing(e.jid)&&u.panels.chat.setProcessing(!0)};if(u.onScoopSelect=N,v&&(w.createScoopTab(v.jid),await N(v)),te=new vx({onPendingHandoffsChange:m}),l===`standalone`||l===`electron-overlay`){let e=await i(),t=$b(l,e!==null)?s:null,n=await g({locationHref:window.location.href,storage:window.localStorage,envBaseUrl:null,defaultWorkerBaseUrl:t,runtimeConfigFetcher:async()=>e}),r=null,a=null,o=null;$h(()=>k?(e,t)=>k.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),Bf(()=>k?()=>k.getBestFollowerForTeleport():null),Vf(()=>k?()=>k.getConnectedFollowers():null);let c=e=>{o&&=(clearInterval(o),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new Zb(e.channel,{browserTransport:p.getTransport(),browserAPI:p,onSnapshot:e=>{u.panels.chat.loadMessages(e)},onUserMessage:e=>{u.panels.chat.addUserMessage(e)},onStatus:e=>{u.panels.chat.setProcessing(e===`processing`)},onTargetsChanged:()=>void i()});r=n,p.setTrayTargetProvider(n),u.panels.chat.setAgent(n),n.requestSnapshot();let i=async()=>{try{let e=await p.listPages();n.advertiseTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})),t)}catch{}};o=setInterval(i,5e3),i(),$.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},f=e=>{a?.cancel(),o&&=(clearInterval(o),null),r?.close(),r=null,a=Tb({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:em()},{onConnected:e=>c(e),onReconnecting:e=>{$.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{$.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{f(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{o&&clearInterval(o),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)f(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new Yb({browserTransport:p.getTransport(),browserAPI:p,getMessages:()=>u.panels.chat.getMessages(),getScoopJid:()=>v?.jid??`cone`,onFollowerMessage:(e,t)=>{u.panels.chat.addUserMessage(e),A.sendMessage(e,t)},onFollowerAbort:()=>{A.stop()}}),k=t,nm(()=>t.getConnectedFollowers()),p.setTrayTargetProvider(t),i&&clearInterval(i);let n=async()=>{try{let e=await p.listPages();t.setLocalTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})))}catch{}};i=setInterval(n,5e3),n(),r=new Cb({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{$.info(`Tray follower data channel opened`,{controllerId:e.controllerId,bootstrapId:e.bootstrapId,attempt:e.attempt,runtime:e.runtime}),t.addFollower(e.bootstrapId,n,{runtime:e.runtime,connectedAt:e.connectedAt??void 0})}})};a(),h.add(e=>{t.broadcastEvent(e)}),e=new Xp({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:em(),onControlMessage:e=>{if(e.type===`webhook.event`){ie.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{$.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),am(async()=>{t.stop(),r.stop(),e.stop(),await e.clearSession();let n=await e.start(),i=d(window.location.href,n.workerBaseUrl,n.trayId);return i!==window.location.href&&window.history.replaceState(window.history.state,``,i),a(),Kp()}),e.start().then(e=>{let t=d(window.location.href,e.workerBaseUrl,e.trayId);t!==window.location.href&&window.history.replaceState(window.history.state,``,t)}).catch(e=>{$.warn(`Leader tray join failed`,{error:e instanceof Error?e.message:String(e)})}),window.addEventListener(`beforeunload`,()=>{clearInterval(i),t.stop(),r.stop(),e.stop()},{once:!0})}}$.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:w.getScoops().length}),Lv().catch(()=>{})}Ox().catch(e=>{$.error(`Fatal error`,e);let t=document.getElementById(`app`);if(t){let n=document.createElement(`div`);n.style.cssText=`padding: 2rem; text-align: center;`;let r=document.createElement(`h1`);r.style.color=`var(--s2-negative, #e34850)`,r.textContent=`Failed to start`;let i=document.createElement(`p`);i.style.color=`var(--s2-content-tertiary, #717171)`,i.textContent=e.message,n.appendChild(r),n.appendChild(i);let a=document.createElement(`button`);for(a.textContent=`Reset all data & reload`,a.style.cssText=`margin-top: 1rem; padding: 0.5rem 1.5rem; background: var(--s2-negative, #e34850); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 14px;`,a.addEventListener(`click`,async()=>{a.disabled=!0,a.textContent=`Resetting…`;let e=await indexedDB.databases();await Promise.all(e.map(e=>e.name?new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()}):Promise.resolve())),location.reload()}),n.appendChild(a);t.firstChild;)t.removeChild(t.firstChild);t.appendChild(n)}});export{Xv as a,ci as c,qy as i,ai as l,tb as n,Ta as o,rb as r,oi as s,eb as t};
13138
+ `,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&ax(e.data)&&u.setActiveTab(ex(`http://localhost/?tab=${e.data.tab??``}`))}),window.addEventListener(`keydown`,e=>{e.code===`Semicolon`&&(e.metaKey||e.ctrlKey)&&!e.shiftKey&&!e.altKey&&!e.repeat&&(e.preventDefault(),e.stopPropagation(),window.parent.postMessage({type:`slicc-electron-overlay:toggle`},`*`))},!0)}let f=wx();await u.panels.chat.initSession(`session-cone`),$.info(`Session initialized`);let p=new Se,m=e=>{u.setPendingHandoffCount(e.length),u.panels.chat.setPendingHandoffs(e)},h=new Set,_=e=>{$.debug(`Emit to UI`,{type:e.type,listenerCount:h.size});for(let t of h)try{t(e)}catch(t){$.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},v=null,y=new Map,b=new Map;function x(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function S(e){let t=b.get(e);return t||(t=[],b.set(e,t)),t}function C(e,t){let n=S(e),r=y.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${x()}`,y.set(e,r);let i=w.getScoops().find(t=>t.jid===e),a=i?.isCone?`cone`:i?.name??`unknown`,o={id:r,role:`assistant`,content:``,timestamp:Date.now(),toolCalls:[],isStreaming:!0,source:a,channel:t};return n.push(o),v?.jid===e&&_({type:`message_start`,messageId:r}),o}let w=new ab(u.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),v?.jid===e&&(_({type:`content_delta`,messageId:r.id,text:t}),n||_({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=S(e),n=y.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),v?.jid===e&&_({type:`content_done`,messageId:n}),y.delete(e)}},onSendMessage:(e,t)=>{$.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${x()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};w.handleMessage(r),S(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),v?.jid===e&&(_({type:`message_start`,messageId:n}),_({type:`content_delta`,messageId:n,text:t}),_({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(u.panels.scoops.updateScoopStatus(e,t),u.updateScoopSwitcherStatus?.(e,t),v?.jid===e){if(u.setAgentProcessing(t===`processing`),t===`processing`)u.panels.chat.setProcessing(!0);else if(t===`ready`){u.panels.chat.setProcessing(!1);let t=y.get(e)??`done-${e}-${x()}`;y.delete(e),_({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{$.error(`Scoop error`,{scoopJid:e,error:t}),v?.jid===e&&_({type:`error`,error:t})},getBrowserAPI:()=>p,onToolStart:(e,t,n)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let r=C(e);r.toolCalls||=[],r.toolCalls.push({id:x(),name:t,input:n}),v?.jid===e&&_({type:`tool_use_start`,messageId:r.id,toolName:t,toolInput:n})},onToolEnd:(e,t,n,r)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let i=S(e),a=y.get(e);if(a){let e=i.find(e=>e.id===a);if(e?.toolCalls){let i=[...e.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);i&&(i.result=n,i.isError=r)}}v?.jid===e&&a&&_({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=y.get(e);i?_({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):$.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=y.get(e);n&&_({type:`tool_ui_done`,messageId:n,requestId:t})},onIncomingMessage:(e,t)=>{let n={id:t.id,role:`user`,content:t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content,timestamp:new Date(t.timestamp).getTime(),source:t.channel===`delegation`?`delegation`:void 0,channel:t.channel};S(e).push(n),v?.jid===e&&(_({type:`message_start`,messageId:t.id}),_({type:`content_delta`,messageId:t.id,text:n.content}),_({type:`content_done`,messageId:t.id}))}});await w.init(),u.panels.scoops.setOrchestrator(w),u.panels.memory.setOrchestrator(w),u.setScoopSwitcherOrchestrator?.(w);let E=w.getSharedFS();if(E){u.panels.fileBrowser.setFs(E),$.info(`File browser wired to shared VFS`);let e=new BroadcastChannel(`preview-vfs`);e.onmessage=t=>{if(t.data?.type!==`preview-vfs-read`)return;let{id:n,path:r,asText:i}=t.data;(async()=>{try{let t=i?`utf-8`:`binary`,a=await E.readFile(r,{encoding:t});e.postMessage({type:`preview-vfs-response`,id:n,content:a})}catch(t){let i=t instanceof Error?t.message:String(t);i.includes(`ENOENT`)||$.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},Tx(E,(e,t)=>{t===`error`?$.warn(`Dropped skill install failed`,{message:e}):$.info(`Dropped skill installed`,{message:e}),f(e,t)},async()=>{await u.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await r(async()=>{let{WasmShell:e}=await import(`./shell-zRiJffsM.js`);return{WasmShell:e}},[]),{fetchSecretEnvVars:t}=await r(async()=>{let{fetchSecretEnvVars:e}=await import(`./secret-env-B32GVtBN.js`);return{fetchSecretEnvVars:e}},[]),n=await t(),i=new e({fs:E,browserAPI:p,env:Object.keys(n).length>0?n:void 0});await u.panels.terminal.mountShell(i),$.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await r(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-UyxqvRBs.js`);return{BshWatchdog:e}},__vite__mapDeps([27,17])),t=new e({browserAPI:p,scriptCatalog:i.getScriptCatalog(),fs:E});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),$.info(`BSH navigation watchdog started`)}catch(e){$.warn(`Failed to start BSH watchdog`,e)}}catch(e){$.warn(`Failed to mount shell to terminal`,e)}}let D=w.getScoops(),ee=D.some(e=>e.isCone);if(a)$.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!ee)v=await u.panels.scoops.createScoop(`Cone`,!0),$.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=D.find(t=>t.folder===e);t?(v=t,$.info(`Restored scoop from URL`,{folder:e})):v=D.find(e=>e.isCone)??D[0]}else v=D.find(e=>e.isCone)??D[0]}v&&u.panels.memory.setSelectedScoop(v.jid);let k=null,te=null,A={sendMessage(e,t){if(!v){_({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:v.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};S(v.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),k?.broadcastUserMessage(e,n.id),w.handleMessage(n),w.createScoopTab(v.jid)},onEvent(e){return h.add(e),()=>h.delete(e)},stop(){v&&(w.stopScoop(v.jid),w.clearQueuedMessages(v.jid).catch(e=>{$.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};u.panels.chat.setAgent(A),u.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=w.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await oe(t),u.setActiveTab(`chat`),A.sendMessage(gx(e),`handoff-${e.handoffId}`);let n=te?.clearHandoff(e.handoffId);n&&await Promise.allSettled(n.targetIds.map(e=>p.closePage(e)))},onDismiss:async e=>{let t=te?.clearHandoff(e.handoffId);t&&await Promise.allSettled(t.targetIds.map(e=>p.closePage(e)))}}),u.panels.chat.setDeleteQueuedMessageCallback(e=>{if(v){w.deleteQueuedMessage(v.jid,e).catch(t=>{$.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=b.get(v.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),$.info(`Cone agent handle wired to chat UI`);let{getLickManager:ne}=await r(async()=>{let{getLickManager:e}=await import(`./lick-manager-BVqr-e_y.js`);return{getLickManager:e}},[]),ie=ne();await ie.init(),w.setLickManager(ie);let ae=e=>{let t=e.type===`webhook`,n=e.type===`sprinkle`,r=e.type===`fswatch`,i=e.type===`session-reload`,a=t?e.webhookName:n?e.sprinkleName:r?e.fswatchName:i?`session-reload`:e.cronName,o=t?e.webhookId:n?e.sprinkleName:r?e.fswatchId:i?`session-reload`:e.cronId,s=e.type;if($.debug(`Lick event`,{type:e.type,name:a,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&E?.writeFile(`/shared/.welcomed`,`1`).catch(e=>$.warn(`Failed to persist welcome marker`,e)),n===`shortcut-migrate`&&j?.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&E&&Sx(E).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(n&&e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){(async()=>{try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await xx(t),j?.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),j?.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}})();return}let c=w.getScoops(),l;if(l=e.targetScoop?c.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`):c.find(e=>e.isCone),l){let c=`${s}-${o}-${Date.now()}`,d=`[${t?`Webhook Event`:n?`Sprinkle Event`:r?`File Watch Event`:i?`Session Reload`:`Cron Event`}: ${a}]\n\`\`\`json\n${JSON.stringify(e.body,null,2)}\n\`\`\``,f={id:c,chatJid:l.jid,senderId:s,senderName:`${s}:${a}`,content:d,timestamp:e.timestamp,fromAssistant:!1,channel:s};S(l.jid).push({id:c,role:`user`,content:d,timestamp:Date.now(),source:`lick`,channel:s}),v?.jid===l.jid&&u.panels.chat.addLickMessage(c,d,s),$.info(`Routing lick to scoop`,{type:s,name:a,scoopJid:l.jid}),w.handleMessage(f)}else $.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};ie.setEventHandler(ae),E&&se().then(async e=>{if(e.length===0)return;let t=[];for(let{path:n,handle:r}of e)try{if(!(`queryPermission`in r)){t.push({path:n,dirName:r.name});continue}await r.queryPermission({mode:`readwrite`})===`granted`?(await E.mount(n,r),$.info(`Restored mount from previous session`,{path:n,name:r.name})):t.push({path:n,dirName:r.name})}catch{t.push({path:n,dirName:r.name})}t.length>0&&ae({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:t}})}).catch(e=>$.warn(`Failed to restore persisted mounts`,e)),u.panels.chat.onInlineSprinkleLick=(e,t)=>{ae({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let j=null;if(E){if(j=new mx(E,ae,{addSprinkle:(e,t,n,r)=>u.addSprinkle(e,t,n,r),removeSprinkle:e=>u.removeSprinkle(e)},()=>{let e=w.getScoops().find(e=>e.isCone);e&&(w.stopScoop(e.jid),w.clearQueuedMessages(e.jid).catch(e=>{$.error(`Failed to clear queued messages on sprinkle stopCone`,{error:e instanceof Error?e.message:String(e)})}))}),window.__slicc_sprinkleManager=j,window.__slicc_reloadSkills=()=>w.reloadAllSkills(),await j.refresh(),u.onSprinkleClose=e=>j.close(e),u.getAvailableSprinkles=()=>{let e=new Set(j.opened());return j.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},u.onOpenSprinkle=(e,t)=>j.open(e,t),u.updateAddButtons(),!await E.exists(`/shared/.welcomed`)&&localStorage.getItem(`slicc-welcomed`)&&(await E.writeFile(`/shared/.welcomed`,`1`).catch(()=>{}),localStorage.removeItem(`slicc-welcomed`)),!await E.exists(`/shared/.welcomed`)&&!a&&j.available().some(e=>e.name===`welcome`))try{await j.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}await j.restoreOpenSprinkles(),$.info(`SprinkleManager initialized`)}let M=()=>{let e=nx(window.location.href),t=new WebSocket(e);t.onopen=()=>{$.info(`Lick WebSocket connected`)},t.onmessage=async e=>{try{let n=JSON.parse(e.data);if(n.requestId){let e;try{switch(n.type){case`list_webhooks`:e={type:`response`,requestId:n.requestId,data:ie.listWebhooks()};break;case`create_webhook`:{let t=await ie.createWebhook(n.name||`default`,n.scoop,n.filter),r=Kp().session,i=r?.webhookUrl?ix(r.webhookUrl,t.id):rx(window.location.href,t.id);e={type:`response`,requestId:n.requestId,data:{...t,url:i}};break}case`delete_webhook`:e=await ie.deleteWebhook(n.id)?{type:`response`,requestId:n.requestId,data:{ok:!0}}:{type:`response`,requestId:n.requestId,data:{error:`Webhook not found`}};break;case`list_crontasks`:e={type:`response`,requestId:n.requestId,data:ie.listCronTasks()};break;case`create_crontask`:{if(!n.name)throw Error(`name is required`);if(!n.cron)throw Error(`cron is required`);let t=await ie.createCronTask(n.name,n.cron,n.scoop,n.filter);e={type:`response`,requestId:n.requestId,data:t};break}case`delete_crontask`:e=await ie.deleteCronTask(n.id)?{type:`response`,requestId:n.requestId,data:{ok:!0}}:{type:`response`,requestId:n.requestId,data:{error:`Cron task not found`}};break;case`tray_status`:{let t=Kp();e={type:`response`,requestId:n.requestId,data:{state:t.state,joinUrl:t.session?.joinUrl??null,workerBaseUrl:t.session?.workerBaseUrl??null,trayId:t.session?.trayId??null}};break}default:e={type:`response`,requestId:n.requestId,error:`Unknown request type: ${n.type}`}}}catch(t){e={type:`response`,requestId:n.requestId,error:t instanceof Error?t.message:String(t)}}t.send(JSON.stringify(e));return}n.type===`webhook_event`&&ie.handleWebhookEvent(n.webhookId,n.headers,n.body),n.type===`handoff_event`&&te&&te.injectHandoff(n.payload,n.sourceUrl)}catch(e){$.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{$.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(M,3e3)},t.onerror=e=>{$.error(`Lick WebSocket error`,{error:String(e)})}};M(),u.onModelChange=e=>{localStorage.setItem(`selected-model`,e),w.updateModel()};let N=new Set;u.onClearChat=async()=>{await w.clearAllMessages(),b.clear(),N.clear()},u.onClearFilesystem=async()=>{await w.resetFilesystem()};let oe=async e=>{$.info(`Scoop selected`,{jid:e.jid,name:e.name}),v=e,w.createScoopTab(e.jid),u.panels.memory.setSelectedScoop(e.jid),u.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=b.get(e.jid),r=!N.has(e.jid),i=e.isCone?void 0:e.name;if(!r&&n&&n.length>0)await u.panels.chat.switchToContext(t,!e.isCone,i),u.panels.chat.loadMessages(n);else{if(await u.panels.chat.switchToContext(t,!e.isCone,i),u.panels.chat.getMessages().length===0){let t=await w.getMessagesForScoop(e.jid);for(let e of t){let t=e.channel===`webhook`||e.channel===`cron`,n=e.channel===`delegation`;t?u.panels.chat.addUserMessage(e.content):n?u.panels.chat.addUserMessage(`**[Instructions from sliccy]**\n\n${e.content}`):e.fromAssistant?(_({type:`message_start`,messageId:e.id}),_({type:`content_delta`,messageId:e.id,text:e.content}),_({type:`content_done`,messageId:e.id})):u.panels.chat.addUserMessage(e.content)}}let n=u.panels.chat.getMessages(),r=new Set(n.map(e=>e.id)),a=S(e.jid),o=a.filter(e=>!r.has(e.id));a.length=0,a.push(...n,...o),o.length>0&&u.panels.chat.loadMessages(a)}e.isCone&&w.isProcessing(e.jid)&&u.panels.chat.setProcessing(!0),N.add(e.jid)};if(u.onScoopSelect=oe,v&&(w.createScoopTab(v.jid),await oe(v)),te=new vx({onPendingHandoffsChange:m}),l===`standalone`||l===`electron-overlay`){let e=await i(),t=$b(l,e!==null)?s:null,n=await g({locationHref:window.location.href,storage:window.localStorage,envBaseUrl:null,defaultWorkerBaseUrl:t,runtimeConfigFetcher:async()=>e}),r=null,a=null,o=null;$h(()=>k?(e,t)=>k.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),Bf(()=>k?()=>k.getBestFollowerForTeleport():null),Vf(()=>k?()=>k.getConnectedFollowers():null);let c=e=>{o&&=(clearInterval(o),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new Zb(e.channel,{browserTransport:p.getTransport(),browserAPI:p,onSnapshot:e=>{u.panels.chat.loadMessages(e)},onUserMessage:e=>{u.panels.chat.addUserMessage(e)},onStatus:e=>{u.panels.chat.setProcessing(e===`processing`)},onTargetsChanged:()=>void i()});r=n,p.setTrayTargetProvider(n),u.panels.chat.setAgent(n),n.requestSnapshot();let i=async()=>{try{let e=await p.listPages();n.advertiseTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})),t)}catch{}};o=setInterval(i,5e3),i(),$.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},f=e=>{a?.cancel(),o&&=(clearInterval(o),null),r?.close(),r=null,a=Tb({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:em()},{onConnected:e=>c(e),onReconnecting:e=>{$.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{$.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{f(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{o&&clearInterval(o),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)f(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new Yb({browserTransport:p.getTransport(),browserAPI:p,getMessages:()=>u.panels.chat.getMessages(),getScoopJid:()=>v?.jid??`cone`,onFollowerMessage:(e,t)=>{u.panels.chat.addUserMessage(e),A.sendMessage(e,t)},onFollowerAbort:()=>{A.stop()}}),k=t,nm(()=>t.getConnectedFollowers()),p.setTrayTargetProvider(t),i&&clearInterval(i);let n=async()=>{try{let e=await p.listPages();t.setLocalTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})))}catch{}};i=setInterval(n,5e3),n(),r=new Cb({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{$.info(`Tray follower data channel opened`,{controllerId:e.controllerId,bootstrapId:e.bootstrapId,attempt:e.attempt,runtime:e.runtime}),t.addFollower(e.bootstrapId,n,{runtime:e.runtime,connectedAt:e.connectedAt??void 0})}})};a(),h.add(e=>{t.broadcastEvent(e)}),e=new Xp({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:em(),onControlMessage:e=>{if(e.type===`webhook.event`){ie.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{$.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),am(async()=>{t.stop(),r.stop(),e.stop(),await e.clearSession();let n=await e.start(),i=d(window.location.href,n.workerBaseUrl,n.trayId);return i!==window.location.href&&window.history.replaceState(window.history.state,``,i),a(),Kp()}),e.start().then(e=>{let t=d(window.location.href,e.workerBaseUrl,e.trayId);t!==window.location.href&&window.history.replaceState(window.history.state,``,t)}).catch(e=>{$.warn(`Leader tray join failed`,{error:e instanceof Error?e.message:String(e)})}),window.addEventListener(`beforeunload`,()=>{clearInterval(i),t.stop(),r.stop(),e.stop()},{once:!0})}}$.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:w.getScoops().length}),Lv().catch(()=>{})}Ox().catch(e=>{$.error(`Fatal error`,e);let t=document.getElementById(`app`);if(t){let n=document.createElement(`div`);n.style.cssText=`padding: 2rem; text-align: center;`;let r=document.createElement(`h1`);r.style.color=`var(--s2-negative, #e34850)`,r.textContent=`Failed to start`;let i=document.createElement(`p`);i.style.color=`var(--s2-content-tertiary, #717171)`,i.textContent=e.message,n.appendChild(r),n.appendChild(i);let a=document.createElement(`button`);for(a.textContent=`Reset all data & reload`,a.style.cssText=`margin-top: 1rem; padding: 0.5rem 1.5rem; background: var(--s2-negative, #e34850); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 14px;`,a.addEventListener(`click`,async()=>{a.disabled=!0,a.textContent=`Resetting…`;let e=await indexedDB.databases();await Promise.all(e.map(e=>e.name?new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()}):Promise.resolve())),location.reload()}),n.appendChild(a);t.firstChild;)t.removeChild(t.firstChild);t.appendChild(n)}});export{Xv as a,ci as c,qy as i,ai as l,tb as n,Ta as o,rb as r,oi as s,eb as t};
@@ -0,0 +1 @@
1
+ import{r as e}from"./index-CP8O9WCU.js";export{e as getLickManager};
@@ -0,0 +1 @@
1
+ import{i as e}from"./index-CP8O9WCU.js";export{e as fetchSecretEnvVars};
@@ -0,0 +1 @@
1
+ import{a as e}from"./index-CP8O9WCU.js";export{e as WasmShell};
@@ -0,0 +1 @@
1
+ import{c as e}from"./index-CP8O9WCU.js";export{e as collectThemeCSS};
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>slicc</title>
7
7
  <link rel="icon" type="image/png" href="/logos/sliccy-color-1scoops-32x32.png" />
8
- <script type="module" crossorigin src="/assets/index-BceaW5U4.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CP8O9WCU.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-zsgVPwQN.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-D4M6sveU.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/logger-B-No_qN_.js">
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>slicc</title>
7
7
  <link rel="icon" type="image/png" href="/logos/sliccy-color-1scoops-32x32.png" />
8
- <script type="module" crossorigin src="/assets/index-BceaW5U4.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CP8O9WCU.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-zsgVPwQN.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-D4M6sveU.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/logger-B-No_qN_.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliccy",
3
- "version": "1.64.2",
3
+ "version": "1.64.3",
4
4
  "description": "Browser-based coding agent with thin CLI server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -63,7 +63,7 @@
63
63
  "@semantic-release/release-notes-generator": "14.1.0",
64
64
  "@types/node": "^24.0.0",
65
65
  "esbuild": "0.28.0",
66
- "eslint": "10.2.0",
66
+ "eslint": "10.2.1",
67
67
  "eslint-config-prettier": "10.1.8",
68
68
  "globals": "17.5.0",
69
69
  "husky": "9.1.7",
@@ -1 +0,0 @@
1
- import{r as e}from"./index-BceaW5U4.js";export{e as getLickManager};
@@ -1 +0,0 @@
1
- import{i as e}from"./index-BceaW5U4.js";export{e as fetchSecretEnvVars};
@@ -1 +0,0 @@
1
- import{a as e}from"./index-BceaW5U4.js";export{e as WasmShell};
@@ -1 +0,0 @@
1
- import{c as e}from"./index-BceaW5U4.js";export{e as collectThemeCSS};