sliccy 1.30.0 → 1.30.2
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/dist/ui/assets/{es-BP_Xj9ix.js → es-DcLnEgGG.js} +1 -1
- package/dist/ui/assets/{index-DpmXhFTV.js → index-zYZwcB_n.js} +7 -7
- package/dist/ui/assets/lick-manager-CEJ1osaY.js +1 -0
- package/dist/ui/assets/shell-CnndfXEH.js +1 -0
- package/dist/ui/assets/sprinkle-renderer-BFoiL80v.js +1 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui/packages/webapp/index.html +1 -1
- package/package.json +2 -2
- package/dist/ui/assets/lick-manager-DYq4Y_1C.js +0 -1
- package/dist/ui/assets/shell-DFibR_CB.js +0 -1
- package/dist/ui/assets/sprinkle-renderer-Ba7TDqre.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sql-wasm-BM0NbefL.js","assets/chunk-zsgVPwQN.js","assets/__vite-browser-external-RyPUarNg.js","assets/pyodide-CBYrCcoc.js","assets/preload-helper-ca-nBW7U.js","assets/es-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sql-wasm-BM0NbefL.js","assets/chunk-zsgVPwQN.js","assets/__vite-browser-external-RyPUarNg.js","assets/pyodide-CBYrCcoc.js","assets/preload-helper-ca-nBW7U.js","assets/es-DcLnEgGG.js","assets/dist-BWlKscHB.js","assets/provider-settings-UKXNpw6a.js","assets/provider-settings-DxWipiXF.js","assets/env-api-keys-DlVZ9FrG.js","assets/simple-options-BCaE9Yc6.js","assets/json-parse-JW3qhabb.js","assets/tray-follower-status-M8dOhnzY.js","assets/logger-B-No_qN_.js","assets/providers-D8wPZdve.js","assets/skills-Ke92WMkl.js","assets/skills-CTi4XTwR.js","assets/fs-f8JZDPIF.js","assets/browser-DHa7-69Q.js","assets/xterm-BmfB5bmM.css","assets/offscreen-client-ABShEPNe.js","assets/cdp-bn5Tu_JK.js","assets/bsh-watchdog-By5z523c.js"])))=>i.map(i=>d[i]);
|
|
2
2
|
import{i as e,o as t,t as n}from"./chunk-zsgVPwQN.js";import{t as r}from"./logger-B-No_qN_.js";import{c as i,f as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as _,y as v}from"./tray-follower-status-M8dOhnzY.js";import{t as y}from"./preload-helper-ca-nBW7U.js";import{A as b,D as x,E as S,O as C,S as w,_ as T,c as E,g as D,h as O,j as ee,k as te,n as ne,o as k,p as re,r as ie,s as ae,v as oe,x as se,y as ce}from"./provider-settings-DxWipiXF.js";import{n as le,t as ue}from"./browser-DHa7-69Q.js";import{a as de,i as fe,n as A,r as pe,s as me}from"./fs-f8JZDPIF.js";import{b as he,d as ge,n as _e}from"./skills-CTi4XTwR.js";import{a as ve,c as ye,d as be,i as xe,l as j,n as M,o as Se,r as Ce,s as we,u as Te}from"./cdp-bn5Tu_JK.js";import{_ as N,a as Ee,b as P,c as F,d as De,f as Oe,g as ke,h as Ae,i as je,l as Me,m as Ne,n as Pe,o as Fe,p as Ie,r as Le,s as Re,t as ze,u as Be,v as Ve,x as I,y as He}from"./db-CogIG09c.js";import{t as Ue}from"./magick-wasm-BR29mZjN.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();function We(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var Ge=We();function Ke(e){Ge=e}var qe={exec:()=>null};function Je(e,t=``){let n=typeof e==`string`?e:e.source,r={replace:(e,t)=>{let i=typeof t==`string`?t:t.source;return i=i.replace(Xe.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var Ye=(()=>{try{return!0}catch{return!1}})(),Xe={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),hrRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}#`),htmlBeginRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}<(?:[a-z].*>|!--)`,`i`),blockquoteBeginRegex:e=>RegExp(`^ {0,${Math.min(3,e-1)}}>`)},Ze=/^(?:[ \t]*(?:\n|$))+/,Qe=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,$e=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,et=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,tt=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,nt=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,rt=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,it=Je(rt).replace(/bull/g,nt).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,``).getRegex(),at=Je(rt).replace(/bull/g,nt).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),ot=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,st=/^[^\n]+/,ct=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,lt=Je(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,ct).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),ut=Je(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,nt).getRegex(),dt=`address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul`,ft=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,pt=Je(`^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))`,`i`).replace(`comment`,ft).replace(`tag`,dt).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),mt=Je(ot).replace(`hr`,et).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,dt).getRegex(),ht={blockquote:Je(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,mt).getRegex(),code:Qe,def:lt,fences:$e,heading:tt,hr:et,html:pt,lheading:it,list:ut,newline:Ze,paragraph:mt,table:qe,text:st},gt=Je(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,et).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`blockquote`,` {0,3}>`).replace(`code`,`(?: {4}| {0,3} )[^\\n]`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,dt).getRegex(),_t={...ht,lheading:at,table:gt,paragraph:Je(ot).replace(`hr`,et).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,gt).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,dt).getRegex()},vt={...ht,html:Je(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,ft).replace(/tag/g,`(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b`).getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:qe,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:Je(ot).replace(`hr`,et).replace(`heading`,` *#{1,6} *[^
|
|
3
3
|
]`).replace(`lheading`,it).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`|fences`,``).replace(`|list`,``).replace(`|html`,``).replace(`|tag`,``).getRegex()},yt=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,bt=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,xt=/^( {2,}|\\)\n(?!\s*$)/,St=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,Ct=/[\p{P}\p{S}]/u,wt=/[\s\p{P}\p{S}]/u,Tt=/[^\s\p{P}\p{S}]/u,Et=Je(/^((?![*_])punctSpace)/,`u`).replace(/punctSpace/g,wt).getRegex(),Dt=/(?!~)[\p{P}\p{S}]/u,Ot=/(?!~)[\s\p{P}\p{S}]/u,kt=/(?:[^\s\p{P}\p{S}]|~)/u,At=Je(/link|precode-code|html/,`g`).replace(`link`,/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace(`precode-`,Ye?"(?<!`)()":"(^^|[^`])").replace(`code`,/(?<b>`+)[^`]+\k<b>(?!`)/).replace(`html`,/<(?! )[^<>]*?>/).getRegex(),jt=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,Mt=Je(jt,`u`).replace(/punct/g,Ct).getRegex(),Nt=Je(jt,`u`).replace(/punct/g,Dt).getRegex(),Pt=`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)`,Ft=Je(Pt,`gu`).replace(/notPunctSpace/g,Tt).replace(/punctSpace/g,wt).replace(/punct/g,Ct).getRegex(),It=Je(Pt,`gu`).replace(/notPunctSpace/g,kt).replace(/punctSpace/g,Ot).replace(/punct/g,Dt).getRegex(),Lt=Je(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)`,`gu`).replace(/notPunctSpace/g,Tt).replace(/punctSpace/g,wt).replace(/punct/g,Ct).getRegex(),Rt=Je(/^~~?(?:((?!~)punct)|[^\s~])/,`u`).replace(/punct/g,Ct).getRegex(),zt=Je(`^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,Tt).replace(/punctSpace/g,wt).replace(/punct/g,Ct).getRegex(),Bt=Je(/\\(punct)/,`gu`).replace(/punct/g,Ct).getRegex(),Vt=Je(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace(`scheme`,/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(`email`,/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Ht=Je(ft).replace(`(?:-->|$)`,`-->`).getRegex(),Ut=Je(`^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>`).replace(`comment`,Ht).replace(`attribute`,/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),Wt=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,Gt=Je(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace(`label`,Wt).replace(`href`,/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace(`title`,/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Kt=Je(/^!?\[(label)\]\[(ref)\]/).replace(`label`,Wt).replace(`ref`,ct).getRegex(),qt=Je(/^!?\[(ref)\](?:\[\])?/).replace(`ref`,ct).getRegex(),Jt=Je(`reflink|nolink(?!\\()`,`g`).replace(`reflink`,Kt).replace(`nolink`,qt).getRegex(),Yt=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,Xt={_backpedal:qe,anyPunctuation:Bt,autolink:Vt,blockSkip:At,br:xt,code:bt,del:qe,delLDelim:qe,delRDelim:qe,emStrongLDelim:Mt,emStrongRDelimAst:Ft,emStrongRDelimUnd:Lt,escape:yt,link:Gt,nolink:qt,punctuation:Et,reflink:Kt,reflinkSearch:Jt,tag:Ut,text:St,url:qe},Zt={...Xt,link:Je(/^!?\[(label)\]\((.*?)\)/).replace(`label`,Wt).getRegex(),reflink:Je(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace(`label`,Wt).getRegex()},Qt={...Xt,emStrongRDelimAst:It,emStrongLDelim:Nt,delLDelim:Rt,delRDelim:zt,url:Je(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace(`protocol`,Yt).replace(`email`,/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:Je(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace(`protocol`,Yt).getRegex()},$t={...Qt,br:Je(xt).replace(`{2,}`,`*`).getRegex(),text:Je(Qt.text).replace(`\\b_`,`\\b_| {2,}\\n`).replace(/\{2,\}/g,`*`).getRegex()},en={normal:ht,gfm:_t,pedantic:vt},tn={normal:Xt,gfm:Qt,breaks:$t,pedantic:Zt},nn={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},rn=e=>nn[e];function an(e,t){if(t){if(Xe.escapeTest.test(e))return e.replace(Xe.escapeReplace,rn)}else if(Xe.escapeTestNoEncode.test(e))return e.replace(Xe.escapeReplaceNoEncode,rn);return e}function on(e){try{e=encodeURI(e).replace(Xe.percentDecode,`%`)}catch{return null}return e}function sn(e,t){let n=e.replace(Xe.findPipe,(e,t,n)=>{let r=!1,i=t;for(;--i>=0&&n[i]===`\\`;)r=!r;return r?`|`:` |`}).split(Xe.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length<t;)n.push(``);for(;r<n.length;r++)n[r]=n[r].trim().replace(Xe.slashPipe,`|`);return n}function cn(e,t,n){let r=e.length;if(r===0)return``;let i=0;for(;i<r;){let a=e.charAt(r-i-1);if(a===t&&!n)i++;else if(a!==t&&n)i++;else break}return e.slice(0,r-i)}function ln(e,t){if(e.indexOf(t[1])===-1)return-1;let n=0;for(let r=0;r<e.length;r++)if(e[r]===`\\`)r++;else if(e[r]===t[0])n++;else if(e[r]===t[1]&&(n--,n<0))return r;return n>0?-2:-1}function un(e,t=0){let n=t,r=``;for(let t of e)if(t===` `){let e=4-n%4;r+=` `.repeat(e),n+=e}else r+=t,n++;return r}function dn(e,t,n,r,i){let a=t.href,o=t.title||null,s=e[1].replace(i.other.outputLinkReplace,`$1`);r.state.inLink=!0;let c={type:e[0].charAt(0)===`!`?`image`:`link`,raw:n,href:a,title:o,text:s,tokens:r.inlineTokens(s)};return r.state.inLink=!1,c}function fn(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(`
|
|
4
4
|
`).map(e=>{let t=e.match(n.other.beginningSpace);if(t===null)return e;let[r]=t;return r.length>=i.length?e.slice(i.length):e}).join(`
|
|
@@ -175,7 +175,7 @@ mark{background:color-mix(in srgb,var(--s2-accent) 25%,transparent);color:inheri
|
|
|
175
175
|
</style>
|
|
176
176
|
<script>${ii}<\/script>
|
|
177
177
|
</head>
|
|
178
|
-
<body class="sprinkle-inline">${t}</body></html>`;if(ri)return ci(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 oi(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(ai(a,i,t))}return r}function si(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function ci(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 li=r(`tool-ui-renderer`),ui=typeof chrome<`u`&&!!chrome?.runtime?.id,di=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){ui?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(()=>{li.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){li.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(li.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 y(async()=>{let{collectThemeCSS:e}=await import(`./sprinkle-renderer-Ba7TDqre.js`);return{collectThemeCSS:e}},[]),r=n();t.contentWindow.postMessage({type:`tool-ui-render`,id:this.requestId,nonce:this.nonce,html:e,themeCSS:r},`*`)}renderWithInlineSprinkle(e){let t=document.createElement(`div`);t.className=`msg__inline-sprinkle`,this.container.appendChild(t),this.inlineSprinkle=ai(t,e,(e,t)=>{li.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)}},fi=new Map;function pi(e,t,n){let r=fi.get(t);r&&r.dispose();let i=new di(e,t);return fi.set(t,i),i.render(n).catch(e=>{li.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function mi(e){let t=fi.get(e);t&&(t.dispose(),fi.delete(e))}var hi=r(`chat-panel`);function gi(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var _i={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 vi(e){return _i[e]??`?`}function yi(e){return e.role===`assistant`?zr(e.content):Rr(e.content)}var bi=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;onModelChange;constructor(e){this.container=e,this.sessionStore=new Gr,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:gi(),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()}addUserMessage(e){let t={id:gi(),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.container.appendChild(this.messagesEl),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 Yr({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=>{hi.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:Zr()}),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)}toggleVoiceMode(){this.voiceMode=!this.voiceMode,this.micBtn.classList.toggle(`chat__mic-btn--active`,this.voiceMode),this.voiceMode?this.voiceInput?.start():this.voiceInput?.stop()}sendMessage(){let e=this.textarea.value.trim();if(!e)return;this.autoScrollAttached=!0,this.hideJumpPill();let t=this.isStreaming,n={id:gi(),role:`user`,content:e,timestamp:Date.now(),queued:t||void 0};this.messages.push(n),this.appendMessageEl(n),this.persistSession(),this.textarea.value=``,this.textarea.style.height=`auto`,this.isStreaming||this.setStreamingState(!0),this.agent?.sendMessage(e,n.id)}handleAgentEvent(e){switch(hi.debug(`Agent event`,{type:e.type}),e.type){case`message_start`:this.handleMessageStart(e.messageId);break;case`content_delta`:this.handleContentDelta(e.messageId,e.text);break;case`content_done`:this.handleContentDone(e.messageId);break;case`tool_use_start`:this.handleToolUseStart(e.messageId,e.toolName,e.toolInput);break;case`tool_result`:this.handleToolResult(e.messageId,e.toolName,e.result,e.isError);break;case`tool_ui`:this.handleToolUI(e.messageId,e.toolName,e.requestId,e.html);break;case`tool_ui_done`:this.handleToolUIDone(e.messageId,e.requestId);break;case`turn_end`:this.handleTurnEnd(e.messageId);break;case`error`:this.handleError(e.error);break;case`screenshot`:break;case`terminal_output`:this.terminalOutputCallback?.(e.text);break}}handleMessageStart(e){this.setStreamingState(!0),this.currentStreamId=e;let t={id:e,role:`assistant`,content:``,timestamp:Date.now(),isStreaming:!0,toolCalls:[]};this.messages.push(t),this.appendMessageEl(t)}handleContentDelta(e,t){this.findMessage(e)&&(this.pendingDeltaText+=t,this.streamingRafId===null&&(this.streamingRafId=requestAnimationFrame(()=>this.flushPendingDelta())))}handleContentDone(e){if(this.pendingDeltaText&&this.currentStreamId===e){let t=this.findMessage(e);t&&(t.content+=this.pendingDeltaText)}this.cancelPendingDelta();let t=this.findMessage(e);t&&(t.isStreaming=!1,this.updateMessageEl(e))}handleToolUseStart(e,t,n){let r=this.findMessage(e);r&&(r.toolCalls||=[],r.toolCalls.push({id:gi(),name:t,input:n}),this.updateMessageEl(e))}handleToolResult(e,t,n,r){let i=this.findMessage(e);if(!i||!i.toolCalls)return;let a=[...i.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);if(a){let e=n.match(/<img:(data:image\/[^>]+)>/);a.result=n.replace(/<img:data:image\/[^>]+>/g,``).trim(),e&&(a._screenshotDataUrl=e[1]),a.isError=r}this.updateMessageEl(e)}handleToolUI(e,t,n,r,i=0){let a=this.findMessage(e);if(!a||!a.toolCalls){if(i<10){setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100);return}hi.warn(`handleToolUI: message or toolCalls not found after retries`,{messageId:e});return}let o=[...a.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);if(!o){hi.warn(`handleToolUI: no matching tool call found`,{messageId:e,toolName:t});return}o._toolUIRequestId=n;let s=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(!s){if(i<10){setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100);return}hi.warn(`handleToolUI: wrapper element not found after retries`,{messageId:e});return}let c=[...s.querySelectorAll(`.tool-call`)].reverse().find(e=>e.querySelector(`.tool-call__name`)?.textContent===t);if(c){c instanceof HTMLDetailsElement&&(c.open=!0);let e=c.querySelector(`.tool-call__ui`);e||(e=document.createElement(`div`),e.className=`tool-call__ui`,c.appendChild(e)),pi(e,n,r)}else i<10?setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100):hi.warn(`handleToolUI: tool call element not found in DOM after retries`,{toolName:t})}handleToolUIDone(e,t){mi(t)}handleTurnEnd(e){this.setStreamingState(!1),this.currentStreamId=null,this.persistSession()}handleError(e){this.setStreamingState(!1),this.currentStreamId=null;let t=this.messages[this.messages.length-1];if(t?.role===`assistant`&&t.isStreaming)t.isStreaming=!1,t.content+=`\n\n**Error:** ${e}`,this.updateMessageEl(t.id);else{let t={id:gi(),role:`assistant`,content:`**Error:** ${e}`,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}this.persistSession()}setStreamingState(e){this.isStreaming=e;try{this.renderModelSelector()}catch{}if(this.stopBtn.style.display=e?`flex`:`none`,this.sendBtn.style.display=e?`none`:`flex`,this.textarea.disabled=!1,e){this.voiceInput?.isListening()&&this.voiceInput.stop(),this.micBtn.classList.remove(`chat__mic-btn--listening`);let e=this.messages.find(e=>e.queued);e&&(e.queued=!1,this.updateMessageEl(e.id))}e||(this.voiceMode?(this.micBtn.classList.add(`chat__mic-btn--listening`),this.voiceInput?.start()):this.textarea.focus())}renderModelSelector(){let e=this.modelSelectorEl;if(!e)return;for(;e.firstChild;)e.removeChild(e.firstChild);let t=ae(),n=O(),r=D(),i=[];for(let e of t)for(let t of e.models)i.push({providerId:e.providerId,id:t.id,name:t.name,reasoning:t.reasoning});i.sort((e,t)=>e.reasoning===t.reasoning?e.name.localeCompare(t.name):e.reasoning?-1:1);let a=i.find(e=>e.id===n&&e.providerId===r)||i[0];if(!a)return;let o=this.isStreaming,s=document.createElement(`button`);if(s.className=`chat__model-btn chat__model-btn--compact`,o&&s.classList.add(`chat__model-btn--disabled`),s.textContent=a.name,!o){let e=document.createElement(`span`);e.className=`chat__model-chevron`,e.innerHTML=`<svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M4.5 6l3.5 4 3.5-4z"/></svg>`,s.appendChild(e)}if(o)e.appendChild(s);else{let t=!1,a=document.createElement(`div`);a.className=`chat__model-menu`;let o=()=>{for(a.style.display=t?`block`:`none`;a.firstChild;)a.removeChild(a.firstChild);if(t)for(let e of i){let i=document.createElement(`div`);i.className=`chat__model-menu-item`;let o=e.id===n&&e.providerId===r;o&&i.classList.add(`chat__model-menu-item--active`);let s=document.createElement(`span`);if(s.textContent=e.name,i.appendChild(s),o){let e=document.createElement(`span`);e.className=`chat__model-check`,e.innerHTML=`<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M6.5 12.5l-4-4 1.4-1.4 2.6 2.6 5.6-5.6 1.4 1.4z"/></svg>`,i.appendChild(e)}i.addEventListener(`click`,()=>{let n=`${e.providerId}:${e.id}`;se(n),this.onModelChange?.(n),t=!1,this.renderModelSelector()}),a.appendChild(i)}};s.addEventListener(`click`,e=>{e.stopPropagation(),t=!t,o()}),document.addEventListener(`click`,()=>{t=!1,o()},{once:!0}),e.appendChild(s),e.appendChild(a),o()}}refreshModelSelector(){this.renderModelSelector()}findMessage(e){return this.messages.find(t=>t.id===e)}flushPendingDelta(){if(this.streamingRafId=null,!this.pendingDeltaText||!this.currentStreamId)return;let e=this.findMessage(this.currentStreamId);if(!e){this.pendingDeltaText=``;return}e.content+=this.pendingDeltaText,this.pendingDeltaText=``,this.updateStreamingContent(this.currentStreamId)}cancelPendingDelta(){this.streamingRafId!==null&&(cancelAnimationFrame(this.streamingRafId),this.streamingRafId=null),this.pendingDeltaText=``}updateStreamingContent(e){let t=this.findMessage(e);if(!t)return;let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(!n)return;let r=n.querySelector(`.msg__content`);if(r){if(r.innerHTML=yi(t),t.isStreaming){let e=document.createElement(`span`);e.className=`streaming-cursor`,r.appendChild(e)}}else if(t.content.trim().length>0){this.updateMessageEl(e);return}this.scrollToBottom()}renderMessages(){this.disposeAllInlineSprinkles(),this.messagesInner.innerHTML=``;let e=null,t=0,n=-1;for(let e=this.messages.length-1;e>=0;e--)if(this.messages[e].role===`assistant`){n=e;break}for(let r=0;r<this.messages.length;r++){let i=this.messages[r],a=this.shouldShowLabel(i,e,t),o=this.createMessageEl(i,a,r===n);this.messagesInner.appendChild(o),e=i.role,t=i.timestamp}this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}appendMessageEl(e){let t=this.messagesInner.querySelector(`.msg__feedback`);t&&t.remove();let n=this.messages.length>=2?this.messages[this.messages.length-2]:null,r=this.shouldShowLabel(e,n?.role??null,n?.timestamp??0),i=e.role===`assistant`,a=this.createMessageEl(e,r,i);this.messagesInner.appendChild(a),this.scrollToBottom()}shouldShowLabel(e,t,n){return e.source===`lick`||e.channel===`webhook`||e.channel===`cron`||e.role!==t||e.timestamp-n>12e4}updateMessageEl(e){let t=this.findMessage(e);if(!t)return;let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(n){this.disposeInlineSprinklesForMessage(e);let r=this.messages.indexOf(t),i=r>0?this.messages[r-1]:null,a=this.shouldShowLabel(t,i?.role??null,i?.timestamp??0),o=!1;if(t.role===`assistant`){let e=-1;for(let t=this.messages.length-1;t>=0;t--)if(this.messages[t].role===`assistant`){e=t;break}o=r===e}let s=this.createMessageEl(t,a,o);n.replaceWith(s)}this.scrollToBottom()}createMessageEl(e,t=!0,n=!1){if(e.source===`lick`||e.channel===`webhook`||e.channel===`cron`){let t=document.createElement(`div`);return t.className=`msg-group`,t.setAttribute(`data-msg-id`,e.id),t.appendChild(this.createLickEl(e)),t}let r=document.createElement(`div`);r.className=`msg-group${t?``:` msg-group--continuation`}`,r.setAttribute(`data-msg-id`,e.id);let i=document.createElement(`div`);if(i.className=`msg msg--${e.role}${e.queued?` msg--queued`:``}`,t){let t,n,r=this.currentScoopName!==null;e.role===`user`?e.source===`delegation`||e.channel===`delegation`?(t=`S`,n=`sliccy`):(t=`U`,n=`You`):r?(t=(this.currentScoopName||`S`).charAt(0).toUpperCase(),n=`@${this.currentScoopName}`):e.source&&e.source!==`cone`?(t=e.source.charAt(0).toUpperCase(),n=e.source):(t=`S`,n=`sliccy`);let a=document.createElement(`div`);a.className=`msg__role`;let o=document.createElement(`span`);if(o.className=`msg__icon`,o.textContent=t,a.appendChild(o),a.appendChild(document.createTextNode(` ${n}`)),e.queued){let t=document.createElement(`span`);t.className=`msg__queued-badge`,t.textContent=`queued`,a.appendChild(t);let n=document.createElement(`button`);n.className=`msg__queued-delete`,n.textContent=`×`,n.title=`Remove queued message`,n.addEventListener(`click`,t=>{t.stopPropagation(),this.deleteQueuedMessage(e.id)}),a.appendChild(n)}i.appendChild(a)}let a=(e.source===`lick`||e.channel===`webhook`||e.channel===`cron`)&&this.sessionId===`session-cone`,o=e.source&&e.source!==`cone`&&e.source!==`lick`&&e.role===`assistant`&&this.sessionId===`session-cone`;if(a||o){let t=document.createElement(`details`);t.className=`msg__collapsible`;let n=document.createElement(`summary`);n.className=`msg__summary`,n.textContent=e.content.slice(0,60).replace(/\n/g,` `)+(e.content.length>60?`...`:``),t.appendChild(n);let r=document.createElement(`div`);r.className=`msg__content`,r.innerHTML=yi(e),e.isStreaming||this.hydrateInlineSprinklesInEl(r,e.id),t.appendChild(r),i.appendChild(t)}else{let t=document.createElement(`div`);if(t.className=`msg__content`,t.innerHTML=yi(e),e.isStreaming){let e=document.createElement(`span`);e.className=`streaming-cursor`,t.appendChild(e)}else this.hydrateInlineSprinklesInEl(t,e.id);i.appendChild(t)}let s=e.content.trim().length>0;if(s&&r.appendChild(i),e.toolCalls)for(let t of e.toolCalls)r.appendChild(this.createToolCallEl(t));return e.role===`assistant`&&!e.isStreaming&&!e.queued&&s&&n&&r.appendChild(this.createFeedbackRow()),r}createFeedbackRow(){let e=document.createElement(`div`);e.className=`msg__feedback`;let t=document.createElement(`button`);return t.className=`msg__feedback-btn`,t.dataset.tooltip=`Copy chat`,t.setAttribute(`aria-label`,`Copy chat`),t.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="m11.75,18h-7.5c-1.24,0-2.25-1.01-2.25-2.25v-7.5c0-1.24,1.01-2.25,2.25-2.25.41,0,.75.34.75.75s-.34.75-.75.75c-.41,0-.75.34-.75.75v7.5c0,.41.34.75.75.75h7.5c.41,0,.75-.34.75-.75,0-.41.34-.75.75-.75s.75.34.75.75c0,1.24-1.01,2.25-2.25,2.25Z"/><path d="m6.75,5c-.41,0-.75-.34-.75-.75,0-1.24,1.01-2.25,2.25-2.25.41,0,.75.34.75.75s-.34.75-.75.75c-.41,0-.75.34-.75.75,0,.41-.34.75-.75.75Z"/><path d="m13,3.5h-2c-.41,0-.75-.34-.75-.75s.34-.75.75-.75h2c.41,0,.75.34.75.75s-.34.75-.75.75Z"/><path d="m13,14h-2c-.41,0-.75-.34-.75-.75s.34-.75.75-.75h2c.41,0,.75.34.75.75s-.34.75-.75.75Z"/><path d="m15.75,14c-.41,0-.75-.34-.75-.75s.34-.75.75-.75c.41,0,.75-.34.75-.75,0-.41.34-.75.75-.75s.75.34.75.75c0,1.24-1.01,2.25-2.25,2.25Z"/><path d="m17.25,5c-.41,0-.75-.34-.75-.75,0-.41-.34-.75-.75-.75-.41,0-.75-.34-.75-.75s.34-.75.75-.75c1.24,0,2.25,1.01,2.25,2.25,0,.41-.34.75-.75.75Z"/><path d="m17.25,9.75c-.41,0-.75-.34-.75-.75v-2c0-.41.34-.75.75-.75s.75.34.75.75v2c0,.41-.34.75-.75.75Z"/><path d="m6.75,9.75c-.41,0-.75-.34-.75-.75v-2c0-.41.34-.75.75-.75s.75.34.75.75v2c0,.41-.34.75-.75.75Z"/><path d="m8.25,14c-1.24,0-2.25-1.01-2.25-2.25,0-.41.34-.75.75-.75s.75.34.75.75c0,.41.34.75.75.75.41,0,.75.34.75.75s-.34.75-.75.75Z"/></svg>`,t.addEventListener(`click`,async()=>{let e=this.getMessages(),n=``;for(let t of e){let e=t.role===`user`?`User`:`Assistant`;if(n+=`## ${e}\n${t.content}\n\n`,t.toolCalls)for(let e of t.toolCalls)n+=`### Tool: ${e.name}\nInput: ${JSON.stringify(e.input,null,2)}\nResult: ${e.result??``}\n\n`}await navigator.clipboard.writeText(n),t.style.color=`var(--s2-positive)`,setTimeout(()=>{t.style.color=``},1500)}),e.appendChild(t),e}createLickEl(e){let t=document.createElement(`details`);t.className=`lick`;let n=e.channel===`webhook`?`Webhook`:e.channel===`cron`?`Cron`:`Event`,r=document.createElement(`summary`);r.className=`lick__header`,r.innerHTML=`<span class="lick__icon">E</span> <span class="lick__type">${n}</span>`;let i=document.createElement(`span`);i.className=`lick__preview`;let a=e.content.replace(/\[Webhook Event:.*?\]\n```json\n?/s,``).slice(0,50);i.textContent=a.replace(/\n/g,` `)+(a.length>=50?`...`:``),r.appendChild(i),t.appendChild(r);let o=document.createElement(`div`);return o.className=`lick__details`,o.innerHTML=Rr(e.content),t.appendChild(o),t}createToolCallEl(e){vi(e.name);let t=document.createElement(`details`);t.className=`tool-call`;let n=document.createElement(`summary`);if(n.className=`tool-call__header`,n.innerHTML=`<span class="tool-call__icon"><svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg></span> <span class="tool-call__name">${Er(e.name)}</span>`,e.input!==void 0){let t=document.createElement(`span`);t.className=`tool-call__preview`;let r=typeof e.input==`string`?e.input:JSON.stringify(e.input);t.textContent=r.slice(0,40)+(r.length>40?`...`:``),n.appendChild(t)}let r=document.createElement(`span`);e.result===void 0?r.className=`tool-call__status tool-call__status--running`:e.isError?(r.className=`tool-call__status tool-call__status--error`,r.textContent=`failed`):(r.className=`tool-call__status tool-call__status--success`,r.textContent=`✓`),n.appendChild(r),t.appendChild(n);let i=document.createElement(`div`);if(i.className=`tool-call__details`,e.input!==void 0){let t=document.createElement(`div`);t.className=`tool-call__input`;let n=document.createElement(`div`);n.className=`tool-call__label`,n.textContent=`Input:`,t.appendChild(n);let r=document.createElement(`pre`);r.innerHTML=Br(e.input),t.appendChild(r),i.appendChild(t)}if(e.result!==void 0){let t=document.createElement(`div`);t.className=`tool-call__result${e.isError?` tool-call__result--error`:``}`;let n=document.createElement(`div`);n.className=`tool-call__label`,n.textContent=e.isError?`Error:`:`Result:`,t.appendChild(n);let r=document.createElement(`pre`);r.textContent=e.result,t.appendChild(r),i.appendChild(t)}let a=e._screenshotDataUrl;if(a){let e=document.createElement(`img`);e.src=a,e.className=`tool-call__screenshot`,e.title=`Click to view full size`,e.addEventListener(`click`,e=>{e.stopPropagation();let t=window.open(`about:blank`);if(t){let e=t.document.createElement(`img`);e.src=a,t.document.title=`Screenshot`,t.document.body.style.margin=`0`,t.document.body.style.background=document.documentElement.classList.contains(`theme-light`)?`#f0f0f0`:`#141414`,t.document.body.appendChild(e)}}),i.appendChild(e)}return t.appendChild(i),t}scrollToBottom(e=!1){if(!e&&!this.autoScrollAttached){this.showJumpPill();return}requestAnimationFrame(()=>{this.messagesEl.scrollTop=this.messagesEl.scrollHeight,this.lastScrollTop=this.messagesEl.scrollTop})}showJumpPill(){this.jumpPill.classList.add(`chat__jump-pill--visible`)}hideJumpPill(){this.jumpPill.classList.remove(`chat__jump-pill--visible`)}persistSession(){this.sessionStore.saveMessages(this.sessionId,this.messages).catch(()=>{})}disposeInlineSprinklesForMessage(e){let t=this.inlineSprinkles.get(e);t&&(si(t),this.inlineSprinkles.delete(e))}disposeAllInlineSprinkles(){for(let[,e]of this.inlineSprinkles)si(e);this.inlineSprinkles.clear()}hydrateInlineSprinklesInEl(e,t){let n=oi(e,(e,t)=>this.onInlineSprinkleLick?.(e,t));n.length&&this.inlineSprinkles.set(t,n)}dispose(){this.cancelPendingDelta(),this.disposeAllInlineSprinkles(),this.unsubscribe?.(),this.voiceInput?.destroy(),this.keydownListener&&=(document.removeEventListener(`keydown`,this.keydownListener),null),this.container.innerHTML=``}},xi=class{container;terminalViewEl;previewViewEl;previewEmptyEl;previewBtn;shell=null;activeView=`terminal`;onClearTerminal;constructor(e,t={}){this.container=e,this.onClearTerminal=t.onClearTerminal??null,this.render()}async mountShell(e){this.shell?.setPreviewStateListener(null),this.shell=e;let t=document.createElement(`div`);t.className=`terminal-panel__mount`,this.terminalViewEl.appendChild(t),await e.mount(t);let n=t.querySelector(`.terminal-panel__terminal-host`),r=t.querySelector(`.terminal-panel__preview`);if(!n||!r)throw Error(`terminal mount did not create expected hosts`);this.terminalViewEl.replaceChildren(n),this.previewViewEl.replaceChildren(this.previewEmptyEl),this.previewViewEl.appendChild(r),e.setPreviewStateListener(e=>this.handlePreviewStateChange(e))}clearTerminal(){this.shell?.clearTerminal()}async runCommand(e){return this.shell?(/^\s*imgcat(?:\s|$)/.test(e)||this.setActiveView(`terminal`),this.shell.executeCommandInTerminal(e)):{stdout:``,stderr:`terminal is unavailable
|
|
178
|
+
<body class="sprinkle-inline">${t}</body></html>`;if(ri)return ci(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 oi(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(ai(a,i,t))}return r}function si(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function ci(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 li=r(`tool-ui-renderer`),ui=typeof chrome<`u`&&!!chrome?.runtime?.id,di=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){ui?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(()=>{li.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){li.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(li.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 y(async()=>{let{collectThemeCSS:e}=await import(`./sprinkle-renderer-BFoiL80v.js`);return{collectThemeCSS:e}},[]),r=n();t.contentWindow.postMessage({type:`tool-ui-render`,id:this.requestId,nonce:this.nonce,html:e,themeCSS:r},`*`)}renderWithInlineSprinkle(e){let t=document.createElement(`div`);t.className=`msg__inline-sprinkle`,this.container.appendChild(t),this.inlineSprinkle=ai(t,e,(e,t)=>{li.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)}},fi=new Map;function pi(e,t,n){let r=fi.get(t);r&&r.dispose();let i=new di(e,t);return fi.set(t,i),i.render(n).catch(e=>{li.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function mi(e){let t=fi.get(e);t&&(t.dispose(),fi.delete(e))}var hi=r(`chat-panel`);function gi(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var _i={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 vi(e){return _i[e]??`?`}function yi(e){return e.role===`assistant`?zr(e.content):Rr(e.content)}var bi=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;onModelChange;constructor(e){this.container=e,this.sessionStore=new Gr,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:gi(),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()}addUserMessage(e){let t={id:gi(),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.container.appendChild(this.messagesEl),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 Yr({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=>{hi.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:Zr()}),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)}toggleVoiceMode(){this.voiceMode=!this.voiceMode,this.micBtn.classList.toggle(`chat__mic-btn--active`,this.voiceMode),this.voiceMode?this.voiceInput?.start():this.voiceInput?.stop()}sendMessage(){let e=this.textarea.value.trim();if(!e)return;this.autoScrollAttached=!0,this.hideJumpPill();let t=this.isStreaming,n={id:gi(),role:`user`,content:e,timestamp:Date.now(),queued:t||void 0};this.messages.push(n),this.appendMessageEl(n),this.persistSession(),this.textarea.value=``,this.textarea.style.height=`auto`,this.isStreaming||this.setStreamingState(!0),this.agent?.sendMessage(e,n.id)}handleAgentEvent(e){switch(hi.debug(`Agent event`,{type:e.type}),e.type){case`message_start`:this.handleMessageStart(e.messageId);break;case`content_delta`:this.handleContentDelta(e.messageId,e.text);break;case`content_done`:this.handleContentDone(e.messageId);break;case`tool_use_start`:this.handleToolUseStart(e.messageId,e.toolName,e.toolInput);break;case`tool_result`:this.handleToolResult(e.messageId,e.toolName,e.result,e.isError);break;case`tool_ui`:this.handleToolUI(e.messageId,e.toolName,e.requestId,e.html);break;case`tool_ui_done`:this.handleToolUIDone(e.messageId,e.requestId);break;case`turn_end`:this.handleTurnEnd(e.messageId);break;case`error`:this.handleError(e.error);break;case`screenshot`:break;case`terminal_output`:this.terminalOutputCallback?.(e.text);break}}handleMessageStart(e){this.setStreamingState(!0),this.currentStreamId=e;let t={id:e,role:`assistant`,content:``,timestamp:Date.now(),isStreaming:!0,toolCalls:[]};this.messages.push(t),this.appendMessageEl(t)}handleContentDelta(e,t){this.findMessage(e)&&(this.pendingDeltaText+=t,this.streamingRafId===null&&(this.streamingRafId=requestAnimationFrame(()=>this.flushPendingDelta())))}handleContentDone(e){if(this.pendingDeltaText&&this.currentStreamId===e){let t=this.findMessage(e);t&&(t.content+=this.pendingDeltaText)}this.cancelPendingDelta();let t=this.findMessage(e);t&&(t.isStreaming=!1,this.updateMessageEl(e))}handleToolUseStart(e,t,n){let r=this.findMessage(e);r&&(r.toolCalls||=[],r.toolCalls.push({id:gi(),name:t,input:n}),this.updateMessageEl(e))}handleToolResult(e,t,n,r){let i=this.findMessage(e);if(!i||!i.toolCalls)return;let a=[...i.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);if(a){let e=n.match(/<img:(data:image\/[^>]+)>/);a.result=n.replace(/<img:data:image\/[^>]+>/g,``).trim(),e&&(a._screenshotDataUrl=e[1]),a.isError=r}this.updateMessageEl(e)}handleToolUI(e,t,n,r,i=0){let a=this.findMessage(e);if(!a||!a.toolCalls){if(i<10){setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100);return}hi.warn(`handleToolUI: message or toolCalls not found after retries`,{messageId:e});return}let o=[...a.toolCalls].reverse().find(e=>e.name===t&&e.result===void 0);if(!o){hi.warn(`handleToolUI: no matching tool call found`,{messageId:e,toolName:t});return}o._toolUIRequestId=n;let s=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(!s){if(i<10){setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100);return}hi.warn(`handleToolUI: wrapper element not found after retries`,{messageId:e});return}let c=[...s.querySelectorAll(`.tool-call`)].reverse().find(e=>e.querySelector(`.tool-call__name`)?.textContent===t);if(c){c instanceof HTMLDetailsElement&&(c.open=!0);let e=c.querySelector(`.tool-call__ui`);e||(e=document.createElement(`div`),e.className=`tool-call__ui`,c.appendChild(e)),pi(e,n,r)}else i<10?setTimeout(()=>this.handleToolUI(e,t,n,r,i+1),100):hi.warn(`handleToolUI: tool call element not found in DOM after retries`,{toolName:t})}handleToolUIDone(e,t){mi(t)}handleTurnEnd(e){this.setStreamingState(!1),this.currentStreamId=null,this.persistSession()}handleError(e){this.setStreamingState(!1),this.currentStreamId=null;let t=this.messages[this.messages.length-1];if(t?.role===`assistant`&&t.isStreaming)t.isStreaming=!1,t.content+=`\n\n**Error:** ${e}`,this.updateMessageEl(t.id);else{let t={id:gi(),role:`assistant`,content:`**Error:** ${e}`,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}this.persistSession()}setStreamingState(e){this.isStreaming=e;try{this.renderModelSelector()}catch{}if(this.stopBtn.style.display=e?`flex`:`none`,this.sendBtn.style.display=e?`none`:`flex`,this.textarea.disabled=!1,e){this.voiceInput?.isListening()&&this.voiceInput.stop(),this.micBtn.classList.remove(`chat__mic-btn--listening`);let e=this.messages.find(e=>e.queued);e&&(e.queued=!1,this.updateMessageEl(e.id))}e||(this.voiceMode?(this.micBtn.classList.add(`chat__mic-btn--listening`),this.voiceInput?.start()):this.textarea.focus())}renderModelSelector(){let e=this.modelSelectorEl;if(!e)return;for(;e.firstChild;)e.removeChild(e.firstChild);let t=ae(),n=O(),r=D(),i=[];for(let e of t)for(let t of e.models)i.push({providerId:e.providerId,id:t.id,name:t.name,reasoning:t.reasoning});i.sort((e,t)=>e.reasoning===t.reasoning?e.name.localeCompare(t.name):e.reasoning?-1:1);let a=i.find(e=>e.id===n&&e.providerId===r)||i[0];if(!a)return;let o=this.isStreaming,s=document.createElement(`button`);if(s.className=`chat__model-btn chat__model-btn--compact`,o&&s.classList.add(`chat__model-btn--disabled`),s.textContent=a.name,!o){let e=document.createElement(`span`);e.className=`chat__model-chevron`,e.innerHTML=`<svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M4.5 6l3.5 4 3.5-4z"/></svg>`,s.appendChild(e)}if(o)e.appendChild(s);else{let t=!1,a=document.createElement(`div`);a.className=`chat__model-menu`;let o=()=>{for(a.style.display=t?`block`:`none`;a.firstChild;)a.removeChild(a.firstChild);if(t)for(let e of i){let i=document.createElement(`div`);i.className=`chat__model-menu-item`;let o=e.id===n&&e.providerId===r;o&&i.classList.add(`chat__model-menu-item--active`);let s=document.createElement(`span`);if(s.textContent=e.name,i.appendChild(s),o){let e=document.createElement(`span`);e.className=`chat__model-check`,e.innerHTML=`<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M6.5 12.5l-4-4 1.4-1.4 2.6 2.6 5.6-5.6 1.4 1.4z"/></svg>`,i.appendChild(e)}i.addEventListener(`click`,()=>{let n=`${e.providerId}:${e.id}`;se(n),this.onModelChange?.(n),t=!1,this.renderModelSelector()}),a.appendChild(i)}};s.addEventListener(`click`,e=>{e.stopPropagation(),t=!t,o()}),document.addEventListener(`click`,()=>{t=!1,o()},{once:!0}),e.appendChild(s),e.appendChild(a),o()}}refreshModelSelector(){this.renderModelSelector()}findMessage(e){return this.messages.find(t=>t.id===e)}flushPendingDelta(){if(this.streamingRafId=null,!this.pendingDeltaText||!this.currentStreamId)return;let e=this.findMessage(this.currentStreamId);if(!e){this.pendingDeltaText=``;return}e.content+=this.pendingDeltaText,this.pendingDeltaText=``,this.updateStreamingContent(this.currentStreamId)}cancelPendingDelta(){this.streamingRafId!==null&&(cancelAnimationFrame(this.streamingRafId),this.streamingRafId=null),this.pendingDeltaText=``}updateStreamingContent(e){let t=this.findMessage(e);if(!t)return;let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(!n)return;let r=n.querySelector(`.msg__content`);if(r){if(r.innerHTML=yi(t),t.isStreaming){let e=document.createElement(`span`);e.className=`streaming-cursor`,r.appendChild(e)}}else if(t.content.trim().length>0){this.updateMessageEl(e);return}this.scrollToBottom()}renderMessages(){this.disposeAllInlineSprinkles(),this.messagesInner.innerHTML=``;let e=null,t=0,n=-1;for(let e=this.messages.length-1;e>=0;e--)if(this.messages[e].role===`assistant`){n=e;break}for(let r=0;r<this.messages.length;r++){let i=this.messages[r],a=this.shouldShowLabel(i,e,t),o=this.createMessageEl(i,a,r===n);this.messagesInner.appendChild(o),e=i.role,t=i.timestamp}this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}appendMessageEl(e){let t=this.messagesInner.querySelector(`.msg__feedback`);t&&t.remove();let n=this.messages.length>=2?this.messages[this.messages.length-2]:null,r=this.shouldShowLabel(e,n?.role??null,n?.timestamp??0),i=e.role===`assistant`,a=this.createMessageEl(e,r,i);this.messagesInner.appendChild(a),this.scrollToBottom()}shouldShowLabel(e,t,n){return e.source===`lick`||e.channel===`webhook`||e.channel===`cron`||e.role!==t||e.timestamp-n>12e4}updateMessageEl(e){let t=this.findMessage(e);if(!t)return;let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);if(n){this.disposeInlineSprinklesForMessage(e);let r=this.messages.indexOf(t),i=r>0?this.messages[r-1]:null,a=this.shouldShowLabel(t,i?.role??null,i?.timestamp??0),o=!1;if(t.role===`assistant`){let e=-1;for(let t=this.messages.length-1;t>=0;t--)if(this.messages[t].role===`assistant`){e=t;break}o=r===e}let s=this.createMessageEl(t,a,o);n.replaceWith(s)}this.scrollToBottom()}createMessageEl(e,t=!0,n=!1){if(e.source===`lick`||e.channel===`webhook`||e.channel===`cron`){let t=document.createElement(`div`);return t.className=`msg-group`,t.setAttribute(`data-msg-id`,e.id),t.appendChild(this.createLickEl(e)),t}let r=document.createElement(`div`);r.className=`msg-group${t?``:` msg-group--continuation`}`,r.setAttribute(`data-msg-id`,e.id);let i=document.createElement(`div`);if(i.className=`msg msg--${e.role}${e.queued?` msg--queued`:``}`,t){let t,n,r=this.currentScoopName!==null;e.role===`user`?e.source===`delegation`||e.channel===`delegation`?(t=`S`,n=`sliccy`):(t=`U`,n=`You`):r?(t=(this.currentScoopName||`S`).charAt(0).toUpperCase(),n=`@${this.currentScoopName}`):e.source&&e.source!==`cone`?(t=e.source.charAt(0).toUpperCase(),n=e.source):(t=`S`,n=`sliccy`);let a=document.createElement(`div`);a.className=`msg__role`;let o=document.createElement(`span`);if(o.className=`msg__icon`,o.textContent=t,a.appendChild(o),a.appendChild(document.createTextNode(` ${n}`)),e.queued){let t=document.createElement(`span`);t.className=`msg__queued-badge`,t.textContent=`queued`,a.appendChild(t);let n=document.createElement(`button`);n.className=`msg__queued-delete`,n.textContent=`×`,n.title=`Remove queued message`,n.addEventListener(`click`,t=>{t.stopPropagation(),this.deleteQueuedMessage(e.id)}),a.appendChild(n)}i.appendChild(a)}let a=(e.source===`lick`||e.channel===`webhook`||e.channel===`cron`)&&this.sessionId===`session-cone`,o=e.source&&e.source!==`cone`&&e.source!==`lick`&&e.role===`assistant`&&this.sessionId===`session-cone`;if(a||o){let t=document.createElement(`details`);t.className=`msg__collapsible`;let n=document.createElement(`summary`);n.className=`msg__summary`,n.textContent=e.content.slice(0,60).replace(/\n/g,` `)+(e.content.length>60?`...`:``),t.appendChild(n);let r=document.createElement(`div`);r.className=`msg__content`,r.innerHTML=yi(e),e.isStreaming||this.hydrateInlineSprinklesInEl(r,e.id),t.appendChild(r),i.appendChild(t)}else{let t=document.createElement(`div`);if(t.className=`msg__content`,t.innerHTML=yi(e),e.isStreaming){let e=document.createElement(`span`);e.className=`streaming-cursor`,t.appendChild(e)}else this.hydrateInlineSprinklesInEl(t,e.id);i.appendChild(t)}let s=e.content.trim().length>0;if(s&&r.appendChild(i),e.toolCalls)for(let t of e.toolCalls)r.appendChild(this.createToolCallEl(t));return e.role===`assistant`&&!e.isStreaming&&!e.queued&&s&&n&&r.appendChild(this.createFeedbackRow()),r}createFeedbackRow(){let e=document.createElement(`div`);e.className=`msg__feedback`;let t=document.createElement(`button`);return t.className=`msg__feedback-btn`,t.dataset.tooltip=`Copy chat`,t.setAttribute(`aria-label`,`Copy chat`),t.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="m11.75,18h-7.5c-1.24,0-2.25-1.01-2.25-2.25v-7.5c0-1.24,1.01-2.25,2.25-2.25.41,0,.75.34.75.75s-.34.75-.75.75c-.41,0-.75.34-.75.75v7.5c0,.41.34.75.75.75h7.5c.41,0,.75-.34.75-.75,0-.41.34-.75.75-.75s.75.34.75.75c0,1.24-1.01,2.25-2.25,2.25Z"/><path d="m6.75,5c-.41,0-.75-.34-.75-.75,0-1.24,1.01-2.25,2.25-2.25.41,0,.75.34.75.75s-.34.75-.75.75c-.41,0-.75.34-.75.75,0,.41-.34.75-.75.75Z"/><path d="m13,3.5h-2c-.41,0-.75-.34-.75-.75s.34-.75.75-.75h2c.41,0,.75.34.75.75s-.34.75-.75.75Z"/><path d="m13,14h-2c-.41,0-.75-.34-.75-.75s.34-.75.75-.75h2c.41,0,.75.34.75.75s-.34.75-.75.75Z"/><path d="m15.75,14c-.41,0-.75-.34-.75-.75s.34-.75.75-.75c.41,0,.75-.34.75-.75,0-.41.34-.75.75-.75s.75.34.75.75c0,1.24-1.01,2.25-2.25,2.25Z"/><path d="m17.25,5c-.41,0-.75-.34-.75-.75,0-.41-.34-.75-.75-.75-.41,0-.75-.34-.75-.75s.34-.75.75-.75c1.24,0,2.25,1.01,2.25,2.25,0,.41-.34.75-.75.75Z"/><path d="m17.25,9.75c-.41,0-.75-.34-.75-.75v-2c0-.41.34-.75.75-.75s.75.34.75.75v2c0,.41-.34.75-.75.75Z"/><path d="m6.75,9.75c-.41,0-.75-.34-.75-.75v-2c0-.41.34-.75.75-.75s.75.34.75.75v2c0,.41-.34.75-.75.75Z"/><path d="m8.25,14c-1.24,0-2.25-1.01-2.25-2.25,0-.41.34-.75.75-.75s.75.34.75.75c0,.41.34.75.75.75.41,0,.75.34.75.75s-.34.75-.75.75Z"/></svg>`,t.addEventListener(`click`,async()=>{let e=this.getMessages(),n=``;for(let t of e){let e=t.role===`user`?`User`:`Assistant`;if(n+=`## ${e}\n${t.content}\n\n`,t.toolCalls)for(let e of t.toolCalls)n+=`### Tool: ${e.name}\nInput: ${JSON.stringify(e.input,null,2)}\nResult: ${e.result??``}\n\n`}await navigator.clipboard.writeText(n),t.style.color=`var(--s2-positive)`,setTimeout(()=>{t.style.color=``},1500)}),e.appendChild(t),e}createLickEl(e){let t=document.createElement(`details`);t.className=`lick`;let n=e.channel===`webhook`?`Webhook`:e.channel===`cron`?`Cron`:`Event`,r=document.createElement(`summary`);r.className=`lick__header`,r.innerHTML=`<span class="lick__icon">E</span> <span class="lick__type">${n}</span>`;let i=document.createElement(`span`);i.className=`lick__preview`;let a=e.content.replace(/\[Webhook Event:.*?\]\n```json\n?/s,``).slice(0,50);i.textContent=a.replace(/\n/g,` `)+(a.length>=50?`...`:``),r.appendChild(i),t.appendChild(r);let o=document.createElement(`div`);return o.className=`lick__details`,o.innerHTML=Rr(e.content),t.appendChild(o),t}createToolCallEl(e){vi(e.name);let t=document.createElement(`details`);t.className=`tool-call`;let n=document.createElement(`summary`);if(n.className=`tool-call__header`,n.innerHTML=`<span class="tool-call__icon"><svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg></span> <span class="tool-call__name">${Er(e.name)}</span>`,e.input!==void 0){let t=document.createElement(`span`);t.className=`tool-call__preview`;let r=typeof e.input==`string`?e.input:JSON.stringify(e.input);t.textContent=r.slice(0,40)+(r.length>40?`...`:``),n.appendChild(t)}let r=document.createElement(`span`);e.result===void 0?r.className=`tool-call__status tool-call__status--running`:e.isError?(r.className=`tool-call__status tool-call__status--error`,r.textContent=`failed`):(r.className=`tool-call__status tool-call__status--success`,r.textContent=`✓`),n.appendChild(r),t.appendChild(n);let i=document.createElement(`div`);if(i.className=`tool-call__details`,e.input!==void 0){let t=document.createElement(`div`);t.className=`tool-call__input`;let n=document.createElement(`div`);n.className=`tool-call__label`,n.textContent=`Input:`,t.appendChild(n);let r=document.createElement(`pre`);r.innerHTML=Br(e.input),t.appendChild(r),i.appendChild(t)}if(e.result!==void 0){let t=document.createElement(`div`);t.className=`tool-call__result${e.isError?` tool-call__result--error`:``}`;let n=document.createElement(`div`);n.className=`tool-call__label`,n.textContent=e.isError?`Error:`:`Result:`,t.appendChild(n);let r=document.createElement(`pre`);r.textContent=e.result,t.appendChild(r),i.appendChild(t)}let a=e._screenshotDataUrl;if(a){let e=document.createElement(`img`);e.src=a,e.className=`tool-call__screenshot`,e.title=`Click to view full size`,e.addEventListener(`click`,e=>{e.stopPropagation();let t=window.open(`about:blank`);if(t){let e=t.document.createElement(`img`);e.src=a,t.document.title=`Screenshot`,t.document.body.style.margin=`0`,t.document.body.style.background=document.documentElement.classList.contains(`theme-light`)?`#f0f0f0`:`#141414`,t.document.body.appendChild(e)}}),i.appendChild(e)}return t.appendChild(i),t}scrollToBottom(e=!1){if(!e&&!this.autoScrollAttached){this.showJumpPill();return}requestAnimationFrame(()=>{this.messagesEl.scrollTop=this.messagesEl.scrollHeight,this.lastScrollTop=this.messagesEl.scrollTop})}showJumpPill(){this.jumpPill.classList.add(`chat__jump-pill--visible`)}hideJumpPill(){this.jumpPill.classList.remove(`chat__jump-pill--visible`)}persistSession(){this.sessionStore.saveMessages(this.sessionId,this.messages).catch(()=>{})}disposeInlineSprinklesForMessage(e){let t=this.inlineSprinkles.get(e);t&&(si(t),this.inlineSprinkles.delete(e))}disposeAllInlineSprinkles(){for(let[,e]of this.inlineSprinkles)si(e);this.inlineSprinkles.clear()}hydrateInlineSprinklesInEl(e,t){let n=oi(e,(e,t)=>this.onInlineSprinkleLick?.(e,t));n.length&&this.inlineSprinkles.set(t,n)}dispose(){this.cancelPendingDelta(),this.disposeAllInlineSprinkles(),this.unsubscribe?.(),this.voiceInput?.destroy(),this.keydownListener&&=(document.removeEventListener(`keydown`,this.keydownListener),null),this.container.innerHTML=``}},xi=class{container;terminalViewEl;previewViewEl;previewEmptyEl;previewBtn;shell=null;activeView=`terminal`;onClearTerminal;constructor(e,t={}){this.container=e,this.onClearTerminal=t.onClearTerminal??null,this.render()}async mountShell(e){this.shell?.setPreviewStateListener(null),this.shell=e;let t=document.createElement(`div`);t.className=`terminal-panel__mount`,this.terminalViewEl.appendChild(t),await e.mount(t);let n=t.querySelector(`.terminal-panel__terminal-host`),r=t.querySelector(`.terminal-panel__preview`);if(!n||!r)throw Error(`terminal mount did not create expected hosts`);this.terminalViewEl.replaceChildren(n),this.previewViewEl.replaceChildren(this.previewEmptyEl),this.previewViewEl.appendChild(r),e.setPreviewStateListener(e=>this.handlePreviewStateChange(e))}clearTerminal(){this.shell?.clearTerminal()}async runCommand(e){return this.shell?(/^\s*imgcat(?:\s|$)/.test(e)||this.setActiveView(`terminal`),this.shell.executeCommandInTerminal(e)):{stdout:``,stderr:`terminal is unavailable
|
|
179
179
|
`,exitCode:1}}refit(){this.shell?.refit()}getBodyElement(){return this.container}render(){this.container.innerHTML=``,this.container.classList.add(`terminal-panel`);let e=document.createElement(`div`);e.className=`file-browser__header`;let t=document.createElement(`span`);if(t.className=`file-browser__header-title`,t.textContent=`Terminal`,e.appendChild(t),this.onClearTerminal){let t=document.createElement(`button`);t.className=`file-browser__header-btn`,t.dataset.tooltip=`Clear Terminal`,t.setAttribute(`aria-label`,`Clear Terminal`),t.innerHTML=`<svg width="14" height="14" viewBox="0 0 20 20" fill="none"><path d="m8.249,15.021c-.4,0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.778.01-.001.021-.001.03-.001.4,0,.733.317.748.72l.25,6.5c.017.414-.307.763-.72.778-.01.001-.021.001-.03.001Z" fill="currentColor"/><path d="m11.751,15.021c-.01,0-.02,0-.03-.001-.413-.016-.736-.364-.72-.778l.25-6.5c.015-.403.348-.72.748-.72.01,0,.02,0,.03.001.413.016.736.364.72.778l-.25,6.5c-.015.403-.348.72-.748.72Z" fill="currentColor"/><path d="m17,4h-3.5v-.75c0-1.24-1.01-2.25-2.25-2.25h-2.5c-1.24,0-2.25,1.01-2.25,2.25v.75h-3.5c-.414,0-.75.336-.75.75s.336.75.75.75h.52l.422,10.342c.048,1.21,1.036,2.158,2.248,2.158h7.619c1.212,0,2.2-.948,2.248-2.158l.422-10.342h.52c.414,0,.75-.336.75-.75s-.336-.75-.75-.75Zm-9-.75c0-.413.337-.75.75-.75h2.5c.413,0,.75.337.75.75v.75h-4v-.75Zm6.56,12.531c-.017.403-.346.719-.75.719h-7.619c-.404,0-.733-.316-.75-.719l-.42-10.281h9.959l-.42,10.281Z" fill="currentColor"/></svg>`,t.addEventListener(`click`,()=>this.onClearTerminal()),e.appendChild(t)}this.previewBtn=document.createElement(`button`),this.previewBtn.className=`file-browser__header-btn`,this.previewBtn.setAttribute(`aria-label`,`Toggle preview`),this.previewBtn.dataset.tooltip=`Preview`,this.previewBtn.disabled=!0;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 20 20`),r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,`1.5`),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`stroke-linejoin`,`round`);let i=document.createElementNS(n,`path`);i.setAttribute(`d`,`M2 10s3-6 8-6 8 6 8 6-3 6-8 6-8-6-8-6z`),r.appendChild(i);let a=document.createElementNS(n,`circle`);a.setAttribute(`cx`,`10`),a.setAttribute(`cy`,`10`),a.setAttribute(`r`,`2.5`),r.appendChild(a),this.previewBtn.appendChild(r),this.previewBtn.addEventListener(`click`,()=>{this.previewBtn.disabled||this.setActiveView(this.activeView===`preview`?`terminal`:`preview`)}),e.appendChild(this.previewBtn),this.container.appendChild(e),this.terminalViewEl=document.createElement(`div`),this.terminalViewEl.className=`terminal-panel__view`,this.container.appendChild(this.terminalViewEl),this.previewViewEl=document.createElement(`div`),this.previewViewEl.className=`terminal-panel__view`,this.container.appendChild(this.previewViewEl),this.previewEmptyEl=document.createElement(`div`),this.previewEmptyEl.className=`terminal-panel__empty-state`,this.previewEmptyEl.textContent=`Run imgcat to preview media here.`,this.previewViewEl.appendChild(this.previewEmptyEl),this.setActiveView(`terminal`)}dispose(){this.shell?.setPreviewStateListener(null),this.shell?.dispose(),this.container.innerHTML=``}setActiveView(e){this.activeView=e,this.previewBtn.classList.toggle(`file-browser__header-btn--active`,e===`preview`),this.terminalViewEl.style.display=e===`terminal`?`flex`:`none`,this.previewViewEl.style.display=e===`preview`?`flex`:`none`,e===`terminal`&&this.refit()}handlePreviewStateChange(e){this.previewBtn.disabled=!e,this.previewEmptyEl.style.display=e?`none`:`flex`,e?this.setActiveView(`preview`):this.activeView===`preview`&&this.setActiveView(`terminal`)}};function Si(e){return e<1024?e+` B`:e<1024*1024?(e/1024).toFixed(1)+`K`:e<1024*1024*1024?(e/(1024*1024)).toFixed(1)+`M`:(e/(1024*1024*1024)).toFixed(1)+`G`}function Ci(e){let t=`http://www.w3.org/2000/svg`,n=document.createElementNS(t,`svg`);n.setAttribute(`width`,`14`),n.setAttribute(`height`,`14`),n.setAttribute(`viewBox`,`0 0 20 20`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`1.5`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`stroke-linejoin`,`round`),n.style.flexShrink=`0`;for(let r of e){let e=document.createElementNS(t,`path`);e.setAttribute(`d`,r),n.appendChild(e)}return n}function wi(){return Ci([`M2 6V5a1 1 0 0 1 1-1h4l2 2h8a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6z`])}function Ti(){return Ci([`M6 2h5l5 5v9a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z`,`M11 2v5h5`])}function Ei(e){let t=`http://www.w3.org/2000/svg`,n=document.createElementNS(t,`svg`);n.setAttribute(`width`,`10`),n.setAttribute(`height`,`10`),n.setAttribute(`viewBox`,`0 0 20 20`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`2`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`stroke-linejoin`,`round`),n.style.flexShrink=`0`,n.style.transition=`transform 130ms ease`,e&&(n.style.transform=`rotate(90deg)`);let r=document.createElementNS(t,`path`);return r.setAttribute(`d`,`M7 5l5 5-5 5`),n.appendChild(r),n}function Di(e){return`'${e.replace(/'/g,`'\\''`)}'`}function Oi(e){return`${f(e)?`imgcat`:`cat`} ${Di(e)}`}var ki=class{container;bodyEl;fs=null;expandedDirs=new Set([`/`]);refreshTimer=null;onRunCommand;onClearFilesystem;selectedPath=null;keydownHandler=null;constructor(e,t={}){this.container=e,this.onRunCommand=t.onRunCommand??null,this.onClearFilesystem=t.onClearFilesystem??null,this.render()}setFs(e){this.fs=e,this.refresh(),this.refreshTimer=setInterval(()=>this.refresh(),3e3)}async refresh(){if(!this.fs)return;let e=document.createElement(`div`);try{await this.renderDir(`/`,e,0)}catch(e){console.warn(`[FileBrowser] Refresh failed:`,e instanceof Error?e.message:String(e));return}if(e.innerHTML===this.bodyEl.innerHTML){this.applySelection();return}let t=this.container.contains(document.activeElement);for(;this.bodyEl.firstChild;)this.bodyEl.removeChild(this.bodyEl.firstChild);for(;e.firstChild;)this.bodyEl.appendChild(e.firstChild);this.applySelection(),t&&this.selectedPath&&this.bodyEl.querySelector(`.file-browser__item--selected`)?.focus()}render(){for(;this.container.firstChild;)this.container.removeChild(this.container.firstChild);if(this.container.classList.add(`file-browser`),this.onClearFilesystem){let e=document.createElement(`div`);e.className=`file-browser__header`;let t=document.createElement(`span`);t.className=`file-browser__header-title`,t.textContent=`Files`,e.appendChild(t);let n=document.createElement(`button`);n.className=`file-browser__header-btn`,n.setAttribute(`aria-label`,`Clear filesystem`),n.dataset.tooltip=`Clear filesystem`,n.innerHTML=`<svg width="14" height="14" viewBox="0 0 20 20" fill="none"><path d="m8.249,15.021c-.4,0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.778.01-.001.021-.001.03-.001.4,0,.733.317.748.72l.25,6.5c.017.414-.307.763-.72.778-.01.001-.021.001-.03.001Z" fill="currentColor"/><path d="m11.751,15.021c-.01,0-.02,0-.03-.001-.413-.016-.736-.364-.72-.778l.25-6.5c.015-.403.348-.72.748-.72.01,0,.02,0,.03.001.413.016.736.364.72.778l-.25,6.5c-.015.403-.348.72-.748.72Z" fill="currentColor"/><path d="m17,4h-3.5v-.75c0-1.24-1.01-2.25-2.25-2.25h-2.5c-1.24,0-2.25,1.01-2.25,2.25v.75h-3.5c-.414,0-.75.336-.75.75s.336.75.75.75h.52l.422,10.342c.048,1.21,1.036,2.158,2.248,2.158h7.619c1.212,0,2.2-.948,2.248-2.158l.422-10.342h.52c.414,0,.75-.336.75-.75s-.336-.75-.75-.75Zm-9-.75c0-.413.337-.75.75-.75h2.5c.413,0,.75.337.75.75v.75h-4v-.75Zm6.56,12.531c-.017.403-.346.719-.75.719h-7.619c-.404,0-.733-.316-.75-.719l-.42-10.281h9.959l-.42,10.281Z" fill="currentColor"/></svg>`,n.addEventListener(`click`,async()=>{await this.onClearFilesystem?.(),location.reload()}),e.appendChild(n),this.container.appendChild(e)}this.bodyEl=document.createElement(`div`),this.bodyEl.className=`file-browser__body`,this.container.appendChild(this.bodyEl),this.setupKeydown()}async renderDir(e,t,n){if(!this.fs)return;let r;try{r=await this.fs.readDir(e)}catch(t){console.warn(`[FileBrowser] readDir failed:`,e,t instanceof Error?t.message:String(t));return}let i=r.filter(e=>e.type===`directory`).sort((e,t)=>e.name.localeCompare(t.name)),a=r.filter(e=>e.type===`file`).sort((e,t)=>e.name.localeCompare(t.name));for(let r of[...i,...a]){let i=e===`/`?`/`+r.name:e+`/`+r.name,a=document.createElement(`div`);if(a.className=`file-browser__item`,a.style.paddingLeft=12+n*16+`px`,a.dataset.path=r.type===`directory`&&!i.endsWith(`/`)?i+`/`:i,r.type===`directory`){let e=this.expandedDirs.has(i),o=document.createElement(`span`);o.className=`file-browser__arrow`,o.appendChild(Ei(e)),a.appendChild(o);let s=document.createElement(`span`);s.className=`file-browser__icon`,s.appendChild(wi()),a.appendChild(s);let c=document.createElement(`span`);c.className=`file-browser__name`,c.textContent=r.name,a.appendChild(c);let l=document.createElement(`button`);l.className=`file-browser__action-btn`,l.style.marginLeft=`auto`,l.textContent=`ZIP`,l.title=`Download as ZIP`,l.addEventListener(`click`,e=>{e.stopPropagation(),this.downloadDirAsZip(i,r.name)}),a.appendChild(l),a.style.cursor=`pointer`,a.addEventListener(`click`,()=>{this.selectPath(i,`directory`),this.expandedDirs.has(i)?this.expandedDirs.delete(i):this.expandedDirs.add(i),this.refresh()}),t.appendChild(a),e&&await this.renderDir(i,t,n+1)}else{let e=document.createElement(`span`);e.className=`file-browser__arrow`,a.appendChild(e);let n=document.createElement(`span`);n.className=`file-browser__icon`,n.appendChild(Ti()),a.appendChild(n);let o=document.createElement(`span`);o.className=`file-browser__name`,o.textContent=r.name,a.appendChild(o);try{let e=await this.fs.stat(i),t=document.createElement(`span`);t.className=`file-browser__size`,t.textContent=Si(e.size),a.appendChild(t)}catch(e){console.warn(`[FileBrowser] stat failed:`,i,e instanceof Error?e.message:String(e))}let s=document.createElement(`button`);s.className=`file-browser__action-btn`,s.style.marginLeft=`8px`,s.textContent=`CAT`,s.title=this.onRunCommand?f(i)?`Preview media in terminal`:`Preview in terminal`:`Terminal unavailable`,s.disabled=!this.onRunCommand,s.addEventListener(`click`,e=>{e.stopPropagation(),this.previewFile(i)}),a.appendChild(s),a.addEventListener(`click`,()=>{this.selectPath(i,`file`)}),t.appendChild(a)}}}async collectFiles(e,t){if(!this.fs)return{};let n={},r=await this.fs.readDir(e);for(let i of r){let r=e===`/`?`/`+i.name:e+`/`+i.name,a=t?t+`/`+i.name:i.name;if(i.type===`directory`){let e=await this.collectFiles(r,a);Object.assign(n,e)}else{let e=await this.fs.readFile(r,{encoding:`binary`});n[a]=e instanceof Uint8Array?e:new TextEncoder().encode(e)}}return n}async downloadDirAsZip(e,t){if(this.fs)try{let n=le(await this.collectFiles(e,``)),r=new Blob([n.buffer],{type:`application/zip`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t+`.zip`,a.click(),URL.revokeObjectURL(i)}catch(t){console.error(`[FileBrowser] ZIP download failed:`,e,t instanceof Error?t.message:String(t))}}previewFile(e){if(!this.onRunCommand)return;let t=Oi(e);Promise.resolve(this.onRunCommand(t)).catch(t=>{console.error(`[FileBrowser] Preview command failed:`,e,t instanceof Error?t.message:String(t))})}selectPath(e,t){this.selectedPath=t===`directory`&&!e.endsWith(`/`)?e+`/`:e,this.applySelection(),this.bodyEl.querySelector(`.file-browser__item--selected`)?.focus()}applySelection(){let e=this.bodyEl.querySelector(`.file-browser__item--selected`);if(e&&(e.classList.remove(`file-browser__item--selected`),e.removeAttribute(`tabindex`)),!this.selectedPath)return;let t=this.bodyEl.querySelectorAll(`.file-browser__item`);for(let e of t)if(e.dataset.path===this.selectedPath){e.classList.add(`file-browser__item--selected`),e.tabIndex=0;break}}setupKeydown(){this.keydownHandler=e=>{!(e.metaKey||e.ctrlKey)||e.key!==`c`||this.selectedPath&&window.getSelection()?.isCollapsed!==!1&&(e.preventDefault(),navigator.clipboard.writeText(this.selectedPath).then(()=>{this.flashCopyFeedback()}).catch(e=>{console.warn(`[FileBrowser] Clipboard write failed:`,e instanceof Error?e.message:String(e))}))},this.container.addEventListener(`keydown`,this.keydownHandler)}flashCopyFeedback(){let e=this.bodyEl.querySelector(`.file-browser__item--selected`);e&&(e.classList.add(`file-browser__item--copy-flash`),setTimeout(()=>{e.classList.remove(`file-browser__item--copy-flash`)},300))}dispose(){for(this.keydownHandler&&=(this.container.removeEventListener(`keydown`,this.keydownHandler),null),this.refreshTimer&&=(clearInterval(this.refreshTimer),null);this.container.firstChild;)this.container.removeChild(this.container.firstChild)}},Ai=class{container;bodyEl;orchestrator=null;selectedScoopJid=null;refreshTimer=null;constructor(e){this.container=e,this.render()}setOrchestrator(e){this.orchestrator=e,this.refresh(),this.refreshTimer=setInterval(()=>this.refresh(),5e3)}setSelectedScoop(e){this.selectedScoopJid=e,this.refresh()}async refresh(){if(!this.orchestrator)return;let e=document.createElement(`div`);e.className=`memory-panel__content`;let t=document.createElement(`div`);t.className=`memory-panel__section`;let n=document.createElement(`div`);n.className=`memory-panel__section-header`,n.textContent=`Global Memory (/shared/CLAUDE.md)`,t.appendChild(n);let r=document.createElement(`div`);r.className=`memory-panel__memory-content`;try{r.textContent=await this.orchestrator.getGlobalMemory()||`(empty)`}catch{r.textContent=`(not available)`}if(t.appendChild(r),e.appendChild(t),this.selectedScoopJid){let t=this.orchestrator.getScoopContext(this.selectedScoopJid),n=this.orchestrator.getScoop(this.selectedScoopJid);if(t&&n){let r=document.createElement(`div`);r.className=`memory-panel__section`;let i=document.createElement(`div`);i.className=`memory-panel__section-header`,i.textContent=`${n.isCone?`Cone`:`Scoop`}: ${n.assistantLabel}`,r.appendChild(i);let a=document.createElement(`div`);a.className=`memory-panel__memory-content`;try{let e=t.getFS();if(e){let t=n.isCone?`/workspace/CLAUDE.md`:`/scoops/${n.folder}/CLAUDE.md`,r=await e.readFile(t,{encoding:`utf-8`});a.textContent=typeof r==`string`?r:new TextDecoder().decode(r)}else a.textContent=`(filesystem not ready)`}catch{a.textContent=`(no memory file yet)`}r.appendChild(a),e.appendChild(r)}}if(e.innerHTML!==this.bodyEl.innerHTML){for(;this.bodyEl.firstChild;)this.bodyEl.removeChild(this.bodyEl.firstChild);for(;e.firstChild;)this.bodyEl.appendChild(e.firstChild)}}render(){for(;this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.classList.add(`memory-panel`),this.bodyEl=document.createElement(`div`),this.bodyEl.className=`memory-panel__body`,this.container.appendChild(this.bodyEl)}dispose(){this.refreshTimer&&=(clearInterval(this.refreshTimer),null)}},ji=r(`scoops-panel`),Mi=class{container;orchestrator=null;callbacks;selectedScoopJid=null;scoopStatuses=new Map;expanded=!1;constructor(e,t){this.container=e,this.callbacks=t,this.render()}toggleExpanded(){this.expanded=!this.expanded,this.container.classList.toggle(`layout__scoops--expanded`,this.expanded);let e=this.container.querySelector(`.scoops-hamburger`);e&&(e.innerHTML=this.expanded?`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M9.86241 16.4551C9.66612 16.4551 9.46886 16.3779 9.32237 16.2246L3.83507 10.5215C3.5548 10.2315 3.5548 9.77247 3.83507 9.48243L9.33507 3.76563C9.62218 3.4668 10.0978 3.45801 10.3946 3.74512C10.6935 4.03223 10.7032 4.50684 10.4151 4.80469L5.41613 10.002L10.4025 15.1855C10.6906 15.4834 10.6808 15.958 10.382 16.2451C10.2374 16.3857 10.0499 16.4551 9.86241 16.4551Z"/><path d="M15.6124 16.4551C15.4161 16.4551 15.2189 16.3779 15.0724 16.2246L9.58507 10.5215C9.3048 10.2315 9.3048 9.77247 9.58507 9.48243L15.0851 3.76563C15.3722 3.4668 15.8478 3.45801 16.1446 3.74512C16.4435 4.03223 16.4532 4.50684 16.1652 4.80469L11.1661 10.002L16.1525 15.1855C16.4406 15.4834 16.4308 15.958 16.132 16.2451C15.9874 16.3857 15.7999 16.4551 15.6124 16.4551Z"/></svg>`:`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M9.61805 16.2451C9.31922 15.958 9.30945 15.4834 9.59754 15.1855L14.5839 10.002L9.58485 4.80469C9.29677 4.50684 9.30653 4.03223 9.60536 3.74512C9.90223 3.45801 10.3778 3.4668 10.6649 3.76563L16.1649 9.48243C16.4452 9.77247 16.4452 10.2315 16.1649 10.5215L10.6776 16.2246C10.5311 16.3779 10.3339 16.4551 10.1376 16.4551C9.95008 16.4551 9.76258 16.3857 9.61805 16.2451Z"/><path d="M3.86805 16.2451C3.56922 15.958 3.55945 15.4834 3.84754 15.1855L8.83387 10.002L3.83485 4.80469C3.54677 4.50684 3.55653 4.03223 3.85536 3.74512C4.15223 3.45801 4.62782 3.4668 4.91493 3.76563L10.4149 9.48243C10.6952 9.77247 10.6952 10.2315 10.4149 10.5215L4.92763 16.2246C4.78114 16.3779 4.58388 16.4551 4.38759 16.4551C4.20008 16.4551 4.01258 16.3857 3.86805 16.2451Z"/></svg>`)}setOrchestrator(e){this.orchestrator=e,this.refreshScoops()}updateScoopStatus(e,t){this.scoopStatuses.set(e,t),this.refreshScoops()}refreshScoops(){if(!this.orchestrator)return;document.querySelectorAll(`.scoop-fixed-tooltip`).forEach(e=>e.remove());let e=this.orchestrator.getScoops(),t=e.find(e=>e.isCone),n=e.filter(e=>!e.isCone),r=`http://www.w3.org/2000/svg`,i=[`#e8457a`,`#f08c5a`,`#9b6dd7`,`#42b8a0`,`#d4953e`],a=[`#fde4ec`,`#fef0e4`,`#efe4f8`,`#e0f5ef`,`#fef3e0`],o=this.container.querySelector(`.scoop-cone-header`);if(o){for(;o.firstChild;)o.removeChild(o.firstChild);if(t){let e=this.scoopStatuses.get(t.jid)??`inactive`,n=t.jid===this.selectedScoopJid,i=`#e07030`,a=`#fef0e0`,s=document.createElement(`div`);s.className=`scoop-item scoop-item--cone ${n?`selected`:``} status-${e}`,s.dataset.jid=t.jid,s.setAttribute(`aria-label`,t.assistantLabel),s.style.setProperty(`--scoop-accent`,i),s.style.setProperty(`--scoop-accent-bg`,a);let c=document.createElement(`div`);c.className=`scoop-icon-wrap scoop-icon-wrap--cone`,c.style.background=a,c.style.width=`40px`,c.style.height=`40px`;let l=document.createElementNS(r,`svg`);l.setAttribute(`width`,`24`),l.setAttribute(`height`,`24`),l.setAttribute(`fill`,i),l.setAttribute(`viewBox`,`100 195 230 235`);let u=document.createElementNS(r,`path`);if(u.setAttribute(`d`,`M331.2,128.8c1.6-4.8,2.4-11.2,2.4-16.8c0-20.8-12.8-40-31.2-48.8c-8-36-47.2-63.2-92.8-63.2c-48,0-88,29.6-93.6,68.8C102.4,79.2,94.4,95.2,94.4,112c0,4.8,0.8,9.6,1.6,13.6c-7.2,9.6-10.4,20.8-10.4,32C85.6,180,100,200,120,208l85.6,212.8c1.6,3.2,4,4.8,7.2,4.8s6.4-1.6,7.2-4.8L305.6,208c20-8,34.4-27.2,34.4-50.4C340,147.2,336.8,136.8,331.2,128.8z M139.2,216l-1.6-3.2h0.8c1.6,0,2.4,0,4,0L139.2,216z M145.6,232.8l23.2-24.8c4.8,6.4,11.2,11.2,18.4,14.4l12,12l-28.8,30.4l-20.8-22.4L145.6,232.8z M210.4,246.4l28.8,30.4L210.4,308l-28.8-31.2L210.4,246.4z M168.8,289.6l1.6-1.6l28.8,32l-12.8,13.6L168.8,289.6z M212,396.8l-18.4-46.4l16.8-18.4l19.2,21.6L212,396.8z M236.8,336l-15.2-16.8l28.8-31.2l4,4L236.8,336z M250.4,264.8l-28.8-30.4l11.2-12c8-3.2,14.4-8,19.2-14.4l25.6,27.2L250.4,264.8z M284,218.4l-6.4-6.4c2.4,0,4.8,0.8,8,0.8h0.8L284,218.4z M285.6,196c-9.6,0-19.2-4-26.4-11.2c-1.6-1.6-4.8-2.4-7.2-2.4c-2.4,0.8-4.8,2.4-5.6,4.8c-6.4,13.6-20,23.2-35.2,23.2c-14.4,0-28-8.8-34.4-21.6c-0.8-2.4-3.2-4-5.6-4.8c-0.8,0-0.8,0-1.6,0c-1.6,0-4,0.8-5.6,2.4c-7.2,6.4-16,9.6-25.6,9.6c-20.8,0-38.4-16.8-38.4-38.4c0-9.6,3.2-18.4,9.6-24.8c1.6-2.4,2.4-5.6,1.6-8c-1.6-4-2.4-8.8-2.4-12.8c0-12.8,6.4-24.8,17.6-32c2.4-1.6,3.2-4,4-6.4c2.4-32,36.8-57.6,78.4-57.6c39.2,0,72.8,23.2,77.6,54.4c0.8,3.2,2.4,5.6,4.8,6.4c15.2,5.6,24.8,20,24.8,36c0,4.8-0.8,10.4-3.2,15.2c-0.8,2.4-0.8,5.6,0.8,8c4.8,6.4,8,14.4,8,23.2C323.2,179.2,306.4,196,285.6,196z`),l.appendChild(u),c.appendChild(l),e===`processing`||e===`ready`||e===`error`){let t=document.createElement(`span`);t.className=`scoop-dot scoop-dot--${e}`,c.appendChild(t)}s.appendChild(c);let d=document.createElement(`div`);d.className=`scoop-info`;let f=document.createElement(`div`);if(f.className=`scoop-name`,f.textContent=t.assistantLabel,d.appendChild(f),e===`processing`||e===`error`){let t=document.createElement(`div`);t.className=`scoop-subtitle`,t.textContent=e===`processing`?`Working…`:`Error`,d.appendChild(t)}s.appendChild(d);let p=document.createElement(`div`);if(p.className=`scoop-actions`,e===`processing`){let e=document.createElement(`span`);e.className=`scoop-spin-dot`,p.appendChild(e)}else if(e===`error`){let e=document.createElement(`span`);e.className=`scoop-err-dot`,p.appendChild(e)}s.appendChild(p),s.addEventListener(`click`,()=>this.selectScoop(t));let m=t.assistantLabel;s.addEventListener(`mouseenter`,()=>{if(this.expanded)return;let e=document.createElement(`div`);e.className=`scoop-fixed-tooltip`,e.textContent=m,document.body.appendChild(e);let t=s.getBoundingClientRect();e.style.top=`${t.top+t.height/2}px`,e.style.left=`${t.right+8}px`,s.__tip=e}),s.addEventListener(`mouseleave`,()=>{let e=s.__tip;e&&(e.remove(),s.__tip=null)}),o.appendChild(s)}}let s=this.container.querySelector(`.scoops-list`);if(s){for(;s.firstChild;)s.removeChild(s.firstChild);if(n.length===0){this.callbacks.onScoopsChanged?.(e);return}for(let e=0;e<n.length;e++){let t=n[e],o=this.scoopStatuses.get(t.jid)??`inactive`,c=t.jid===this.selectedScoopJid,l=i[e%i.length],u=a[e%a.length],d=document.createElement(`div`);d.className=`scoop-item ${c?`selected`:``} status-${o}`,d.dataset.jid=t.jid;let f=t.assistantLabel.replace(/-scoop$/,``);d.setAttribute(`aria-label`,f),d.style.setProperty(`--scoop-accent`,l),d.style.setProperty(`--scoop-accent-bg`,u);let p=document.createElement(`div`);p.className=`scoop-icon-wrap`,p.style.background=u;let m=document.createElementNS(r,`svg`);m.setAttribute(`width`,`20`),m.setAttribute(`height`,`20`),m.setAttribute(`fill`,l),m.setAttribute(`viewBox`,`70 0 290 210`);let h=document.createElementNS(r,`path`);if(h.setAttribute(`d`,`M331.2,128.8c1.6-4.8,2.4-11.2,2.4-16.8c0-20.8-12.8-40-31.2-48.8c-8-36-47.2-63.2-92.8-63.2c-48,0-88,29.6-93.6,68.8C102.4,79.2,94.4,95.2,94.4,112c0,4.8,0.8,9.6,1.6,13.6c-7.2,9.6-10.4,20.8-10.4,32C85.6,180,100,200,120,208l85.6,212.8c1.6,3.2,4,4.8,7.2,4.8s6.4-1.6,7.2-4.8L305.6,208c20-8,34.4-27.2,34.4-50.4C340,147.2,336.8,136.8,331.2,128.8z M285.6,196c-9.6,0-19.2-4-26.4-11.2c-1.6-1.6-4.8-2.4-7.2-2.4c-2.4,0.8-4.8,2.4-5.6,4.8c-6.4,13.6-20,23.2-35.2,23.2c-14.4,0-28-8.8-34.4-21.6c-0.8-2.4-3.2-4-5.6-4.8c-0.8,0-0.8,0-1.6,0c-1.6,0-4,0.8-5.6,2.4c-7.2,6.4-16,9.6-25.6,9.6c-20.8,0-38.4-16.8-38.4-38.4c0-9.6,3.2-18.4,9.6-24.8c1.6-2.4,2.4-5.6,1.6-8c-1.6-4-2.4-8.8-2.4-12.8c0-12.8,6.4-24.8,17.6-32c2.4-1.6,3.2-4,4-6.4c2.4-32,36.8-57.6,78.4-57.6c39.2,0,72.8,23.2,77.6,54.4c0.8,3.2,2.4,5.6,4.8,6.4c15.2,5.6,24.8,20,24.8,36c0,4.8-0.8,10.4-3.2,15.2c-0.8,2.4-0.8,5.6,0.8,8c4.8,6.4,8,14.4,8,23.2C323.2,179.2,306.4,196,285.6,196z`),m.appendChild(h),p.appendChild(m),o===`processing`||o===`ready`||o===`error`){let e=document.createElement(`span`);e.className=`scoop-dot scoop-dot--${o}`,p.appendChild(e)}d.appendChild(p);let g=document.createElement(`div`);g.className=`scoop-info`;let _=document.createElement(`div`);if(_.className=`scoop-name`,_.textContent=f,g.appendChild(_),o===`processing`||o===`error`){let e=document.createElement(`div`);e.className=`scoop-subtitle`,e.textContent=o===`processing`?`Working…`:`Error`,g.appendChild(e)}d.appendChild(g);let v=document.createElement(`div`);if(v.className=`scoop-actions`,o===`processing`){let e=document.createElement(`span`);e.className=`scoop-spin-dot`,v.appendChild(e)}else if(o===`error`){let e=document.createElement(`span`);e.className=`scoop-err-dot`,v.appendChild(e)}let y=document.createElement(`button`);y.className=`scoop-delete`,y.dataset.tooltip=`Delete scoop`,y.setAttribute(`aria-label`,`Delete scoop`),y.innerHTML=`<svg width="14" height="14" viewBox="0 0 20 20" fill="none"><path d="M6 6L14 14M14 6L6 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>`,v.appendChild(y),d.appendChild(v),d.addEventListener(`click`,e=>{e.target.closest(`.scoop-delete`)?this.deleteScoop(t.jid):this.selectScoop(t)}),d.addEventListener(`mouseenter`,()=>{if(this.expanded)return;let e=document.createElement(`div`);e.className=`scoop-fixed-tooltip`,e.textContent=f,document.body.appendChild(e);let t=d.getBoundingClientRect();e.style.top=`${t.top+t.height/2}px`,e.style.left=`${t.right+8}px`,d.__tip=e}),d.addEventListener(`mouseleave`,()=>{let e=d.__tip;e&&(e.remove(),d.__tip=null)}),s.appendChild(d)}this.callbacks.onScoopsChanged?.(e)}}selectScoop(e){this.selectedScoopJid=e.jid,this.refreshScoops(),this.callbacks.onScoopSelect(e);let t=new URL(window.location.href);e.isCone?t.searchParams.delete(`scoop`):t.searchParams.set(`scoop`,e.folder),history.replaceState(null,``,t.toString())}selectScoopByFolder(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoops().find(t=>t.folder===e);t&&this.selectScoop(t)}setSelectedJid(e){this.selectedScoopJid=e,this.refreshScoops()}getSelectedScoopJid(){return this.selectedScoopJid}async deleteScoop(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoop(e);if(t){if(t.isCone){alert(`Cannot delete the cone`);return}if(confirm(`Delete scoop "${t.name}"? This cannot be undone.`)){try{await this.orchestrator.unregisterScoop(e)}catch(e){let t=e instanceof Error?e.message:String(e);alert(t);return}this.selectedScoopJid===e&&(this.selectedScoopJid=null),this.refreshScoops(),ji.info(`Scoop deleted`,{jid:e,name:t.name})}}}async createScoop(e,t=!1){if(!this.orchestrator)throw Error(`Orchestrator not set`);let n=t?`cone`:this.sanitizeFolderName(e)+`-scoop`,r=t?`cone_${Date.now()}`:`scoop_${n}_${Date.now()}`,i={jid:r,name:e,folder:n,trigger:t?void 0:`@${n}`,requiresTrigger:!t,isCone:t,type:t?`cone`:`scoop`,assistantLabel:t?`sliccy`:n,addedAt:new Date().toISOString()};return await this.orchestrator.registerScoop(i),this.refreshScoops(),ji.info(`Scoop created`,{jid:r,name:e,isCone:t}),i}sanitizeFolderName(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,50)||`scoop`}render(){for(;this.container.firstChild;)this.container.removeChild(this.container.firstChild);let e=document.createElement(`div`);e.className=`scoops-panel`;let t=document.createElement(`button`);t.className=`scoops-hamburger`,t.dataset.tooltip=`Toggle navigation`,t.dataset.tooltipPos=`right`,t.setAttribute(`aria-label`,`Toggle navigation`),t.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M9.61805 16.2451C9.31922 15.958 9.30945 15.4834 9.59754 15.1855L14.5839 10.002L9.58485 4.80469C9.29677 4.50684 9.30653 4.03223 9.60536 3.74512C9.90223 3.45801 10.3778 3.4668 10.6649 3.76563L16.1649 9.48243C16.4452 9.77247 16.4452 10.2315 16.1649 10.5215L10.6776 16.2246C10.5311 16.3779 10.3339 16.4551 10.1376 16.4551C9.95008 16.4551 9.76258 16.3857 9.61805 16.2451Z"/><path d="M3.86805 16.2451C3.56922 15.958 3.55945 15.4834 3.84754 15.1855L8.83387 10.002L3.83485 4.80469C3.54677 4.50684 3.55653 4.03223 3.85536 3.74512C4.15223 3.45801 4.62782 3.4668 4.91493 3.76563L10.4149 9.48243C10.6952 9.77247 10.6952 10.2315 10.4149 10.5215L4.92763 16.2246C4.78114 16.3779 4.58388 16.4551 4.38759 16.4551C4.20008 16.4551 4.01258 16.3857 3.86805 16.2451Z"/></svg>`,t.addEventListener(`click`,()=>this.toggleExpanded()),e.appendChild(t);let n=document.createElement(`div`);n.className=`scoop-cone-header`,e.appendChild(n);let r=document.createElement(`div`);r.className=`scoops-list`,e.appendChild(r),this.container.appendChild(e);let i=document.createElement(`style`);i.textContent=`
|
|
180
180
|
.scoops-panel {
|
|
181
181
|
display: flex;
|
|
@@ -2766,7 +2766,7 @@ except BaseException:
|
|
|
2766
2766
|
`,stderr:``,exitCode:0}}function XW(e){let t=``,n=8192;for(let r=0;r<e.length;r+=n)t+=String.fromCharCode(...e.subarray(r,r+n));return btoa(t)}function ZW(){return HP(`open`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return YW();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
|
|
2767
2767
|
`,exitCode:1};let n=e.includes(`--download`)||e.includes(`-d`),r=e.includes(`--view`)||e.includes(`-v`),i=e.filter(e=>!JW.includes(e));if(i.length===0)return YW();let a=[];for(let e of i){if(MW(e)){window.open(e,`_blank`,`noopener,noreferrer`),a.push(`opened ${e}`);continue}let i=t.fs.resolvePath(t.cwd,e);if(i.endsWith(`.shtml`)){let e=typeof window<`u`?window.__slicc_sprinkleManager:void 0;if(e){let t=(i.split(`/`).pop()??``).replace(/\.shtml$/,``);try{await e.open(t),a.push(`opened sprinkle ${t} from ${i}`)}catch(e){return{stdout:``,stderr:`open: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}else{let e=LW(i);window.open(e,`_blank`,`noopener,noreferrer`),a.push(`opened ${i} → ${e}`)}continue}if(r){let n;try{n=await t.fs.stat(i)}catch{return{stdout:``,stderr:`open: no such file: ${e}\n`,exitCode:1}}if(!n.isFile)return{stdout:``,stderr:`open: not a file: ${e}\n`,exitCode:1};let r;try{r=await t.fs.readFileBuffer(i)}catch{return{stdout:``,stderr:`open: failed to read: ${e}\n`,exitCode:1}}let o=IW(i),s=XW(new Uint8Array(r));a.push(`${i} (${Math.round(r.byteLength/1024)} KB)\n<img:data:${o};base64,${s}>`)}else if(n){let n;try{n=await t.fs.stat(i)}catch{return{stdout:``,stderr:`open: no such file: ${e}\n`,exitCode:1}}if(!n.isFile)return{stdout:``,stderr:`open: not a file: ${e}\n`,exitCode:1};let r;try{r=await t.fs.readFileBuffer(i)}catch{return{stdout:``,stderr:`open: failed to read: ${e}\n`,exitCode:1}}let o=new Uint8Array(r.byteLength);o.set(r);let s=new Blob([o.buffer],{type:IW(i)}),c=URL.createObjectURL(s),l=document.createElement(`a`);l.href=c,l.download=kW(i)||`download`,l.style.display=`none`,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(c),0),a.push(`downloaded ${i}`)}else{let e=LW(i);window.open(e,`_blank`,`noopener,noreferrer`),a.push(`opened ${i} → ${e}`)}}return{stdout:a.join(`
|
|
2768
2768
|
`)+`
|
|
2769
|
-
`,stderr:``,exitCode:0}})}var QW=null,$W=null;async function eG(){return QW||=y(()=>import(`./es-
|
|
2769
|
+
`,stderr:``,exitCode:0}})}var QW=null,$W=null;async function eG(){return QW||=y(()=>import(`./es-DcLnEgGG.js`),__vite__mapDeps([5,1,2])),QW}async function tG(){return $W||=y(()=>import(`./dist-BWlKscHB.js`),__vite__mapDeps([6,4])),$W}function nG(e){return e.endsWith(`right`)?{range:e.slice(0,-5),rotation:90}:e.endsWith(`left`)?{range:e.slice(0,-4),rotation:270}:e.endsWith(`down`)?{range:e.slice(0,-4),rotation:180}:{range:e}}function rG(e){let{range:t,rotation:n}=nG(e);if(/^\d+$/.test(t)){let e=parseInt(t,10);return{start:e,end:e,rotation:n}}let r=t.match(/^(\d+)-(\d+|end)$/);if(r)return{start:parseInt(r[1],10),end:r[2]===`end`?`end`:parseInt(r[2],10),rotation:n};throw Error(`Invalid page range: ${e}`)}function iG(e,t){let n=e.start,r=e.end;if(n<1||n>t)throw Error(`Page ${n} out of range (1-${t})`);let i=r===`end`?t:r;if(i<1||i>t)throw Error(`Page ${i} out of range (1-${t})`);if(i<n)throw Error(`Invalid range: ${n}-${i}`);let a=[];for(let e=n;e<=i;e++)a.push(e);return a}function aG(){return{stdout:`usage: pdftk <input.pdf> <operation> [args...]
|
|
2770
2770
|
|
|
2771
2771
|
Operations:
|
|
2772
2772
|
dump_data Print metadata (page count, title, author, etc.)
|
|
@@ -3193,7 +3193,7 @@ Usage: mount <target-path>
|
|
|
3193
3193
|
console.info = __origConsole.info;
|
|
3194
3194
|
return { stdout: __stdout.join(''), stderr: __stderr.join('') };
|
|
3195
3195
|
`,i=document.querySelector(`iframe[data-js-tool]`);i||(i=document.createElement(`iframe`),i.style.display=`none`,i.dataset.jsTool=`true`,i.src=chrome.runtime.getURL(`sandbox.html`),document.body.appendChild(i),await new Promise(e=>{i.addEventListener(`load`,()=>e(),{once:!0})}));let a=`jsh-${Date.now()}-${Math.random().toString(36).slice(2)}`,o=e=>{let t=e.data;!t||t.type!==`vfs`||(async()=>{try{let e,r=t.args?.[0]?n.fs.resolvePath(n.cwd,t.args[0]):t.args?.[0];switch(t.op){case`readFile`:e=await n.fs.readFile(r);break;case`readFileBinary`:e=await n.fs.readFileBuffer(r);break;case`writeFile`:await n.fs.writeFile(r,t.args[1]),e=!0;break;case`writeFileBinary`:await n.fs.writeFile(r,t.binaryData??new Uint8Array),e=!0;break;case`readDir`:e=await n.fs.readdir(r);break;case`exists`:e=await n.fs.exists(r);break;case`stat`:{let t=await n.fs.stat(r);e={isDirectory:t.isDirectory,isFile:t.isFile,size:t.size};break}case`mkdir`:await n.fs.mkdir(r,{recursive:!0}),e=!0;break;case`rm`:await n.fs.rm(r,{recursive:!0}),e=!0;break}i.contentWindow.postMessage({type:`vfs_response`,id:t.id,result:e},`*`)}catch(e){let n=e instanceof Error?e.message:String(e);i.contentWindow.postMessage({type:`vfs_response`,id:t.id,error:n},`*`)}})()};window.addEventListener(`message`,o);let s=e=>{let t=e.data;!t||t.type!==`shell_exec`||(async()=>{try{let e=await u(t.command);i.contentWindow.postMessage({type:`shell_exec_response`,id:t.id,result:e},`*`)}catch(e){let n=e instanceof Error?e.message:String(e);i.contentWindow.postMessage({type:`shell_exec_response`,id:t.id,error:n},`*`)}})()};window.addEventListener(`message`,s);let l=e=>{let t=e.data;!t||t.type!==`fetch_proxy`||(async()=>{try{let e={method:t.init?.method??`GET`,cache:`no-store`};t.init?.headers&&(e.headers=t.init.headers),t.init?.body&&![`GET`,`HEAD`].includes(e.method)&&(e.body=t.init.body);let n=await fetch(t.url,e),r=await n.arrayBuffer(),a={};n.headers.forEach((e,t)=>{a[t]=e}),i.contentWindow.postMessage({type:`fetch_proxy_response`,id:t.id,status:n.status,statusText:n.statusText,headers:a,body:new Uint8Array(r)},`*`)}catch(e){let n=e instanceof Error?e.message:String(e);i.contentWindow.postMessage({type:`fetch_proxy_response`,id:t.id,error:n},`*`)}})()};window.addEventListener(`message`,l);let d=await new Promise((e,t)=>{let n,o=t=>{if(t.data?.type===`exec_result`&&t.data.id===a)if(window.removeEventListener(`message`,o),clearTimeout(n),t.data.error)e({stdout:``,stderr:t.data.error+`
|
|
3196
|
-
`});else try{let n=JSON.parse(t.data.result);e({stdout:n.stdout||``,stderr:n.stderr||``})}catch{e({stdout:t.data.result||``,stderr:``})}};n=setTimeout(()=>{window.removeEventListener(`message`,o),t(Error(`jsh eval timed out (30s)`))},3e4),window.addEventListener(`message`,o),i.contentWindow.postMessage({type:`exec`,id:a,code:r},`*`)});return window.removeEventListener(`message`,o),window.removeEventListener(`message`,s),window.removeEventListener(`message`,l),{stdout:d.stdout,stderr:d.stderr,exitCode:d.stderr?1:0}}let a=Object.getPrototypeOf(async function(){}).constructor;return await new a(`fs`,`process`,`console`,`require`,`module`,`exports`,`__state`,`exec`,`"use strict";\nconst globalThis = __state;\nconst global = __state;\n${e}`)(l,c,s,d,f,f.exports,DW,u),{stdout:r.join(``),stderr:i.join(``),exitCode:0}}catch(e){if(e instanceof OW)return{stdout:r.join(``),stderr:i.join(``),exitCode:e.code};let t=e instanceof Error?e.stack??e.message:String(e);return{stdout:r.join(``),stderr:`${i.join(``)}${t}\n`,exitCode:1}}}function Nq(e){let t=[],n=``,r=0;for(;r<e.length;){let i=e[r];if(i===`"`){for(r++;r<e.length&&e[r]!==`"`;)n+=e[r],r++;r++}else if(i===`'`){for(r++;r<e.length&&e[r]!==`'`;)n+=e[r],r++;r++}else i===`\\`&&r+1<e.length&&e[r+1]===` `?(n+=` `,r+=2):/\s/.test(i)?(n.length>0&&(t.push(n),n=``),r++):(n+=i,r++)}return n.length>0&&t.push(n),t}var Pq=null,Fq=!1;function Iq(){return typeof chrome<`u`&&chrome?.runtime?.id?`extension`:typeof document<`u`&&document.documentElement?.dataset?.electronOverlay?`electron`:`cli`}async function Lq(){if(!Fq&&!(typeof localStorage<`u`&&localStorage.getItem(`telemetry-disabled`)===`true`))try{typeof window<`u`&&(window.SAMPLE_PAGEVIEWS_AT_RATE=`high`),Pq=(await y(()=>import(`./src-CpO2JX79.js`),[])).sampleRUM,Fq=!0,Pq&&Pq(`navigate`,{source:typeof document<`u`?document.referrer:``,target:Iq()})}catch{}}function Rq(e,t){Pq?.(`formsubmit`,{source:e,target:t})}function zq(e){Pq?.(`fill`,{source:e})}function Bq(e){Pq?.(`viewblock`,{source:e})}function Vq(e){let t=e.length>1&&e.endsWith(`/`)?e.slice(0,-1):e,n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}function Hq(e){if(!e)return!0;let t=e.toLowerCase();return t.startsWith(`text/`)||t.includes(`json`)||t.includes(`xml`)||t.includes(`javascript`)||t.includes(`ecmascript`)||t.includes(`html`)||t.includes(`css`)||t.includes(`svg`)}async function Uq(e,t){if(Hq(e.headers.get(`content-type`)??``))return e.text();let n=await e.arrayBuffer(),r=new Uint8Array(n),i=new TextDecoder(`iso-8859-1`).decode(n);return rV(i,r),t&&iV(t,r),i}function Wq(e){if(e){if(e instanceof Headers){let t={};return e.forEach((e,n)=>{t[n]=e}),t}return e}}function Gq(e,t){if(e){if((t?.[`Content-Type`]??t?.[`content-type`]??``).includes(`multipart/form-data`)){let t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}return e}}function Kq(e){if(!e)return{};let t={};for(let[n,r]of Object.entries(e)){let e=n.toLowerCase();e===`cookie`?t[`X-Proxy-Cookie`]=r:e===`origin`?t[`X-Proxy-Origin`]=r:e===`referer`?t[`X-Proxy-Referer`]=r:e.startsWith(`proxy-`)?t[`X-Proxy-${n}`]=r:t[n]=r}return t}function qq(e){let t={};for(let[n,r]of Object.entries(e))n.toLowerCase()===`x-proxy-set-cookie`?t[`set-cookie`]=r:t[n]=r;return t}function Jq(){return typeof chrome<`u`&&chrome?.runtime?.id?async(e,t)=>{let n=Wq(t?.headers),r=await fetch(e,{method:t?.method??`GET`,headers:n,body:Gq(t?.body,n)}),i=await Uq(r,e),a={};return r.headers.forEach((e,t)=>{a[t]=e}),{status:r.status,statusText:r.statusText,headers:a,body:i,url:e}}:async(e,t)=>{let n=t?.method??`GET`,r={...Kq(Wq(t?.headers)),"X-Target-URL":e},i={method:n,headers:r,cache:`no-store`};t?.body&&![`GET`,`HEAD`].includes(n)&&(i.body=Gq(t.body,r));let a=await fetch(`/api/fetch-proxy`,i);if(a.status===502||a.status===400){let e=await a.text(),t=`Proxy error ${a.status}`;try{t=JSON.parse(e).error??t}catch{}throw Error(t)}let o=await Uq(a,e),s={};a.headers.forEach((e,t)=>{s[t]=e});let c=qq(s);return{status:a.status,statusText:a.statusText,headers:c,body:o,url:e}}}var Yq=class{bash;vfsAdapter;gitCommands;mountCommands;terminal=null;fitAddon=null;terminalHost=null;previewHost=null;previewUrls=[];previewStateListener=null;hasPreview=!1;resizeObserver=null;themeObserver=null;currentLine=``;cursorPos=0;history=[];historyIndex=-1;isExecuting=!1;continuationBuffer=``;lastEnv;cwd;builtinCommandNames;constructor(e){this.options=e,this.vfsAdapter=new sV(e.fs);let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new UH({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new Aq({fs:e.fs});let r=this.createGitCustomCommand(),i=PK({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,browserAPI:e.browserAPI}),a=this.createMountCustomCommand(),o=Jq(),s=[r,a,Oq(e.fs),Dq(e.fs,o),...i];this.bash=new XB({fs:this.vfsAdapter,cwd:t,env:n,fetch:o,customCommands:s});let c=s.map(e=>e.name);this.builtinCommandNames=new Set([...FP(),...IP(),...c]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t}createGitCustomCommand(){let e=this.gitCommands;return HP(`git`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}createMountCustomCommand(){let e=this.mountCommands;return HP(`mount`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}getBash(){return this.bash}getCwd(){return this.cwd}getEnv(){return{...this.lastEnv}}async getFilteredJshCommands(){let e=await tK(this.options.fs),t=new Map;for(let[n,r]of e)this.builtinCommandNames.has(n)||t.set(n,r);return t}async getJshCommandNames(){return[...(await this.getFilteredJshCommands()).keys()]}async tryJshFallback(e){let t=e.trim(),n=t.indexOf(` `),r=n>=0?t.slice(0,n):t,i=n>=0?t.slice(n+1).trim():``,a=(await this.getFilteredJshCommands()).get(r);if(!a)return null;let o=await
|
|
3196
|
+
`});else try{let n=JSON.parse(t.data.result);e({stdout:n.stdout||``,stderr:n.stderr||``})}catch{e({stdout:t.data.result||``,stderr:``})}};n=setTimeout(()=>{window.removeEventListener(`message`,o),t(Error(`jsh eval timed out (30s)`))},3e4),window.addEventListener(`message`,o),i.contentWindow.postMessage({type:`exec`,id:a,code:r},`*`)});return window.removeEventListener(`message`,o),window.removeEventListener(`message`,s),window.removeEventListener(`message`,l),{stdout:d.stdout,stderr:d.stderr,exitCode:d.stderr?1:0}}let a=Object.getPrototypeOf(async function(){}).constructor;return await new a(`fs`,`process`,`console`,`require`,`module`,`exports`,`__state`,`exec`,`"use strict";\nconst globalThis = __state;\nconst global = __state;\n${e}`)(l,c,s,d,f,f.exports,DW,u),{stdout:r.join(``),stderr:i.join(``),exitCode:0}}catch(e){if(e instanceof OW)return{stdout:r.join(``),stderr:i.join(``),exitCode:e.code};let t=e instanceof Error?e.stack??e.message:String(e);return{stdout:r.join(``),stderr:`${i.join(``)}${t}\n`,exitCode:1}}}function Nq(e){let t=[],n=``,r=0;for(;r<e.length;){let i=e[r];if(i===`"`){for(r++;r<e.length&&e[r]!==`"`;)n+=e[r],r++;r++}else if(i===`'`){for(r++;r<e.length&&e[r]!==`'`;)n+=e[r],r++;r++}else i===`\\`&&r+1<e.length&&e[r+1]===` `?(n+=` `,r+=2):/\s/.test(i)?(n.length>0&&(t.push(n),n=``),r++):(n+=i,r++)}return n.length>0&&t.push(n),t}var Pq=null,Fq=!1;function Iq(){return typeof chrome<`u`&&chrome?.runtime?.id?`extension`:typeof document<`u`&&document.documentElement?.dataset?.electronOverlay?`electron`:`cli`}async function Lq(){if(!Fq&&!(typeof localStorage<`u`&&localStorage.getItem(`telemetry-disabled`)===`true`))try{typeof window<`u`&&(window.SAMPLE_PAGEVIEWS_AT_RATE=`high`),Pq=(await y(()=>import(`./src-CpO2JX79.js`),[])).sampleRUM,Fq=!0,Pq&&Pq(`navigate`,{source:typeof document<`u`?document.referrer:``,target:Iq()})}catch{}}function Rq(e,t){Pq?.(`formsubmit`,{source:e,target:t})}function zq(e){Pq?.(`fill`,{source:e})}function Bq(e){Pq?.(`viewblock`,{source:e})}function Vq(e){let t=e.length>1&&e.endsWith(`/`)?e.slice(0,-1):e,n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}function Hq(e){if(!e)return!0;let t=e.toLowerCase();return t.startsWith(`text/`)||t.includes(`json`)||t.includes(`xml`)||t.includes(`javascript`)||t.includes(`ecmascript`)||t.includes(`html`)||t.includes(`css`)||t.includes(`svg`)}async function Uq(e,t){if(Hq(e.headers.get(`content-type`)??``))return e.text();let n=await e.arrayBuffer(),r=new Uint8Array(n),i=new TextDecoder(`iso-8859-1`).decode(n);return rV(i,r),t&&iV(t,r),i}function Wq(e){if(e){if(e instanceof Headers){let t={};return e.forEach((e,n)=>{t[n]=e}),t}return e}}function Gq(e,t){if(e){if((t?.[`Content-Type`]??t?.[`content-type`]??``).includes(`multipart/form-data`)){let t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}return e}}function Kq(e){if(!e)return{};let t={};for(let[n,r]of Object.entries(e)){let e=n.toLowerCase();e===`cookie`?t[`X-Proxy-Cookie`]=r:e===`origin`?t[`X-Proxy-Origin`]=r:e===`referer`?t[`X-Proxy-Referer`]=r:e.startsWith(`proxy-`)?t[`X-Proxy-${n}`]=r:t[n]=r}return t}function qq(e){let t={};for(let[n,r]of Object.entries(e))n.toLowerCase()===`x-proxy-set-cookie`?t[`set-cookie`]=r:t[n]=r;return t}function Jq(){return typeof chrome<`u`&&chrome?.runtime?.id?async(e,t)=>{let n=Wq(t?.headers),r=await fetch(e,{method:t?.method??`GET`,headers:n,body:Gq(t?.body,n)}),i=await Uq(r,e),a={};return r.headers.forEach((e,t)=>{a[t]=e}),{status:r.status,statusText:r.statusText,headers:a,body:i,url:e}}:async(e,t)=>{let n=t?.method??`GET`,r={...Kq(Wq(t?.headers)),"X-Target-URL":e},i={method:n,headers:r,cache:`no-store`};t?.body&&![`GET`,`HEAD`].includes(n)&&(i.body=Gq(t.body,r));let a=await fetch(`/api/fetch-proxy`,i);if(a.status===502||a.status===400){let e=await a.text(),t=`Proxy error ${a.status}`;try{t=JSON.parse(e).error??t}catch{}throw Error(t)}let o=await Uq(a,e),s={};a.headers.forEach((e,t)=>{s[t]=e});let c=qq(s);return{status:a.status,statusText:a.statusText,headers:c,body:o,url:e}}}var Yq=class{bash;vfsAdapter;gitCommands;mountCommands;terminal=null;fitAddon=null;terminalHost=null;previewHost=null;previewUrls=[];previewStateListener=null;hasPreview=!1;resizeObserver=null;themeObserver=null;currentLine=``;cursorPos=0;history=[];historyIndex=-1;isExecuting=!1;continuationBuffer=``;lastEnv;cwd;builtinCommandNames;constructor(e){this.options=e,this.vfsAdapter=new sV(e.fs);let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new UH({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new Aq({fs:e.fs});let r=this.createGitCustomCommand(),i=PK({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,browserAPI:e.browserAPI}),a=this.createMountCustomCommand(),o=Jq(),s=[r,a,Oq(e.fs),Dq(e.fs,o),...i];this.bash=new XB({fs:this.vfsAdapter,cwd:t,env:n,fetch:o,customCommands:s});let c=s.map(e=>e.name);this.builtinCommandNames=new Set([...FP(),...IP(),...c]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t}createGitCustomCommand(){let e=this.gitCommands;return HP(`git`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}createMountCustomCommand(){let e=this.mountCommands;return HP(`mount`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}getBash(){return this.bash}getCwd(){return this.cwd}getEnv(){return{...this.lastEnv}}async getFilteredJshCommands(){let e=await tK(this.options.jshDiscoveryFs??this.options.fs),t=new Map;for(let[n,r]of e)this.builtinCommandNames.has(n)||t.set(n,r);return t}async getJshCommandNames(){return[...(await this.getFilteredJshCommands()).keys()]}async tryJshFallback(e){let t=e.trim(),n=t.indexOf(` `),r=n>=0?t.slice(0,n):t,i=n>=0?t.slice(n+1).trim():``,a=(await this.getFilteredJshCommands()).get(r);if(!a)return null;let o=i?Nq(i):[],s=this.options.jshDiscoveryFs??this.options.fs,c;try{let e=await s.readFile(a,{encoding:`utf-8`});c=typeof e==`string`?e:new TextDecoder().decode(e)}catch{return{stdout:``,stderr:`jsh: cannot read script '${a}'\n`,exitCode:127,env:this.lastEnv}}let l=[`node`,a,...o],u=await Mq(c,l,{fs:this.vfsAdapter,cwd:this.cwd,env:new Map(Object.entries(this.lastEnv)),stdin:``,exec:(e,t)=>this.bash.exec(e,{env:this.lastEnv,cwd:t?.cwd??this.cwd})});return{stdout:u.stdout,stderr:u.stderr,exitCode:u.exitCode,env:this.lastEnv}}async runCommand(e){zq(e.trim().split(/\s+/)[0]||`unknown`);let t=await this.bash.exec(e,{env:this.lastEnv,cwd:this.cwd});if(t.env&&(this.lastEnv={...t.env}),t.env?.PWD&&(this.cwd=t.env.PWD),t.exitCode===127){let t=await this.tryJshFallback(e);if(t)return t}return t}async mount(e){let t=e??this.options.container;if(!t)throw Error(`No container element provided`);let{Terminal:n}=await y(async()=>{let{Terminal:e}=await import(`./xterm-BdneTMM8.js`);return{Terminal:e}},[]),{FitAddon:r}=await y(async()=>{let{FitAddon:e}=await import(`./addon-fit-Dq6sROpn.js`);return{FitAddon:e}},[]);await y(()=>Promise.resolve({}),__vite__mapDeps([19]));let i=!document.documentElement.classList.contains(`theme-light`),a={background:`#141414`,foreground:`#cfcfcf`,cursor:`#3562ff`,cursorAccent:`#141414`,selectionBackground:`#3562ff40`,selectionForeground:`#ffffff`,black:`#1a1a1a`,red:`#e34850`,green:`#2d9d78`,yellow:`#e68619`,blue:`#3562ff`,magenta:`#a962e8`,cyan:`#2db9be`,white:`#cfcfcf`,brightBlack:`#5a5a5a`,brightRed:`#e34850`,brightGreen:`#2d9d78`,brightYellow:`#e68619`,brightBlue:`#4a75ff`,brightMagenta:`#a962e8`,brightCyan:`#2db9be`,brightWhite:`#ffffff`},o={background:`#f0f0f0`,foreground:`#1a1a1a`,cursor:`#2b54db`,cursorAccent:`#f0f0f0`,selectionBackground:`#2b54db30`,selectionForeground:`#000000`,black:`#1a1a1a`,red:`#d73220`,green:`#268e6c`,yellow:`#d17a00`,blue:`#2b54db`,magenta:`#8839ef`,cyan:`#1a9088`,white:`#e8e8e8`,brightBlack:`#6e6e6e`,brightRed:`#d73220`,brightGreen:`#268e6c`,brightYellow:`#d17a00`,brightBlue:`#1e44c4`,brightMagenta:`#8839ef`,brightCyan:`#1a9088`,brightWhite:`#ffffff`};this.terminal=new n({cursorBlink:!0,fontSize:11,fontFamily:`'Source Code Pro', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace`,theme:i?a:o,convertEol:!0}),this.themeObserver?.disconnect(),this.themeObserver=new MutationObserver(()=>{if(!this.terminal)return;let e=document.documentElement.classList.contains(`theme-light`);this.terminal.options.theme=e?o:a}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`]}),this.fitAddon=new r,this.terminal.loadAddon(this.fitAddon),t.replaceChildren(),this.terminalHost=document.createElement(`div`),this.terminalHost.className=`terminal-panel__terminal-host`,t.appendChild(this.terminalHost),this.previewHost=document.createElement(`div`),this.previewHost.className=`terminal-panel__preview`,t.appendChild(this.previewHost),this.terminal.open(this.terminalHost),this.fitAddon.fit(),this.resizeObserver?.disconnect(),this.resizeObserver=new ResizeObserver(()=>this.refit()),this.resizeObserver.observe(this.terminalHost),this.terminal.writeln(`\x1B[1mslicc\x1B[0m \x1B[90mshell (powered by just-bash)\x1B[0m`),this.terminal.writeln(`\x1B[90mType "help" for available commands.\x1B[0m
|
|
3197
3197
|
`),this.showPrompt(),this.setupInputHandler()}async executeCommand(e){let t=await this.runCommand(e);return{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode}}async executeScriptFile(e,t=[]){return jq(e,t,{fs:this.vfsAdapter,cwd:this.cwd,env:new Map(Object.entries(this.lastEnv)),stdin:``,exec:(e,t)=>this.bash.exec(e,{env:this.lastEnv,cwd:t?.cwd??this.cwd})})}refit(){this.fitAddon?.fit()}setPreviewStateListener(e){this.previewStateListener=e,this.previewStateListener?.(this.hasPreview)}async executeCommandInTerminal(e){let t=e.trim();if(!t)return{stdout:``,stderr:``,exitCode:0};if(!this.terminal)return this.executeCommand(t);if(this.isExecuting||this.currentLine.length>0||this.continuationBuffer.length>0)return{stdout:``,stderr:`terminal is busy; finish current input first
|
|
3198
3198
|
`,exitCode:1};this.history[this.history.length-1]!==t&&this.history.push(t),this.historyIndex=-1,this.terminal.write(t),this.terminal.writeln(``),this.isExecuting=!0;try{let e=await this.runCommand(t);return e.stdout&&this.writeToTerminal(e.stdout),e.stderr&&this.writeToTerminal(e.stderr,!0),{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode}}catch(e){let t=`Error: ${e instanceof Error?e.message:String(e)}\n`;return this.writeToTerminal(t,!0),{stdout:``,stderr:t,exitCode:1}}finally{this.isExecuting=!1,this.showPrompt()}}clearTerminal(){this.terminal?.clear(),this.clearMediaPreview()}dispose(){this.themeObserver?.disconnect(),this.themeObserver=null,this.resizeObserver?.disconnect(),this.resizeObserver=null,this.clearMediaPreview(),this.terminal?.dispose(),this.terminal=null,this.fitAddon=null,this.terminalHost=null,this.previewHost=null}showPrompt(){if(!this.terminal)return;let e=this.cwd===`/`?`/`:this.cwd.split(`/`).pop()??this.cwd;this.terminal.write(`\x1b[34m${e}\x1b[0m \x1b[90m$\x1b[0m `)}setupInputHandler(){this.terminal&&this.terminal.onData(e=>{if(!this.isExecuting){if(e.startsWith(`\x1B[`)||e.startsWith(`\x1BO`)){switch(e){case`\x1B[A`:this.handleHistoryUp();return;case`\x1B[B`:this.handleHistoryDown();return;case`\x1B[C`:this.handleArrowRight();return;case`\x1B[D`:this.handleArrowLeft();return;case`\x1B[H`:case`\x1BOH`:case`\x1B[1~`:this.handleHome();return;case`\x1B[F`:case`\x1BOF`:case`\x1B[4~`:this.handleEnd();return;case`\x1B[3~`:this.handleDelete();return}return}for(let t of e)switch(t){case`\r`:this.handleEnter();break;case``:this.handleBackspace();break;case``:this.handleCtrlC();break;case` `:this.handleTab();break;default:t>=` `&&this.insertChar(t)}}})}getPromptWidth(){return(this.cwd===`/`?`/`:this.cwd.split(`/`).pop()??this.cwd).length+3}getCursorVisualLine(){let e=0;for(let[t,n]of this.currentLine.split(`
|
|
3199
3199
|
`).entries()){if(e+n.length>=this.cursorPos)return t;e+=n.length+1}return 0}positionTerminalCursor(){let e=this.currentLine.split(`
|
|
@@ -14042,7 +14042,7 @@ The following skills are available. To use a skill, first read its full instruct
|
|
|
14042
14042
|
${e.map(e=>{let t=e.metadata.allowedTools?` Allowed tools: ${e.metadata.allowedTools.join(`, `)}\n`:``;return`- **${e.metadata.name}**: ${e.metadata.description}\n${t} Path: ${e.path}`}).join(`
|
|
14043
14043
|
`)}
|
|
14044
14044
|
---`}async function BJ(e,t=`/workspace/skills`){let n=NJ();for(let[r,i]of Object.entries(n)){let n=r.slice(18),a=n.startsWith(`/workspace/skills`),o=n.startsWith(`/workspace/scripts`);if(!a&&!o)continue;let s=n;a&&t!==`/workspace/skills`&&(s=n.replace(`/workspace/skills`,t)),o&&t!==`/workspace/skills`&&(s=t.replace(`/workspace/skills`,``)+n);try{await e.stat(s)}catch{let t=s.substring(0,s.lastIndexOf(`/`));try{await e.mkdir(t,{recursive:!0})}catch{}await e.writeFile(s,i),kJ.info(`Created default file`,{path:s})}}}async function VJ(e){let t=NJ();for(let[n,r]of Object.entries(t)){let t=n.slice(18);if(t.startsWith(`/shared/`))try{await e.stat(t)}catch{let n=t.substring(0,t.lastIndexOf(`/`));try{await e.mkdir(n,{recursive:!0})}catch{}await e.writeFile(t,r),kJ.info(`Created default shared file`,{path:t})}}}var HJ=r(`scoop-management-tools`);function UJ(e){let{scoop:t,onSendMessage:n,onFeedScoop:r,getScoops:i,onScoopScoop:a,onDropScoop:o,onSetGlobalMemory:s,getGlobalMemory:c}=e,l=[];return l.push({name:`send_message`,description:`Send a message immediately while you're still working. Use this for progress updates or to send multiple messages. Your final output is also sent to the user, so use this for interim updates.`,inputSchema:{type:`object`,properties:{text:{type:`string`,description:`The message text to send`},sender:{type:`string`,description:`Optional sender name/role (e.g., "Researcher"). Defaults to assistant name.`}},required:[`text`]},execute:async e=>{let{text:r,sender:i}=e;return n(r,i),HJ.info(`Message sent`,{scoopFolder:t.folder,textLength:r.length}),{content:`Message sent.`}}}),t.isCone&&r&&l.push({name:`feed_scoop`,description:`Give a scoop a task and activate it. You MUST provide a complete, self-contained prompt — the scoop has NO access to your conversation history. Include all necessary context, instructions, file paths, URLs, and expected output format. The scoop will work independently and you'll be notified when it finishes.`,inputSchema:{type:`object`,properties:{scoop_name:{type:`string`,description:`The scoop folder name (e.g., "test-scoop"). Use list_scoops to see available scoops.`},prompt:{type:`string`,description:`Complete, self-contained instructions for the scoop. Include ALL context — the scoop cannot see your conversation.`}},required:[`scoop_name`,`prompt`]},execute:async e=>{let{scoop_name:t,prompt:n}=e,a=i().find(e=>e.folder===t||e.name===t);if(!a)return{content:`Scoop "${t}" not found. Available: ${i().filter(e=>!e.isCone).map(e=>e.folder).join(`, `)}`,isError:!0};if(a.isCone)return{content:`Cannot feed the cone (yourself).`,isError:!0};try{return await r(a.jid,n),HJ.info(`Fed scoop`,{target:a.folder,promptLength:n.length}),{content:`Task sent to ${a.folder}. You will be notified when it completes.`}}catch(e){return{content:`Failed to feed scoop: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}}),t.isCone&&(l.push({name:`list_scoops`,description:`List all registered scoops.`,inputSchema:{type:`object`,properties:{}},execute:async()=>{let e=i();return e.length===0?{content:`No scoops registered.`}:{content:`Registered scoops:\n${e.map(e=>e.isCone?`- ${e.assistantLabel} (${e.folder}) [CONE]`:`- ${e.name} (${e.folder})`).join(`
|
|
14045
|
-
`)}`}}}),a&&l.push({name:`scoop_scoop`,description:`Create a new scoop. Optionally specify a model and/or a prompt. If prompt is provided, the scoop starts working immediately after creation (no separate feed_scoop needed).`,inputSchema:{type:`object`,properties:{name:{type:`string`,description:`Display name for the scoop (e.g., "hero-block")`},model:{type:`string`,description:`Model ID for this scoop (e.g., "claude-sonnet-4-6"). If omitted, uses the same model as the cone.`},prompt:{type:`string`,description:`Task prompt for the scoop. If provided, the scoop starts working immediately after creation.`}},required:[`name`]},execute:async e=>{let{name:t,model:n,prompt:i}=e,o=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,50)+`-scoop`;try{let e=await a({name:t,folder:o,trigger:`@${o}`,isCone:!1,type:`scoop`,requiresTrigger:!0,assistantLabel:o,addedAt:new Date().toISOString(),config:n?{modelId:n}:void 0});return HJ.info(`Scoop created`,{name:t,folder:o}),i&&r?(r(e.jid,i).catch(e=>{let n=e instanceof Error?e.message:String(e);HJ.error(`Auto-feed failed`,{name:t,error:n})}),{content:`Scoop "${t}" created as "${o}" and task sent. It will start working as soon as initialization completes.`}):{content:`Scoop "${t}" created as "${o}". Use feed_scoop to give it a task.`}}catch(e){return{content:`Failed to create scoop: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}}),o&&l.push({name:`drop_scoop`,description:`Remove a scoop and stop its work. The scoop will be unregistered and its context destroyed.`,inputSchema:{type:`object`,properties:{scoop_name:{type:`string`,description:`The scoop folder name (e.g., "test-scoop"). Use list_scoops to see available scoops.`}},required:[`scoop_name`]},execute:async e=>{let{scoop_name:t}=e,n=i().find(e=>e.folder===t||e.name===t);if(!n)return{content:`Scoop "${t}" not found. Available: ${i().filter(e=>!e.isCone).map(e=>e.folder).join(`, `)}`,isError:!0};if(n.isCone)return{content:`Cannot drop the cone (yourself).`,isError:!0};try{return await o(n.jid),HJ.info(`Scoop dropped`,{name:n.name,folder:n.folder}),{content:`Scoop "${n.name}" (${n.folder}) has been dropped.`}}catch(e){return{content:`Failed to drop scoop: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}}),s&&c&&l.push({name:`update_global_memory`,description:`Update the global CLAUDE.md memory file that is shared across all scoops. Use this instead of write_file for /shared/CLAUDE.md.`,inputSchema:{type:`object`,properties:{content:{type:`string`,description:`The new content for the global memory file`}},required:[`content`]},execute:async e=>{let{content:t}=e;try{return await s(t),HJ.info(`Global memory updated`),{content:`Global memory updated successfully.`}}catch(e){return{content:`Failed to update global memory: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}})),l}var WJ=r(`scoop-context`);function GJ(e){return/image exceeds.*maximum/i.test(e)||/Could not process image/i.test(e)||/invalid.*image/i.test(e)||/image.*too (large|big)/i.test(e)}var KJ=class{scoop;callbacks;fs=null;shell=null;agent=null;status=`initializing`;isProcessing=!1;didStreamDeltas=!1;unsubscribe=null;sessionStore=null;sessionId;sessionCreatedAt=0;isRecovering=!1;skillsFs=null;skillsDir=`/workspace/skills`;constructor(e,t,n,r,i){this.scoop=e,this.callbacks=t,this.fs=n,this.sessionStore=r??null,this.skillsFs=i??null,this.sessionId=e.jid}async init(){this.setStatus(`initializing`);try{if(!this.fs)throw Error(`Filesystem not provided`);WJ.info(`Filesystem ready`,{folder:this.scoop.folder}),await this.ensureDirectoryStructure();let e=this.scoop.isCone?`/`:`/scoops/${this.scoop.folder}/workspace`,t=this.callbacks.getBrowserAPI();this.shell=new Yq({fs:this.fs,cwd:e,browserAPI:t}),WJ.info(`WasmShell initialized`,{folder:this.scoop.folder})
|
|
14045
|
+
`)}`}}}),a&&l.push({name:`scoop_scoop`,description:`Create a new scoop. Optionally specify a model and/or a prompt. If prompt is provided, the scoop starts working immediately after creation (no separate feed_scoop needed).`,inputSchema:{type:`object`,properties:{name:{type:`string`,description:`Display name for the scoop (e.g., "hero-block")`},model:{type:`string`,description:`Model ID for this scoop (e.g., "claude-sonnet-4-6"). If omitted, uses the same model as the cone.`},prompt:{type:`string`,description:`Task prompt for the scoop. If provided, the scoop starts working immediately after creation.`}},required:[`name`]},execute:async e=>{let{name:t,model:n,prompt:i}=e,o=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,50)+`-scoop`;try{let e=await a({name:t,folder:o,trigger:`@${o}`,isCone:!1,type:`scoop`,requiresTrigger:!0,assistantLabel:o,addedAt:new Date().toISOString(),config:n?{modelId:n}:void 0});return HJ.info(`Scoop created`,{name:t,folder:o}),i&&r?(r(e.jid,i).catch(e=>{let n=e instanceof Error?e.message:String(e);HJ.error(`Auto-feed failed`,{name:t,error:n})}),{content:`Scoop "${t}" created as "${o}" and task sent. It will start working as soon as initialization completes.`}):{content:`Scoop "${t}" created as "${o}". Use feed_scoop to give it a task.`}}catch(e){return{content:`Failed to create scoop: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}}),o&&l.push({name:`drop_scoop`,description:`Remove a scoop and stop its work. The scoop will be unregistered and its context destroyed.`,inputSchema:{type:`object`,properties:{scoop_name:{type:`string`,description:`The scoop folder name (e.g., "test-scoop"). Use list_scoops to see available scoops.`}},required:[`scoop_name`]},execute:async e=>{let{scoop_name:t}=e,n=i().find(e=>e.folder===t||e.name===t);if(!n)return{content:`Scoop "${t}" not found. Available: ${i().filter(e=>!e.isCone).map(e=>e.folder).join(`, `)}`,isError:!0};if(n.isCone)return{content:`Cannot drop the cone (yourself).`,isError:!0};try{return await o(n.jid),HJ.info(`Scoop dropped`,{name:n.name,folder:n.folder}),{content:`Scoop "${n.name}" (${n.folder}) has been dropped.`}}catch(e){return{content:`Failed to drop scoop: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}}),s&&c&&l.push({name:`update_global_memory`,description:`Update the global CLAUDE.md memory file that is shared across all scoops. Use this instead of write_file for /shared/CLAUDE.md.`,inputSchema:{type:`object`,properties:{content:{type:`string`,description:`The new content for the global memory file`}},required:[`content`]},execute:async e=>{let{content:t}=e;try{return await s(t),HJ.info(`Global memory updated`),{content:`Global memory updated successfully.`}}catch(e){return{content:`Failed to update global memory: ${e instanceof Error?e.message:String(e)}`,isError:!0}}}})),l}var WJ=r(`scoop-context`);function GJ(e){return/image exceeds.*maximum/i.test(e)||/Could not process image/i.test(e)||/invalid.*image/i.test(e)||/image.*too (large|big)/i.test(e)}var KJ=class{scoop;callbacks;fs=null;shell=null;agent=null;status=`initializing`;isProcessing=!1;didStreamDeltas=!1;unsubscribe=null;sessionStore=null;sessionId;sessionCreatedAt=0;isRecovering=!1;skillsFs=null;skillsDir=`/workspace/skills`;constructor(e,t,n,r,i){this.scoop=e,this.callbacks=t,this.fs=n,this.sessionStore=r??null,this.skillsFs=i??null,this.sessionId=e.jid}async init(){this.setStatus(`initializing`);try{if(!this.fs)throw Error(`Filesystem not provided`);WJ.info(`Filesystem ready`,{folder:this.scoop.folder}),await this.ensureDirectoryStructure();let e=this.scoop.isCone?`/`:`/scoops/${this.scoop.folder}/workspace`,t=this.callbacks.getBrowserAPI();this.skillsDir=`/workspace/skills`,this.scoop.isCone&&await BJ(this.fs,this.skillsDir);let n=this.skillsFs??this.fs;this.shell=new Yq({fs:this.fs,cwd:e,browserAPI:t,jshDiscoveryFs:this.skillsFs?n:void 0}),WJ.info(`WasmShell initialized`,{folder:this.scoop.folder});let r=await IJ(n,this.skillsDir),i=UJ({scoop:this.scoop,onSendMessage:this.callbacks.onSendMessage,getScoops:this.callbacks.getScoops,onFeedScoop:this.callbacks.onFeedScoop,onScoopScoop:this.callbacks.onScoopScoop,onDropScoop:this.callbacks.onDropScoop,onSetGlobalMemory:this.callbacks.setGlobalMemory,getGlobalMemory:this.callbacks.getGlobalMemory}),a=C([...Zq(this.fs),aJ(this.shell),cJ(this.fs),...i]),o=this.scoop.isCone?`/workspace/CLAUDE.md`:`/scoops/${this.scoop.folder}/CLAUDE.md`,s=``;try{let e=await this.fs.readFile(o,{encoding:`utf-8`});s=typeof e==`string`?e:new TextDecoder().decode(e)}catch{}let c=await this.callbacks.getGlobalMemory();if(c)try{this.scoop.isCone&&await(`getUnderlyingFS`in this.fs?this.fs.getUnderlyingFS():this.fs).writeFile(`/shared/CLAUDE.md`,c)}catch{}let l=E();if(!l){let e=D();throw Error(`No API key configured for provider "${e}"`)}let u=this.scoop.config?.modelId?ce(this.scoop.config.modelId):oe(),d=this.buildSystemPrompt(c,s,r),f=[];if(this.sessionStore)try{let e=await this.sessionStore.load(this.sessionId);e&&(f=e.messages,this.sessionCreatedAt=e.createdAt,WJ.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:f.length}))}catch(e){WJ.error(`Failed to restore agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)}),this.callbacks.onError(`Conversation history could not be restored. Starting fresh.`)}let p=x({model:u,getApiKey:()=>E()??void 0});this.agent=new b({initialState:{model:u,tools:a,systemPrompt:d,messages:f},getApiKey:()=>l,transformContext:p}),this.unsubscribe=this.agent.subscribe(e=>this.handleAgentEvent(e)),this.setStatus(`ready`),WJ.info(`ScoopContext initialized`,{folder:this.scoop.folder,toolCount:a.length})}catch(e){let t=e instanceof Error?e.message:String(e);WJ.error(`ScoopContext init failed`,{folder:this.scoop.folder,error:t}),this.setStatus(`error`),this.callbacks.onError(`Failed to initialize: ${t}`)}}async prompt(e){if(!this.agent){this.callbacks.onError(`Agent not initialized`);return}let t=this.agent.state?.isStreaming??!1;if(this.isProcessing||t){WJ.info(`Queueing prompt via followUp while processing`,{folder:this.scoop.folder,isProcessing:this.isProcessing,agentIsStreaming:t}),this.agent.followUp({role:`user`,content:[{type:`text`,text:e}],timestamp:Date.now()});return}this.isProcessing=!0,this.didStreamDeltas=!1,this.setStatus(`processing`);try{await this.agent.prompt(e)}catch(e){let t=e instanceof Error?e.message:String(e);WJ.error(`Agent error`,{folder:this.scoop.folder,error:t}),this.callbacks.onError(t)}finally{this.isProcessing=!1,this.setStatus(`ready`)}}stop(){this.agent?.clearAllQueues?.(),this.agent?.abort?.(),this.isProcessing=!1,this.setStatus(`ready`)}clearMessages(){this.agent?.clearMessages()}getAgentMessages(){return this.agent?.state?.messages?structuredClone(this.agent.state.messages):[]}getSessionId(){return this.sessionId}getFS(){return this.fs}getShell(){return this.shell}updateModel(){if(!this.agent)return;let e=oe();this.agent.setModel(e),WJ.info(`Model updated on running agent`,{folder:this.scoop.folder,model:e.id})}async reloadSkills(){if(!this.agent)return;let e=await IJ(this.skillsFs??this.fs,this.skillsDir),t=``,n=this.scoop.isCone?`/workspace/CLAUDE.md`:`/scoops/${this.scoop.folder}/CLAUDE.md`;try{let e=await this.fs.readFile(n,{encoding:`utf-8`});t=typeof e==`string`?e:new TextDecoder().decode(e)}catch{}let r=await this.callbacks.getGlobalMemory(),i=this.buildSystemPrompt(r,t,e);this.agent.setSystemPrompt(i),WJ.info(`Skills reloaded`,{folder:this.scoop.folder,skillCount:e.length})}dispose(){this.unsubscribe?.(),this.shell?.dispose(),this.agent=null,this.shell=null,this.fs=null}setStatus(e){this.status=e,this.callbacks.onStatusChange(e)}handleAgentEvent(e){switch(e.type){case`message_update`:{let t=e.assistantMessageEvent;t.type===`text_delta`&&(this.didStreamDeltas=!0,this.callbacks.onResponse(t.delta,!0));break}case`tool_execution_start`:this.callbacks.onToolStart?.(e.toolName,e.args);break;case`tool_execution_update`:{let t=e.partialResult;for(let n of t?.content??[])n.type===`tool_ui`&&n.requestId&&n.html?this.callbacks.onToolUI?.(e.toolName,n.requestId,n.html):n.type===`tool_ui_done`&&n.requestId&&this.callbacks.onToolUIDone?.(n.requestId);break}case`tool_execution_end`:{let t=e.result,n=[];for(let e of t?.content??[])e.type===`text`&&e.text&&n.push(e.text),e.type===`image`&&e.data&&e.mimeType&&n.push(`<img:data:${e.mimeType};base64,${e.data}>`);this.callbacks.onToolEnd?.(e.toolName,n.join(`
|
|
14046
14046
|
`),e.isError);break}case`message_end`:if(e.message.role===`assistant`){let t=e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(``);t&&!this.didStreamDeltas&&this.callbacks.onResponse(t,!1)}break;case`turn_end`:this.callbacks.onResponseDone();break;case`agent_end`:{let t=e.messages;if(t.length>0){let e=t[t.length-1];if(e.role===`assistant`&&e.errorMessage){let n=e.errorMessage;if(!this.isRecovering&&GJ(n)){this.recoverFromImageError(t);break}if(!this.isRecovering&&ee(e)){this.recoverFromOverflow(t);break}this.isRecovering=!1,this.callbacks.onError(n)}else this.isRecovering=!1}let n=this.agent?.state?.messages??e.messages;this.sessionStore&&n.length>0&&this.sessionStore.save({id:this.sessionId,messages:n,config:{},createdAt:this.sessionCreatedAt||Date.now(),updatedAt:Date.now()}).catch(e=>{WJ.error(`Failed to save agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)})});break}}}recoverFromOverflow(e){if(this.agent){WJ.warn(`Context overflow detected, attempting recovery`,{folder:this.scoop.folder,messageCount:e.length}),this.isRecovering=`overflow`,this.callbacks.onResponse(`Context window exceeded — recovering by trimming oversized messages...`,!1);try{let t=e.slice(0,-1),n=0;for(let e=t.length-1;e>=0&&n<5;e--){let r=t[e];if(!Array.isArray(r.content))continue;let i=0;for(let e of r.content)e.type===`text`&&e.text&&(i+=e.text.length),e.type===`image`&&e.data&&(i+=e.data.length);if(i>4e4){let a={type:`text`,text:`[Content removed: ${r.role===`toolResult`?`tool result`:r.role} was too large for context window (${Math.round(i/1e3)}K chars). The operation completed but output could not be retained.]`};if(r.role===`assistant`){let n=r.content.filter(e=>e.type===`toolCall`);t[e]={...r,content:[a,...n]}}else t[e]={...r,content:[a]};n++,WJ.info(`Replaced oversized message`,{index:e,role:r.role,size:i,preservedToolCalls:r.role===`assistant`?r.content.filter(e=>e.type===`toolCall`).length:0})}}this.agent.replaceMessages(t);let r=n>0?`[System: Context overflow recovered. ${n} oversized message(s) were replaced with placeholders to fit within the context window. The conversation continues — you may need to re-read files or re-run commands if their output was removed.]`:`[System: Context overflow recovered. Older messages were trimmed. The conversation continues — compaction will summarize history on the next turn.]`;this.agent.prompt(r).catch(e=>{WJ.error(`Recovery re-prompt failed`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)}),this.isRecovering=!1,this.callbacks.onError(`Context overflow recovery failed: ${e instanceof Error?e.message:String(e)}`)})}catch(e){WJ.error(`Recovery failed`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)}),this.isRecovering=!1,this.callbacks.onError(`Context overflow recovery failed: ${e instanceof Error?e.message:String(e)}`)}}}recoverFromImageError(e){if(this.agent){WJ.warn(`Image processing error detected, attempting recovery`,{folder:this.scoop.folder,messageCount:e.length}),this.isRecovering=`image`,this.callbacks.onResponse(`Image rejected by API — removing problematic images and continuing...`,!1);try{let t=e.slice(0,-1),n=0,r=Math.max(0,t.length-10);for(let e=t.length-1;e>=r;e--){let r=t[e];if(!Array.isArray(r.content)||!r.content.some(e=>e.type===`image`))continue;let i=r.content.filter(e=>e.type!==`image`);i.length===0?t[e]={...r,content:[{type:`text`,text:`[Image removed: rejected by API]`}]}:t[e]={...r,content:i},n++}this.agent.replaceMessages(t);let i=`[System: An image was rejected by the API and has been removed from the conversation (${n} message(s) affected). The conversation continues without the image.]`;this.agent.prompt(i).catch(e=>{WJ.error(`Image recovery re-prompt failed`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)}),this.isRecovering=!1,this.callbacks.onError(`Image error recovery failed: ${e instanceof Error?e.message:String(e)}`)})}catch(e){WJ.error(`Image recovery failed`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)}),this.isRecovering=!1,this.callbacks.onError(`Image error recovery failed: ${e instanceof Error?e.message:String(e)}`)}}}async ensureDirectoryStructure(){if(!this.fs)return;let e=this.scoop.isCone?[`/workspace`,`/shared`,`/scoops`,`/home`,`/tmp`]:[`/scoops/${this.scoop.folder}`,`/scoops/${this.scoop.folder}/workspace`,`/scoops/${this.scoop.folder}/home`,`/scoops/${this.scoop.folder}/tmp`,`/shared`];for(let t of e)try{await this.fs.mkdir(t,{recursive:!0})}catch{}let t=this.scoop.isCone?`/workspace/CLAUDE.md`:`/scoops/${this.scoop.folder}/CLAUDE.md`;try{await this.fs.readFile(t)}catch{let e=`# ${this.scoop.assistantLabel} Memory
|
|
14047
14047
|
|
|
14048
14048
|
${this.scoop.isCone?`Role: Cone (main orchestrator)`:`Scoop: ${this.scoop.name}`}
|
|
@@ -14125,7 +14125,7 @@ ${t}
|
|
|
14125
14125
|
---`);let a=zJ(n);return a&&(i+=a),i}},qJ=r(`scheduler`),JJ=class{callbacks;pollInterval=null;running=!1;constructor(e){this.callbacks=e}start(){this.running||(this.running=!0,this.pollInterval=window.setInterval(()=>this.checkTasks(),6e4),this.checkTasks(),qJ.info(`Scheduler started`))}stop(){this.pollInterval&&=(clearInterval(this.pollInterval),null),this.running=!1,qJ.info(`Scheduler stopped`)}async createTask(e,t,n,r){let i={id:`task-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,groupFolder:e,prompt:t,scheduleType:n,scheduleValue:r,status:`active`,nextRun:this.calculateNextRun(n,r),lastRun:null,createdAt:new Date().toISOString()};return await He(i),qJ.info(`Task created`,{id:i.id,groupFolder:e,scheduleType:n}),i}async updateTask(e,t){let n=await Ne(e);if(!n)return null;let r={...n,...t};return(t.scheduleType||t.scheduleValue)&&(r.nextRun=this.calculateNextRun(r.scheduleType,r.scheduleValue)),await He(r),qJ.info(`Task updated`,{id:e,updates:Object.keys(t)}),r}async pauseTask(e){return await this.updateTask(e,{status:`paused`})!==null}async resumeTask(e){return await Ne(e)?(await this.updateTask(e,{status:`active`}),!0):!1}async deleteTask(e){return await Ne(e)?(await Ee(e),qJ.info(`Task deleted`,{id:e}),!0):!1}async getTasksByScoop(e){return(await Me()).filter(t=>t.groupFolder===e)}async getAllTasks(){return Me()}async checkTasks(){let e=await Me(),t=new Date;for(let n of e)n.status===`active`&&n.nextRun&&(new Date(n.nextRun)>t||await this.runTask(n))}async runTask(e){let t=this.callbacks.getScoop(e.groupFolder);if(!t){qJ.warn(`Task scoop not found`,{taskId:e.id,groupFolder:e.groupFolder});return}qJ.info(`Running task`,{id:e.id,groupFolder:e.groupFolder});try{let n=new Date().toISOString(),r=this.calculateNextRun(e.scheduleType,e.scheduleValue),i=e.scheduleType===`once`?`completed`:e.status;await He({...e,lastRun:n,nextRun:r,status:i}),await this.callbacks.onTaskRun(e,t),qJ.info(`Task completed`,{id:e.id})}catch(t){qJ.error(`Task execution failed`,{id:e.id,error:t instanceof Error?t.message:String(t)})}}calculateNextRun(e,t){let n=new Date;switch(e){case`cron`:return this.getNextCronTime(t,n)?.toISOString()??null;case`interval`:{let e=parseInt(t,10);return isNaN(e)||e<=0?null:new Date(n.getTime()+e).toISOString()}case`once`:return new Date(t)>n?t:null;default:return null}}getNextCronTime(e,t){let n=e.trim().split(/\s+/);if(n.length!==5)return null;let[r,i,a,o,s]=n,c=new Date(t);c.setSeconds(0),c.setMilliseconds(0),c.setMinutes(c.getMinutes()+1);for(let e=0;e<527040;e++){if(this.cronMatches(c,r,i,a,o,s))return c;c.setMinutes(c.getMinutes()+1)}return null}cronMatches(e,t,n,r,i,a){return this.cronFieldMatches(e.getMinutes(),t)&&this.cronFieldMatches(e.getHours(),n)&&this.cronFieldMatches(e.getDate(),r)&&this.cronFieldMatches(e.getMonth()+1,i)&&this.cronFieldMatches(e.getDay(),a)}cronFieldMatches(e,t){if(t===`*`)return!0;if(t.includes(`,`))return t.split(`,`).some(t=>this.cronFieldMatches(e,t.trim()));if(t.includes(`-`)){let[n,r]=t.split(`-`).map(e=>parseInt(e,10));return e>=n&&e<=r}if(t.includes(`/`)){let[n,r]=t.split(`/`),i=parseInt(r,10);if(n===`*`)return e%i===0;let a=parseInt(n,10);return e>=a&&(e-a)%i===0}return parseInt(t,10)===e}},YJ=r(`lick-manager`),XJ=class{webhooks=new Map;crontasks=new Map;cronInterval=null;eventHandler=null;async init(){await Ae();let e=await Be();for(let t of e)this.webhooks.set(t.id,t);YJ.info(`Loaded webhooks`,{count:this.webhooks.size});let t=await Re();for(let e of t)this.crontasks.set(e.id,e);YJ.info(`Loaded crontasks`,{count:this.crontasks.size}),this.cronInterval=setInterval(()=>this.runCronScheduler(),6e4),YJ.info(`Cron scheduler started`)}dispose(){this.cronInterval&&=(clearInterval(this.cronInterval),null)}setEventHandler(e){this.eventHandler=e}async createWebhook(e,t,n){let r=this.generateId(),i={id:r,name:e,createdAt:new Date().toISOString(),filter:n,scoop:t};return n&&this.compileFilter(n,!0),this.webhooks.set(r,i),await P(i),YJ.info(`Webhook created`,{id:r,name:e,scoop:t}),i}async deleteWebhook(e){return this.webhooks.has(e)?(this.webhooks.delete(e),await Fe(e),YJ.info(`Webhook deleted`,{id:e}),!0):!1}listWebhooks(){return Array.from(this.webhooks.values())}getWebhook(e){return this.webhooks.get(e)}handleWebhookEvent(e,t,n){let r=this.webhooks.get(e);if(!r){YJ.warn(`Webhook not found`,{webhookId:e});return}let i={type:`webhook`,webhookId:e,webhookName:r.name,targetScoop:r.scoop,timestamp:new Date().toISOString(),headers:t,body:n};if(r.filter)try{let t=this.compileFilter(r.filter,!0)(i);if(t===!1){YJ.debug(`Webhook event dropped by filter`,{webhookId:e,name:r.name});return}typeof t==`object`&&t&&(i=t)}catch(t){YJ.error(`Webhook filter error`,{webhookId:e,error:t instanceof Error?t.message:String(t)})}YJ.info(`Webhook event received`,{webhookId:e,name:r.name,targetScoop:r.scoop}),this.eventHandler?.(i)}async createCronTask(e,t,n,r){let i=this.getNextCronTime(t,new Date);if(!i)throw Error(`Invalid cron expression`);r&&this.compileFilter(r,!1);let a=this.generateId(),o={id:a,name:e,cron:t,scoop:n,filter:r,nextRun:i.toISOString(),lastRun:null,status:`active`,createdAt:new Date().toISOString()};return this.crontasks.set(a,o),await ke(o),YJ.info(`Cron task created`,{id:a,name:e,cron:t,scoop:n}),o}async deleteCronTask(e){return this.crontasks.has(e)?(this.crontasks.delete(e),await Pe(e),YJ.info(`Cron task deleted`,{id:e}),!0):!1}listCronTasks(){return Array.from(this.crontasks.values())}getCronTask(e){return this.crontasks.get(e)}getLicksForScoop(e,t){let n=n=>n===e||n===t||`${n}-scoop`===t;return{webhooks:Array.from(this.webhooks.values()).filter(e=>n(e.scoop)),cronTasks:Array.from(this.crontasks.values()).filter(e=>n(e.scoop))}}async runCronScheduler(){let e=new Date;for(let t of this.crontasks.values()){if(t.status!==`active`||!t.nextRun||new Date(t.nextRun)>e)continue;let n={time:e.toISOString()};if(t.filter)try{let r=this.compileFilter(t.filter,!1)(null);if(r===!1){YJ.debug(`Cron task skipped by filter`,{id:t.id,name:t.name}),t.nextRun=this.getNextCronTime(t.cron,e)?.toISOString()??null,t.lastRun=e.toISOString(),await ke(t);continue}typeof r==`object`&&r&&(n=r)}catch(e){YJ.error(`Cron filter error`,{id:t.id,error:e instanceof Error?e.message:String(e)})}let r={type:`cron`,cronId:t.id,cronName:t.name,targetScoop:t.scoop,timestamp:e.toISOString(),body:n};YJ.info(`Cron task running`,{id:t.id,name:t.name}),this.eventHandler?.(r),t.nextRun=this.getNextCronTime(t.cron,e)?.toISOString()??null,t.lastRun=e.toISOString(),await ke(t)}}generateId(){let e=``;for(let t=0;t<12;t++)e+=`abcdefghijklmnopqrstuvwxyz0123456789`[Math.floor(Math.random()*36)];return e}compileFilter(e,t){try{return t?Function(`event`,`return (${e})(event);`):Function(`return (${e})();`)}catch(e){throw Error(`Invalid filter function: ${e instanceof Error?e.message:String(e)}`)}}getNextCronTime(e,t){let n=e.trim().split(/\s+/);if(n.length!==5)return null;let[r,i,a,o,s]=n,c=new Date(t);c.setSeconds(0),c.setMilliseconds(0),c.setMinutes(c.getMinutes()+1);let l=(e,t)=>{if(t===`*`)return!0;if(t.includes(`,`))return t.split(`,`).some(t=>l(e,t.trim()));if(t.includes(`-`)){let[n,r]=t.split(`-`).map(e=>parseInt(e,10));return e>=n&&e<=r}if(t.includes(`/`)){let[n,r]=t.split(`/`),i=parseInt(r,10);if(n===`*`)return e%i===0;let a=parseInt(n,10);return e>=a&&(e-a)%i===0}return parseInt(t,10)===e};for(let e=0;e<527040;e++){if(l(c.getMinutes(),r)&&l(c.getHours(),i)&&l(c.getDate(),a)&&l(c.getMonth()+1,o)&&l(c.getDay(),s))return c;c.setMinutes(c.getMinutes()+1)}return null}};function ZJ(e,t,n){if(t.length===0&&n.length===0)return null;let r=[];t.length>0&&r.push(`${t.length} active webhook${t.length>1?`s`:``}`),n.length>0&&r.push(`${n.length} active cron task${n.length>1?`s`:``}`);let i=[...t.map(e=>` webhook delete ${e.id}`),...n.map(e=>` crontask delete ${e.id}`)].join(`
|
|
14126
14126
|
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}var QJ=null;function $J(){return QJ||=new XJ,QJ}var eY=r(`orchestrator`),tY=class{scoops=new Map;tabs=new Map;contexts=new Map;messageQueues=new Map;lastAgentTimestamp=new Map;container;callbacks;config;pollInterval=null;scheduler=null;globalMemoryCache=``;sharedFs=null;scoopResponseBuffer=new Map;lickManager=null;sessionStore=null;constructor(e,t,n={name:`sliccy`,triggerPattern:/^@sliccy\b/i}){this.container=e,this.callbacks=t,this.config=n}async init(){await Ae(),this.sharedFs=await pe.create({dbName:`slicc-fs`}),this.sessionStore=new te,await this.ensureRootStructure();let e=await F();for(let t of Object.values(e)){t.isCone&&(t.trigger=void 0,t.requiresTrigger=!1,t.assistantLabel=t.assistantLabel||`sliccy`),this.scoops.set(t.jid,t),this.messageQueues.set(t.jid,[]);let e=await Ie(`lastAgentTs_${t.jid}`);e&&this.lastAgentTimestamp.set(t.jid,e)}await this.ensureGlobalMemory(),this.scheduler=new JJ({onTaskRun:async(e,t)=>{eY.info(`Running scheduled task`,{taskId:e.id,scoop:t.name}),await this.sendPrompt(t.jid,`[SCHEDULED TASK]\n\n${e.prompt}`,`scheduler`,`Scheduled Task`)},getScoop:e=>{for(let t of this.scoops.values())if(t.folder===e)return t}}),this.scheduler.start(),eY.info(`Orchestrator initialized`,{scoopCount:this.scoops.size});for(let e of this.scoops.values())await this.createScoopTab(e.jid);this.startMessageLoop()}async ensureRootStructure(){if(this.sharedFs)for(let e of[`/workspace`,`/shared`,`/scoops`,`/home`,`/tmp`])try{await this.sharedFs.mkdir(e,{recursive:!0})}catch{}}async ensureGlobalMemory(){if(this.sharedFs){await VJ(this.sharedFs);try{let e=await this.sharedFs.readFile(`/shared/CLAUDE.md`,{encoding:`utf-8`});this.globalMemoryCache=typeof e==`string`?e:new TextDecoder().decode(e)}catch{eY.warn(`Global memory file not found after creating defaults`)}}}async getGlobalMemory(){if(this.globalMemoryCache)return this.globalMemoryCache;if(this.sharedFs)try{let e=await this.sharedFs.readFile(`/shared/CLAUDE.md`,{encoding:`utf-8`});this.globalMemoryCache=typeof e==`string`?e:new TextDecoder().decode(e)}catch{}return this.globalMemoryCache}async setGlobalMemory(e){this.sharedFs&&(await this.sharedFs.writeFile(`/shared/CLAUDE.md`,e),this.globalMemoryCache=e,eY.info(`Global memory updated`))}getSharedFS(){return this.sharedFs}setLickManager(e){this.lickManager=e}async registerScoop(e){await Ve(e),this.scoops.set(e.jid,e),this.messageQueues.set(e.jid,[]),eY.info(`Scoop registered`,{jid:e.jid,name:e.name}),this.createScoopTab(e.jid).catch(t=>{let n=t instanceof Error?t.message:String(t);eY.error(`Scoop init failed`,{jid:e.jid,error:n})})}async unregisterScoop(e){let t=this.scoops.get(e);if(t&&this.lickManager){let{webhooks:e,cronTasks:n}=this.lickManager.getLicksForScoop(t.name,t.folder),r=ZJ(t.folder,e,n);if(r)throw r}await this.destroyScoopTab(e),this.sessionStore?.delete(e).catch(t=>{eY.warn(`Failed to delete agent session`,{jid:e,error:t instanceof Error?t.message:String(t)})}),await je(e),this.scoops.delete(e),this.messageQueues.delete(e),this.lastAgentTimestamp.delete(e),eY.info(`Scoop unregistered`,{jid:e})}getScoops(){return Array.from(this.scoops.values())}getScoop(e){return this.scoops.get(e)}async resetFilesystem(){for(let[e,t]of this.contexts.entries())t.stop(),this.contexts.delete(e);this.sharedFs=await pe.create({dbName:`slicc-fs`,wipe:!0}),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await BJ(this.sharedFs).catch(e=>{eY.warn(`Failed to re-seed default skills`,{error:e instanceof Error?e.message:String(e)})}),eY.info(`Filesystem reset and defaults re-seeded`)}async clearAllMessages(){await ze(),this.sessionStore&&await this.sessionStore.clearAll().catch(e=>{eY.warn(`Failed to clear agent sessions`,{error:e instanceof Error?e.message:String(e)})});for(let e of this.contexts.values())e.clearMessages();this.lastAgentTimestamp.clear();for(let e of this.scoops.keys())this.messageQueues.set(e,[]);eY.info(`All messages cleared`)}async handleMessage(e){eY.info(`handleMessage`,{id:e.id,chatJid:e.chatJid,sender:e.senderName,channel:e.channel,contentPreview:e.content.slice(0,80)});let t=this.scoops.get(e.chatJid);Rq(t?.isCone?`cone`:t?.name??`unknown`,localStorage.getItem(`selected-model`)??`unknown`),await N(e),await this.routeToScoop(e)}async delegateToScoop(e,t,n){let r=this.scoops.get(e);if(!r)throw Error(`Scoop not found: ${e}`);let i={id:`delegate-${Date.now()}-${Math.random().toString(36).slice(2)}`,chatJid:e,senderId:`cone`,senderName:n,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`delegation`};await N(i),this.callbacks.onIncomingMessage?.(e,i),eY.info(`Delegating to scoop`,{scoopJid:e,scoopName:r.name,promptLength:t.length}),this.sendPrompt(e,t,`cone`,n).catch(t=>{let n=t instanceof Error?t.message:String(t);eY.error(`Delegation failed`,{scoopJid:e,error:n}),this.callbacks.onError(e,`Delegation failed: ${n}`)})}async routeToScoop(e){let t=this.scoops.get(e.chatJid);if(!t){eY.info(`routeToScoop: unregistered target`,{chatJid:e.chatJid});return}let n=e.channel===`webhook`||e.channel===`cron`;if(!t.isCone&&t.requiresTrigger&&t.trigger&&!n&&!e.content.includes(t.trigger)){eY.info(`routeToScoop: trigger not found in content`,{chatJid:e.chatJid,trigger:t.trigger,contentPreview:e.content.slice(0,80)});return}let r=this.messageQueues.get(e.chatJid)??[];r.push(e),this.messageQueues.set(e.chatJid,r);let i=this.tabs.get(e.chatJid);if(eY.debug(`routeToScoop: queued`,{chatJid:e.chatJid,scoopName:t.name,tabStatus:i?.status??`no-tab`,queueLength:r.length}),i?.status===`error`){eY.info(`routeToScoop: tab in error state, retrying init`,{chatJid:e.chatJid});try{await this.createScoopTab(e.chatJid),i=this.tabs.get(e.chatJid)}catch{eY.warn(`routeToScoop: retry init failed`,{chatJid:e.chatJid})}}i?.status===`ready`&&await this.processScoopQueue(e.chatJid)}async createScoopTab(e){let t=this.scoops.get(e);if(!t)throw Error(`Scoop not found: ${e}`);if(this.contexts.has(e))if(this.tabs.get(e)?.status===`error`)eY.info(`Re-creating context after error`,{jid:e}),this.contexts.get(e)?.dispose(),this.contexts.delete(e),this.tabs.delete(e);else{eY.debug(`Context already exists`,{jid:e});return}if(!this.sharedFs)throw Error(`Shared filesystem not initialized`);let n=`scoop-${t.folder}-${Date.now()}`,r=t.isCone?this.sharedFs:new A(this.sharedFs,[`/scoops/${t.folder}/`,`/shared/`],[`/workspace/`]),i=new KJ(t,{onResponse:(n,r)=>{if(this.callbacks.onResponse(e,n,r),!t.isCone)if(r){let t=this.scoopResponseBuffer.get(e)??``;this.scoopResponseBuffer.set(e,t+n)}else this.scoopResponseBuffer.set(e,n)},onResponseDone:()=>{let t=this.tabs.get(e);t&&(t.lastActivity=new Date().toISOString(),this.tabs.set(e,t)),this.callbacks.onResponseDone(e)},onError:t=>{let n=this.tabs.get(e);n&&(n.status=`error`,n.error=t,this.tabs.set(e,n)),this.callbacks.onError(e,t),this.callbacks.onStatusChange(e,`error`)},onStatusChange:n=>{let r=this.tabs.get(e);if(r&&(r.status=n,r.lastActivity=new Date().toISOString(),this.tabs.set(e,r)),this.callbacks.onStatusChange(e,n),n===`ready`&&!t.isCone){let n=this.scoopResponseBuffer.get(e);if(this.scoopResponseBuffer.delete(e),n){let r=Array.from(this.scoops.values()).find(e=>e.isCone);if(r){let i=n.length>2e3?n.slice(0,2e3)+`
|
|
14127
14127
|
... (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`};eY.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);eY.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(),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`)),eY.info(`Scoop context created`,{jid:e,contextId:n})}async destroyScoopTab(e){let t=this.contexts.get(e);t&&(t.dispose(),this.contexts.delete(e),this.tabs.delete(e),eY.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 eY.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(eY.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){eY.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){eY.error(`Context not found after creation`,{jid:e});return}this.scoopResponseBuffer.delete(e),a&&(a.status=`processing`,a.lastActivity=new Date().toISOString(),this.tabs.set(e,a),this.callbacks.onStatusChange(e,`processing`)),eY.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){eY.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){eY.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(eY.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:a,dbMessageCount:o.length,queueLength:t.length}),o.length===0){eY.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(`
|
|
14128
|
-
`);this.messageQueues.set(e,[]);let c=o[o.length-1];this.lastAgentTimestamp.set(e,c.timestamp),await I(`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);eY.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();eY.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=>{eY.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),eY.info(`Skills reloaded across all contexts`,{count:e.length})}stopScoop(e){let t=this.contexts.get(e);t&&t.stop()}async shutdown(){this.stopMessageLoop(),this.scheduler?.stop(),this.scheduler=null;for(let e of this.contexts.keys())await this.destroyScoopTab(e);eY.info(`Orchestrator shutdown`)}};r(`heartbeat`);var nY=r(`tray-follower`);async function rY(e){let t=await uY(await(e.fetchImpl??fetch)(e.joinUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:e.controllerId,runtime:e.runtime})}));return nY.info(`Follower tray attach response`,{trayId:t.trayId,action:t.result.action,code:t.result.code,participantCount:t.participantCount}),iY(t)}function iY(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 aY(e){return lY(await dY(e,{action:`poll`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,cursor:e.cursor}))}async function oY(e){return lY(await dY(e,{action:`answer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,answer:e.answer}))}async function sY(e){return lY(await dY(e,{action:`ice-candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:e.candidate}))}async function cY(e){return lY(await dY(e,{action:`retry`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,runtime:e.runtime}))}function lY(e){return{trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,bootstrap:e.bootstrap,events:e.events}}async function uY(e){let t=null,n=null;try{t=await e.text(),n=JSON.parse(t)}catch{}if(!fY(n)){let n=t?t.slice(0,200):`(empty)`;throw nY.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 dY(e,t){let n=await(e.fetchImpl??fetch)(e.joinUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>null);if(!pY(r))throw Error(`Tray follower bootstrap returned an invalid response (${n.status})`);return r}function fY(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`&&mY(r.bootstrap):r.action===`fail`?(r.code===`INVALID_JOIN_CAPABILITY`||r.code===`TRAY_EXPIRED`)&&typeof r.error==`string`:!1}function pY(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`&&mY(t.bootstrap)&&Array.isArray(t.events)}function mY(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 hY=r(`tray-webrtc`),gY=`tray-control`,_Y=250,vY=class{peerConnectionFactory;dataChannelLabel;peers=new Map;iceServers;constructor(e){this.options=e,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>xY(this.iceServers)),this.dataChannelLabel=e.dataChannelLabel??gY}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=CY(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`)&&(hY.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`?(hY.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`?(hY.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:SY(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){hY.warn(`Failed to report tray bootstrap failure`,{error:e instanceof Error?e.message:String(e)})}}}},yY=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??(()=>xY(this.iceServers)),this.controllerIdFactory=e.controllerIdFactory??(()=>crypto.randomUUID()),this.sleep=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),this.pollIntervalMs=e.pollIntervalMs??_Y}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}),hY.info(`Follower tray join starting`,{joinUrl:this.options.joinUrl});let n=0;for(;;){wY(this.stopped),n++;let t;try{t=await rY({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;hY.info(`Follower tray attach waiting`,{attempt:n,code:t.code,retryAfterMs:e}),n%10==0&&hY.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}),hY.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}),hY.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}),hY.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(wY(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 aY({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 oY({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,answer:SY(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 cY({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`)&&(hY.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?(hY.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?(hY.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=CY(n);r&&sY({joinUrl:this.options.joinUrl,controllerId:e,bootstrapId:t,candidate:r,fetchImpl:this.fetchImpl}).catch(e=>{hY.warn(`Failed to send follower ICE candidate`,{error:e instanceof Error?e.message:String(e)})})}),r}};function bY(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 yY({...e,sleep:o,onDisconnected:e=>{s||(hY.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}),hY.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}),hY.info(`Reconnect successful`,{attempt:f,trayId:i.trayId}),t.onConnected(i);return}catch(e){g=e instanceof Error?e.message:String(e),hY.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}),hY.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||hY.warn(`Initial follower connection failed`,{error:e instanceof Error?e.message:String(e)})}),u}function xY(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 SY(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 CY(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 wY(e){if(e)throw Error(`Tray follower stopped before WebRTC bootstrap completed`)}var TY=64*1024;async function EY(e,t){try{switch(t.op){case`readFile`:return await DY(e,t.path,t.encoding);case`writeFile`:return[await OY(e,t.path,t.content,t.encoding)];case`stat`:return[await kY(e,t.path)];case`readDir`:return[await AY(e,t.path)];case`mkdir`:return[await jY(e,t.path,t.recursive)];case`rm`:return[await MY(e,t.path,t.recursive)];case`exists`:return[await NY(e,t.path)];case`walk`:return[await PY(e,t.path)];default:return[{ok:!1,error:`Unknown fs operation: ${t.op}`}]}}catch(e){return[IY(e)]}}async function DY(e,t,n){return(n??`utf-8`)===`utf-8`?FY(await e.readFile(t,{encoding:`utf-8`}),`utf-8`):FY(LY(await e.readFile(t,{encoding:`binary`})),`base64`)}async function OY(e,t,n,r){if(r===`base64`){let r=RY(n);await e.writeFile(t,r)}else await e.writeFile(t,n);return{ok:!0,data:{type:`void`}}}async function kY(e,t){return{ok:!0,data:{type:`stat`,stat:await e.stat(t)}}}async function AY(e,t){return{ok:!0,data:{type:`dirEntries`,entries:await e.readDir(t)}}}async function jY(e,t,n){return await e.mkdir(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function MY(e,t,n){return await e.rm(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function NY(e,t){return{ok:!0,data:{type:`exists`,exists:await e.exists(t)}}}async function PY(e,t){let n=[];for await(let r of e.walk(t))n.push(r);return{ok:!0,data:{type:`paths`,paths:n}}}function FY(e,t){if(e.length<=TY)return[{ok:!0,data:{type:`file`,content:e,encoding:t}}];let n=Math.ceil(e.length/TY),r=[];for(let i=0;i<n;i++){let a=i*TY,o=e.slice(a,a+TY);r.push({ok:!0,data:{type:`file`,content:o,encoding:t},chunkIndex:i,totalChunks:n})}return r}function IY(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 LY(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function RY(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 zY=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()]}},BY=r(`data-channel-keepalive`),VY=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++,BY.debug(`Missed pong`,{missedPongs:this.missedPongs,maxMissed:this.maxMissed}),this.missedPongs>=this.maxMissed)){BY.warn(`Channel declared dead`,{missedPongs:this.missedPongs}),this.stop(),this.onDead();return}this.awaitingPong=!0,this.sendPing()}}},HY=r(`tray-leader-sync`);function UY(e){return e?e.includes(`standalone`)?`standalone`:e.includes(`extension`)?`extension`:e.includes(`electron`)?`electron`:`unknown`:`unknown`}var WY=class{followers=new Map;registry=new zY;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=xe(t),i=r.onMessage(t=>{this.handleFollowerMessage(e,t)}),a=new VY({sendPing:()=>r.send({type:`ping`}),onDead:()=>{HY.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:UY(n?.runtime)}),HY.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(),HY.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();ye(t.sync,n,r),HY.debug(`Snapshot sent to follower`,{bootstrapId:e,messageCount:n.length})}handleFollowerMessage(e,t){switch(t.type){case`user_message`:HY.info(`Follower user message received`,{bootstrapId:e,messageId:t.messageId}),this.options.onFollowerMessage(t.text,t.messageId);break;case`abort`:HY.info(`Follower abort received`,{bootstrapId:e}),this.options.onFollowerAbort();break;case`request_snapshot`:HY.info(`Follower snapshot request received`,{bootstrapId:e}),this.sendSnapshotToFollower(e);break;case`targets.advertise`:HY.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),HY.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 M({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),HY.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);we(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=ve(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&&we(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 EY(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?EY(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})})}},GY=r(`tray-follower-sync`),KY=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=Ce(e),this.unsubscribe=this.sync.onMessage(e=>{this.handleLeaderMessage(e)}),this.keepalive=new VY({sendPing:()=>this.sync.send({type:`ping`}),onDead:()=>{GY.warn(`Leader keepalive dead, cleaning up`),this.handleDisconnect(`Keepalive timeout — leader not responding`),this.options.onDead?.()}}),this.keepalive.start(),e.addEventListener(`close`,()=>{GY.warn(`Data channel closed`),this.handleDisconnect(`Data channel closed`)}),e.addEventListener(`error`,()=>{GY.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}),GY.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`}),GY.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(),GY.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`:GY.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=Se(this.snapshotChunkBuffer,e);this.snapshotChunkBuffer=t.buffer,t.result&&(GY.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),GY.debug(`Skipping own message echo`,{messageId:e.messageId});break}GY.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`:GY.warn(`Error from leader`,{error:e.error}),this.emitEvent({type:`error`,error:e.error});break;case`targets.registry`:GY.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){GY.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}}createRemoteTransport(e,t){let n=new M({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),GY.debug(`Tracking remote CDP session`,{remoteSessionId:e})}n===`Target.detachFromTarget`&&i&&this.remoteCDPSessions.has(i)&&(this.remoteCDPSessions.delete(i),GY.debug(`Removed remote CDP session on detach`,{sessionId:i})),we(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=ve(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 EY(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 qY(e,t){if(t)return`extension`;try{return XY(new URL(e))?`electron-overlay`:`standalone`}catch{return`standalone`}}function JY(e,t){return e===`electron-overlay`||e===`standalone`&&t}function YY(e){try{let t=new URL(e).searchParams.get(`tab`);return t&&Hi(t)?t:Bi}catch{return Bi}}function XY(e){return e.pathname===`/electron`||e.pathname===`/electron/`||e.searchParams.get(`runtime`)===`electron-overlay`}function ZY(e){let t=new URL(e);return`${t.protocol===`https:`?`wss:`:`ws:`}//${t.host}/licks-ws`}function QY(e,t){return`${new URL(e).origin}/webhooks/${t}`}function $Y(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function eX(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`slicc-electron-overlay:set-tab`}var tX=[`/shared/sprinkles`];async function nX(e){let t=new Map;for(let n of tX)await e.exists(n)&&await rX(e,n,t);return await rX(e,`/`,t),t}async function rX(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.shtml`))continue;let t=iX(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:aX(i,t),autoOpen:oX(i)})}}}function iX(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function aX(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 oX(e){return/data-sprinkle-autoopen\b/.test(e)}var sX=class{listeners=new Map;lickHandler;fs;closeHandler;constructor(e,t,n){this.fs=e,this.lickHandler=t,this.closeHandler=n}createAPI(e){return{name:e,lick:t=>{let n=typeof t==`string`?t:t.action,r=typeof t==`string`?void 0:t.data,i={type:`sprinkle`,sprinkleName:e,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:n,data:r}};this.lickHandler(i)},on:(t,n)=>{let r=`${e}:${t}`,i=this.listeners.get(r);i||(i=new Set,this.listeners.set(r,i)),i.add(n)},off:(t,n)=>{let r=`${e}:${t}`;this.listeners.get(r)?.delete(n)},readFile:async e=>await this.fs.readFile(e,{encoding:`utf-8`}),setState:t=>{try{localStorage.setItem(`slicc-sprinkle-state:${e}`,JSON.stringify(t))}catch{}},getState:()=>{try{let t=localStorage.getItem(`slicc-sprinkle-state:${e}`);return t?JSON.parse(t):null}catch{return null}},open:e=>{let t=/^https?:|^chrome-extension:/.test(e)?e:LW(e);window.open(t,`_blank`)},close:()=>this.closeHandler(e)}}pushUpdate(e,t){let n=`${e}:update`,r=this.listeners.get(n);if(r)for(let e of r)try{e(t)}catch{}}removeSprinkle(e){for(let t of this.listeners.keys())t.startsWith(`${e}:`)&&this.listeners.delete(t)}},cX=r(`sprinkle-manager`),lX=`slicc-open-sprinkles`,uX=class{fs;bridge;callbacks;availableSprinkles=new Map;openSprinkles=new Map;constructor(e,t,n){this.fs=e,this.bridge=new sX(e,t,e=>this.close(e)),this.callbacks=n}async restoreOpenSprinkles(){try{let e=localStorage.getItem(lX);if(!e){for(let e of this.availableSprinkles.values())if(e.autoOpen)try{await this.open(e.name)}catch{cX.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{cX.warn(`Failed to restore sprinkle`,{name:e})}}catch{}}persistOpenSprinkles(){try{localStorage.setItem(lX,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),cX.info(`Auto-opened new sprinkle after install`,{name:e.name})}catch{cX.warn(`Failed to auto-open new sprinkle`,{name:e.name})}}async refresh(){this.availableSprinkles=await nX(this.fs),cX.info(`Discovered sprinkles`,{count:this.availableSprinkles.size})}async open(e,t){if(this.openSprinkles.has(e)){cX.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 ei(i,this.bridge.createAPI(e));await a.render(r,e),this.openSprinkles.get(e).renderer=a,this.persistOpenSprinkles(),Bq(e),cX.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(),cX.info(`Sprinkle closed`,{name:e}))}available(){return Array.from(this.availableSprinkles.values())}opened(){return Array.from(this.openSprinkles.keys())}sendToSprinkle(e,t){let n=this.openSprinkles.get(e);if(!n){cX.warn(`Cannot send to closed sprinkle`,{name:e});return}this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t)}},dX=r(`main`);function fX(){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 pX(){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 mX(e,t,n){let r=fX(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ia(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ia(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=aa(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 ge(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 hX(e){let{OffscreenClient:t}=await y(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-ABShEPNe.js`);return{OffscreenClient:e}},__vite__mapDeps([20,13])),{VirtualFS:n}=await y(async()=>{let{VirtualFS:e}=await import(`./fs-f8JZDPIF.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([17,1])),r=new qi(e,!0);window.__slicc_debug_tabs=e=>r.setDebugTabs(e),await r.panels.chat.initSession(`session-cone`);let i=null,a=await n.create({dbName:`slicc-fs`});r.panels.fileBrowser.setFs(a),dX.info(`File browser wired to shared VFS (local IndexedDB)`);let o=new BroadcastChannel(`preview-vfs`);o.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 a.readFile(n,{encoding:e});o.postMessage({type:`preview-vfs-response`,id:t,content:i})}catch(e){let r=e instanceof Error?e.message:String(e);r.includes(`ENOENT`)||dX.error(`Preview VFS read failed`,{path:n,error:r}),o.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},mX(a,pX(),async()=>{await r.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-DFibR_CB.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await y(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-bn5Tu_JK.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([21,1,4,13])),i=new t;await i.connect();let o=new e({fs:a,browserAPI:new n(i)});await r.panels.terminal.mountShell(o),dX.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){dX.warn(`Failed to mount shell to terminal`,e)}let s,c=new Set,l=async e=>{i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid),r.setScoopSwitcherSelected?.(e.jid),r.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=e.isCone?void 0:e.name;await r.panels.chat.switchToContext(t,!e.isCone,n),s.isProcessing(e.jid)&&r.panels.chat.setProcessing(!0)};s=new t({onStatusChange:(e,t)=>{r.panels.scoops.updateScoopStatus(e,t),r.updateScoopSwitcherStatus?.(e,t),i?.jid===e&&(r.setAgentProcessing(t===`processing`),t===`processing`?r.panels.chat.setProcessing(!0):t===`ready`&&r.panels.chat.setProcessing(!1))},onScoopCreated:e=>{r.panels.scoops.refreshScoops(),r.refreshScoopSwitcher?.(),i||(i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid))},onScoopListUpdate:()=>{let e=new Set(s.getScoops().map(e=>e.folder));for(let t of c)e.has(t)||r.panels.chat.deleteSessionById(`session-${t}`);if(c=e,r.panels.scoops.refreshScoops(),r.refreshScoopSwitcher?.(),!i){let e=s.getScoops().find(e=>e.isCone);e&&(i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid))}},onIncomingMessage:(e,t)=>{if(i?.jid===e){let e=t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content;r.panels.chat.addUserMessage(e)}},onReady:async()=>{try{dX.info(`Offscreen engine ready, scoop count:`,s.getScoops().length),window.localStorage.getItem(`slicc.trayJoinUrl`)&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`refresh-tray-runtime`}}).catch(()=>{});let e=i??s.getScoops().find(e=>e.isCone)??s.getScoops()[0];e&&(i=e,s.selectedScoopJid=e.jid,await l(e))}catch(e){dX.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),s.setLocalFS(a);let u=s.createAgentHandle();r.panels.chat.setAgent(u),r.panels.scoops.setOrchestrator(s),r.panels.memory.setOrchestrator(s),r.setScoopSwitcherOrchestrator?.(s),r.onScoopSelect=l,r.onModelChange=e=>{localStorage.setItem(`selected-model`,e),s.updateModel()},r.onClearChat=async()=>{let e=s.getScoops();for(let t of e){let e=t.isCone?`session-cone`:`session-${t.folder}`;await r.panels.chat.deleteSessionById(e)}s.clearAllMessages()},r.onClearFilesystem=async()=>{s.clearFilesystem()},r.panels.chat.onInlineSprinkleLick=(e,t)=>{s.sendSprinkleLick(`inline`,{action:e,data:t})};let d=new uX(a,e=>{e.type===`sprinkle`&&(e.sprinkleName===`welcome`&&e.body?.action===`onboarding-complete`&&localStorage.setItem(`slicc-welcomed`,`1`),s.sendSprinkleLick(e.sprinkleName,e.body))},{addSprinkle:(e,t,n,i)=>r.addSprinkle(e,t,n,i),removeSprinkle:e=>r.removeSprinkle(e)});if(window.__slicc_sprinkleManager=d,window.__slicc_reloadSkills=()=>(chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}}),Promise.resolve()),s.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 d.refresh(),e=d.available();break;case`opened`:e=d.opened();break;case`refresh`:await d.refresh(),e=d.available().length;break;case`open`:await d.open(r),e=!0;break;case`close`:d.close(r),e=!0;break;case`send`:d.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await d.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 d.refresh(),r.onSprinkleClose=e=>d.close(e),r.getAvailableSprinkles=()=>{let e=new Set(d.opened());return d.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},r.onOpenSprinkle=(e,t)=>d.open(e,t),r.updateAddButtons(),await d.restoreOpenSprinkles(),!localStorage.getItem(`slicc-welcomed`)&&d.available().some(e=>e.name===`welcome`))try{await d.open(`welcome`)}catch(e){dX.warn(`Failed to open welcome sprinkle`,e)}dX.info(`SprinkleManager initialized (extension mode)`),s.requestState(),dX.info(`Extension UI connected to offscreen agent engine`),Lq().catch(()=>{})}async function gX(){S(),ta();let e=document.getElementById(`app`);if(!e)throw Error(`#app element not found`);`serviceWorker`in navigator&&navigator.serviceWorker.register(`/preview-sw.js`,{scope:`/preview/`}).then(()=>dX.info(`Preview SW registered`)).catch(e=>dX.error(`Preview SW registration failed — preview feature will not work`,e)),ne();let t=E(),n=c(window.localStorage);!t&&!n&&(await w({preferTrayJoin:!(window.location.port===`5710`||window.location.port===`3000`||window.location.port===``)}),t=E());let r=!t&&c(window.localStorage),a=typeof chrome<`u`&&!!chrome?.runtime?.id,o=qY(window.location.href,a);if(o===`extension`)return hX(e);let l=new qi(e,o===`electron-overlay`);if(o===`electron-overlay`){let e=YY(window.location.href);l.setActiveTab(e);let t=document.createElement(`style`);t.id=`slicc-electron-overlay-runtime-style`,t.textContent=`
|
|
14128
|
+
`);this.messageQueues.set(e,[]);let c=o[o.length-1];this.lastAgentTimestamp.set(e,c.timestamp),await I(`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);eY.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();eY.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=>{eY.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),eY.info(`Skills reloaded across all contexts`,{count:e.length})}stopScoop(e){let t=this.contexts.get(e);t&&t.stop()}async shutdown(){this.stopMessageLoop(),this.scheduler?.stop(),this.scheduler=null;for(let e of this.contexts.keys())await this.destroyScoopTab(e);eY.info(`Orchestrator shutdown`)}};r(`heartbeat`);var nY=r(`tray-follower`);async function rY(e){let t=await uY(await(e.fetchImpl??fetch)(e.joinUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:e.controllerId,runtime:e.runtime})}));return nY.info(`Follower tray attach response`,{trayId:t.trayId,action:t.result.action,code:t.result.code,participantCount:t.participantCount}),iY(t)}function iY(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 aY(e){return lY(await dY(e,{action:`poll`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,cursor:e.cursor}))}async function oY(e){return lY(await dY(e,{action:`answer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,answer:e.answer}))}async function sY(e){return lY(await dY(e,{action:`ice-candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:e.candidate}))}async function cY(e){return lY(await dY(e,{action:`retry`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,runtime:e.runtime}))}function lY(e){return{trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,bootstrap:e.bootstrap,events:e.events}}async function uY(e){let t=null,n=null;try{t=await e.text(),n=JSON.parse(t)}catch{}if(!fY(n)){let n=t?t.slice(0,200):`(empty)`;throw nY.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 dY(e,t){let n=await(e.fetchImpl??fetch)(e.joinUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>null);if(!pY(r))throw Error(`Tray follower bootstrap returned an invalid response (${n.status})`);return r}function fY(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`&&mY(r.bootstrap):r.action===`fail`?(r.code===`INVALID_JOIN_CAPABILITY`||r.code===`TRAY_EXPIRED`)&&typeof r.error==`string`:!1}function pY(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`&&mY(t.bootstrap)&&Array.isArray(t.events)}function mY(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 hY=r(`tray-webrtc`),gY=`tray-control`,_Y=250,vY=class{peerConnectionFactory;dataChannelLabel;peers=new Map;iceServers;constructor(e){this.options=e,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>xY(this.iceServers)),this.dataChannelLabel=e.dataChannelLabel??gY}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=CY(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`)&&(hY.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`?(hY.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`?(hY.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:SY(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){hY.warn(`Failed to report tray bootstrap failure`,{error:e instanceof Error?e.message:String(e)})}}}},yY=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??(()=>xY(this.iceServers)),this.controllerIdFactory=e.controllerIdFactory??(()=>crypto.randomUUID()),this.sleep=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),this.pollIntervalMs=e.pollIntervalMs??_Y}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}),hY.info(`Follower tray join starting`,{joinUrl:this.options.joinUrl});let n=0;for(;;){wY(this.stopped),n++;let t;try{t=await rY({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;hY.info(`Follower tray attach waiting`,{attempt:n,code:t.code,retryAfterMs:e}),n%10==0&&hY.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}),hY.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}),hY.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}),hY.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(wY(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 aY({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 oY({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,answer:SY(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 cY({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`)&&(hY.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?(hY.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?(hY.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=CY(n);r&&sY({joinUrl:this.options.joinUrl,controllerId:e,bootstrapId:t,candidate:r,fetchImpl:this.fetchImpl}).catch(e=>{hY.warn(`Failed to send follower ICE candidate`,{error:e instanceof Error?e.message:String(e)})})}),r}};function bY(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 yY({...e,sleep:o,onDisconnected:e=>{s||(hY.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}),hY.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}),hY.info(`Reconnect successful`,{attempt:f,trayId:i.trayId}),t.onConnected(i);return}catch(e){g=e instanceof Error?e.message:String(e),hY.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}),hY.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||hY.warn(`Initial follower connection failed`,{error:e instanceof Error?e.message:String(e)})}),u}function xY(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 SY(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 CY(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 wY(e){if(e)throw Error(`Tray follower stopped before WebRTC bootstrap completed`)}var TY=64*1024;async function EY(e,t){try{switch(t.op){case`readFile`:return await DY(e,t.path,t.encoding);case`writeFile`:return[await OY(e,t.path,t.content,t.encoding)];case`stat`:return[await kY(e,t.path)];case`readDir`:return[await AY(e,t.path)];case`mkdir`:return[await jY(e,t.path,t.recursive)];case`rm`:return[await MY(e,t.path,t.recursive)];case`exists`:return[await NY(e,t.path)];case`walk`:return[await PY(e,t.path)];default:return[{ok:!1,error:`Unknown fs operation: ${t.op}`}]}}catch(e){return[IY(e)]}}async function DY(e,t,n){return(n??`utf-8`)===`utf-8`?FY(await e.readFile(t,{encoding:`utf-8`}),`utf-8`):FY(LY(await e.readFile(t,{encoding:`binary`})),`base64`)}async function OY(e,t,n,r){if(r===`base64`){let r=RY(n);await e.writeFile(t,r)}else await e.writeFile(t,n);return{ok:!0,data:{type:`void`}}}async function kY(e,t){return{ok:!0,data:{type:`stat`,stat:await e.stat(t)}}}async function AY(e,t){return{ok:!0,data:{type:`dirEntries`,entries:await e.readDir(t)}}}async function jY(e,t,n){return await e.mkdir(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function MY(e,t,n){return await e.rm(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function NY(e,t){return{ok:!0,data:{type:`exists`,exists:await e.exists(t)}}}async function PY(e,t){let n=[];for await(let r of e.walk(t))n.push(r);return{ok:!0,data:{type:`paths`,paths:n}}}function FY(e,t){if(e.length<=TY)return[{ok:!0,data:{type:`file`,content:e,encoding:t}}];let n=Math.ceil(e.length/TY),r=[];for(let i=0;i<n;i++){let a=i*TY,o=e.slice(a,a+TY);r.push({ok:!0,data:{type:`file`,content:o,encoding:t},chunkIndex:i,totalChunks:n})}return r}function IY(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 LY(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function RY(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 zY=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()]}},BY=r(`data-channel-keepalive`),VY=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++,BY.debug(`Missed pong`,{missedPongs:this.missedPongs,maxMissed:this.maxMissed}),this.missedPongs>=this.maxMissed)){BY.warn(`Channel declared dead`,{missedPongs:this.missedPongs}),this.stop(),this.onDead();return}this.awaitingPong=!0,this.sendPing()}}},HY=r(`tray-leader-sync`);function UY(e){return e?e.includes(`standalone`)?`standalone`:e.includes(`extension`)?`extension`:e.includes(`electron`)?`electron`:`unknown`:`unknown`}var WY=class{followers=new Map;registry=new zY;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=xe(t),i=r.onMessage(t=>{this.handleFollowerMessage(e,t)}),a=new VY({sendPing:()=>r.send({type:`ping`}),onDead:()=>{HY.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:UY(n?.runtime)}),HY.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(),HY.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();ye(t.sync,n,r),HY.debug(`Snapshot sent to follower`,{bootstrapId:e,messageCount:n.length})}handleFollowerMessage(e,t){switch(t.type){case`user_message`:HY.info(`Follower user message received`,{bootstrapId:e,messageId:t.messageId}),this.options.onFollowerMessage(t.text,t.messageId);break;case`abort`:HY.info(`Follower abort received`,{bootstrapId:e}),this.options.onFollowerAbort();break;case`request_snapshot`:HY.info(`Follower snapshot request received`,{bootstrapId:e}),this.sendSnapshotToFollower(e);break;case`targets.advertise`:HY.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),HY.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 M({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),HY.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);we(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=ve(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&&we(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 EY(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?EY(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})})}},GY=r(`tray-follower-sync`),KY=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=Ce(e),this.unsubscribe=this.sync.onMessage(e=>{this.handleLeaderMessage(e)}),this.keepalive=new VY({sendPing:()=>this.sync.send({type:`ping`}),onDead:()=>{GY.warn(`Leader keepalive dead, cleaning up`),this.handleDisconnect(`Keepalive timeout — leader not responding`),this.options.onDead?.()}}),this.keepalive.start(),e.addEventListener(`close`,()=>{GY.warn(`Data channel closed`),this.handleDisconnect(`Data channel closed`)}),e.addEventListener(`error`,()=>{GY.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}),GY.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`}),GY.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(),GY.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`:GY.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=Se(this.snapshotChunkBuffer,e);this.snapshotChunkBuffer=t.buffer,t.result&&(GY.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),GY.debug(`Skipping own message echo`,{messageId:e.messageId});break}GY.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`:GY.warn(`Error from leader`,{error:e.error}),this.emitEvent({type:`error`,error:e.error});break;case`targets.registry`:GY.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){GY.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}}createRemoteTransport(e,t){let n=new M({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),GY.debug(`Tracking remote CDP session`,{remoteSessionId:e})}n===`Target.detachFromTarget`&&i&&this.remoteCDPSessions.has(i)&&(this.remoteCDPSessions.delete(i),GY.debug(`Removed remote CDP session on detach`,{sessionId:i})),we(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=ve(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 EY(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 qY(e,t){if(t)return`extension`;try{return XY(new URL(e))?`electron-overlay`:`standalone`}catch{return`standalone`}}function JY(e,t){return e===`electron-overlay`||e===`standalone`&&t}function YY(e){try{let t=new URL(e).searchParams.get(`tab`);return t&&Hi(t)?t:Bi}catch{return Bi}}function XY(e){return e.pathname===`/electron`||e.pathname===`/electron/`||e.searchParams.get(`runtime`)===`electron-overlay`}function ZY(e){let t=new URL(e);return`${t.protocol===`https:`?`wss:`:`ws:`}//${t.host}/licks-ws`}function QY(e,t){return`${new URL(e).origin}/webhooks/${t}`}function $Y(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function eX(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`slicc-electron-overlay:set-tab`}var tX=[`/shared/sprinkles`];async function nX(e){let t=new Map;for(let n of tX)await e.exists(n)&&await rX(e,n,t);return await rX(e,`/`,t),t}async function rX(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.shtml`))continue;let t=iX(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:aX(i,t),autoOpen:oX(i)})}}}function iX(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function aX(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 oX(e){return/data-sprinkle-autoopen\b/.test(e)}var sX=class{listeners=new Map;lickHandler;fs;closeHandler;constructor(e,t,n){this.fs=e,this.lickHandler=t,this.closeHandler=n}createAPI(e){return{name:e,lick:t=>{let n=typeof t==`string`?t:t.action,r=typeof t==`string`?void 0:t.data,i={type:`sprinkle`,sprinkleName:e,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:n,data:r}};this.lickHandler(i)},on:(t,n)=>{let r=`${e}:${t}`,i=this.listeners.get(r);i||(i=new Set,this.listeners.set(r,i)),i.add(n)},off:(t,n)=>{let r=`${e}:${t}`;this.listeners.get(r)?.delete(n)},readFile:async e=>await this.fs.readFile(e,{encoding:`utf-8`}),setState:t=>{try{localStorage.setItem(`slicc-sprinkle-state:${e}`,JSON.stringify(t))}catch{}},getState:()=>{try{let t=localStorage.getItem(`slicc-sprinkle-state:${e}`);return t?JSON.parse(t):null}catch{return null}},open:e=>{let t=/^https?:|^chrome-extension:/.test(e)?e:LW(e);window.open(t,`_blank`)},close:()=>this.closeHandler(e)}}pushUpdate(e,t){let n=`${e}:update`,r=this.listeners.get(n);if(r)for(let e of r)try{e(t)}catch{}}removeSprinkle(e){for(let t of this.listeners.keys())t.startsWith(`${e}:`)&&this.listeners.delete(t)}},cX=r(`sprinkle-manager`),lX=`slicc-open-sprinkles`,uX=class{fs;bridge;callbacks;availableSprinkles=new Map;openSprinkles=new Map;constructor(e,t,n){this.fs=e,this.bridge=new sX(e,t,e=>this.close(e)),this.callbacks=n}async restoreOpenSprinkles(){try{let e=localStorage.getItem(lX);if(!e){for(let e of this.availableSprinkles.values())if(e.autoOpen)try{await this.open(e.name)}catch{cX.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{cX.warn(`Failed to restore sprinkle`,{name:e})}}catch{}}persistOpenSprinkles(){try{localStorage.setItem(lX,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),cX.info(`Auto-opened new sprinkle after install`,{name:e.name})}catch{cX.warn(`Failed to auto-open new sprinkle`,{name:e.name})}}async refresh(){this.availableSprinkles=await nX(this.fs),cX.info(`Discovered sprinkles`,{count:this.availableSprinkles.size})}async open(e,t){if(this.openSprinkles.has(e)){cX.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 ei(i,this.bridge.createAPI(e));await a.render(r,e),this.openSprinkles.get(e).renderer=a,this.persistOpenSprinkles(),Bq(e),cX.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(),cX.info(`Sprinkle closed`,{name:e}))}available(){return Array.from(this.availableSprinkles.values())}opened(){return Array.from(this.openSprinkles.keys())}sendToSprinkle(e,t){let n=this.openSprinkles.get(e);if(!n){cX.warn(`Cannot send to closed sprinkle`,{name:e});return}this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t)}},dX=r(`main`);function fX(){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 pX(){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 mX(e,t,n){let r=fX(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ia(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ia(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=aa(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 ge(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 hX(e){let{OffscreenClient:t}=await y(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-ABShEPNe.js`);return{OffscreenClient:e}},__vite__mapDeps([20,13])),{VirtualFS:n}=await y(async()=>{let{VirtualFS:e}=await import(`./fs-f8JZDPIF.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([17,1])),r=new qi(e,!0);window.__slicc_debug_tabs=e=>r.setDebugTabs(e),await r.panels.chat.initSession(`session-cone`);let i=null,a=await n.create({dbName:`slicc-fs`});r.panels.fileBrowser.setFs(a),dX.info(`File browser wired to shared VFS (local IndexedDB)`);let o=new BroadcastChannel(`preview-vfs`);o.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 a.readFile(n,{encoding:e});o.postMessage({type:`preview-vfs-response`,id:t,content:i})}catch(e){let r=e instanceof Error?e.message:String(e);r.includes(`ENOENT`)||dX.error(`Preview VFS read failed`,{path:n,error:r}),o.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},mX(a,pX(),async()=>{await r.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-CnndfXEH.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await y(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-bn5Tu_JK.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([21,1,4,13])),i=new t;await i.connect();let o=new e({fs:a,browserAPI:new n(i)});await r.panels.terminal.mountShell(o),dX.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){dX.warn(`Failed to mount shell to terminal`,e)}let s,c=new Set,l=async e=>{i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid),r.setScoopSwitcherSelected?.(e.jid),r.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=e.isCone?void 0:e.name;await r.panels.chat.switchToContext(t,!e.isCone,n),s.isProcessing(e.jid)&&r.panels.chat.setProcessing(!0)};s=new t({onStatusChange:(e,t)=>{r.panels.scoops.updateScoopStatus(e,t),r.updateScoopSwitcherStatus?.(e,t),i?.jid===e&&(r.setAgentProcessing(t===`processing`),t===`processing`?r.panels.chat.setProcessing(!0):t===`ready`&&r.panels.chat.setProcessing(!1))},onScoopCreated:e=>{r.panels.scoops.refreshScoops(),r.refreshScoopSwitcher?.(),i||(i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid))},onScoopListUpdate:()=>{let e=new Set(s.getScoops().map(e=>e.folder));for(let t of c)e.has(t)||r.panels.chat.deleteSessionById(`session-${t}`);if(c=e,r.panels.scoops.refreshScoops(),r.refreshScoopSwitcher?.(),!i){let e=s.getScoops().find(e=>e.isCone);e&&(i=e,s.selectedScoopJid=e.jid,r.panels.memory.setSelectedScoop(e.jid))}},onIncomingMessage:(e,t)=>{if(i?.jid===e){let e=t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content;r.panels.chat.addUserMessage(e)}},onReady:async()=>{try{dX.info(`Offscreen engine ready, scoop count:`,s.getScoops().length),window.localStorage.getItem(`slicc.trayJoinUrl`)&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`refresh-tray-runtime`}}).catch(()=>{});let e=i??s.getScoops().find(e=>e.isCone)??s.getScoops()[0];e&&(i=e,s.selectedScoopJid=e.jid,await l(e))}catch(e){dX.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),s.setLocalFS(a);let u=s.createAgentHandle();r.panels.chat.setAgent(u),r.panels.scoops.setOrchestrator(s),r.panels.memory.setOrchestrator(s),r.setScoopSwitcherOrchestrator?.(s),r.onScoopSelect=l,r.onModelChange=e=>{localStorage.setItem(`selected-model`,e),s.updateModel()},r.onClearChat=async()=>{let e=s.getScoops();for(let t of e){let e=t.isCone?`session-cone`:`session-${t.folder}`;await r.panels.chat.deleteSessionById(e)}s.clearAllMessages()},r.onClearFilesystem=async()=>{s.clearFilesystem()},r.panels.chat.onInlineSprinkleLick=(e,t)=>{s.sendSprinkleLick(`inline`,{action:e,data:t})};let d=new uX(a,e=>{e.type===`sprinkle`&&(e.sprinkleName===`welcome`&&e.body?.action===`onboarding-complete`&&localStorage.setItem(`slicc-welcomed`,`1`),s.sendSprinkleLick(e.sprinkleName,e.body))},{addSprinkle:(e,t,n,i)=>r.addSprinkle(e,t,n,i),removeSprinkle:e=>r.removeSprinkle(e)});if(window.__slicc_sprinkleManager=d,window.__slicc_reloadSkills=()=>(chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}}),Promise.resolve()),s.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 d.refresh(),e=d.available();break;case`opened`:e=d.opened();break;case`refresh`:await d.refresh(),e=d.available().length;break;case`open`:await d.open(r),e=!0;break;case`close`:d.close(r),e=!0;break;case`send`:d.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await d.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 d.refresh(),r.onSprinkleClose=e=>d.close(e),r.getAvailableSprinkles=()=>{let e=new Set(d.opened());return d.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},r.onOpenSprinkle=(e,t)=>d.open(e,t),r.updateAddButtons(),await d.restoreOpenSprinkles(),!localStorage.getItem(`slicc-welcomed`)&&d.available().some(e=>e.name===`welcome`))try{await d.open(`welcome`)}catch(e){dX.warn(`Failed to open welcome sprinkle`,e)}dX.info(`SprinkleManager initialized (extension mode)`),s.requestState(),dX.info(`Extension UI connected to offscreen agent engine`),Lq().catch(()=>{})}async function gX(){S(),ta();let e=document.getElementById(`app`);if(!e)throw Error(`#app element not found`);`serviceWorker`in navigator&&navigator.serviceWorker.register(`/preview-sw.js`,{scope:`/preview/`}).then(()=>dX.info(`Preview SW registered`)).catch(e=>dX.error(`Preview SW registration failed — preview feature will not work`,e)),ne();let t=E(),n=c(window.localStorage);!t&&!n&&(await w({preferTrayJoin:!(window.location.port===`5710`||window.location.port===`3000`||window.location.port===``)}),t=E());let r=!t&&c(window.localStorage),a=typeof chrome<`u`&&!!chrome?.runtime?.id,o=qY(window.location.href,a);if(o===`extension`)return hX(e);let l=new qi(e,o===`electron-overlay`);if(o===`electron-overlay`){let e=YY(window.location.href);l.setActiveTab(e);let t=document.createElement(`style`);t.id=`slicc-electron-overlay-runtime-style`,t.textContent=`
|
|
14129
14129
|
#app > .tab-bar { display: none !important; }
|
|
14130
14130
|
#app > .tab-content {
|
|
14131
14131
|
height: calc(100vh - var(--s2-header-height));
|
|
@@ -14133,4 +14133,4 @@ ${t}
|
|
|
14133
14133
|
#app > .tab-content > .tab-content__panel {
|
|
14134
14134
|
height: 100%;
|
|
14135
14135
|
}
|
|
14136
|
-
`,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&eX(e.data)&&l.setActiveTab(YY(`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 u=pX();await l.panels.chat.initSession(`session-cone`),dX.info(`Session initialized`);let f=new Te,p=new Set,m=e=>{dX.debug(`Emit to UI`,{type:e.type,listenerCount:p.size});for(let t of p)try{t(e)}catch(t){dX.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},h=null,_=new Map,v=new Map;function b(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function x(e){let t=v.get(e);return t||(t=[],v.set(e,t)),t}function C(e,t){let n=x(e),r=_.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${b()}`,_.set(e,r);let i=T.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),h?.jid===e&&m({type:`message_start`,messageId:r}),o}let T=new tY(l.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),h?.jid===e&&(m({type:`content_delta`,messageId:r.id,text:t}),n||m({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=x(e),n=_.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),h?.jid===e&&m({type:`content_done`,messageId:n}),_.delete(e)}},onSendMessage:(e,t)=>{dX.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${b()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};T.handleMessage(r),x(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),h?.jid===e&&(m({type:`message_start`,messageId:n}),m({type:`content_delta`,messageId:n,text:t}),m({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(l.panels.scoops.updateScoopStatus(e,t),l.updateScoopSwitcherStatus?.(e,t),h?.jid===e){if(l.setAgentProcessing(t===`processing`),t===`processing`)l.panels.chat.setProcessing(!0);else if(t===`ready`){l.panels.chat.setProcessing(!1);let t=_.get(e)??`done-${e}-${b()}`;_.delete(e),m({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{dX.error(`Scoop error`,{scoopJid:e,error:t}),h?.jid===e&&m({type:`error`,error:t})},getBrowserAPI:()=>f,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:b(),name:t,input:n}),h?.jid===e&&m({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=x(e),a=_.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)}}h?.jid===e&&a&&m({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=_.get(e);i?m({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):dX.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=_.get(e);n&&m({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};x(e).push(n),h?.jid===e&&(m({type:`message_start`,messageId:t.id}),m({type:`content_delta`,messageId:t.id,text:n.content}),m({type:`content_done`,messageId:t.id}))}});await T.init(),l.panels.scoops.setOrchestrator(T),l.panels.memory.setOrchestrator(T),l.setScoopSwitcherOrchestrator?.(T);let D=T.getSharedFS();if(D){l.panels.fileBrowser.setFs(D),dX.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 D.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`)||dX.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},mX(D,(e,t)=>{t===`error`?dX.warn(`Dropped skill install failed`,{message:e}):dX.info(`Dropped skill installed`,{message:e}),u(e,t)},async()=>{await l.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-DFibR_CB.js`);return{WasmShell:e}},[]),t=new e({fs:D,browserAPI:f});await l.panels.terminal.mountShell(t),dX.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await y(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-By5z523c.js`);return{BshWatchdog:e}},__vite__mapDeps([22,13])),t=new e({browserAPI:f,fs:D});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),dX.info(`BSH navigation watchdog started`)}catch(e){dX.warn(`Failed to start BSH watchdog`,e)}}catch(e){dX.warn(`Failed to mount shell to terminal`,e)}}let O=T.getScoops(),ee=O.some(e=>e.isCone);if(r)dX.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!ee)h=await l.panels.scoops.createScoop(`Cone`,!0),dX.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=O.find(t=>t.folder===e);t?(h=t,dX.info(`Restored scoop from URL`,{folder:e})):h=O.find(e=>e.isCone)??O[0]}else h=O.find(e=>e.isCone)??O[0]}h&&l.panels.memory.setSelectedScoop(h.jid);let te=null,k={sendMessage(e,t){if(!h){m({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:h.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};x(h.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),te?.broadcastUserMessage(e,n.id),T.handleMessage(n),T.createScoopTab(h.jid)},onEvent(e){return p.add(e),()=>p.delete(e)},stop(){h&&(T.stopScoop(h.jid),T.clearQueuedMessages(h.jid).catch(e=>{dX.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};l.panels.chat.setAgent(k),l.panels.chat.setDeleteQueuedMessageCallback(e=>{if(h){T.deleteQueuedMessage(h.jid,e).catch(t=>{dX.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=v.get(h.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),dX.info(`Cone agent handle wired to chat UI`);let{getLickManager:re}=await y(async()=>{let{getLickManager:e}=await import(`./lick-manager-DYq4Y_1C.js`);return{getLickManager:e}},[]),ie=re();await ie.init(),T.setLickManager(ie);let ae=e=>{let t=e.type===`webhook`,n=e.type===`sprinkle`,r=t?e.webhookName:n?e.sprinkleName:e.cronName,i=t?e.webhookId:n?e.sprinkleName:e.cronId,a=e.type;dX.debug(`Lick event`,{type:e.type,name:r,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`&&e.body?.action===`onboarding-complete`&&localStorage.setItem(`slicc-welcomed`,`1`);let o=T.getScoops(),s;if(s=n||!e.targetScoop?o.find(e=>e.isCone):o.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`),s){let o=`${a}-${i}-${Date.now()}`,c=`[${t?`Webhook Event`:n?`Sprinkle Event`:`Cron Event`}: ${r}]\n\`\`\`json\n${JSON.stringify(e.body,null,2)}\n\`\`\``,u={id:o,chatJid:s.jid,senderId:a,senderName:`${a}:${r}`,content:c,timestamp:e.timestamp,fromAssistant:!1,channel:a};x(s.jid).push({id:o,role:`user`,content:c,timestamp:Date.now(),source:`lick`,channel:a}),h?.jid===s.jid&&l.panels.chat.addLickMessage(o,c,a),dX.info(`Routing lick to scoop`,{type:a,name:r,scoopJid:s.jid}),T.handleMessage(u)}else dX.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};ie.setEventHandler(ae),l.panels.chat.onInlineSprinkleLick=(e,t)=>{ae({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let oe=null;if(D){if(oe=new uX(D,ae,{addSprinkle:(e,t,n,r)=>l.addSprinkle(e,t,n,r),removeSprinkle:e=>l.removeSprinkle(e)}),window.__slicc_sprinkleManager=oe,window.__slicc_reloadSkills=()=>T.reloadAllSkills(),await oe.refresh(),l.onSprinkleClose=e=>oe.close(e),l.getAvailableSprinkles=()=>{let e=new Set(oe.opened());return oe.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},l.onOpenSprinkle=(e,t)=>oe.open(e,t),l.updateAddButtons(),!localStorage.getItem(`slicc-welcomed`)&&oe.available().some(e=>e.name===`welcome`))try{await oe.open(`welcome`)}catch(e){dX.warn(`Failed to open welcome sprinkle`,e)}await oe.restoreOpenSprinkles(),dX.info(`SprinkleManager initialized`)}let se=()=>{let e=ZY(window.location.href),t=new WebSocket(e);t.onopen=()=>{dX.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=QU().session,i=r?.webhookUrl?$Y(r.webhookUrl,t.id):QY(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=QU();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)}catch(e){dX.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{dX.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(se,3e3)},t.onerror=e=>{dX.error(`Lick WebSocket error`,{error:String(e)})}};se(),l.onModelChange=e=>{localStorage.setItem(`selected-model`,e),T.updateModel()},l.onClearChat=async()=>{await T.clearAllMessages(),v.clear()},l.onClearFilesystem=async()=>{await T.resetFilesystem()};let ce=async e=>{dX.info(`Scoop selected`,{jid:e.jid,name:e.name}),h=e,T.createScoopTab(e.jid),l.panels.memory.setSelectedScoop(e.jid),l.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=v.get(e.jid),r=e.isCone?void 0:e.name;if(n&&n.length>0)await l.panels.chat.switchToContext(t,!e.isCone,r),l.panels.chat.loadMessages(n);else if(await l.panels.chat.switchToContext(t,!e.isCone,r),l.panels.chat.getMessages().length===0){let t=await T.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};x(e.jid).push(t),l.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`};x(e.jid).push(t),l.panels.chat.addUserMessage(t.content)}else n.fromAssistant?(m({type:`message_start`,messageId:n.id}),m({type:`content_delta`,messageId:n.id,text:n.content}),m({type:`content_done`,messageId:n.id})):l.panels.chat.addUserMessage(n.content)}}e.isCone&&T.isProcessing(e.jid)&&l.panels.chat.setProcessing(!0)};if(l.onScoopSelect=ce,h&&(T.createScoopTab(h.jid),await ce(h)),o===`standalone`||o===`electron-overlay`){let e=await i(),t=JY(o,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,c=null;zG(()=>te?(e,t)=>te.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),KH(()=>te?()=>te.getBestFollowerForTeleport():null),qH(()=>te?()=>te.getConnectedFollowers():null);let u=e=>{c&&=(clearInterval(c),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new KY(e.channel,{browserTransport:f.getTransport(),browserAPI:f,onSnapshot:e=>{l.panels.chat.loadMessages(e)},onUserMessage:e=>{l.panels.chat.addUserMessage(e)},onStatus:e=>{l.panels.chat.setProcessing(e===`processing`)},onTargetsChanged:()=>void i()});r=n,f.setTrayTargetProvider(n),l.panels.chat.setAgent(n),n.requestSnapshot();let i=async()=>{try{let e=await f.listPages();n.advertiseTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})),t)}catch{}};c=setInterval(i,5e3),i(),dX.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},m=e=>{a?.cancel(),c&&=(clearInterval(c),null),r?.close(),r=null,a=bY({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:oW()},{onConnected:e=>u(e),onReconnecting:e=>{dX.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{dX.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{m(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{c&&clearInterval(c),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)m(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new WY({browserTransport:f.getTransport(),browserAPI:f,getMessages:()=>l.panels.chat.getMessages(),getScoopJid:()=>h?.jid??`cone`,onFollowerMessage:(e,t)=>{l.panels.chat.addUserMessage(e),k.sendMessage(e,t)},onFollowerAbort:()=>{k.stop()}}),te=t,cW(()=>t.getConnectedFollowers()),f.setTrayTargetProvider(t),i&&clearInterval(i);let n=async()=>{try{let e=await f.listPages();t.setLocalTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})))}catch{}};i=setInterval(n,5e3),n(),r=new vY({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{dX.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(),p.add(e=>{t.broadcastEvent(e)}),e=new nW({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:oW(),onControlMessage:e=>{if(e.type===`webhook.event`){ie.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{dX.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),dW(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(),QU()}),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=>{dX.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})}}dX.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:T.getScoops().length}),Lq().catch(()=>{})}gX().catch(e=>{dX.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{AH as a,ni as c,Yq as i,$r as l,ZJ as n,sV as o,$J as r,ei as s,XJ as t};
|
|
14136
|
+
`,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&eX(e.data)&&l.setActiveTab(YY(`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 u=pX();await l.panels.chat.initSession(`session-cone`),dX.info(`Session initialized`);let f=new Te,p=new Set,m=e=>{dX.debug(`Emit to UI`,{type:e.type,listenerCount:p.size});for(let t of p)try{t(e)}catch(t){dX.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},h=null,_=new Map,v=new Map;function b(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function x(e){let t=v.get(e);return t||(t=[],v.set(e,t)),t}function C(e,t){let n=x(e),r=_.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${b()}`,_.set(e,r);let i=T.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),h?.jid===e&&m({type:`message_start`,messageId:r}),o}let T=new tY(l.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),h?.jid===e&&(m({type:`content_delta`,messageId:r.id,text:t}),n||m({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=x(e),n=_.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),h?.jid===e&&m({type:`content_done`,messageId:n}),_.delete(e)}},onSendMessage:(e,t)=>{dX.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${b()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};T.handleMessage(r),x(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),h?.jid===e&&(m({type:`message_start`,messageId:n}),m({type:`content_delta`,messageId:n,text:t}),m({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(l.panels.scoops.updateScoopStatus(e,t),l.updateScoopSwitcherStatus?.(e,t),h?.jid===e){if(l.setAgentProcessing(t===`processing`),t===`processing`)l.panels.chat.setProcessing(!0);else if(t===`ready`){l.panels.chat.setProcessing(!1);let t=_.get(e)??`done-${e}-${b()}`;_.delete(e),m({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{dX.error(`Scoop error`,{scoopJid:e,error:t}),h?.jid===e&&m({type:`error`,error:t})},getBrowserAPI:()=>f,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:b(),name:t,input:n}),h?.jid===e&&m({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=x(e),a=_.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)}}h?.jid===e&&a&&m({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=_.get(e);i?m({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):dX.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=_.get(e);n&&m({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};x(e).push(n),h?.jid===e&&(m({type:`message_start`,messageId:t.id}),m({type:`content_delta`,messageId:t.id,text:n.content}),m({type:`content_done`,messageId:t.id}))}});await T.init(),l.panels.scoops.setOrchestrator(T),l.panels.memory.setOrchestrator(T),l.setScoopSwitcherOrchestrator?.(T);let D=T.getSharedFS();if(D){l.panels.fileBrowser.setFs(D),dX.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 D.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`)||dX.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},mX(D,(e,t)=>{t===`error`?dX.warn(`Dropped skill install failed`,{message:e}):dX.info(`Dropped skill installed`,{message:e}),u(e,t)},async()=>{await l.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-CnndfXEH.js`);return{WasmShell:e}},[]),t=new e({fs:D,browserAPI:f});await l.panels.terminal.mountShell(t),dX.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await y(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-By5z523c.js`);return{BshWatchdog:e}},__vite__mapDeps([22,13])),t=new e({browserAPI:f,fs:D});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),dX.info(`BSH navigation watchdog started`)}catch(e){dX.warn(`Failed to start BSH watchdog`,e)}}catch(e){dX.warn(`Failed to mount shell to terminal`,e)}}let O=T.getScoops(),ee=O.some(e=>e.isCone);if(r)dX.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!ee)h=await l.panels.scoops.createScoop(`Cone`,!0),dX.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=O.find(t=>t.folder===e);t?(h=t,dX.info(`Restored scoop from URL`,{folder:e})):h=O.find(e=>e.isCone)??O[0]}else h=O.find(e=>e.isCone)??O[0]}h&&l.panels.memory.setSelectedScoop(h.jid);let te=null,k={sendMessage(e,t){if(!h){m({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:h.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};x(h.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),te?.broadcastUserMessage(e,n.id),T.handleMessage(n),T.createScoopTab(h.jid)},onEvent(e){return p.add(e),()=>p.delete(e)},stop(){h&&(T.stopScoop(h.jid),T.clearQueuedMessages(h.jid).catch(e=>{dX.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};l.panels.chat.setAgent(k),l.panels.chat.setDeleteQueuedMessageCallback(e=>{if(h){T.deleteQueuedMessage(h.jid,e).catch(t=>{dX.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=v.get(h.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),dX.info(`Cone agent handle wired to chat UI`);let{getLickManager:re}=await y(async()=>{let{getLickManager:e}=await import(`./lick-manager-CEJ1osaY.js`);return{getLickManager:e}},[]),ie=re();await ie.init(),T.setLickManager(ie);let ae=e=>{let t=e.type===`webhook`,n=e.type===`sprinkle`,r=t?e.webhookName:n?e.sprinkleName:e.cronName,i=t?e.webhookId:n?e.sprinkleName:e.cronId,a=e.type;dX.debug(`Lick event`,{type:e.type,name:r,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`&&e.body?.action===`onboarding-complete`&&localStorage.setItem(`slicc-welcomed`,`1`);let o=T.getScoops(),s;if(s=n||!e.targetScoop?o.find(e=>e.isCone):o.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`),s){let o=`${a}-${i}-${Date.now()}`,c=`[${t?`Webhook Event`:n?`Sprinkle Event`:`Cron Event`}: ${r}]\n\`\`\`json\n${JSON.stringify(e.body,null,2)}\n\`\`\``,u={id:o,chatJid:s.jid,senderId:a,senderName:`${a}:${r}`,content:c,timestamp:e.timestamp,fromAssistant:!1,channel:a};x(s.jid).push({id:o,role:`user`,content:c,timestamp:Date.now(),source:`lick`,channel:a}),h?.jid===s.jid&&l.panels.chat.addLickMessage(o,c,a),dX.info(`Routing lick to scoop`,{type:a,name:r,scoopJid:s.jid}),T.handleMessage(u)}else dX.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};ie.setEventHandler(ae),l.panels.chat.onInlineSprinkleLick=(e,t)=>{ae({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let oe=null;if(D){if(oe=new uX(D,ae,{addSprinkle:(e,t,n,r)=>l.addSprinkle(e,t,n,r),removeSprinkle:e=>l.removeSprinkle(e)}),window.__slicc_sprinkleManager=oe,window.__slicc_reloadSkills=()=>T.reloadAllSkills(),await oe.refresh(),l.onSprinkleClose=e=>oe.close(e),l.getAvailableSprinkles=()=>{let e=new Set(oe.opened());return oe.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},l.onOpenSprinkle=(e,t)=>oe.open(e,t),l.updateAddButtons(),!localStorage.getItem(`slicc-welcomed`)&&oe.available().some(e=>e.name===`welcome`))try{await oe.open(`welcome`)}catch(e){dX.warn(`Failed to open welcome sprinkle`,e)}await oe.restoreOpenSprinkles(),dX.info(`SprinkleManager initialized`)}let se=()=>{let e=ZY(window.location.href),t=new WebSocket(e);t.onopen=()=>{dX.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=QU().session,i=r?.webhookUrl?$Y(r.webhookUrl,t.id):QY(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=QU();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)}catch(e){dX.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{dX.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(se,3e3)},t.onerror=e=>{dX.error(`Lick WebSocket error`,{error:String(e)})}};se(),l.onModelChange=e=>{localStorage.setItem(`selected-model`,e),T.updateModel()},l.onClearChat=async()=>{await T.clearAllMessages(),v.clear()},l.onClearFilesystem=async()=>{await T.resetFilesystem()};let ce=async e=>{dX.info(`Scoop selected`,{jid:e.jid,name:e.name}),h=e,T.createScoopTab(e.jid),l.panels.memory.setSelectedScoop(e.jid),l.panels.scoops.setSelectedJid(e.jid);let t=e.isCone?`session-cone`:`session-${e.folder}`,n=v.get(e.jid),r=e.isCone?void 0:e.name;if(n&&n.length>0)await l.panels.chat.switchToContext(t,!e.isCone,r),l.panels.chat.loadMessages(n);else if(await l.panels.chat.switchToContext(t,!e.isCone,r),l.panels.chat.getMessages().length===0){let t=await T.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};x(e.jid).push(t),l.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`};x(e.jid).push(t),l.panels.chat.addUserMessage(t.content)}else n.fromAssistant?(m({type:`message_start`,messageId:n.id}),m({type:`content_delta`,messageId:n.id,text:n.content}),m({type:`content_done`,messageId:n.id})):l.panels.chat.addUserMessage(n.content)}}e.isCone&&T.isProcessing(e.jid)&&l.panels.chat.setProcessing(!0)};if(l.onScoopSelect=ce,h&&(T.createScoopTab(h.jid),await ce(h)),o===`standalone`||o===`electron-overlay`){let e=await i(),t=JY(o,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,c=null;zG(()=>te?(e,t)=>te.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),KH(()=>te?()=>te.getBestFollowerForTeleport():null),qH(()=>te?()=>te.getConnectedFollowers():null);let u=e=>{c&&=(clearInterval(c),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new KY(e.channel,{browserTransport:f.getTransport(),browserAPI:f,onSnapshot:e=>{l.panels.chat.loadMessages(e)},onUserMessage:e=>{l.panels.chat.addUserMessage(e)},onStatus:e=>{l.panels.chat.setProcessing(e===`processing`)},onTargetsChanged:()=>void i()});r=n,f.setTrayTargetProvider(n),l.panels.chat.setAgent(n),n.requestSnapshot();let i=async()=>{try{let e=await f.listPages();n.advertiseTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})),t)}catch{}};c=setInterval(i,5e3),i(),dX.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},m=e=>{a?.cancel(),c&&=(clearInterval(c),null),r?.close(),r=null,a=bY({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:oW()},{onConnected:e=>u(e),onReconnecting:e=>{dX.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{dX.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{m(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{c&&clearInterval(c),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)m(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new WY({browserTransport:f.getTransport(),browserAPI:f,getMessages:()=>l.panels.chat.getMessages(),getScoopJid:()=>h?.jid??`cone`,onFollowerMessage:(e,t)=>{l.panels.chat.addUserMessage(e),k.sendMessage(e,t)},onFollowerAbort:()=>{k.stop()}}),te=t,cW(()=>t.getConnectedFollowers()),f.setTrayTargetProvider(t),i&&clearInterval(i);let n=async()=>{try{let e=await f.listPages();t.setLocalTargets(e.map(e=>({targetId:e.targetId,title:e.title,url:e.url})))}catch{}};i=setInterval(n,5e3),n(),r=new vY({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{dX.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(),p.add(e=>{t.broadcastEvent(e)}),e=new nW({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:oW(),onControlMessage:e=>{if(e.type===`webhook.event`){ie.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{dX.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),dW(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(),QU()}),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=>{dX.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})}}dX.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:T.getScoops().length}),Lq().catch(()=>{})}gX().catch(e=>{dX.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{AH as a,ni as c,Yq as i,$r as l,ZJ as n,sV as o,$J as r,ei as s,XJ as t};
|