sliccy 1.45.0 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sql-wasm-qYiWqMYu.js","assets/chunk-zsgVPwQN.js","assets/__vite-browser-external-lxqD0Xm6.js","assets/pyodide-BCAXW07g.js","assets/preload-helper-ca-nBW7U.js","assets/es-BIXR_JMx.js","assets/pako-CHJVeFxh.js","assets/dist-BvrWiVk7.js","assets/provider-settings-YOjGG5m2.js","assets/provider-settings-DNI-f2dL.js","assets/env-api-keys-DlVZ9FrG.js","assets/simple-options-FPdEz6rB.js","assets/json-parse-JW3qhabb.js","assets/tray-follower-status-BlQSlF6m.js","assets/logger-B-No_qN_.js","assets/providers-BkGRqgnv.js","assets/skills-BRtu25Xa.js","assets/constants-DzDPiuHe.js","assets/skills-AKjvBI03.js","assets/fs-BQWb1K18.js","assets/xterm-BmfB5bmM.css","assets/offscreen-client-CciDOOoa.js","assets/cdp-DhV8bm4P.js","assets/bsh-watchdog-DOU_MEY1.js"])))=>i.map(i=>d[i]);
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-BlQSlF6m.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 ee,k as te,n as ne,o as re,p as ie,r as ae,s as oe,v as se,x as ce,y as O}from"./provider-settings-DNI-f2dL.js";import{f as le,l as ue,p as de,s as fe,u as pe}from"./constants-DzDPiuHe.js";import{a as me,i as he,n as ge,r as _e,s as ve}from"./fs-BQWb1K18.js";import{d as ye,n as be}from"./skills-AKjvBI03.js";import{a as xe,c as Se,d as Ce,i as we,l as Te,n as k,o as Ee,r as De,s as Oe,u as ke}from"./cdp-DhV8bm4P.js";import{_ as Ae,a as je,b as Me,c as Ne,d as Pe,f as Fe,g as Ie,h as Le,i as Re,l as ze,m as Be,n as Ve,o as He,p as Ue,r as We,s as Ge,t as Ke,u as qe,v as Je,x as A,y as Ye}from"./db-CogIG09c.js";import{t as Xe}from"./pako-CHJVeFxh.js";import{t as Ze}from"./__vite-browser-external-lxqD0Xm6.js";import{t as Qe}from"./magick-wasm-D_mriary.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 $e(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var et=$e();function tt(e){et=e}var nt={exec:()=>null};function rt(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(at.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var it=(()=>{try{return!0}catch{return!1}})(),at={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)}}>`)},ot=/^(?:[ \t]*(?:\n|$))+/,st=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,ct=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,lt=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,ut=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,dt=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,ft=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,pt=rt(ft).replace(/bull/g,dt).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(),mt=rt(ft).replace(/bull/g,dt).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(),ht=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,gt=/^[^\n]+/,_t=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,vt=rt(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,_t).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),yt=rt(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,dt).getRegex(),bt=`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`,xt=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,St=rt(`^ {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`,xt).replace(`tag`,bt).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ct=rt(ht).replace(`hr`,lt).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`,bt).getRegex(),wt={blockquote:rt(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,Ct).getRegex(),code:st,def:vt,fences:ct,heading:ut,hr:lt,html:St,lheading:pt,list:yt,newline:ot,paragraph:Ct,table:nt,text:gt},Tt=rt(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,lt).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`,bt).getRegex(),Et={...wt,lheading:mt,table:Tt,paragraph:rt(ht).replace(`hr`,lt).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,Tt).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`,bt).getRegex()},Dt={...wt,html:rt(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,xt).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:nt,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:rt(ht).replace(`hr`,lt).replace(`heading`,` *#{1,6} *[^
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sql-wasm-qYiWqMYu.js","assets/chunk-zsgVPwQN.js","assets/__vite-browser-external-lxqD0Xm6.js","assets/pyodide-BCAXW07g.js","assets/preload-helper-ca-nBW7U.js","assets/es-BIXR_JMx.js","assets/pako-CHJVeFxh.js","assets/dist-BvrWiVk7.js","assets/provider-settings-Bkf2ADq8.js","assets/provider-settings-DNI-f2dL.js","assets/env-api-keys-DlVZ9FrG.js","assets/simple-options-FPdEz6rB.js","assets/json-parse-JW3qhabb.js","assets/tray-follower-status-BlQSlF6m.js","assets/logger-B-No_qN_.js","assets/providers-BkGRqgnv.js","assets/skills-BRtu25Xa.js","assets/constants-DzDPiuHe.js","assets/skills-AKjvBI03.js","assets/fs-BQWb1K18.js","assets/xterm-BmfB5bmM.css","assets/offscreen-client-CciDOOoa.js","assets/cdp-D7T7EeS9.js","assets/bsh-watchdog-DOU_MEY1.js"])))=>i.map(i=>d[i]);
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-BlQSlF6m.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 ee,k as te,n as ne,o as re,p as ie,r as ae,s as oe,v as se,x as ce,y as O}from"./provider-settings-DNI-f2dL.js";import{f as le,l as ue,p as de,s as fe,u as pe}from"./constants-DzDPiuHe.js";import{a as me,i as he,n as ge,r as _e,s as ve}from"./fs-BQWb1K18.js";import{d as ye,n as be}from"./skills-AKjvBI03.js";import{a as xe,c as Se,d as Ce,i as we,l as Te,n as k,o as Ee,r as De,s as Oe,u as ke}from"./cdp-D7T7EeS9.js";import{_ as Ae,a as je,b as Me,c as Ne,d as Pe,f as Fe,g as Ie,h as Le,i as Re,l as ze,m as Be,n as Ve,o as He,p as Ue,r as We,s as Ge,t as Ke,u as qe,v as Je,x as A,y as Ye}from"./db-CogIG09c.js";import{t as Xe}from"./pako-CHJVeFxh.js";import{t as Ze}from"./__vite-browser-external-lxqD0Xm6.js";import{t as Qe}from"./magick-wasm-D_mriary.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 $e(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var et=$e();function tt(e){et=e}var nt={exec:()=>null};function rt(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(at.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var it=(()=>{try{return!0}catch{return!1}})(),at={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)}}>`)},ot=/^(?:[ \t]*(?:\n|$))+/,st=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,ct=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,lt=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,ut=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,dt=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,ft=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,pt=rt(ft).replace(/bull/g,dt).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(),mt=rt(ft).replace(/bull/g,dt).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(),ht=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,gt=/^[^\n]+/,_t=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,vt=rt(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,_t).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),yt=rt(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,dt).getRegex(),bt=`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`,xt=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,St=rt(`^ {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`,xt).replace(`tag`,bt).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ct=rt(ht).replace(`hr`,lt).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`,bt).getRegex(),wt={blockquote:rt(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,Ct).getRegex(),code:st,def:vt,fences:ct,heading:ut,hr:lt,html:St,lheading:pt,list:yt,newline:ot,paragraph:Ct,table:nt,text:gt},Tt=rt(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,lt).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`,bt).getRegex(),Et={...wt,lheading:mt,table:Tt,paragraph:rt(ht).replace(`hr`,lt).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,Tt).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`,bt).getRegex()},Dt={...wt,html:rt(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,xt).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:nt,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:rt(ht).replace(`hr`,lt).replace(`heading`,` *#{1,6} *[^
3
3
  ]`).replace(`lheading`,pt).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`|fences`,``).replace(`|list`,``).replace(`|html`,``).replace(`|tag`,``).getRegex()},Ot=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,kt=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,At=/^( {2,}|\\)\n(?!\s*$)/,jt=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,Mt=/[\p{P}\p{S}]/u,Nt=/[\s\p{P}\p{S}]/u,Pt=/[^\s\p{P}\p{S}]/u,Ft=rt(/^((?![*_])punctSpace)/,`u`).replace(/punctSpace/g,Nt).getRegex(),It=/(?!~)[\p{P}\p{S}]/u,Lt=/(?!~)[\s\p{P}\p{S}]/u,Rt=/(?:[^\s\p{P}\p{S}]|~)/u,zt=rt(/link|precode-code|html/,`g`).replace(`link`,/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace(`precode-`,it?"(?<!`)()":"(^^|[^`])").replace(`code`,/(?<b>`+)[^`]+\k<b>(?!`)/).replace(`html`,/<(?! )[^<>]*?>/).getRegex(),Bt=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,Vt=rt(Bt,`u`).replace(/punct/g,Mt).getRegex(),Ht=rt(Bt,`u`).replace(/punct/g,It).getRegex(),Ut=`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)`,Wt=rt(Ut,`gu`).replace(/notPunctSpace/g,Pt).replace(/punctSpace/g,Nt).replace(/punct/g,Mt).getRegex(),Gt=rt(Ut,`gu`).replace(/notPunctSpace/g,Rt).replace(/punctSpace/g,Lt).replace(/punct/g,It).getRegex(),Kt=rt(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)`,`gu`).replace(/notPunctSpace/g,Pt).replace(/punctSpace/g,Nt).replace(/punct/g,Mt).getRegex(),qt=rt(/^~~?(?:((?!~)punct)|[^\s~])/,`u`).replace(/punct/g,Mt).getRegex(),Jt=rt(`^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,Pt).replace(/punctSpace/g,Nt).replace(/punct/g,Mt).getRegex(),Yt=rt(/\\(punct)/,`gu`).replace(/punct/g,Mt).getRegex(),Xt=rt(/^<(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(),Zt=rt(xt).replace(`(?:-->|$)`,`-->`).getRegex(),Qt=rt(`^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`,Zt).replace(`attribute`,/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),$t=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,en=rt(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace(`label`,$t).replace(`href`,/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace(`title`,/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),tn=rt(/^!?\[(label)\]\[(ref)\]/).replace(`label`,$t).replace(`ref`,_t).getRegex(),nn=rt(/^!?\[(ref)\](?:\[\])?/).replace(`ref`,_t).getRegex(),rn=rt(`reflink|nolink(?!\\()`,`g`).replace(`reflink`,tn).replace(`nolink`,nn).getRegex(),an=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,on={_backpedal:nt,anyPunctuation:Yt,autolink:Xt,blockSkip:zt,br:At,code:kt,del:nt,delLDelim:nt,delRDelim:nt,emStrongLDelim:Vt,emStrongRDelimAst:Wt,emStrongRDelimUnd:Kt,escape:Ot,link:en,nolink:nn,punctuation:Ft,reflink:tn,reflinkSearch:rn,tag:Qt,text:jt,url:nt},sn={...on,link:rt(/^!?\[(label)\]\((.*?)\)/).replace(`label`,$t).getRegex(),reflink:rt(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace(`label`,$t).getRegex()},cn={...on,emStrongRDelimAst:Gt,emStrongLDelim:Ht,delLDelim:qt,delRDelim:Jt,url:rt(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace(`protocol`,an).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:rt(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace(`protocol`,an).getRegex()},ln={...cn,br:rt(At).replace(`{2,}`,`*`).getRegex(),text:rt(cn.text).replace(`\\b_`,`\\b_| {2,}\\n`).replace(/\{2,\}/g,`*`).getRegex()},un={normal:wt,gfm:Et,pedantic:Dt},dn={normal:on,gfm:cn,breaks:ln,pedantic:sn},fn={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`},pn=e=>fn[e];function mn(e,t){if(t){if(at.escapeTest.test(e))return e.replace(at.escapeReplace,pn)}else if(at.escapeTestNoEncode.test(e))return e.replace(at.escapeReplaceNoEncode,pn);return e}function hn(e){try{e=encodeURI(e).replace(at.percentDecode,`%`)}catch{return null}return e}function gn(e,t){let n=e.replace(at.findPipe,(e,t,n)=>{let r=!1,i=t;for(;--i>=0&&n[i]===`\\`;)r=!r;return r?`|`:` |`}).split(at.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(at.slashPipe,`|`);return n}function _n(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 vn(e){let t=e.split(`
4
4
  `),n=t.length-1;for(;n>=0&&!t[n].trim();)n--;return t.length-n<=2?e:t.slice(0,n+1).join(`
5
5
  `)}function yn(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 bn(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 xn(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 Sn(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(`
@@ -180,7 +180,7 @@ mark{background:color-mix(in srgb,var(--s2-accent) 25%,transparent);color:inheri
180
180
  </style>
181
181
  <script>${mi}<\/script>
182
182
  </head>
183
- <body class="sprinkle-inline">${t}</body></html>`;if(pi)return vi(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 gi(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(hi(a,i,t))}return r}function _i(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function vi(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 yi=r(`tool-ui-renderer`),bi=typeof chrome<`u`&&!!chrome?.runtime?.id,xi=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){bi?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(()=>{yi.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){yi.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(yi.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-Dlqdvfe5.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=hi(t,e,(e,t)=>{yi.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)}},Si=new Map;function Ci(e,t,n){let r=Si.get(t);r&&r.dispose();let i=new xi(e,t);return Si.set(t,i),i.render(n).catch(e=>{yi.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function wi(e){let t=Si.get(e);t&&(t.dispose(),Si.delete(e))}var Ti=r(`chat-panel`);function Ei(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var Di={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 Oi(e){return Di[e]??`?`}function ki(e){return e.role===`assistant`?Yr(e.content):Jr(e.content)}var Ai=class{container;messagesEl;messagesInner;inputArea;textarea;sendBtn;stopBtn;micBtn;voiceInput=null;voiceMode=!1;keydownListener=null;messages=[];agent=null;unsubscribe=null;isStreaming=!1;currentStreamId=null;sessionStore;sessionId;readOnly=!1;terminalOutputCallback=null;currentScoopName=null;autoScrollAttached=!0;lastScrollTop=0;jumpPill;onDeleteQueuedMessage=null;pendingDeltaText=``;streamingRafId=null;inlineSprinkles=new Map;onInlineSprinkleLick;modelSelectorEl;handoffsEl;pendingHandoffs=[];onAcceptPendingHandoff=null;onDismissPendingHandoff=null;onModelChange;constructor(e){this.container=e,this.sessionStore=new ti,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:Ei(),role:`assistant`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t),this.persistSession()}addLickMessage(e,t,n){let r={id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:n};this.messages.push(r),this.appendMessageEl(r),this.persistSession()}getMessages(){return[...this.messages]}loadMessages(e){this.messages=e.map(e=>({...e,isStreaming:!1})),this.renderMessages(),this.persistSession(),this.renderModelSelector()}clear(){this.messages=[],this.renderMessages(),this.renderModelSelector()}setPendingHandoffs(e){this.pendingHandoffs=[...e],this.renderPendingHandoffs()}setPendingHandoffActions(e){this.onAcceptPendingHandoff=e.onAccept,this.onDismissPendingHandoff=e.onDismiss,this.renderPendingHandoffs()}addUserMessage(e){let t={id:Ei(),role:`user`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}deleteQueuedMessage(e){let t=this.messages.findIndex(t=>t.id===e);if(t===-1)return;this.messages.splice(t,1);let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);n&&n.remove(),this.persistSession(),this.onDeleteQueuedMessage?.(e)}render(){this.container.innerHTML=``,this.container.classList.add(`chat`),this.messagesEl=document.createElement(`div`),this.messagesEl.className=`chat__messages`,this.messagesInner=document.createElement(`div`),this.messagesInner.className=`chat__messages-inner`,this.messagesEl.appendChild(this.messagesInner),this.handoffsEl=document.createElement(`div`),this.handoffsEl.className=`chat__handoffs`,this.handoffsEl.hidden=!0,this.messagesEl.appendChild(this.handoffsEl),this.container.appendChild(this.messagesEl),this.renderPendingHandoffs(),this.messagesEl.addEventListener(`scroll`,()=>{let{scrollTop:e,scrollHeight:t,clientHeight:n}=this.messagesEl;t-e-n<=250?(this.autoScrollAttached=!0,this.hideJumpPill()):e<this.lastScrollTop&&(this.autoScrollAttached=!1),this.lastScrollTop=e},{passive:!0}),this.inputArea=document.createElement(`div`);let e=this.inputArea;e.className=`chat__input-area`;let t=document.createElement(`div`);t.className=`chat__input-area-inner`,this.textarea=document.createElement(`textarea`),this.textarea.className=`chat__textarea`,this.textarea.placeholder=`What shall we build?`,this.textarea.rows=1,this.sendBtn=document.createElement(`button`),this.sendBtn.className=`chat__send-btn`,this.sendBtn.innerHTML=`<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1.25C5.167 1.25 1.25 5.167 1.25 10s3.917 8.75 8.75 8.75 8.75-3.918 8.75-8.75S14.833 1.25 10 1.25zm3.527 8.284a.75.75 0 0 1-1.06 0L10.75 7.82v6.172a.75.75 0 0 1-1.5 0V7.812L7.527 9.534a.75.75 0 1 1-1.06-1.06l2.998-2.998a.75.75 0 0 1 1.06-.001l3.002 2.998a.75.75 0 0 1 0 1.061z"/></svg>`,this.sendBtn.dataset.tooltip=`Send message`,this.sendBtn.dataset.tooltipPos=`top`,this.stopBtn=document.createElement(`button`),this.stopBtn.className=`chat__stop-btn`,this.stopBtn.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M13.75 4H6.25A2.25 2.25 0 0 0 4 6.25v7.5A2.25 2.25 0 0 0 6.25 16h7.5A2.25 2.25 0 0 0 16 13.75v-7.5A2.25 2.25 0 0 0 13.75 4z"/></svg>`,this.stopBtn.dataset.tooltip=`Stop generation`,this.stopBtn.style.display=`none`,this.micBtn=document.createElement(`button`),this.micBtn.className=`chat__mic-btn`;let n=`http://www.w3.org/2000/svg`,r=document.createElementNS(n,`svg`);r.setAttribute(`width`,`16`),r.setAttribute(`height`,`16`),r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,`2`),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`stroke-linejoin`,`round`);let i=document.createElementNS(n,`path`);i.setAttribute(`d`,`M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z`);let a=document.createElementNS(n,`path`);a.setAttribute(`d`,`M19 10v2a7 7 0 0 1-14 0v-2`);let o=document.createElementNS(n,`line`);o.setAttribute(`x1`,`12`),o.setAttribute(`y1`,`19`),o.setAttribute(`x2`,`12`),o.setAttribute(`y2`,`23`);let s=document.createElementNS(n,`line`);s.setAttribute(`x1`,`8`),s.setAttribute(`y1`,`23`),s.setAttribute(`x2`,`16`),s.setAttribute(`y2`,`23`),r.append(i,a,o,s),this.micBtn.appendChild(r),this.micBtn.dataset.tooltip=`Voice (Ctrl+Shift+V)`;let c=document.createElement(`div`);c.className=`chat__input-wrapper`,c.appendChild(this.textarea);let l=document.createElement(`div`);l.className=`chat__action-bar`;let u=document.createElement(`div`);u.className=`chat__action-bar-left`,u.appendChild(this.micBtn),l.appendChild(u),this.modelSelectorEl=document.createElement(`div`),this.modelSelectorEl.className=`chat__model-selector`,this.renderModelSelector(),l.appendChild(this.modelSelectorEl);let d=document.createElement(`div`);d.className=`chat__action-bar-right`,d.appendChild(this.sendBtn),d.appendChild(this.stopBtn),l.appendChild(d),c.appendChild(l),t.appendChild(c),e.appendChild(t),this.container.appendChild(e),this.jumpPill=document.createElement(`button`),this.jumpPill.className=`chat__jump-pill`,this.jumpPill.textContent=`↓ New activity`,this.jumpPill.addEventListener(`click`,()=>{this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}),this.container.appendChild(this.jumpPill),this.textarea.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),this.sendMessage())}),this.textarea.addEventListener(`input`,()=>{this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`}),this.sendBtn.addEventListener(`click`,()=>this.sendMessage()),this.stopBtn.addEventListener(`click`,()=>{this.agent?.stop();for(let e of this.messages)e.queued&&(e.queued=!1,this.updateMessageEl(e.id));this.setStreamingState(!1)}),this.voiceInput=new ai({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=>{Ti.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:si()}),this.micBtn.addEventListener(`click`,()=>{this.toggleVoiceMode()}),this.keydownListener=e=>{e.shiftKey&&(e.ctrlKey||e.metaKey)&&e.key===`V`&&(e.preventDefault(),this.toggleVoiceMode())},document.addEventListener(`keydown`,this.keydownListener)}renderPendingHandoffs(){if(!this.handoffsEl)return;if(this.pendingHandoffs.length===0){this.handoffsEl.hidden=!0,this.handoffsEl.innerHTML=``;return}let e=this.pendingHandoffs.length===1?`1 pending handoff`:`${this.pendingHandoffs.length} pending handoffs`;this.handoffsEl.hidden=!1,this.handoffsEl.innerHTML=`
183
+ <body class="sprinkle-inline">${t}</body></html>`;if(pi)return vi(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 gi(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(hi(a,i,t))}return r}function _i(e){for(let t of e)try{t.dispose()}catch{}e.length=0}function vi(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 yi=r(`tool-ui-renderer`),bi=typeof chrome<`u`&&!!chrome?.runtime?.id,xi=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){bi?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(()=>{yi.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){yi.warn(`Tool UI message nonce mismatch`,{expected:this.nonce,received:n.nonce});return}n.type===`tool-ui-action`&&n.id===this.requestId?(yi.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-9SeK_akJ.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=hi(t,e,(e,t)=>{yi.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)}},Si=new Map;function Ci(e,t,n){let r=Si.get(t);r&&r.dispose();let i=new xi(e,t);return Si.set(t,i),i.render(n).catch(e=>{yi.error(`Failed to render tool UI`,{requestId:t,error:e.message})}),i}function wi(e){let t=Si.get(e);t&&(t.dispose(),Si.delete(e))}var Ti=r(`chat-panel`);function Ei(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var Di={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 Oi(e){return Di[e]??`?`}function ki(e){return e.role===`assistant`?Yr(e.content):Jr(e.content)}var Ai=class{container;messagesEl;messagesInner;inputArea;textarea;sendBtn;stopBtn;micBtn;voiceInput=null;voiceMode=!1;keydownListener=null;messages=[];agent=null;unsubscribe=null;isStreaming=!1;currentStreamId=null;sessionStore;sessionId;readOnly=!1;terminalOutputCallback=null;currentScoopName=null;autoScrollAttached=!0;lastScrollTop=0;jumpPill;onDeleteQueuedMessage=null;pendingDeltaText=``;streamingRafId=null;inlineSprinkles=new Map;onInlineSprinkleLick;modelSelectorEl;handoffsEl;pendingHandoffs=[];onAcceptPendingHandoff=null;onDismissPendingHandoff=null;onModelChange;constructor(e){this.container=e,this.sessionStore=new ti,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:Ei(),role:`assistant`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t),this.persistSession()}addLickMessage(e,t,n){let r={id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:n};this.messages.push(r),this.appendMessageEl(r),this.persistSession()}getMessages(){return[...this.messages]}loadMessages(e){this.messages=e.map(e=>({...e,isStreaming:!1})),this.renderMessages(),this.persistSession(),this.renderModelSelector()}clear(){this.messages=[],this.renderMessages(),this.renderModelSelector()}setPendingHandoffs(e){this.pendingHandoffs=[...e],this.renderPendingHandoffs()}setPendingHandoffActions(e){this.onAcceptPendingHandoff=e.onAccept,this.onDismissPendingHandoff=e.onDismiss,this.renderPendingHandoffs()}addUserMessage(e){let t={id:Ei(),role:`user`,content:e,timestamp:Date.now()};this.messages.push(t),this.appendMessageEl(t)}deleteQueuedMessage(e){let t=this.messages.findIndex(t=>t.id===e);if(t===-1)return;this.messages.splice(t,1);let n=this.messagesEl.querySelector(`[data-msg-id="${e}"]`);n&&n.remove(),this.persistSession(),this.onDeleteQueuedMessage?.(e)}render(){this.container.innerHTML=``,this.container.classList.add(`chat`),this.messagesEl=document.createElement(`div`),this.messagesEl.className=`chat__messages`,this.messagesInner=document.createElement(`div`),this.messagesInner.className=`chat__messages-inner`,this.messagesEl.appendChild(this.messagesInner),this.handoffsEl=document.createElement(`div`),this.handoffsEl.className=`chat__handoffs`,this.handoffsEl.hidden=!0,this.messagesEl.appendChild(this.handoffsEl),this.container.appendChild(this.messagesEl),this.renderPendingHandoffs(),this.messagesEl.addEventListener(`scroll`,()=>{let{scrollTop:e,scrollHeight:t,clientHeight:n}=this.messagesEl;t-e-n<=250?(this.autoScrollAttached=!0,this.hideJumpPill()):e<this.lastScrollTop&&(this.autoScrollAttached=!1),this.lastScrollTop=e},{passive:!0}),this.inputArea=document.createElement(`div`);let e=this.inputArea;e.className=`chat__input-area`;let t=document.createElement(`div`);t.className=`chat__input-area-inner`,this.textarea=document.createElement(`textarea`),this.textarea.className=`chat__textarea`,this.textarea.placeholder=`What shall we build?`,this.textarea.rows=1,this.sendBtn=document.createElement(`button`),this.sendBtn.className=`chat__send-btn`,this.sendBtn.innerHTML=`<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M10 1.25C5.167 1.25 1.25 5.167 1.25 10s3.917 8.75 8.75 8.75 8.75-3.918 8.75-8.75S14.833 1.25 10 1.25zm3.527 8.284a.75.75 0 0 1-1.06 0L10.75 7.82v6.172a.75.75 0 0 1-1.5 0V7.812L7.527 9.534a.75.75 0 1 1-1.06-1.06l2.998-2.998a.75.75 0 0 1 1.06-.001l3.002 2.998a.75.75 0 0 1 0 1.061z"/></svg>`,this.sendBtn.dataset.tooltip=`Send message`,this.sendBtn.dataset.tooltipPos=`top`,this.stopBtn=document.createElement(`button`),this.stopBtn.className=`chat__stop-btn`,this.stopBtn.innerHTML=`<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M13.75 4H6.25A2.25 2.25 0 0 0 4 6.25v7.5A2.25 2.25 0 0 0 6.25 16h7.5A2.25 2.25 0 0 0 16 13.75v-7.5A2.25 2.25 0 0 0 13.75 4z"/></svg>`,this.stopBtn.dataset.tooltip=`Stop generation`,this.stopBtn.style.display=`none`,this.micBtn=document.createElement(`button`),this.micBtn.className=`chat__mic-btn`;let n=`http://www.w3.org/2000/svg`,r=document.createElementNS(n,`svg`);r.setAttribute(`width`,`16`),r.setAttribute(`height`,`16`),r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,`2`),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`stroke-linejoin`,`round`);let i=document.createElementNS(n,`path`);i.setAttribute(`d`,`M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z`);let a=document.createElementNS(n,`path`);a.setAttribute(`d`,`M19 10v2a7 7 0 0 1-14 0v-2`);let o=document.createElementNS(n,`line`);o.setAttribute(`x1`,`12`),o.setAttribute(`y1`,`19`),o.setAttribute(`x2`,`12`),o.setAttribute(`y2`,`23`);let s=document.createElementNS(n,`line`);s.setAttribute(`x1`,`8`),s.setAttribute(`y1`,`23`),s.setAttribute(`x2`,`16`),s.setAttribute(`y2`,`23`),r.append(i,a,o,s),this.micBtn.appendChild(r),this.micBtn.dataset.tooltip=`Voice (Ctrl+Shift+V)`;let c=document.createElement(`div`);c.className=`chat__input-wrapper`,c.appendChild(this.textarea);let l=document.createElement(`div`);l.className=`chat__action-bar`;let u=document.createElement(`div`);u.className=`chat__action-bar-left`,u.appendChild(this.micBtn),l.appendChild(u),this.modelSelectorEl=document.createElement(`div`),this.modelSelectorEl.className=`chat__model-selector`,this.renderModelSelector(),l.appendChild(this.modelSelectorEl);let d=document.createElement(`div`);d.className=`chat__action-bar-right`,d.appendChild(this.sendBtn),d.appendChild(this.stopBtn),l.appendChild(d),c.appendChild(l),t.appendChild(c),e.appendChild(t),this.container.appendChild(e),this.jumpPill=document.createElement(`button`),this.jumpPill.className=`chat__jump-pill`,this.jumpPill.textContent=`↓ New activity`,this.jumpPill.addEventListener(`click`,()=>{this.autoScrollAttached=!0,this.hideJumpPill(),this.scrollToBottom(!0)}),this.container.appendChild(this.jumpPill),this.textarea.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),this.sendMessage())}),this.textarea.addEventListener(`input`,()=>{this.textarea.style.height=`auto`,this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+`px`}),this.sendBtn.addEventListener(`click`,()=>this.sendMessage()),this.stopBtn.addEventListener(`click`,()=>{this.agent?.stop();for(let e of this.messages)e.queued&&(e.queued=!1,this.updateMessageEl(e.id));this.setStreamingState(!1)}),this.voiceInput=new ai({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=>{Ti.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:si()}),this.micBtn.addEventListener(`click`,()=>{this.toggleVoiceMode()}),this.keydownListener=e=>{e.shiftKey&&(e.ctrlKey||e.metaKey)&&e.key===`V`&&(e.preventDefault(),this.toggleVoiceMode())},document.addEventListener(`keydown`,this.keydownListener)}renderPendingHandoffs(){if(!this.handoffsEl)return;if(this.pendingHandoffs.length===0){this.handoffsEl.hidden=!0,this.handoffsEl.innerHTML=``;return}let e=this.pendingHandoffs.length===1?`1 pending handoff`:`${this.pendingHandoffs.length} pending handoffs`;this.handoffsEl.hidden=!1,this.handoffsEl.innerHTML=`
184
184
  <div class="chat__handoffs-inner">
185
185
  <div class="chat__handoffs-header">${Ir(e)}</div>
186
186
  ${this.pendingHandoffs.map(e=>this.renderPendingHandoffCard(e)).join(``)}
@@ -2395,7 +2395,7 @@ Available commands:
2395
2395
  `,exitCode:128};let r=n[0],i=n[1],a=r.startsWith(`/`)?r:`${e}/${r}`,o=i.startsWith(`/`)?i:`${e}/${i}`,s;try{s=await this.options.fs.readFile(a,{encoding:`binary`})}catch{return{stdout:``,stderr:`fatal: bad source, source=${r}, destination=${i}\n`,exitCode:128}}let c=o.lastIndexOf(`/`);return c!==-1&&await this.options.fs.mkdir(o.slice(0,c),{recursive:!0}),await this.options.fs.writeFile(o,s),await this.options.fs.rm(a),await Z.add({fs:this.lfs,dir:e,filepath:i}),await Z.remove({fs:this.lfs,dir:e,filepath:r}),{stdout:``,stderr:``,exitCode:0}}async revParse(e,t){if(t.includes(`--show-toplevel`))try{return{stdout:`${await Z.findRoot({fs:this.lfs,filepath:e})}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`fatal: not a git repository
2396
2396
  `,exitCode:128}}if(t.includes(`--is-inside-work-tree`))try{return await Z.findRoot({fs:this.lfs,filepath:e}),{stdout:`true
2397
2397
  `,stderr:``,exitCode:0}}catch{return{stdout:`false
2398
- `,stderr:``,exitCode:0}}let n=t.find(e=>!e.startsWith(`-`))??`HEAD`;try{return{stdout:`${await Z.resolveRef({fs:this.lfs,dir:e,ref:n})}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`fatal: ambiguous argument '${n}'\n`,exitCode:128}}}parseArg(e,...t){for(let n of t){let t=e.indexOf(n);if(t!==-1&&e[t+1])return e[t+1];for(let t of e)if(t.startsWith(`${n}=`))return t.slice(n.length+1)}}parseBooleanFlag(e,t,n){let r=`--no-${t.slice(2)}`,i=n;for(let n of e)n===t&&(i=!0),n===r&&(i=!1);return i}},Q=r(`playwright-teleport`),zH=null,BH=null;function VH(e){zH=e}function HH(e){BH=e}function UH(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 WH=[`playwright-cli`,`playwright`,`puppeteer`],GH=new WeakMap,KH=new Set([`click`,`dblclick`,`fill`,`type`,`press`,`goto`,`navigate`,`select`,`check`,`uncheck`,`drag`,`dialog-accept`,`dialog-dismiss`]);function qH(e){return e.toISOString().replace(/:/g,`-`)}function JH(e,t){let n=GH.get(e);n||(n=new WeakMap,GH.set(e,n));let r=n.get(t);return r||(r={snapshots:new Map,appTabId:null,harRecorder:null,sessionDirsCreated:!1,teleportWatchers:new Map},n.set(t,r)),r}function YH(e){return e instanceof ve||typeof e==`object`&&e&&`code`in e?e.code===`EEXIST`:e instanceof Error&&e.message.includes(`EEXIST`)}var XH=`function(text) {
2398
+ `,stderr:``,exitCode:0}}let n=t.find(e=>!e.startsWith(`-`))??`HEAD`;try{return{stdout:`${await Z.resolveRef({fs:this.lfs,dir:e,ref:n})}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`fatal: ambiguous argument '${n}'\n`,exitCode:128}}}parseArg(e,...t){for(let n of t){let t=e.indexOf(n);if(t!==-1&&e[t+1])return e[t+1];for(let t of e)if(t.startsWith(`${n}=`))return t.slice(n.length+1)}}parseBooleanFlag(e,t,n){let r=`--no-${t.slice(2)}`,i=n;for(let n of e)n===t&&(i=!0),n===r&&(i=!1);return i}},Q=r(`playwright-teleport`),zH=null,BH=null;function VH(e){zH=e}function HH(e){BH=e}function UH(e){let t=e.match(/^(f[0-9]+)(e[0-9]+)$/);return t?{framePrefix:t[1],isIframe:!0}:{framePrefix:``,isIframe:!1}}function WH(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 GH=[`playwright-cli`,`playwright`,`puppeteer`],KH=new WeakMap,qH=new Set([`click`,`dblclick`,`fill`,`type`,`press`,`goto`,`navigate`,`select`,`check`,`uncheck`,`drag`,`dialog-accept`,`dialog-dismiss`]);function JH(e){return e.toISOString().replace(/:/g,`-`)}function YH(e,t){let n=KH.get(e);n||(n=new WeakMap,KH.set(e,n));let r=n.get(t);return r||(r={snapshots:new Map,appTabId:null,harRecorder:null,sessionDirsCreated:!1,teleportWatchers:new Map},n.set(t,r)),r}function XH(e){return e instanceof ve||typeof e==`object`&&e&&`code`in e?e.code===`EEXIST`:e instanceof Error&&e.message.includes(`EEXIST`)}var ZH=`function(text) {
2399
2399
  const el = this;
2400
2400
  const tag = el.tagName;
2401
2401
  const proto = tag === 'TEXTAREA' ? window.HTMLTextAreaElement.prototype : window.HTMLInputElement.prototype;
@@ -2407,11 +2407,11 @@ Available commands:
2407
2407
  }
2408
2408
  el.dispatchEvent(new Event('input', { bubbles: true }));
2409
2409
  el.dispatchEvent(new Event('change', { bubbles: true }));
2410
- }`,ZH=`function() {
2410
+ }`,QH=`function() {
2411
2411
  const el = this;
2412
2412
  if (el.isContentEditable) return el.textContent || '';
2413
2413
  return el.value ?? '';
2414
- }`,QH=`function() {
2414
+ }`,$H=`function() {
2415
2415
  const el = this;
2416
2416
  if (!(el instanceof HTMLElement)) return false;
2417
2417
  el.focus();
@@ -2435,13 +2435,15 @@ Available commands:
2435
2435
  return true;
2436
2436
  }
2437
2437
  return false;
2438
- }`;async function $H(e){let t=await e.evaluate(`JSON.stringify({ href: location.href, hostname: location.hostname, pathname: location.pathname })`);return JSON.parse(t)}async function eU(e,t){if(!t.sessionDirsCreated){for(let t of[`/.playwright`,`/.playwright/snapshots`,`/.playwright/screenshots`])try{await e.mkdir(t,{recursive:!0})}catch(e){if(!YH(e))throw e}t.sessionDirsCreated=!0}}async function tU(e,t,n,r){try{return await e.withTab(r,async()=>{let n=await e.evaluate(`JSON.stringify({ url: location.href, title: document.title })`),{url:r,title:i}=JSON.parse(n),a=aU(await e.getAccessibilityTree(),new Map,new Map,{value:0}).join(`
2438
+ }`;async function eU(e){let t=await e.evaluate(`JSON.stringify({ href: location.href, hostname: location.hostname, pathname: location.pathname })`);return JSON.parse(t)}async function tU(e,t){if(!t.sessionDirsCreated){for(let t of[`/.playwright`,`/.playwright/snapshots`,`/.playwright/screenshots`])try{await e.mkdir(t,{recursive:!0})}catch(e){if(!XH(e))throw e}t.sessionDirsCreated=!0}}async function nU(e,t,n,r){try{return await e.withTab(r,async()=>{let n=await e.evaluate(`JSON.stringify({ url: location.href, title: document.title })`),{url:r,title:i}=JSON.parse(n),a=oU(await e.getAccessibilityTree(),new Map,new Map,{value:0}).join(`
2439
2439
  `),o=[`Page URL: ${r}`,`Page Title: ${i}`,``,a].join(`
2440
- `),s=`/.playwright/snapshots/page-${qH(new Date)}.yml`;return await t.writeFile(s,o),s})}catch{return null}}async function nU(e,t,n){await eU(e,t);let r=new Date().toISOString(),i=`playwright-cli ${n.command}${n.args.length?` `+n.args.join(` `):``}`,a=n.result.exitCode===0?n.result.stdout.trim()||`OK`:`Error: ${n.result.stderr.trim()}`,o=[`### ${i}`,`- **Time**: ${r}`];if(n.tabUrl||n.targetId){let e=n.tabUrl?`${n.tabUrl}${n.targetId?` (targetId: ${n.targetId})`:``}`:`targetId: ${n.targetId}`;o.push(`- **Tab**: ${e}`)}o.push(`- **Result**: ${a}`),n.snapshotPath&&o.push(``,`[Snapshot](${n.snapshotPath})`),o.push(`---`,``);let s=o.join(`
2440
+ `),s=`/.playwright/snapshots/page-${JH(new Date)}.yml`;return await t.writeFile(s,o),s})}catch{return null}}async function rU(e,t,n){await tU(e,t);let r=new Date().toISOString(),i=`playwright-cli ${n.command}${n.args.length?` `+n.args.join(` `):``}`,a=n.result.exitCode===0?n.result.stdout.trim()||`OK`:`Error: ${n.result.stderr.trim()}`,o=[`### ${i}`,`- **Time**: ${r}`];if(n.tabUrl||n.targetId){let e=n.tabUrl?`${n.tabUrl}${n.targetId?` (targetId: ${n.targetId})`:``}`:`targetId: ${n.targetId}`;o.push(`- **Tab**: ${e}`)}o.push(`- **Result**: ${a}`),n.snapshotPath&&o.push(``,`[Snapshot](${n.snapshotPath})`),o.push(`---`,``);let s=o.join(`
2441
2441
  `)+`
2442
- `,c=`/.playwright/session.md`,l=``;try{let t=await e.readFile(c);l=typeof t==`string`?t:new TextDecoder().decode(t)}catch{}await e.writeFile(c,l+s)}function rU(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`)}function iU(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}function aU(e,t,n,r,i=``){let a=[],o=Ce(e.role,`unknown`).toLowerCase(),s=Ce(e.name),c=Ce(e.value),l=![`none`,`presentation`,`generic`,`rootwebarea`].includes(o)&&(s||o===`textbox`||o===`button`||o===`link`||o===`checkbox`||o===`radio`),u=``;if(l){u=`e${++r.value}`,e.backendNodeId&&n.set(u,e.backendNodeId);let i=iU(s),a=``;a=o===`button`&&s?`button[aria-label="${i}"], button[title="${i}"]`:o===`link`&&s?`a[aria-label="${i}"], a[title="${i}"]`:o===`textbox`?s?`input[aria-label="${i}"], textarea[aria-label="${i}"], [contenteditable][aria-label="${i}"], input[placeholder="${i}"], textarea[placeholder="${i}"], [contenteditable][placeholder="${i}"], input[title="${i}"], textarea[title="${i}"], [contenteditable][title="${i}"]`:`input, textarea, [contenteditable]`:o===`checkbox`?`input[type="checkbox"]`:o===`radio`?`input[type="radio"]`:s?`[aria-label="${i}"], [title="${i}"]`:`[role="${o}"]`,t.set(u,a)}let d=`${i}- ${o}`;if(s&&(d+=` "${rU(s)}"`),u&&(d+=` [ref=${u}]`),c&&(d+=`: "${rU(c)}"`),a.push(d),e.children)for(let o of e.children)a.push(...aU(o,t,n,r,i+` `));return a}async function oU(e,t){if(t.appTabId)return;let n=await e.listPages(),r=typeof window<`u`?window.location.origin:`http://localhost:5710`,i=n.find(e=>e.url.startsWith(r)&&!e.url.includes(`/preview/`));i&&(t.appTabId=i.targetId)}function sU(e,t){return t===e.appTabId}function cU(e){let t=e.url.trim(),n=e.title.trim();return n===`Omnibox Popup`||t.startsWith(`chrome://`)||t.startsWith(`chrome-search://`)||t.startsWith(`chrome-untrusted://`)||t.startsWith(`devtools://`)||t.length===0&&/popup$/i.test(n)}function lU(e,t){return!sU(e,t.targetId)&&!cU(t)}async function uU(e,t){return await oU(e,t),(typeof e.listAllTargets==`function`?await e.listAllTargets():await e.listPages()).filter(e=>lU(t,e))}async function dU(e,t,n){await e.attachToPage(n);let r=await e.evaluate(`JSON.stringify({ url: location.href, title: document.title })`),{url:i,title:a}=JSON.parse(r),o=await e.getAccessibilityTree(),s=new Map,c=new Map,l=aU(o,s,c,{value:0}).join(`
2443
- `),u={url:i,title:a,refToSelector:s,refToBackendNodeId:c,content:l,timestamp:Date.now()};return t.snapshots.set(n,u),{snapshot:u,output:[`Page URL: ${i}`,`Page Title: ${a}`,``,l].join(`
2444
- `)}}function fU(e){let t=new Map;for(let n of e){let e=n.domain??`unknown`;t.set(e,(t.get(e)??0)+1)}return[...t.entries()].sort((e,t)=>t[1]-e[1]).map(([e,t])=>`${t} ${e}`).join(`, `)}var pU={origin:``,localStorage:{},sessionStorage:{}};function mU(e){return Object.keys(e.localStorage).length+Object.keys(e.sessionStorage).length}function hU(e){if(!e)return null;try{return new URL(e).origin}catch{return null}}function gU(e){try{return new URL(`/favicon.ico`,e).toString()}catch{return e}}function _U(e,t,n){let r=hU(t);if(t&&r===e)return t;let i=hU(n);return n&&i===e?n:e||(t??n)}async function vU(e,t){let n=await e.evaluate(`(() => {
2442
+ `,c=`/.playwright/session.md`,l=``;try{let t=await e.readFile(c);l=typeof t==`string`?t:new TextDecoder().decode(t)}catch{}await e.writeFile(c,l+s)}function iU(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`)}function aU(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}function oU(e,t,n,r,i=``,a=``){let o=[],s=Ce(e.role,`unknown`).toLowerCase(),c=Ce(e.name),l=Ce(e.value),u=![`none`,`presentation`,`generic`,`rootwebarea`].includes(s)&&(c||s===`textbox`||s===`button`||s===`link`||s===`checkbox`||s===`radio`),d=``;if(u){d=a+`e${++r.value}`,e.backendNodeId&&n.set(d,e.backendNodeId);let i=aU(c),o=``;o=s===`button`&&c?`button[aria-label="${i}"], button[title="${i}"]`:s===`link`&&c?`a[aria-label="${i}"], a[title="${i}"]`:s===`textbox`?c?`input[aria-label="${i}"], textarea[aria-label="${i}"], [contenteditable][aria-label="${i}"], input[placeholder="${i}"], textarea[placeholder="${i}"], [contenteditable][placeholder="${i}"], input[title="${i}"], textarea[title="${i}"], [contenteditable][title="${i}"]`:`input, textarea, [contenteditable]`:s===`checkbox`?`input[type="checkbox"]`:s===`radio`?`input[type="radio"]`:c?`[aria-label="${i}"], [title="${i}"]`:`[role="${s}"]`,t.set(d,o)}let f=`${i}- ${s}`;if(c&&(f+=` "${iU(c)}"`),d&&(f+=` [ref=${d}]`),l&&(f+=`: "${iU(l)}"`),o.push(f),e.children)for(let s of e.children)o.push(...oU(s,t,n,r,i+` `,a));return o}async function sU(e,t){if(t.appTabId)return;let n=await e.listPages(),r=typeof window<`u`?window.location.origin:`http://localhost:5710`,i=n.find(e=>e.url.startsWith(r)&&!e.url.includes(`/preview/`));i&&(t.appTabId=i.targetId)}function cU(e,t){return t===e.appTabId}function lU(e){let t=e.url.trim(),n=e.title.trim();return n===`Omnibox Popup`||t.startsWith(`chrome://`)||t.startsWith(`chrome-search://`)||t.startsWith(`chrome-untrusted://`)||t.startsWith(`devtools://`)||t.length===0&&/popup$/i.test(n)}function uU(e,t){return!cU(e,t.targetId)&&!lU(t)}async function dU(e,t){return await sU(e,t),(typeof e.listAllTargets==`function`?await e.listAllTargets():await e.listPages()).filter(e=>uU(t,e))}async function fU(e,t,n,r){await e.attachToPage(n);let i=await e.evaluate(`JSON.stringify({ url: location.href, title: document.title })`),{url:a,title:o}=JSON.parse(i),s=await e.getAccessibilityTree(),c=new Map,l=new Map,u=new Map,d=oU(s,c,l,{value:0}).join(`
2443
+ `);if(!r?.noIframes&&typeof e.getFrameTree==`function`)try{let t=(await e.getFrameTree()).filter(e=>e.parentFrameId);if(t.length>0){let n=0,r=d.split(`
2444
+ `),i=[],o=new Set;for(let s of r){i.push(s);let r=s.match(/^(\s*)- iframe\s/);if(!r)continue;let d=s.match(/:\s*"([^"]+)"\s*$/);if(!d)continue;let f=d[1],p=t.find(e=>{if(o.has(e.frameId))return!1;try{let t=new URL(e.url),n=new URL(f,a),r=n.origin+n.pathname.replace(/\/$/,``)+n.search;return t.origin+t.pathname.replace(/\/$/,``)+t.search===r}catch{return e.url===f}});if(!p)continue;o.add(p.frameId),n++;let m=`f${n}`,h=r[1]+` `;try{let t=await e.getAccessibilityTreeForFrame(p.frameId),n=new Map,r=new Map,a=oU(t,n,r,{value:0},h,m);for(let[e,t]of n)c.set(e,t),u.set(e,p.frameId);for(let[e,t]of r)l.set(e,t),u.set(e,p.frameId);i.push(...a)}catch{}}d=i.join(`
2445
+ `)}}catch{}let f={url:a,title:o,refToSelector:c,refToBackendNodeId:l,refToFrameId:u,content:d,timestamp:Date.now()};return t.snapshots.set(n,f),{snapshot:f,output:[`Page URL: ${a}`,`Page Title: ${o}`,``,d].join(`
2446
+ `)}}function pU(e){let t=new Map;for(let n of e){let e=n.domain??`unknown`;t.set(e,(t.get(e)??0)+1)}return[...t.entries()].sort((e,t)=>t[1]-e[1]).map(([e,t])=>`${t} ${e}`).join(`, `)}var mU={origin:``,localStorage:{},sessionStorage:{}};function hU(e){return Object.keys(e.localStorage).length+Object.keys(e.sessionStorage).length}function gU(e){if(!e)return null;try{return new URL(e).origin}catch{return null}}function _U(e){try{return new URL(`/favicon.ico`,e).toString()}catch{return e}}function vU(e,t,n){let r=gU(t);if(t&&r===e)return t;let i=gU(n);return n&&i===e?n:e||(t??n)}async function yU(e,t){let n=await e.evaluate(`(() => {
2445
2447
  const collect = (storage) => {
2446
2448
  const items = {};
2447
2449
  for (let i = 0; i < storage.length; i++) {
@@ -2455,7 +2457,7 @@ Available commands:
2455
2457
  localStorage: collect(window.localStorage),
2456
2458
  sessionStorage: collect(window.sessionStorage),
2457
2459
  });
2458
- })()`);if(typeof n!=`string`||n.length===0)return Q.warn(`Teleport storage capture returned non-string result`,{label:t,type:typeof n}),pU;try{let e=JSON.parse(n);return{origin:typeof e.origin==`string`?e.origin:``,localStorage:e.localStorage??{},sessionStorage:e.sessionStorage??{}}}catch(e){return Q.warn(`Could not parse teleport storage snapshot`,{label:t,error:String(e)}),pU}}function yU(e){return`(() => {
2460
+ })()`);if(typeof n!=`string`||n.length===0)return Q.warn(`Teleport storage capture returned non-string result`,{label:t,type:typeof n}),mU;try{let e=JSON.parse(n);return{origin:typeof e.origin==`string`?e.origin:``,localStorage:e.localStorage??{},sessionStorage:e.sessionStorage??{}}}catch(e){return Q.warn(`Could not parse teleport storage snapshot`,{label:t,error:String(e)}),mU}}function bU(e){return`(() => {
2459
2461
  const snapshot = ${JSON.stringify(e)};
2460
2462
  if (!snapshot.origin || window.location.origin !== snapshot.origin) return;
2461
2463
  const markerKey = '__slicc_teleport_storage_applied__:' + snapshot.origin;
@@ -2471,7 +2473,7 @@ Available commands:
2471
2473
  apply(window.localStorage, snapshot.localStorage || {});
2472
2474
  apply(window.sessionStorage, snapshot.sessionStorage || {});
2473
2475
  try { window.sessionStorage.setItem(markerKey, '1'); } catch {}
2474
- })();`}function bU(e){return`(() => {
2476
+ })();`}function xU(e){return`(() => {
2475
2477
  const snapshot = ${JSON.stringify(e)};
2476
2478
  if (!snapshot.origin || globalThis.location.origin !== snapshot.origin) {
2477
2479
  throw new Error('Teleport storage origin mismatch');
@@ -2489,11 +2491,11 @@ Available commands:
2489
2491
  localStorageCount: Object.keys(snapshot.localStorage || {}).length,
2490
2492
  sessionStorageCount: Object.keys(snapshot.sessionStorage || {}).length,
2491
2493
  });
2492
- })();`}async function xU(e,t,n){let r=mU(t);if(r===0)return;let i=await e.evaluate(bU(t));Q.info(`Applied teleport storage snapshot on current page`,{target:n,totalEntries:r,resultType:typeof i}),Q.debug(`Applied teleport storage snapshot details`,{target:n,origin:t.origin||`(unknown)`,totalEntries:r,resultType:typeof i})}async function SU(e,t,n,r){let i=mU(t);if(i===0)return null;let a=await e.sendCDP(`Page.addScriptToEvaluateOnNewDocument`,{source:yU(t)}),o=typeof a.identifier==`string`?a.identifier:null;return Q.info(`Installed teleport storage init script`,{target:r,totalEntries:i,hasIdentifier:!!o}),Q.debug(`Installed teleport storage init script details`,{target:r,origin:t.origin||`(unknown)`,localStorageCount:Object.keys(t.localStorage).length,sessionStorageCount:Object.keys(t.sessionStorage).length,hasIdentifier:!!o}),o?async()=>{try{await e.attachToPage(n),await e.sendCDP(`Page.removeScriptToEvaluateOnNewDocument`,{identifier:o})}catch(e){Q.warn(`Failed to remove teleport storage init script`,{target:r,error:String(e)})}}:null}async function CU(e){let t=await e.evaluate(`(() => JSON.stringify({
2494
+ })();`}async function SU(e,t,n){let r=hU(t);if(r===0)return;let i=await e.evaluate(xU(t));Q.info(`Applied teleport storage snapshot on current page`,{target:n,totalEntries:r,resultType:typeof i}),Q.debug(`Applied teleport storage snapshot details`,{target:n,origin:t.origin||`(unknown)`,totalEntries:r,resultType:typeof i})}async function CU(e,t,n,r){let i=hU(t);if(i===0)return null;let a=await e.sendCDP(`Page.addScriptToEvaluateOnNewDocument`,{source:bU(t)}),o=typeof a.identifier==`string`?a.identifier:null;return Q.info(`Installed teleport storage init script`,{target:r,totalEntries:i,hasIdentifier:!!o}),Q.debug(`Installed teleport storage init script details`,{target:r,origin:t.origin||`(unknown)`,localStorageCount:Object.keys(t.localStorage).length,sessionStorageCount:Object.keys(t.sessionStorage).length,hasIdentifier:!!o}),o?async()=>{try{await e.attachToPage(n),await e.sendCDP(`Page.removeScriptToEvaluateOnNewDocument`,{identifier:o})}catch(e){Q.warn(`Failed to remove teleport storage init script`,{target:r,error:String(e)})}}:null}async function wU(e){let t=await e.evaluate(`(() => JSON.stringify({
2493
2495
  url: window.location.href,
2494
2496
  title: document.title || '',
2495
2497
  bodySnippet: document.body?.innerText?.replace(/s+/g, ' ').trim().slice(0, 500) || '(empty)',
2496
- }))()`);if(typeof t!=`string`||t.length===0)return{url:``,title:``,bodySnippet:`(unavailable)`};try{let e=JSON.parse(t);return{url:typeof e.url==`string`?e.url:``,title:typeof e.title==`string`?e.title:``,bodySnippet:typeof e.bodySnippet==`string`&&e.bodySnippet.length>0?e.bodySnippet:`(empty)`}}catch{return{url:``,title:``,bodySnippet:`(unparseable)`}}}function wU(e){return/callback|authorize\/resume|error/i.test(e)}async function TU(e,t,n){try{let r=await CU(e),i=`${n}:${r.url}:${r.title}`;if(t.lastFollowerDiagnosticKey===i)return;t.lastFollowerDiagnosticKey=i,Q.debug(`Teleport follower diagnostics`,{reason:n,url:r.url,title:r.title,bodySnippet:r.bodySnippet})}catch(e){Q.warn(`Could not capture teleport follower diagnostics`,{reason:n,error:String(e)})}}async function EU(e,t){let n=e.removeFollowerStorageScript;if(n){e.removeFollowerStorageScript=null;try{await n(),Q.info(`Removed follower teleport storage init script`,{reason:t})}catch(e){Q.warn(`Failed to remove follower teleport storage init script`,{reason:t,error:String(e)})}}}async function DU(e,t){if(Q.warn(`Teleport timed out`,{timeoutMs:t.timeoutMs,phase:t.phase}),Q.debug(`Teleport timeout details`,{timeoutMs:t.timeoutMs,phase:t.phase,followerTargetId:t.followerTargetId}),t.phase=`timedOut`,t.followerTargetId){try{await e.attachToPage(t.followerTargetId),await TU(e,t,`timeout`)}catch(e){Q.warn(`Could not attach to follower for timeout diagnostics`,{error:String(e)})}await EU(t,`timeout`)}if(OU(t),t.followerTargetId)try{await e.closePage(t.followerTargetId)}catch(e){Q.warn(`Failed to close follower tab after timeout`,{error:String(e)})}t.rejectBlock?.(Error(`Teleport timed out after ${Math.round(t.timeoutMs/1e3)}s — human did not complete auth`))}function OU(e){Q.info(`Cleaning up teleport watcher`,{phase:e.phase,hadPoll:!!e.pollInterval,hadTimeout:!!e.timeoutTimer,hadListener:!!e.cleanupListener}),e.pollInterval&&=(clearInterval(e.pollInterval),void 0),e.timeoutTimer&&=(clearTimeout(e.timeoutTimer),void 0),e.cleanupListener&&=(e.cleanupListener(),void 0)}function kU(e,t,n,r,i,a,o,s){Q.info(`Arming teleport watcher`,{timeoutMs:i,runtimeSelection:a?`explicit`:`auto`}),Q.debug(`Arming teleport watcher details`,{startPattern:n.source,returnPattern:r.source,timeoutMs:i,runtimeId:a??`auto`,originalUrl:o});let c={startPattern:n,returnPattern:r,timeoutMs:i,runtimeId:a,phase:`armed`,leaderTargetId:s,originalLeaderUrl:o};return c.completionPromise=new Promise((e,t)=>{c.resolveBlock=e,c.rejectBlock=t}),c.completionPromise.catch(()=>{}),c.pollInterval=setInterval(async()=>{if(c.phase!==`armed`)return;let r=c.leaderTargetId;if(r)try{await e.attachToPage(r);let i=await e.evaluate(`window.location.href`),a=typeof i==`string`?i:String(i);Q.debug(`Polling leader tab URL`,{targetId:r,href:a,startPattern:n.source}),n.test(a)&&(Q.info(`Teleport start pattern matched on leader`),Q.debug(`Teleport start pattern matched on leader details`,{targetId:r,href:a,startPattern:n.source}),AU(e,t,c,a))}catch(e){Q.warn(`Error polling leader tab URL`,{targetId:r,error:String(e)})}},1e3),s&&t.teleportWatchers.set(s,c),c}async function AU(e,t,n,r){if(n.phase===`armed`){n.phase=`teleporting`,Q.info(`Teleport triggered`),Q.debug(`Teleport trigger details`,{triggerUrl:r}),n.pollInterval&&=(clearInterval(n.pollInterval),void 0);try{let i=[],a=pU;try{i=(await e.sendCDP(`Network.getCookies`,{})).cookies??[],Q.info(`Captured leader cookies for follower`,{count:i.length})}catch(e){Q.warn(`Could not capture leader cookies`,{error:String(e)})}try{a=await vU(e,`leader`),Q.info(`Captured leader storage for follower`,{totalEntries:mU(a),localStorageCount:Object.keys(a.localStorage).length,sessionStorageCount:Object.keys(a.sessionStorage).length}),Q.debug(`Captured leader storage for follower details`,{origin:a.origin||`(unknown)`,localStorageCount:Object.keys(a.localStorage).length,sessionStorageCount:Object.keys(a.sessionStorage).length})}catch(e){Q.warn(`Could not capture leader storage`,{error:String(e)})}let o=n.runtimeId;if(!o){let e=zH?.();if(!e)throw Error(`No follower selection available — not connected to a tray`);let t=e();if(!t)throw Error(`No followers connected to teleport to`);o=t.runtimeId}Q.info(`Selected follower for teleport`),Q.debug(`Selected follower for teleport details`,{runtimeId:o});let s=await e.createRemotePage(o,`about:blank`),c=s.includes(`:`)?s:`${o}:${s}`;if(n.followerTargetId=c,Q.info(`Opened follower tab for teleport`),Q.debug(`Opened follower tab for teleport details`,{followerTargetId:c}),await e.attachToPage(c),Q.info(`Attached to follower tab for teleport`),Q.debug(`Attached to follower tab for teleport details`,{followerTargetId:c}),await e.sendCDP(`Page.enable`),i.length>0)try{await e.sendCDP(`Network.setCookies`,{cookies:i}),Q.info(`Injected leader cookies into follower`,{count:i.length})}catch(e){Q.warn(`Could not inject leader cookies into follower`,{error:String(e)})}let l=r;n.removeFollowerStorageScript=await SU(e,a,c,`follower`),Q.info(`Navigating follower to intercepted auth URL`),Q.debug(`Navigating follower to intercepted auth URL details`,{url:l,originalLeaderUrl:n.originalLeaderUrl,triggerUrl:r,storageOrigin:a.origin||`(unknown)`}),await e.sendCDP(`Page.navigate`,{url:l}),Q.info(`Starting teleport timeout timer`,{timeoutMs:n.timeoutMs}),n.timeoutTimer=setTimeout(()=>{(n.phase===`teleporting`||n.phase===`waitingForAuth`||n.phase===`waitingForReturn`)&&DU(e,n)},n.timeoutMs),n.phase=`waitingForAuth`,Q.info(`Teleport waiting for follower auth redirect`),Q.debug(`Teleport waiting for follower auth redirect details`,{startPattern:n.startPattern.source}),n.pollInterval=setInterval(async()=>{if(!(n.phase!==`waitingForAuth`&&n.phase!==`waitingForReturn`))try{await e.attachToPage(c);let r=await e.evaluate(`window.location.href`),i=typeof r==`string`?r:String(r);if(!i)return;if(n.lastFollowerUrl!==i&&(n.lastFollowerUrl=i,Q.debug(`Follower teleport navigation`,{href:i,phase:n.phase})),n.phase===`waitingForAuth`){n.startPattern.test(i)?(n.phase=`waitingForReturn`,Q.info(`Follower reached auth provider; waiting for return pattern`),Q.debug(`Follower reached auth provider details`,{href:i,startPattern:n.startPattern.source})):Q.debug(`Waiting for auth redirect on follower`,{href:i,startPattern:n.startPattern.source});return}Q.debug(`Polling follower tab URL for return`,{href:i,returnPattern:n.returnPattern.source}),wU(i)&&await TU(e,n,`waiting-for-return`),n.returnPattern.test(i)&&(Q.info(`Follower return pattern matched after auth`),Q.debug(`Follower return pattern matched after auth details`,{href:i,returnPattern:n.returnPattern.source}),jU(e,t,n,o))}catch(e){Q.warn(`Error polling follower tab URL`,{error:String(e)})}},1e3)}catch(e){Q.error(`Teleport trigger failed`,{error:String(e)}),await EU(n,`trigger-error`),n.phase=`done`,OU(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}async function jU(e,t,n,r){if(!(n.phase!==`teleporting`&&n.phase!==`waitingForReturn`)){n.phase=`capturing`,Q.info(`Capturing auth state from follower`),Q.debug(`Capturing auth state from follower details`,{followerTargetId:n.followerTargetId,runtimeId:r}),n.pollInterval&&=(clearInterval(n.pollInterval),void 0),n.timeoutTimer&&=(clearTimeout(n.timeoutTimer),void 0);try{Q.info(`Waiting for redirect chain to settle (2s)`),await new Promise(e=>setTimeout(e,2e3)),await e.attachToPage(n.followerTargetId);let t;try{let n=await e.evaluate(`window.location.href`);t=typeof n==`string`?n:String(n),Q.debug(`Captured final URL from follower`,{finalUrl:t})}catch(e){Q.warn(`Could not read follower URL (may be mid-navigation)`,{error:String(e)})}try{let t=await e.evaluate(`document.body?.innerText?.substring(0, 500) || "(empty)"`);Q.debug(`Follower page content at capture time`,{bodyText:t})}catch(e){Q.warn(`Could not read follower page content`,{error:String(e)})}let i=(await e.sendCDP(`Network.getCookies`)).cookies??[],a=i.length>0?fU(i):`none`;Q.info(`Captured cookies from follower`,{count:i.length}),Q.debug(`Captured cookies from follower details`,{count:i.length,domains:a});let o=pU;try{o=await vU(e,`follower`),Q.info(`Captured follower storage for leader`,{totalEntries:mU(o),localStorageCount:Object.keys(o.localStorage).length,sessionStorageCount:Object.keys(o.sessionStorage).length}),Q.debug(`Captured follower storage for leader details`,{origin:o.origin||`(unknown)`,localStorageCount:Object.keys(o.localStorage).length,sessionStorageCount:Object.keys(o.sessionStorage).length})}catch(e){Q.warn(`Could not capture follower storage`,{error:String(e)})}let s=mU(o);await TU(e,n,`capture`),await EU(n,`capture`);try{await e.closePage(n.followerTargetId),Q.info(`Closed follower tab after teleport`),Q.debug(`Closed follower tab after teleport details`,{followerTargetId:n.followerTargetId})}catch(e){Q.warn(`Failed to close follower tab`,{error:String(e)})}let c=n.leaderTargetId,l=o.origin||``,u=_U(l,n.originalLeaderUrl,t),d=hU(n.originalLeaderUrl),f=!!l&&d!==l,p=f?gU(l):null;if(c)if(await e.attachToPage(c),i.length>0&&(await e.sendCDP(`Network.setCookies`,{cookies:i}),Q.info(`Injected cookies into leader tab`,{count:i.length}),Q.debug(`Injected cookies into leader tab details`,{count:i.length,leaderTargetId:c})),f&&p){Q.info(`Hydrating leader storage origin before landing`,{storageEntries:s}),Q.debug(`Hydrating leader storage origin before landing details`,{hydrationUrl:p,landingUrl:u,originalLeaderUrl:n.originalLeaderUrl,finalUrl:t,leaderTargetId:c,storageOrigin:l,storageEntries:s});try{await e.navigate(p),await xU(e,o,`leader`),u&&u!==p&&await e.navigate(u)}catch(t){Q.warn(`Direct leader origin hydration failed, falling back to init-script replay`,{error:String(t)}),Q.debug(`Direct leader origin hydration fallback details`,{hydrationUrl:p,landingUrl:u,error:String(t)});let n=await SU(e,o,c,`leader`);try{u&&await e.navigate(u)}finally{await n?.()}}}else{let r=await SU(e,o,c,`leader`);try{u&&(Q.info(`Navigating leader after auth-state injection`,{hasLandingUrl:!0,storageEntries:s}),Q.debug(`Navigating leader after auth-state injection details`,{landingUrl:u,originalLeaderUrl:n.originalLeaderUrl,finalUrl:t,leaderTargetId:c,storageOrigin:o.origin||`(unknown)`,storageEntries:s}),await e.navigate(u))}finally{await r?.()}}else Q.warn(`No leader tab available for auth-state injection`);n.phase=`done`,OU(n);let m=i.length>0?` (${fU(i)})`:``,h=s>0?` + ${s} storage entr${s===1?`y`:`ies`}`:``,g=u?` (navigated to ${u})`:``,_=`Teleported ${i.length} cookie(s)${m}${h} from ${r}${g}`;Q.info(`Teleport completed successfully`,{cookieCount:i.length,storageEntries:s,landed:!!u}),Q.debug(`Teleport completed successfully details`,{result:_}),n.resolveBlock?.(_)}catch(e){Q.error(`Teleport auth-state capture failed`,{error:String(e)}),await EU(n,`capture-error`),n.phase=`done`,OU(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}function MU(e){return`Usage: ${e} <command> [args...]
2498
+ }))()`);if(typeof t!=`string`||t.length===0)return{url:``,title:``,bodySnippet:`(unavailable)`};try{let e=JSON.parse(t);return{url:typeof e.url==`string`?e.url:``,title:typeof e.title==`string`?e.title:``,bodySnippet:typeof e.bodySnippet==`string`&&e.bodySnippet.length>0?e.bodySnippet:`(empty)`}}catch{return{url:``,title:``,bodySnippet:`(unparseable)`}}}function TU(e){return/callback|authorize\/resume|error/i.test(e)}async function EU(e,t,n){try{let r=await wU(e),i=`${n}:${r.url}:${r.title}`;if(t.lastFollowerDiagnosticKey===i)return;t.lastFollowerDiagnosticKey=i,Q.debug(`Teleport follower diagnostics`,{reason:n,url:r.url,title:r.title,bodySnippet:r.bodySnippet})}catch(e){Q.warn(`Could not capture teleport follower diagnostics`,{reason:n,error:String(e)})}}async function DU(e,t){let n=e.removeFollowerStorageScript;if(n){e.removeFollowerStorageScript=null;try{await n(),Q.info(`Removed follower teleport storage init script`,{reason:t})}catch(e){Q.warn(`Failed to remove follower teleport storage init script`,{reason:t,error:String(e)})}}}async function OU(e,t){if(Q.warn(`Teleport timed out`,{timeoutMs:t.timeoutMs,phase:t.phase}),Q.debug(`Teleport timeout details`,{timeoutMs:t.timeoutMs,phase:t.phase,followerTargetId:t.followerTargetId}),t.phase=`timedOut`,t.followerTargetId){try{await e.attachToPage(t.followerTargetId),await EU(e,t,`timeout`)}catch(e){Q.warn(`Could not attach to follower for timeout diagnostics`,{error:String(e)})}await DU(t,`timeout`)}if(kU(t),t.followerTargetId)try{await e.closePage(t.followerTargetId)}catch(e){Q.warn(`Failed to close follower tab after timeout`,{error:String(e)})}t.rejectBlock?.(Error(`Teleport timed out after ${Math.round(t.timeoutMs/1e3)}s — human did not complete auth`))}function kU(e){Q.info(`Cleaning up teleport watcher`,{phase:e.phase,hadPoll:!!e.pollInterval,hadTimeout:!!e.timeoutTimer,hadListener:!!e.cleanupListener}),e.pollInterval&&=(clearInterval(e.pollInterval),void 0),e.timeoutTimer&&=(clearTimeout(e.timeoutTimer),void 0),e.cleanupListener&&=(e.cleanupListener(),void 0)}function AU(e,t,n,r,i,a,o,s){Q.info(`Arming teleport watcher`,{timeoutMs:i,runtimeSelection:a?`explicit`:`auto`}),Q.debug(`Arming teleport watcher details`,{startPattern:n.source,returnPattern:r.source,timeoutMs:i,runtimeId:a??`auto`,originalUrl:o});let c={startPattern:n,returnPattern:r,timeoutMs:i,runtimeId:a,phase:`armed`,leaderTargetId:s,originalLeaderUrl:o};return c.completionPromise=new Promise((e,t)=>{c.resolveBlock=e,c.rejectBlock=t}),c.completionPromise.catch(()=>{}),c.pollInterval=setInterval(async()=>{if(c.phase!==`armed`)return;let r=c.leaderTargetId;if(r)try{await e.attachToPage(r);let i=await e.evaluate(`window.location.href`),a=typeof i==`string`?i:String(i);Q.debug(`Polling leader tab URL`,{targetId:r,href:a,startPattern:n.source}),n.test(a)&&(Q.info(`Teleport start pattern matched on leader`),Q.debug(`Teleport start pattern matched on leader details`,{targetId:r,href:a,startPattern:n.source}),jU(e,t,c,a))}catch(e){Q.warn(`Error polling leader tab URL`,{targetId:r,error:String(e)})}},1e3),s&&t.teleportWatchers.set(s,c),c}async function jU(e,t,n,r){if(n.phase===`armed`){n.phase=`teleporting`,Q.info(`Teleport triggered`),Q.debug(`Teleport trigger details`,{triggerUrl:r}),n.pollInterval&&=(clearInterval(n.pollInterval),void 0);try{let i=[],a=mU;try{i=(await e.sendCDP(`Network.getCookies`,{})).cookies??[],Q.info(`Captured leader cookies for follower`,{count:i.length})}catch(e){Q.warn(`Could not capture leader cookies`,{error:String(e)})}try{a=await yU(e,`leader`),Q.info(`Captured leader storage for follower`,{totalEntries:hU(a),localStorageCount:Object.keys(a.localStorage).length,sessionStorageCount:Object.keys(a.sessionStorage).length}),Q.debug(`Captured leader storage for follower details`,{origin:a.origin||`(unknown)`,localStorageCount:Object.keys(a.localStorage).length,sessionStorageCount:Object.keys(a.sessionStorage).length})}catch(e){Q.warn(`Could not capture leader storage`,{error:String(e)})}let o=n.runtimeId;if(!o){let e=zH?.();if(!e)throw Error(`No follower selection available — not connected to a tray`);let t=e();if(!t)throw Error(`No followers connected to teleport to`);o=t.runtimeId}Q.info(`Selected follower for teleport`),Q.debug(`Selected follower for teleport details`,{runtimeId:o});let s=await e.createRemotePage(o,`about:blank`),c=s.includes(`:`)?s:`${o}:${s}`;if(n.followerTargetId=c,Q.info(`Opened follower tab for teleport`),Q.debug(`Opened follower tab for teleport details`,{followerTargetId:c}),await e.attachToPage(c),Q.info(`Attached to follower tab for teleport`),Q.debug(`Attached to follower tab for teleport details`,{followerTargetId:c}),await e.sendCDP(`Page.enable`),i.length>0)try{await e.sendCDP(`Network.setCookies`,{cookies:i}),Q.info(`Injected leader cookies into follower`,{count:i.length})}catch(e){Q.warn(`Could not inject leader cookies into follower`,{error:String(e)})}let l=r;n.removeFollowerStorageScript=await CU(e,a,c,`follower`),Q.info(`Navigating follower to intercepted auth URL`),Q.debug(`Navigating follower to intercepted auth URL details`,{url:l,originalLeaderUrl:n.originalLeaderUrl,triggerUrl:r,storageOrigin:a.origin||`(unknown)`}),await e.sendCDP(`Page.navigate`,{url:l}),Q.info(`Starting teleport timeout timer`,{timeoutMs:n.timeoutMs}),n.timeoutTimer=setTimeout(()=>{(n.phase===`teleporting`||n.phase===`waitingForAuth`||n.phase===`waitingForReturn`)&&OU(e,n)},n.timeoutMs),n.phase=`waitingForAuth`,Q.info(`Teleport waiting for follower auth redirect`),Q.debug(`Teleport waiting for follower auth redirect details`,{startPattern:n.startPattern.source}),n.pollInterval=setInterval(async()=>{if(!(n.phase!==`waitingForAuth`&&n.phase!==`waitingForReturn`))try{await e.attachToPage(c);let r=await e.evaluate(`window.location.href`),i=typeof r==`string`?r:String(r);if(!i)return;if(n.lastFollowerUrl!==i&&(n.lastFollowerUrl=i,Q.debug(`Follower teleport navigation`,{href:i,phase:n.phase})),n.phase===`waitingForAuth`){n.startPattern.test(i)?(n.phase=`waitingForReturn`,Q.info(`Follower reached auth provider; waiting for return pattern`),Q.debug(`Follower reached auth provider details`,{href:i,startPattern:n.startPattern.source})):Q.debug(`Waiting for auth redirect on follower`,{href:i,startPattern:n.startPattern.source});return}Q.debug(`Polling follower tab URL for return`,{href:i,returnPattern:n.returnPattern.source}),TU(i)&&await EU(e,n,`waiting-for-return`),n.returnPattern.test(i)&&(Q.info(`Follower return pattern matched after auth`),Q.debug(`Follower return pattern matched after auth details`,{href:i,returnPattern:n.returnPattern.source}),MU(e,t,n,o))}catch(e){Q.warn(`Error polling follower tab URL`,{error:String(e)})}},1e3)}catch(e){Q.error(`Teleport trigger failed`,{error:String(e)}),await DU(n,`trigger-error`),n.phase=`done`,kU(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}async function MU(e,t,n,r){if(!(n.phase!==`teleporting`&&n.phase!==`waitingForReturn`)){n.phase=`capturing`,Q.info(`Capturing auth state from follower`),Q.debug(`Capturing auth state from follower details`,{followerTargetId:n.followerTargetId,runtimeId:r}),n.pollInterval&&=(clearInterval(n.pollInterval),void 0),n.timeoutTimer&&=(clearTimeout(n.timeoutTimer),void 0);try{Q.info(`Waiting for redirect chain to settle (2s)`),await new Promise(e=>setTimeout(e,2e3)),await e.attachToPage(n.followerTargetId);let t;try{let n=await e.evaluate(`window.location.href`);t=typeof n==`string`?n:String(n),Q.debug(`Captured final URL from follower`,{finalUrl:t})}catch(e){Q.warn(`Could not read follower URL (may be mid-navigation)`,{error:String(e)})}try{let t=await e.evaluate(`document.body?.innerText?.substring(0, 500) || "(empty)"`);Q.debug(`Follower page content at capture time`,{bodyText:t})}catch(e){Q.warn(`Could not read follower page content`,{error:String(e)})}let i=(await e.sendCDP(`Network.getCookies`)).cookies??[],a=i.length>0?pU(i):`none`;Q.info(`Captured cookies from follower`,{count:i.length}),Q.debug(`Captured cookies from follower details`,{count:i.length,domains:a});let o=mU;try{o=await yU(e,`follower`),Q.info(`Captured follower storage for leader`,{totalEntries:hU(o),localStorageCount:Object.keys(o.localStorage).length,sessionStorageCount:Object.keys(o.sessionStorage).length}),Q.debug(`Captured follower storage for leader details`,{origin:o.origin||`(unknown)`,localStorageCount:Object.keys(o.localStorage).length,sessionStorageCount:Object.keys(o.sessionStorage).length})}catch(e){Q.warn(`Could not capture follower storage`,{error:String(e)})}let s=hU(o);await EU(e,n,`capture`),await DU(n,`capture`);try{await e.closePage(n.followerTargetId),Q.info(`Closed follower tab after teleport`),Q.debug(`Closed follower tab after teleport details`,{followerTargetId:n.followerTargetId})}catch(e){Q.warn(`Failed to close follower tab`,{error:String(e)})}let c=n.leaderTargetId,l=o.origin||``,u=vU(l,n.originalLeaderUrl,t),d=gU(n.originalLeaderUrl),f=!!l&&d!==l,p=f?_U(l):null;if(c)if(await e.attachToPage(c),i.length>0&&(await e.sendCDP(`Network.setCookies`,{cookies:i}),Q.info(`Injected cookies into leader tab`,{count:i.length}),Q.debug(`Injected cookies into leader tab details`,{count:i.length,leaderTargetId:c})),f&&p){Q.info(`Hydrating leader storage origin before landing`,{storageEntries:s}),Q.debug(`Hydrating leader storage origin before landing details`,{hydrationUrl:p,landingUrl:u,originalLeaderUrl:n.originalLeaderUrl,finalUrl:t,leaderTargetId:c,storageOrigin:l,storageEntries:s});try{await e.navigate(p),await SU(e,o,`leader`),u&&u!==p&&await e.navigate(u)}catch(t){Q.warn(`Direct leader origin hydration failed, falling back to init-script replay`,{error:String(t)}),Q.debug(`Direct leader origin hydration fallback details`,{hydrationUrl:p,landingUrl:u,error:String(t)});let n=await CU(e,o,c,`leader`);try{u&&await e.navigate(u)}finally{await n?.()}}}else{let r=await CU(e,o,c,`leader`);try{u&&(Q.info(`Navigating leader after auth-state injection`,{hasLandingUrl:!0,storageEntries:s}),Q.debug(`Navigating leader after auth-state injection details`,{landingUrl:u,originalLeaderUrl:n.originalLeaderUrl,finalUrl:t,leaderTargetId:c,storageOrigin:o.origin||`(unknown)`,storageEntries:s}),await e.navigate(u))}finally{await r?.()}}else Q.warn(`No leader tab available for auth-state injection`);n.phase=`done`,kU(n);let m=i.length>0?` (${pU(i)})`:``,h=s>0?` + ${s} storage entr${s===1?`y`:`ies`}`:``,g=u?` (navigated to ${u})`:``,_=`Teleported ${i.length} cookie(s)${m}${h} from ${r}${g}`;Q.info(`Teleport completed successfully`,{cookieCount:i.length,storageEntries:s,landed:!!u}),Q.debug(`Teleport completed successfully details`,{result:_}),n.resolveBlock?.(_)}catch(e){Q.error(`Teleport auth-state capture failed`,{error:String(e)}),await DU(n,`capture-error`),n.phase=`done`,kU(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}function NU(e){return`Usage: ${e} <command> [args...]
2497
2499
 
2498
2500
  Commands:
2499
2501
  open [url|/vfs/path] [--foreground|--fg] [--runtime=<id>]
@@ -2513,7 +2515,8 @@ Commands:
2513
2515
  click <ref> Click element by ref (e.g. e5)
2514
2516
  type <text> Type text into focused element
2515
2517
  fill <ref> <text> Fill an input by ref with text
2516
- snapshot Print accessibility tree with refs
2518
+ snapshot [--no-iframes] Print accessibility tree with refs
2519
+ frames List all frames (iframes) in the current tab
2517
2520
  screenshot [--filename=path] [--max-width=N] [--fullPage=true]
2518
2521
  Take screenshot. --max-width downscales the image
2519
2522
  if wider than N pixels (e.g. --max-width=1024).
@@ -2567,18 +2570,20 @@ Commands:
2567
2570
  sessionstorage-clear Clear all sessionStorage
2568
2571
  help Show this help message
2569
2572
 
2570
- Aliases: ${WH.filter(t=>t!==e).join(`, `)}`}function NU(e){let t=[],n={};for(let r of e)if(r.startsWith(`--`)&&r.includes(`=`)){let e=r.indexOf(`=`);n[r.slice(2,e)]=r.slice(e+1)}else r.startsWith(`--`)?n[r.slice(2)]=`true`:t.push(r);return{positional:t,flags:n}}function PU(e){let t=e.tab;return t?{targetId:t}:{error:`Error: --tab <targetId> is required. Run 'playwright-cli tab-list' to get tab IDs.
2571
- `}}function FU(e,t,n){let r=MU(e),i=t?JH(t,n):null;return $P(e,async a=>{if(a.length===0||a[0]===`help`||a[0]===`--help`||a[0]===`-h`)return{stdout:r+`
2572
- `,stderr:``,exitCode:0};if(!t||!i)return{stdout:``,stderr:`${e}: browser APIs are unavailable in this environment\n`,exitCode:1};let o=a[0],s=a.slice(1),{positional:c,flags:l}=NU(s),u;try{switch(o){case`teleport`:{if(l.list===`true`){Q.info(`Listing available follower runtimes`);let e=BH?.();if(!e){u={stdout:``,stderr:`teleport: not connected to a tray
2573
+ Aliases: ${GH.filter(t=>t!==e).join(`, `)}`}function PU(e){let t=[],n={};for(let r of e)if(r.startsWith(`--`)&&r.includes(`=`)){let e=r.indexOf(`=`);n[r.slice(2,e)]=r.slice(e+1)}else r.startsWith(`--`)?n[r.slice(2)]=`true`:t.push(r);return{positional:t,flags:n}}function FU(e){let t=e.tab;return t?{targetId:t}:{error:`Error: --tab <targetId> is required. Run 'playwright-cli tab-list' to get tab IDs.
2574
+ `}}function IU(e,t,n){let r=NU(e),i=t?YH(t,n):null;return $P(e,async a=>{if(a.length===0||a[0]===`help`||a[0]===`--help`||a[0]===`-h`)return{stdout:r+`
2575
+ `,stderr:``,exitCode:0};if(!t||!i)return{stdout:``,stderr:`${e}: browser APIs are unavailable in this environment\n`,exitCode:1};let o=a[0],s=a.slice(1),{positional:c,flags:l}=PU(s),u;try{switch(o){case`teleport`:{if(l.list===`true`){Q.info(`Listing available follower runtimes`);let e=BH?.();if(!e){u={stdout:``,stderr:`teleport: not connected to a tray
2573
2576
  `,exitCode:1};break}let t=e();if(t.length===0){u={stdout:`No followers connected to the tray.
2574
2577
  `,stderr:``,exitCode:0};break}let n=[`Available runtimes for teleport:`];for(let e of t){let t=[e.runtimeId];if(e.floatType&&t.push(`[${e.floatType}]`),e.runtime&&t.push(`(${e.runtime})`),e.lastActivity){let n=Math.round((Date.now()-e.lastActivity)/1e3);t.push(`active ${n}s ago`)}n.push(` ${t.join(` `)}`)}u={stdout:n.join(`
2575
2578
  `)+`
2576
- `,stderr:``,exitCode:0};break}if(l.off===`true`){let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}Q.info(`Disarming teleport watcher via --off`,{targetId:e.targetId});let t=i.teleportWatchers.get(e.targetId);t&&(OU(t),i.teleportWatchers.delete(e.targetId)),u={stdout:`Teleport watcher disarmed
2577
- `,stderr:``,exitCode:0};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=l.start||l[`teleport-start`],r=l.return||l[`teleport-return`];if(!n||!r){u={stdout:``,stderr:`teleport requires --start <regex> and --return <regex>
2579
+ `,stderr:``,exitCode:0};break}if(l.off===`true`){let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}Q.info(`Disarming teleport watcher via --off`,{targetId:e.targetId});let t=i.teleportWatchers.get(e.targetId);t&&(kU(t),i.teleportWatchers.delete(e.targetId)),u={stdout:`Teleport watcher disarmed
2580
+ `,stderr:``,exitCode:0};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=l.start||l[`teleport-start`],r=l.return||l[`teleport-return`];if(!n||!r){u={stdout:``,stderr:`teleport requires --start <regex> and --return <regex>
2578
2581
  `,exitCode:1};break}let a,o;try{a=new RegExp(n)}catch{u={stdout:``,stderr:`Invalid regex for --start: ${n}\n`,exitCode:1};break}try{o=new RegExp(r)}catch{u={stdout:``,stderr:`Invalid regex for --return: ${r}\n`,exitCode:1};break}let s=l.timeout?parseInt(l.timeout,10):300;if(isNaN(s)||s<=0){u={stdout:``,stderr:`--timeout must be a positive number
2579
- `,exitCode:1};break}let c=l.runtime,d=i.teleportWatchers.get(e.targetId);d&&(Q.info(`Disarming existing teleport watcher before re-arming`,{targetId:e.targetId}),OU(d),i.teleportWatchers.delete(e.targetId));let f;try{await t.attachToPage(e.targetId);let n=await t.evaluate(`window.location.href`);f=typeof n==`string`?n:String(n)}catch{}Q.info(`Arming teleport via explicit subcommand`,{targetId:e.targetId,timeoutSec:s,runtimeSelection:c?`explicit`:`auto`}),Q.debug(`Arming teleport via explicit subcommand details`,{targetId:e.targetId,startPattern:n,returnPattern:r,timeoutSec:s,runtimeId:c??`auto`,leaderUrl:f}),kU(t,i,a,o,s*1e3,c,f,e.targetId),u={stdout:`Teleport armed on tab ${e.targetId}. Will trigger when URL matches ${n}\n`,stderr:``,exitCode:0};break}case`open`:case`tab-new`:{let e=c[0]||`about:blank`,n=l.runtime;await oU(t,i);let r;r=n?await t.createRemotePage(n,e):await t.createPage(e);let a=l[`teleport-start`],o=l[`teleport-return`];if(a&&o){Q.info(`Arming teleport via open/tab-new flags`),Q.debug(`Arming teleport via open/tab-new flags details`,{targetId:r,startPattern:a,returnPattern:o});let n,s;try{n=new RegExp(a)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${a}\n`,exitCode:1};break}try{s=new RegExp(o)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${o}\n`,exitCode:1};break}let c=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(r);d&&(OU(d),i.teleportWatchers.delete(r)),kU(t,i,n,s,c*1e3,l[`teleport-runtime`],e,r)}u={stdout:`Opened ${e} in new tab [targetId: ${r}]\n`,stderr:``,exitCode:0};break}case`goto`:case`navigate`:{if(c.length===0){u={stdout:``,stderr:`goto requires a URL
2580
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>(await t.navigate(c[0]),!0)),i.snapshots.delete(e.targetId);let n=l[`teleport-start`],r=l[`teleport-return`];if(n&&r){Q.info(`Arming teleport via goto/navigate flags`),Q.debug(`Arming teleport via goto/navigate flags details`,{targetId:e.targetId,startPattern:n,returnPattern:r});let a,o;try{a=new RegExp(n)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${n}\n`,exitCode:1};break}try{o=new RegExp(r)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${r}\n`,exitCode:1};break}let s=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(e.targetId);d&&(OU(d),i.teleportWatchers.delete(e.targetId)),kU(t,i,a,o,s*1e3,l[`teleport-runtime`],c[0],e.targetId)}u={stdout:`Navigated to ${c[0]}\n`,stderr:``,exitCode:0};break}case`snapshot`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let{output:r}=await t.withTab(e.targetId,async()=>await dU(t,i,e.targetId));if(l.filename){await n.writeFile(l.filename,r),u={stdout:`Snapshot saved to ${l.filename}\n`,stderr:``,exitCode:0};break}u={stdout:r+`
2581
- `,stderr:``,exitCode:0};break}case`screenshot`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let r;if(c[0]&&c[0].startsWith(`e`)){let n=i.snapshots.get(e.targetId);if(!n)throw Error(`No snapshot available. Run "snapshot" first.`);let a=n.refToBackendNodeId.get(c[0]);if(a){let e=t.getTransport(),n=t.getSessionId();await e.send(`DOM.enable`,{},n),await e.send(`Runtime.enable`,{},n);let i=(await e.send(`DOM.resolveNode`,{backendNodeId:a},n)).object;if(i?.objectId){let t=(await e.send(`Runtime.callFunctionOn`,{objectId:i.objectId,functionDeclaration:`function() {
2582
+ `,exitCode:1};break}let c=l.runtime,d=i.teleportWatchers.get(e.targetId);d&&(Q.info(`Disarming existing teleport watcher before re-arming`,{targetId:e.targetId}),kU(d),i.teleportWatchers.delete(e.targetId));let f;try{await t.attachToPage(e.targetId);let n=await t.evaluate(`window.location.href`);f=typeof n==`string`?n:String(n)}catch{}Q.info(`Arming teleport via explicit subcommand`,{targetId:e.targetId,timeoutSec:s,runtimeSelection:c?`explicit`:`auto`}),Q.debug(`Arming teleport via explicit subcommand details`,{targetId:e.targetId,startPattern:n,returnPattern:r,timeoutSec:s,runtimeId:c??`auto`,leaderUrl:f}),AU(t,i,a,o,s*1e3,c,f,e.targetId),u={stdout:`Teleport armed on tab ${e.targetId}. Will trigger when URL matches ${n}\n`,stderr:``,exitCode:0};break}case`open`:case`tab-new`:{let e=c[0]||`about:blank`,n=l.runtime;await sU(t,i);let r;r=n?await t.createRemotePage(n,e):await t.createPage(e);let a=l[`teleport-start`],o=l[`teleport-return`];if(a&&o){Q.info(`Arming teleport via open/tab-new flags`),Q.debug(`Arming teleport via open/tab-new flags details`,{targetId:r,startPattern:a,returnPattern:o});let n,s;try{n=new RegExp(a)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${a}\n`,exitCode:1};break}try{s=new RegExp(o)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${o}\n`,exitCode:1};break}let c=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(r);d&&(kU(d),i.teleportWatchers.delete(r)),AU(t,i,n,s,c*1e3,l[`teleport-runtime`],e,r)}u={stdout:`Opened ${e} in new tab [targetId: ${r}]\n`,stderr:``,exitCode:0};break}case`goto`:case`navigate`:{if(c.length===0){u={stdout:``,stderr:`goto requires a URL
2583
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>(await t.navigate(c[0]),!0)),i.snapshots.delete(e.targetId);let n=l[`teleport-start`],r=l[`teleport-return`];if(n&&r){Q.info(`Arming teleport via goto/navigate flags`),Q.debug(`Arming teleport via goto/navigate flags details`,{targetId:e.targetId,startPattern:n,returnPattern:r});let a,o;try{a=new RegExp(n)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${n}\n`,exitCode:1};break}try{o=new RegExp(r)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${r}\n`,exitCode:1};break}let s=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(e.targetId);d&&(kU(d),i.teleportWatchers.delete(e.targetId)),AU(t,i,a,o,s*1e3,l[`teleport-runtime`],c[0],e.targetId)}u={stdout:`Navigated to ${c[0]}\n`,stderr:``,exitCode:0};break}case`snapshot`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let r=l[`no-iframes`]===`true`,{output:a}=await t.withTab(e.targetId,async()=>await fU(t,i,e.targetId,{noIframes:r}));if(l.filename){await n.writeFile(l.filename,a),u={stdout:`Snapshot saved to ${l.filename}\n`,stderr:``,exitCode:0};break}u={stdout:a+`
2584
+ `,stderr:``,exitCode:0};break}case`frames`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>`Frames in current tab:\n${(await t.getFrameTree()).map(e=>{let t=e.parentFrameId?`child`:`main`,n=e.parentFrameId?` (parent: ${e.parentFrameId})`:``;return` [${t}] ${e.frameId}${n} - ${e.url}`}).join(`
2585
+ `)}`)+`
2586
+ `,stderr:``,exitCode:0};break}case`screenshot`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let r;if(c[0]&&c[0].startsWith(`e`)){let n=i.snapshots.get(e.targetId);if(!n)throw Error(`No snapshot available. Run "snapshot" first.`);let a=n.refToBackendNodeId.get(c[0]);if(a){let e=t.getTransport(),n=t.getSessionId();await e.send(`DOM.enable`,{},n),await e.send(`Runtime.enable`,{},n);let i=(await e.send(`DOM.resolveNode`,{backendNodeId:a},n)).object;if(i?.objectId){let t=(await e.send(`Runtime.callFunctionOn`,{objectId:i.objectId,functionDeclaration:`function() {
2582
2587
  this.scrollIntoView({ block: 'center' });
2583
2588
  const r = this.getBoundingClientRect();
2584
2589
  return { x: r.x + window.scrollX, y: r.y + window.scrollY, width: r.width, height: r.height };
@@ -2588,79 +2593,124 @@ Aliases: ${WH.filter(t=>t!==e).join(`, `)}`}function NU(e){let t=[],n={};for(let
2588
2593
  el.scrollIntoView({ block: 'center' });
2589
2594
  const r = el.getBoundingClientRect();
2590
2595
  return JSON.stringify({ x: r.x + window.scrollX, y: r.y + window.scrollY, width: r.width, height: r.height });
2591
- })()`);i&&(r=JSON.parse(i))}}let a=l[`max-width`]?parseInt(l[`max-width`],10):void 0,o=await t.screenshot({fullPage:l.fullPage===`true`,...r?{clip:r}:{},...a?{maxWidth:a}:{}}),s=l.filename||`/tmp/screenshot-${Date.now()}.png`,u=UH(o);await n.writeFile(s,u);try{await eU(n,i);let e=`/.playwright/screenshots/screenshot-${qH(new Date)}.png`;await n.writeFile(e,u)}catch{}return`Screenshot saved to ${s} (${Math.round(u.length/1024)} KB)`})+`
2596
+ })()`);i&&(r=JSON.parse(i))}}let a=l[`max-width`]?parseInt(l[`max-width`],10):void 0,o=await t.screenshot({fullPage:l.fullPage===`true`,...r?{clip:r}:{},...a?{maxWidth:a}:{}}),s=l.filename||`/tmp/screenshot-${Date.now()}.png`,u=WH(o);await n.writeFile(s,u);try{await tU(n,i);let e=`/.playwright/screenshots/screenshot-${JH(new Date)}.png`;await n.writeFile(e,u)}catch{}return`Screenshot saved to ${s} (${Math.round(u.length/1024)} KB)`})+`
2592
2597
  `,stderr:``,exitCode:0};break}case`click`:{if(c.length===0){u={stdout:``,stderr:`click requires a ref (e.g. e5)
2593
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let a=r.refToBackendNodeId.get(n);if(a)return await t.clickByBackendNodeId(a),i.snapshots.delete(e.targetId),`Clicked ${n}`;let o=r.refToSelector.get(n);if(!o)throw Error(`Unknown ref "${n}". Available: ${[...r.refToSelector.keys()].slice(0,10).join(`, `)}...`);return await t.click(o),i.snapshots.delete(e.targetId),`Clicked ${n}`})+`
2598
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:a}=UH(n),o=r.refToFrameId?.get(n);if(a&&o){let a=r.refToSelector.get(n);if(!a)throw Error(`Unknown ref "${n}" in iframe`);let s=a.split(`,`)[0].trim();return await t.evaluateInFrame(o,`(function() {
2599
+ var el = document.querySelector(${JSON.stringify(s)});
2600
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2601
+ el.scrollIntoView({ block: 'center' });
2602
+ el.click();
2603
+ })()`),i.snapshots.delete(e.targetId),`Clicked ${n} (in iframe)`}let s=r.refToBackendNodeId.get(n);if(s)return await t.clickByBackendNodeId(s),i.snapshots.delete(e.targetId),`Clicked ${n}`;let c=r.refToSelector.get(n);if(!c)throw Error(`Unknown ref "${n}". Available: ${[...r.refToSelector.keys()].slice(0,10).join(`, `)}...`);return await t.click(c),i.snapshots.delete(e.targetId),`Clicked ${n}`})+`
2594
2604
  `,stderr:``,exitCode:0};break}case`type`:{if(c.length===0){u={stdout:``,stderr:`type requires text
2595
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.join(` `);await t.withTab(e.targetId,async()=>{await t.type(n)}),u={stdout:`Typed: ${n}\n`,stderr:``,exitCode:0};break}case`fill`:{if(c.length<2){u={stdout:``,stderr:`fill requires <ref> <text>
2596
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c.slice(1).join(` `);u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let o=a.refToBackendNodeId.get(n);if(o){await t.clickByBackendNodeId(o);let a=t.getTransport(),s=t.getSessionId();await a.send(`DOM.enable`,{},s),await a.send(`Runtime.enable`,{},s);let c=(await a.send(`DOM.resolveNode`,{backendNodeId:o},s)).object;return c?.objectId&&await a.send(`Runtime.callFunctionOn`,{objectId:c.objectId,functionDeclaration:QH,returnByValue:!0},s),await t.type(r),c?.objectId&&((await a.send(`Runtime.callFunctionOn`,{objectId:c.objectId,functionDeclaration:ZH,returnByValue:!0},s)).result?.value??``)!==r&&await a.send(`Runtime.callFunctionOn`,{objectId:c.objectId,functionDeclaration:XH,arguments:[{value:r}],returnByValue:!0},s),i.snapshots.delete(e.targetId),`Filled ${n} with: ${r}`}let s=a.refToSelector.get(n);if(!s)throw Error(`Unknown ref "${n}"`);return await t.click(s),await t.evaluate(`(function() {
2597
- const el = document.querySelector(${JSON.stringify(s)});
2605
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.join(` `);await t.withTab(e.targetId,async()=>{await t.type(n)}),u={stdout:`Typed: ${n}\n`,stderr:``,exitCode:0};break}case`fill`:{if(c.length<2){u={stdout:``,stderr:`fill requires <ref> <text>
2606
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c.slice(1).join(` `);u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:o}=UH(n),s=a.refToFrameId?.get(n);if(o&&s){let o=a.refToSelector.get(n);if(!o)throw Error(`Unknown ref "${n}" in iframe`);let c=o.split(`,`)[0].trim();return await t.evaluateInFrame(s,`(function() {
2607
+ var el = document.querySelector(${JSON.stringify(c)});
2608
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2609
+ el.scrollIntoView({ block: 'center' });
2610
+ el.focus();
2611
+ el.value = '';
2612
+ el.value = ${JSON.stringify(r)};
2613
+ el.dispatchEvent(new Event('input', { bubbles: true }));
2614
+ el.dispatchEvent(new Event('change', { bubbles: true }));
2615
+ })()`),i.snapshots.delete(e.targetId),`Filled ${n} with: ${r} (in iframe)`}let c=a.refToBackendNodeId.get(n);if(c){await t.clickByBackendNodeId(c);let a=t.getTransport(),o=t.getSessionId();await a.send(`DOM.enable`,{},o),await a.send(`Runtime.enable`,{},o);let s=(await a.send(`DOM.resolveNode`,{backendNodeId:c},o)).object;return s?.objectId&&await a.send(`Runtime.callFunctionOn`,{objectId:s.objectId,functionDeclaration:$H,returnByValue:!0},o),await t.type(r),s?.objectId&&((await a.send(`Runtime.callFunctionOn`,{objectId:s.objectId,functionDeclaration:QH,returnByValue:!0},o)).result?.value??``)!==r&&await a.send(`Runtime.callFunctionOn`,{objectId:s.objectId,functionDeclaration:ZH,arguments:[{value:r}],returnByValue:!0},o),i.snapshots.delete(e.targetId),`Filled ${n} with: ${r}`}let l=a.refToSelector.get(n);if(!l)throw Error(`Unknown ref "${n}"`);return await t.click(l),await t.evaluate(`(function() {
2616
+ const el = document.querySelector(${JSON.stringify(l)});
2598
2617
  if (el) {
2599
- return (${QH}).call(el);
2618
+ return (${$H}).call(el);
2600
2619
  }
2601
2620
  return false;
2602
2621
  })()`),await t.type(r),await t.evaluate(`(function() {
2603
- const el = document.querySelector(${JSON.stringify(s.split(`,`)[0].trim())});
2622
+ const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
2604
2623
  if (!el) return '';
2605
- return (${ZH}).call(el);
2624
+ return (${QH}).call(el);
2606
2625
  })()`)!==r&&await t.evaluate(`(function() {
2607
- const el = document.querySelector(${JSON.stringify(s.split(`,`)[0].trim())});
2626
+ const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
2608
2627
  if (!el) return;
2609
- (${XH}).call(el, ${JSON.stringify(r)});
2628
+ (${ZH}).call(el, ${JSON.stringify(r)});
2610
2629
  })()`),i.snapshots.delete(e.targetId),`Filled ${n} with: ${r}`})+`
2611
2630
  `,stderr:``,exitCode:0};break}case`eval`:{if(c.length===0){u={stdout:``,stderr:`eval requires an expression
2612
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.join(` `);u={stdout:(await t.withTab(e.targetId,async()=>{let e=await t.evaluate(n);return typeof e==`string`?e:JSON.stringify(e,null,2)})??`undefined`)+`
2631
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.join(` `);u={stdout:(await t.withTab(e.targetId,async()=>{let e=await t.evaluate(n);return typeof e==`string`?e:JSON.stringify(e,null,2)})??`undefined`)+`
2613
2632
  `,stderr:``,exitCode:0};break}case`eval-file`:{if(c.length===0){u={stdout:``,stderr:`eval-file requires a file path
2614
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let r=c[0],i=l.output,a;try{a=await n.readTextFile(r)}catch(e){u={stdout:``,stderr:`eval-file: cannot read ${r}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1};break}let o=await t.withTab(e.targetId,async()=>{let e=await t.evaluate(a);return typeof e==`string`?e:JSON.stringify(e,null,2)});if(i){let e=o??`null`;await n.writeFile(i,e),u={stdout:`Result saved to ${i} (${Math.round(new TextEncoder().encode(e).length/1024)} KB)\n`,stderr:``,exitCode:0}}else u={stdout:(o??`undefined`)+`
2633
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let r=c[0],i=l.output,a;try{a=await n.readTextFile(r)}catch(e){u={stdout:``,stderr:`eval-file: cannot read ${r}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1};break}let o=await t.withTab(e.targetId,async()=>{let e=await t.evaluate(a);return typeof e==`string`?e:JSON.stringify(e,null,2)});if(i){let e=o??`null`;await n.writeFile(i,e),u={stdout:`Result saved to ${i} (${Math.round(new TextEncoder().encode(e).length/1024)} KB)\n`,stderr:``,exitCode:0}}else u={stdout:(o??`undefined`)+`
2615
2634
  `,stderr:``,exitCode:0};break}case`press`:{if(c.length===0){u={stdout:``,stderr:`press requires a key name
2616
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];await t.withTab(e.targetId,async()=>{let e=t.getTransport(),r=t.getSessionId();await e.send(`Input.dispatchKeyEvent`,{type:`keyDown`,key:n},r),await e.send(`Input.dispatchKeyEvent`,{type:`keyUp`,key:n},r)}),u={stdout:`Pressed ${n}\n`,stderr:``,exitCode:0};break}case`go-back`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`history.back()`)}),i.snapshots.delete(e.targetId),u={stdout:`Navigated back
2617
- `,stderr:``,exitCode:0};break}case`go-forward`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`history.forward()`)}),i.snapshots.delete(e.targetId),u={stdout:`Navigated forward
2618
- `,stderr:``,exitCode:0};break}case`reload`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.sendCDP(`Page.reload`)}),u={stdout:`Reloaded
2619
- `,stderr:``,exitCode:0};break}case`tab-list`:{let e=await uU(t,i);if(e.length===0){u={stdout:`No tabs open
2635
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];await t.withTab(e.targetId,async()=>{let e=t.getTransport(),r=t.getSessionId();await e.send(`Input.dispatchKeyEvent`,{type:`keyDown`,key:n},r),await e.send(`Input.dispatchKeyEvent`,{type:`keyUp`,key:n},r)}),u={stdout:`Pressed ${n}\n`,stderr:``,exitCode:0};break}case`go-back`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`history.back()`)}),i.snapshots.delete(e.targetId),u={stdout:`Navigated back
2636
+ `,stderr:``,exitCode:0};break}case`go-forward`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`history.forward()`)}),i.snapshots.delete(e.targetId),u={stdout:`Navigated forward
2637
+ `,stderr:``,exitCode:0};break}case`reload`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.sendCDP(`Page.reload`)}),u={stdout:`Reloaded
2638
+ `,stderr:``,exitCode:0};break}case`tab-list`:{let e=await dU(t,i);if(e.length===0){u={stdout:`No tabs open
2620
2639
  `,stderr:``,exitCode:0};break}u={stdout:e.map(e=>{let t=!!e.active,n=e.targetId.includes(`:`),r=t?` (active)`:``,i=n?` [remote:${e.targetId.substring(0,e.targetId.indexOf(`:`))}]`:``;return`[${e.targetId}] ${e.url} "${e.title}"${r}${i}`}).join(`
2621
2640
  `)+`
2622
- `,stderr:``,exitCode:0};break}case`tab-close`:case`close`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.closePage(e.targetId),i.snapshots.delete(e.targetId),i.teleportWatchers.delete(e.targetId),u={stdout:`Closed tab ${e.targetId}\n`,stderr:``,exitCode:0};break}case`dblclick`:{if(c.length===0){u={stdout:``,stderr:`dblclick requires a ref (e.g. e5)
2623
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c[1]||`left`;u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let o=a.refToBackendNodeId.get(n);if(!o)throw Error(`Unknown ref "${n}"`);return await t.dblclickByBackendNodeId(o,r),i.snapshots.delete(e.targetId),`Double-clicked ${n}`})+`
2641
+ `,stderr:``,exitCode:0};break}case`tab-close`:case`close`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.closePage(e.targetId),i.snapshots.delete(e.targetId),i.teleportWatchers.delete(e.targetId),u={stdout:`Closed tab ${e.targetId}\n`,stderr:``,exitCode:0};break}case`dblclick`:{if(c.length===0){u={stdout:``,stderr:`dblclick requires a ref (e.g. e5)
2642
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c[1]||`left`;u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:o}=UH(n),s=a.refToFrameId?.get(n);if(o&&s){let r=a.refToSelector.get(n);if(!r)throw Error(`Unknown ref "${n}" in iframe`);let o=r.split(`,`)[0].trim();return await t.evaluateInFrame(s,`(function() {
2643
+ var el = document.querySelector(${JSON.stringify(o)});
2644
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2645
+ el.scrollIntoView({ block: 'center' });
2646
+ el.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }));
2647
+ })()`),i.snapshots.delete(e.targetId),`Double-clicked ${n} (in iframe)`}let c=a.refToBackendNodeId.get(n);if(!c)throw Error(`Unknown ref "${n}"`);return await t.dblclickByBackendNodeId(c,r),i.snapshots.delete(e.targetId),`Double-clicked ${n}`})+`
2624
2648
  `,stderr:``,exitCode:0};break}case`hover`:{if(c.length===0){u={stdout:``,stderr:`hover requires a ref (e.g. e5)
2625
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let a=r.refToBackendNodeId.get(n);if(!a)throw Error(`Unknown ref "${n}"`);return await t.hoverByBackendNodeId(a),`Hovered ${n}`})+`
2649
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:a}=UH(n),o=r.refToFrameId?.get(n);if(a&&o){let e=r.refToSelector.get(n);if(!e)throw Error(`Unknown ref "${n}" in iframe`);let i=e.split(`,`)[0].trim();return await t.evaluateInFrame(o,`(function() {
2650
+ var el = document.querySelector(${JSON.stringify(i)});
2651
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2652
+ el.scrollIntoView({ block: 'center' });
2653
+ el.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
2654
+ })()`),`Hovered ${n} (in iframe)`}let s=r.refToBackendNodeId.get(n);if(!s)throw Error(`Unknown ref "${n}"`);return await t.hoverByBackendNodeId(s),`Hovered ${n}`})+`
2626
2655
  `,stderr:``,exitCode:0};break}case`select`:{if(c.length<2){u={stdout:``,stderr:`select requires <ref> <value>
2627
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c.slice(1).join(` `);u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let o=a.refToBackendNodeId.get(n);if(!o)throw Error(`Unknown ref "${n}"`);return await t.selectByBackendNodeId(o,r),i.snapshots.delete(e.targetId),`Selected "${r}" on ${n}`})+`
2656
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c.slice(1).join(` `);u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:o}=UH(n),s=a.refToFrameId?.get(n);if(o&&s){let o=a.refToSelector.get(n);if(!o)throw Error(`Unknown ref "${n}" in iframe`);let c=o.split(`,`)[0].trim();return await t.evaluateInFrame(s,`(function() {
2657
+ var el = document.querySelector(${JSON.stringify(c)});
2658
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2659
+ el.value = ${JSON.stringify(r)};
2660
+ el.dispatchEvent(new Event('change', { bubbles: true }));
2661
+ })()`),i.snapshots.delete(e.targetId),`Selected "${r}" on ${n} (in iframe)`}let c=a.refToBackendNodeId.get(n);if(!c)throw Error(`Unknown ref "${n}"`);return await t.selectByBackendNodeId(c,r),i.snapshots.delete(e.targetId),`Selected "${r}" on ${n}`})+`
2628
2662
  `,stderr:``,exitCode:0};break}case`check`:{if(c.length===0){u={stdout:``,stderr:`check requires a ref (e.g. e5)
2629
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let a=r.refToBackendNodeId.get(n);if(!a)throw Error(`Unknown ref "${n}"`);let o=await t.setCheckedByBackendNodeId(a,!0);return o===`toggled`&&i.snapshots.delete(e.targetId),o===`already`?`${n} already checked`:`Checked ${n}`})+`
2663
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:a}=UH(n),o=r.refToFrameId?.get(n);if(a&&o){let a=r.refToSelector.get(n);if(!a)throw Error(`Unknown ref "${n}" in iframe`);let s=a.split(`,`)[0].trim();return await t.evaluateInFrame(o,`(function() {
2664
+ var el = document.querySelector(${JSON.stringify(s)});
2665
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2666
+ if (!el.checked) {
2667
+ el.checked = true;
2668
+ el.dispatchEvent(new Event('change', { bubbles: true }));
2669
+ el.dispatchEvent(new MouseEvent('click', { bubbles: true }));
2670
+ }
2671
+ })()`),i.snapshots.delete(e.targetId),`Checked ${n} (in iframe)`}let s=r.refToBackendNodeId.get(n);if(!s)throw Error(`Unknown ref "${n}"`);let c=await t.setCheckedByBackendNodeId(s,!0);return c===`toggled`&&i.snapshots.delete(e.targetId),c===`already`?`${n} already checked`:`Checked ${n}`})+`
2630
2672
  `,stderr:``,exitCode:0};break}case`uncheck`:{if(c.length===0){u={stdout:``,stderr:`uncheck requires a ref (e.g. e5)
2631
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let a=r.refToBackendNodeId.get(n);if(!a)throw Error(`Unknown ref "${n}"`);let o=await t.setCheckedByBackendNodeId(a,!1);return o===`toggled`&&i.snapshots.delete(e.targetId),o===`already`?`${n} already unchecked`:`Unchecked ${n}`})+`
2673
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let r=i.snapshots.get(e.targetId);if(!r)throw Error(`No snapshot available. Run "snapshot" first.`);let{isIframe:a}=UH(n),o=r.refToFrameId?.get(n);if(a&&o){let a=r.refToSelector.get(n);if(!a)throw Error(`Unknown ref "${n}" in iframe`);let s=a.split(`,`)[0].trim();return await t.evaluateInFrame(o,`(function() {
2674
+ var el = document.querySelector(${JSON.stringify(s)});
2675
+ if (!el) throw new Error('Element not found in iframe for ref ${n}');
2676
+ if (el.checked) {
2677
+ el.checked = false;
2678
+ el.dispatchEvent(new Event('change', { bubbles: true }));
2679
+ el.dispatchEvent(new MouseEvent('click', { bubbles: true }));
2680
+ }
2681
+ })()`),i.snapshots.delete(e.targetId),`Unchecked ${n} (in iframe)`}let s=r.refToBackendNodeId.get(n);if(!s)throw Error(`Unknown ref "${n}"`);let c=await t.setCheckedByBackendNodeId(s,!1);return c===`toggled`&&i.snapshots.delete(e.targetId),c===`already`?`${n} already unchecked`:`Unchecked ${n}`})+`
2632
2682
  `,stderr:``,exitCode:0};break}case`drag`:{if(c.length<2){u={stdout:``,stderr:`drag requires <startRef> <endRef>
2633
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c[1];u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let o=a.refToBackendNodeId.get(n),s=a.refToBackendNodeId.get(r);if(!o)throw Error(`Unknown ref "${n}"`);if(!s)throw Error(`Unknown ref "${r}"`);return await t.dragByBackendNodeIds(o,s),i.snapshots.delete(e.targetId),`Dragged ${n} to ${r}`})+`
2683
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0],r=c[1];u={stdout:await t.withTab(e.targetId,async()=>{let a=i.snapshots.get(e.targetId);if(!a)throw Error(`No snapshot available. Run "snapshot" first.`);let o=a.refToBackendNodeId.get(n),s=a.refToBackendNodeId.get(r);if(!o)throw Error(`Unknown ref "${n}"`);if(!s)throw Error(`Unknown ref "${r}"`);return await t.dragByBackendNodeIds(o,s),i.snapshots.delete(e.targetId),`Dragged ${n} to ${r}`})+`
2634
2684
  `,stderr:``,exitCode:0};break}case`resize`:{if(c.length<2){u={stdout:``,stderr:`resize requires <width> <height>
2635
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=parseInt(c[0],10),r=parseInt(c[1],10);if(isNaN(n)||isNaN(r)||n<=0||r<=0){u={stdout:``,stderr:`resize requires positive integer width and height
2636
- `,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=t.getTransport(),i=t.getSessionId();await e.send(`Emulation.setDeviceMetricsOverride`,{width:n,height:r,deviceScaleFactor:1,mobile:!1},i)}),i.snapshots.delete(e.targetId),u={stdout:`Resized viewport to ${n}x${r}\n`,stderr:``,exitCode:0};break}case`dialog-accept`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.length>0?c.join(` `):void 0;await t.withTab(e.targetId,async()=>{let e=t.getTransport(),r=t.getSessionId();await e.send(`Page.enable`,{},r),await e.send(`Page.handleJavaScriptDialog`,{accept:!0,...n===void 0?{}:{promptText:n}},r)}),u={stdout:`Accepted dialog${n?` with "${n}"`:``}\n`,stderr:``,exitCode:0};break}case`dialog-dismiss`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=t.getTransport(),n=t.getSessionId();await e.send(`Page.enable`,{},n),await e.send(`Page.handleJavaScriptDialog`,{accept:!1},n)}),u={stdout:`Dismissed dialog
2637
- `,stderr:``,exitCode:0};break}case`cookie-list`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=(await t.sendCDP(`Network.getCookies`)).cookies??[];return e.length===0?`No cookies`:e.map(e=>`${e.name}=${e.value}\tDomain=${e.domain}\tPath=${e.path}\tSecure=${e.secure}\tHttpOnly=${e.httpOnly}\tExpires=${e.expires}`).join(`
2685
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=parseInt(c[0],10),r=parseInt(c[1],10);if(isNaN(n)||isNaN(r)||n<=0||r<=0){u={stdout:``,stderr:`resize requires positive integer width and height
2686
+ `,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=t.getTransport(),i=t.getSessionId();await e.send(`Emulation.setDeviceMetricsOverride`,{width:n,height:r,deviceScaleFactor:1,mobile:!1},i)}),i.snapshots.delete(e.targetId),u={stdout:`Resized viewport to ${n}x${r}\n`,stderr:``,exitCode:0};break}case`dialog-accept`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c.length>0?c.join(` `):void 0;await t.withTab(e.targetId,async()=>{let e=t.getTransport(),r=t.getSessionId();await e.send(`Page.enable`,{},r),await e.send(`Page.handleJavaScriptDialog`,{accept:!0,...n===void 0?{}:{promptText:n}},r)}),u={stdout:`Accepted dialog${n?` with "${n}"`:``}\n`,stderr:``,exitCode:0};break}case`dialog-dismiss`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=t.getTransport(),n=t.getSessionId();await e.send(`Page.enable`,{},n),await e.send(`Page.handleJavaScriptDialog`,{accept:!1},n)}),u={stdout:`Dismissed dialog
2687
+ `,stderr:``,exitCode:0};break}case`cookie-list`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=(await t.sendCDP(`Network.getCookies`)).cookies??[];return e.length===0?`No cookies`:e.map(e=>`${e.name}=${e.value}\tDomain=${e.domain}\tPath=${e.path}\tSecure=${e.secure}\tHttpOnly=${e.httpOnly}\tExpires=${e.expires}`).join(`
2638
2688
  `)})+`
2639
2689
  `,stderr:``,exitCode:0};break}case`cookie-get`:{if(c.length===0){u={stdout:``,stderr:`cookie-get requires a cookie name
2640
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let e=((await t.sendCDP(`Network.getCookies`)).cookies??[]).filter(e=>e.name===n);if(e.length===0)throw Error(`Cookie "${n}" not found`);return e.map(e=>`${e.name}=${e.value}\tDomain=${e.domain}\tPath=${e.path}\tSecure=${e.secure}\tHttpOnly=${e.httpOnly}\tExpires=${e.expires}`).join(`
2690
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}let n=c[0];u={stdout:await t.withTab(e.targetId,async()=>{let e=((await t.sendCDP(`Network.getCookies`)).cookies??[]).filter(e=>e.name===n);if(e.length===0)throw Error(`Cookie "${n}" not found`);return e.map(e=>`${e.name}=${e.value}\tDomain=${e.domain}\tPath=${e.path}\tSecure=${e.secure}\tHttpOnly=${e.httpOnly}\tExpires=${e.expires}`).join(`
2641
2691
  `)})+`
2642
2692
  `,stderr:``,exitCode:0};break}case`cookie-set`:{if(c.length<2){u={stdout:``,stderr:`cookie-set requires <name> <value>
2643
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=await $H(t),n={name:c[0],value:c[1]};l.domain&&(n.domain=l.domain),l.path&&(n.path=l.path),l.secure===`true`&&(n.secure=!0),l.httpOnly===`true`&&(n.httpOnly=!0),l.expires&&(n.expires=parseFloat(l.expires)),!n.domain&&!n.path&&(n.url=e.href),await t.sendCDP(`Network.setCookie`,n)}),u={stdout:`Cookie "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`cookie-delete`:{if(c.length===0){u={stdout:``,stderr:`cookie-delete requires a cookie name
2644
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e={name:c[0]};l.domain&&(e.domain=l.domain),l.path&&(e.path=l.path),!e.domain&&!e.path&&(e.url=(await $H(t)).href),await t.sendCDP(`Network.deleteCookies`,e)}),u={stdout:`Cookie "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`cookie-clear`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.sendCDP(`Network.clearBrowserCookies`)}),u={stdout:`All cookies cleared
2645
- `,stderr:``,exitCode:0};break}case`localstorage-list`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`JSON.stringify(Object.entries(localStorage))`),n=JSON.parse(e);return n.length===0?`No localStorage entries`:n.map(([e,t])=>`${e}=${t}`).join(`
2693
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=await eU(t),n={name:c[0],value:c[1]};l.domain&&(n.domain=l.domain),l.path&&(n.path=l.path),l.secure===`true`&&(n.secure=!0),l.httpOnly===`true`&&(n.httpOnly=!0),l.expires&&(n.expires=parseFloat(l.expires)),!n.domain&&!n.path&&(n.url=e.href),await t.sendCDP(`Network.setCookie`,n)}),u={stdout:`Cookie "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`cookie-delete`:{if(c.length===0){u={stdout:``,stderr:`cookie-delete requires a cookie name
2694
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e={name:c[0]};l.domain&&(e.domain=l.domain),l.path&&(e.path=l.path),!e.domain&&!e.path&&(e.url=(await eU(t)).href),await t.sendCDP(`Network.deleteCookies`,e)}),u={stdout:`Cookie "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`cookie-clear`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.sendCDP(`Network.clearBrowserCookies`)}),u={stdout:`All cookies cleared
2695
+ `,stderr:``,exitCode:0};break}case`localstorage-list`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`JSON.stringify(Object.entries(localStorage))`),n=JSON.parse(e);return n.length===0?`No localStorage entries`:n.map(([e,t])=>`${e}=${t}`).join(`
2646
2696
  `)})+`
2647
2697
  `,stderr:``,exitCode:0};break}case`localstorage-get`:{if(c.length===0){u={stdout:``,stderr:`localstorage-get requires a key
2648
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`localStorage.getItem(${JSON.stringify(c[0])})`);if(e===null)throw Error(`Key "${c[0]}" not found in localStorage`);return e})+`
2698
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`localStorage.getItem(${JSON.stringify(c[0])})`);if(e===null)throw Error(`Key "${c[0]}" not found in localStorage`);return e})+`
2649
2699
  `,stderr:``,exitCode:0};break}case`localstorage-set`:{if(c.length<2){u={stdout:``,stderr:`localstorage-set requires <key> <value>
2650
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.setItem(${JSON.stringify(c[0])}, ${JSON.stringify(c.slice(1).join(` `))})`)}),u={stdout:`localStorage "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`localstorage-delete`:{if(c.length===0){u={stdout:``,stderr:`localstorage-delete requires a key
2651
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.removeItem(${JSON.stringify(c[0])})`)}),u={stdout:`localStorage "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`localstorage-clear`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.clear()`)}),u={stdout:`localStorage cleared
2652
- `,stderr:``,exitCode:0};break}case`sessionstorage-list`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`JSON.stringify(Object.entries(sessionStorage))`),n=JSON.parse(e);return n.length===0?`No sessionStorage entries`:n.map(([e,t])=>`${e}=${t}`).join(`
2700
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.setItem(${JSON.stringify(c[0])}, ${JSON.stringify(c.slice(1).join(` `))})`)}),u={stdout:`localStorage "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`localstorage-delete`:{if(c.length===0){u={stdout:``,stderr:`localstorage-delete requires a key
2701
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.removeItem(${JSON.stringify(c[0])})`)}),u={stdout:`localStorage "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`localstorage-clear`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`localStorage.clear()`)}),u={stdout:`localStorage cleared
2702
+ `,stderr:``,exitCode:0};break}case`sessionstorage-list`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`JSON.stringify(Object.entries(sessionStorage))`),n=JSON.parse(e);return n.length===0?`No sessionStorage entries`:n.map(([e,t])=>`${e}=${t}`).join(`
2653
2703
  `)})+`
2654
2704
  `,stderr:``,exitCode:0};break}case`sessionstorage-get`:{if(c.length===0){u={stdout:``,stderr:`sessionstorage-get requires a key
2655
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`sessionStorage.getItem(${JSON.stringify(c[0])})`);if(e===null)throw Error(`Key "${c[0]}" not found in sessionStorage`);return e})+`
2705
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}u={stdout:await t.withTab(e.targetId,async()=>{let e=await t.evaluate(`sessionStorage.getItem(${JSON.stringify(c[0])})`);if(e===null)throw Error(`Key "${c[0]}" not found in sessionStorage`);return e})+`
2656
2706
  `,stderr:``,exitCode:0};break}case`sessionstorage-set`:{if(c.length<2){u={stdout:``,stderr:`sessionstorage-set requires <key> <value>
2657
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.setItem(${JSON.stringify(c[0])}, ${JSON.stringify(c.slice(1).join(` `))})`)}),u={stdout:`sessionStorage "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`sessionstorage-delete`:{if(c.length===0){u={stdout:``,stderr:`sessionstorage-delete requires a key
2658
- `,exitCode:1};break}let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.removeItem(${JSON.stringify(c[0])})`)}),u={stdout:`sessionStorage "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`sessionstorage-clear`:{let e=PU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.clear()`)}),u={stdout:`sessionStorage cleared
2659
- `,stderr:``,exitCode:0};break}case`record`:{let e=c[0]||`about:blank`,r=l.filter;await oU(t,i);let a=await t.createPage(e),o=t.getTransport(),s=(await o.send(`Target.attachToTarget`,{targetId:a,flatten:!0})).sessionId;i.harRecorder||=new Te(o,n);let d=await i.harRecorder.startRecording(a,s,r);u={stdout:`Recording started (targetId: ${a}, recordingId: ${d}) at ${e}\nHAR saved to /recordings/${d}/\n`,stderr:``,exitCode:0};break}case`stop-recording`:{if(c.length===0){u={stdout:``,stderr:`stop-recording requires a recordingId
2660
- `,exitCode:1};break}let e=c[0];if(!i.harRecorder){u={stdout:``,stderr:`Recording not found: ${e}\n`,exitCode:1};break}u={stdout:`Recording stopped. HAR files saved to ${await i.harRecorder.stopRecording(e)}\n`,stderr:``,exitCode:0};break}default:u={stdout:``,stderr:`Unknown command: ${o}\nRun "playwright-cli help" for usage.\n`,exitCode:1};break}}catch(e){u={stdout:``,stderr:`Error: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let d=l.tab??null,f=null;KH.has(o)&&u.exitCode===0&&d&&(f=await tU(t,n,i,d));try{await nU(n,i,{command:o,args:s,result:u,snapshotPath:f,targetId:d})}catch{}return u})}var IU=new Map([[`File operations`,[`ls`,`cat`,`head`,`tail`,`wc`,`touch`,`mkdir`,`rm`,`cp`,`mv`,`ln`,`chmod`,`stat`,`readlink`]],[`Text processing`,[`grep`,`sed`,`awk`,`sort`,`uniq`,`cut`,`tr`,`tee`,`diff`]],[`Search`,[`find`,`rg`]],[`Navigation & paths`,[`pwd`,`basename`,`dirname`,`tree`,`du`,`cd`]],[`Archives`,[`zip`,`unzip`,`pdftk`,`pdf`]],[`Media`,[`convert`,`magick`]],[`Audio`,[`say`,`afplay`,`chime`]],[`Environment & shell`,[`echo`,`printf`,`env`,`printenv`,`export`,`alias`,`unalias`,`history`,`clear`,`true`,`false`,`bash`,`sh`,`commands`,`which`,`uname`,`man`,`host`,`oauth-token`,`nuke`]],[`Data processing`,[`xargs`,`jq`,`base64`,`date`]],[`Network`,[`curl`,`wget`,`html-to-markdown`]],[`Version control`,[`git`]],[`Languages`,[`node`,`python`,`python3`,`sqlite3`]],[`Skills`,[`skill`,`upskill`]],[`Browser & UI`,[`serve`,`open`,`imgcat`,...WH,`webhook`]],[`Filesystem`,[`mount`]]]);function LU(e,t=[]){let n=[],r=new Set(e);n.push(`Available commands:
2661
- `);let i=[];for(let[e,t]of IU){let i=t.filter(e=>r.has(e));if(i.length>0){n.push(` ${e}:`),n.push(` ${i.join(`, `)}\n`);for(let e of i)r.delete(e)}}for(let e of r)i.push(e);return i.length>0&&(n.push(` Other:`),n.push(` ${i.sort().join(`, `)}\n`)),t.length>0&&(n.push(` User scripts (.jsh):`),n.push(` ${t.sort().join(`, `)}\n`)),n.push(`Use '<command> --help' for details on a specific command.`),n.join(`
2707
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.setItem(${JSON.stringify(c[0])}, ${JSON.stringify(c.slice(1).join(` `))})`)}),u={stdout:`sessionStorage "${c[0]}" set\n`,stderr:``,exitCode:0};break}case`sessionstorage-delete`:{if(c.length===0){u={stdout:``,stderr:`sessionstorage-delete requires a key
2708
+ `,exitCode:1};break}let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.removeItem(${JSON.stringify(c[0])})`)}),u={stdout:`sessionStorage "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`sessionstorage-clear`:{let e=FU(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{await t.evaluate(`sessionStorage.clear()`)}),u={stdout:`sessionStorage cleared
2709
+ `,stderr:``,exitCode:0};break}case`record`:{let e=c[0]||`about:blank`,r=l.filter;await sU(t,i);let a=await t.createPage(e),o=t.getTransport(),s=(await o.send(`Target.attachToTarget`,{targetId:a,flatten:!0})).sessionId;i.harRecorder||=new Te(o,n);let d=await i.harRecorder.startRecording(a,s,r);u={stdout:`Recording started (targetId: ${a}, recordingId: ${d}) at ${e}\nHAR saved to /recordings/${d}/\n`,stderr:``,exitCode:0};break}case`stop-recording`:{if(c.length===0){u={stdout:``,stderr:`stop-recording requires a recordingId
2710
+ `,exitCode:1};break}let e=c[0];if(!i.harRecorder){u={stdout:``,stderr:`Recording not found: ${e}\n`,exitCode:1};break}u={stdout:`Recording stopped. HAR files saved to ${await i.harRecorder.stopRecording(e)}\n`,stderr:``,exitCode:0};break}default:u={stdout:``,stderr:`Unknown command: ${o}\nRun "playwright-cli help" for usage.\n`,exitCode:1};break}}catch(e){u={stdout:``,stderr:`Error: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let d=l.tab??null,f=null;qH.has(o)&&u.exitCode===0&&d&&(f=await nU(t,n,i,d));try{await rU(n,i,{command:o,args:s,result:u,snapshotPath:f,targetId:d})}catch{}return u})}var LU=new Map([[`File operations`,[`ls`,`cat`,`head`,`tail`,`wc`,`touch`,`mkdir`,`rm`,`cp`,`mv`,`ln`,`chmod`,`stat`,`readlink`]],[`Text processing`,[`grep`,`sed`,`awk`,`sort`,`uniq`,`cut`,`tr`,`tee`,`diff`]],[`Search`,[`find`,`rg`]],[`Navigation & paths`,[`pwd`,`basename`,`dirname`,`tree`,`du`,`cd`]],[`Archives`,[`zip`,`unzip`,`pdftk`,`pdf`]],[`Media`,[`convert`,`magick`]],[`Audio`,[`say`,`afplay`,`chime`]],[`Environment & shell`,[`echo`,`printf`,`env`,`printenv`,`export`,`alias`,`unalias`,`history`,`clear`,`true`,`false`,`bash`,`sh`,`commands`,`which`,`uname`,`man`,`host`,`oauth-token`,`nuke`,`models`]],[`Data processing`,[`xargs`,`jq`,`base64`,`date`]],[`Network`,[`curl`,`wget`,`html-to-markdown`]],[`Version control`,[`git`]],[`Languages`,[`node`,`python`,`python3`,`sqlite3`]],[`Skills`,[`skill`,`upskill`]],[`Browser & UI`,[`serve`,`open`,`imgcat`,...GH,`webhook`]],[`Filesystem`,[`mount`]]]);function RU(e,t=[]){let n=[],r=new Set(e);n.push(`Available commands:
2711
+ `);let i=[];for(let[e,t]of LU){let i=t.filter(e=>r.has(e));if(i.length>0){n.push(` ${e}:`),n.push(` ${i.join(`, `)}\n`);for(let e of i)r.delete(e)}}for(let e of r)i.push(e);return i.length>0&&(n.push(` Other:`),n.push(` ${i.sort().join(`, `)}\n`)),t.length>0&&(n.push(` User scripts (.jsh):`),n.push(` ${t.sort().join(`, `)}\n`)),n.push(`Use '<command> --help' for details on a specific command.`),n.join(`
2662
2712
  `)+`
2663
- `}function RU(e={}){return $P(`commands`,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return{stdout:`commands - display available commands
2713
+ `}function zU(e={}){return $P(`commands`,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return{stdout:`commands - display available commands
2664
2714
 
2665
2715
  Usage: commands [command]
2666
2716
 
@@ -2671,7 +2721,7 @@ If a command name is provided, shows help for that command.
2671
2721
  Otherwise, lists all available commands.
2672
2722
 
2673
2723
  Note: This is an enhanced version of 'help' that shows all custom commands.
2674
- `,stderr:``,exitCode:0};if(t.length>0&&n.exec){let e=t[0];return n.exec(`${e} --help`,{cwd:n.cwd})}return{stdout:LU(n.getRegisteredCommands?.()??[],await e.getJshCommands?.()??[]),stderr:``,exitCode:0}})}function zU(e){let t=e.toLowerCase();return t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)?`JPEG`:t.endsWith(`.png`)?`PNG`:t.endsWith(`.gif`)?`GIF`:t.endsWith(`.webp`)?`WEBP`:t.endsWith(`.bmp`)?`BMP`:t.endsWith(`.tiff`)||t.endsWith(`.tif`)?`TIFF`:t.endsWith(`.avif`)?`AVIF`:`PNG`}function BU(){return{stdout:`usage: convert [input] [operations...] [output]
2724
+ `,stderr:``,exitCode:0};if(t.length>0&&n.exec){let e=t[0];return n.exec(`${e} --help`,{cwd:n.cwd})}return{stdout:RU(n.getRegisteredCommands?.()??[],await e.getJshCommands?.()??[]),stderr:``,exitCode:0}})}function BU(e){let t=e.toLowerCase();return t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)?`JPEG`:t.endsWith(`.png`)?`PNG`:t.endsWith(`.gif`)?`GIF`:t.endsWith(`.webp`)?`WEBP`:t.endsWith(`.bmp`)?`BMP`:t.endsWith(`.tiff`)||t.endsWith(`.tif`)?`TIFF`:t.endsWith(`.avif`)?`AVIF`:`PNG`}function VU(){return{stdout:`usage: convert [input] [operations...] [output]
2675
2725
 
2676
2726
  Operations:
2677
2727
  -resize WxH resize to width x height
@@ -2686,7 +2736,7 @@ Examples:
2686
2736
  convert photo.png -resize 50% smaller.png
2687
2737
  convert image.jpg -rotate 90 -quality 85 rotated.jpg
2688
2738
  convert input.png -crop 100x100+50+50 cropped.png
2689
- `,stderr:``,exitCode:0}}function VU(e=`convert`){return $P(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return BU();let r=[],i=[],a=0;for(;a<t.length;){let n=t[a];if(n===`-resize`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -resize\n`,exitCode:1};i.push({type:`resize`,value:t[a+1]}),a+=2}else if(n===`-rotate`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -rotate\n`,exitCode:1};i.push({type:`rotate`,value:t[a+1]}),a+=2}else if(n===`-crop`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -crop\n`,exitCode:1};i.push({type:`crop`,value:t[a+1]}),a+=2}else if(n===`-quality`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -quality\n`,exitCode:1};i.push({type:`quality`,value:t[a+1]}),a+=2}else if(n.startsWith(`-`))return{stdout:``,stderr:`${e}: unsupported option ${n}\n`,exitCode:1};else r.push(n),a++}if(r.length!==2)return{stdout:``,stderr:`${e}: expected exactly one input file and one output file\n`,exitCode:1};let o=r[0],s=r[1];try{let e=n.fs.resolvePath(n.cwd,o),t=await n.fs.readFileBuffer(e),r=await Qe(),a=null;if(await r.ImageMagick.read(t,async e=>{for(let t of i)switch(t.type){case`resize`:{let n=t.value.match(/^(\d+)%$/);if(n){let t=parseInt(n[1],10),r=Math.round(e.width*t/100),i=Math.round(e.height*t/100);e.resize(r,i)}else{let n=t.value.endsWith(`!`),i=(n?t.value.slice(0,-1):t.value).split(`x`);if(i.length===2){let t=parseInt(i[0],10),a=parseInt(i[1],10);if(n){let n=new r.MagickGeometry(t,a);n.ignoreAspectRatio=!0,e.resize(n)}else e.resize(t,a)}else throw Error(`Invalid resize format: ${t.value}`)}break}case`rotate`:{let n=parseFloat(t.value);if(isNaN(n))throw Error(`Invalid rotation degrees: ${t.value}`);e.rotate(n);break}case`crop`:{if(!t.value.match(/^(\d+)x(\d+)\+(\d+)\+(\d+)$/))throw Error(`Invalid crop format: ${t.value} (expected WxH+X+Y)`);let n=new r.MagickGeometry(t.value);e.crop(n);break}case`quality`:{let n=parseInt(t.value,10);if(isNaN(n)||n<0||n>100)throw Error(`Invalid quality: ${t.value} (must be 0-100)`);e.quality=n;break}}let t=zU(s);e.write(t,e=>{a=e})}),!a)throw Error(`Failed to generate output image`);let c=n.fs.resolvePath(n.cwd,s);return await n.fs.writeFile(c,a),{stdout:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}var HU=r(`tray-leader`),UU=`leader-tray-session`,WU=3e4,GU=1e4,KU={state:`inactive`,session:null,error:null};function qU(){return{...KU,session:KU.session?{...KU.session}:null}}function JU(e){KU={...e,session:e.session?{...e.session}:null}}var YU=class{constructor(e=UU){this.key=e}async load(){return XU(await Ue(this.key))}async save(e){await A(this.key,JSON.stringify(e))}async clear(){await A(this.key,``)}};function XU(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.workerBaseUrl!=`string`||typeof t.trayId!=`string`||typeof t.createdAt!=`string`||typeof t.controllerId!=`string`||typeof t.controllerUrl!=`string`||typeof t.joinUrl!=`string`||typeof t.webhookUrl!=`string`||typeof t.runtime!=`string`?null:{workerBaseUrl:t.workerBaseUrl,trayId:t.trayId,createdAt:t.createdAt,controllerId:t.controllerId,controllerUrl:t.controllerUrl,joinUrl:t.joinUrl,webhookUrl:t.webhookUrl,leaderKey:typeof t.leaderKey==`string`?t.leaderKey:void 0,leaderWebSocketUrl:typeof t.leaderWebSocketUrl==`string`?t.leaderWebSocketUrl:null,runtime:t.runtime}}catch{return null}}var ZU=class{store;fetchImpl;webSocketFactory;pingIntervalMs;connectTimeoutMs;socket=null;pingTimer=null;currentSession=null;constructor(e){this.options=e,this.store=e.store??new YU,this.fetchImpl=e.fetchImpl??tW(),this.webSocketFactory=e.webSocketFactory??(e=>new WebSocket(e)),this.pingIntervalMs=e.pingIntervalMs??WU,this.connectTimeoutMs=e.connectTimeoutMs??GU}async start(){if(this.currentSession&&this.socket)return JU({state:`leader`,session:this.currentSession,error:null}),this.currentSession;JU({state:`connecting`,session:null,error:null}),this.currentSession=null;try{let e=await this.store.load(),t=e?.workerBaseUrl===this.options.workerBaseUrl?e:null,n=await this.attachWithRecovery(t);this.currentSession=n;let r=await this.openLeaderSocket(n.leaderWebSocketUrl);return this.socket=r,this.startPingLoop(r),JU({state:`leader`,session:n,error:null}),HU.info(`Leader joined tray`,{trayId:n.trayId,controllerId:n.controllerId,runtime:n.runtime}),n}catch(e){throw JU({state:`error`,session:this.currentSession,error:e instanceof Error?e.message:String(e)}),e}}stop(){if(this.pingTimer&&=(clearInterval(this.pingTimer),null),this.socket){try{this.socket.close()}catch{}this.socket=null}this.currentSession=null,JU({state:`inactive`,session:null,error:null})}async clearSession(){await this.store.clear()}sendControlMessage(e){if(!this.socket)throw Error(`Tray leader WebSocket is not connected`);this.socket.send(JSON.stringify(e))}async attachWithRecovery(e){try{return await this.claimLeaderSession(e)}catch(t){if(!e||!$U(t))throw t;return HU.warn(`Stored tray session is stale, creating a fresh tray`,{trayId:e.trayId,error:t instanceof Error?t.message:String(t)}),await this.store.clear(),this.claimLeaderSession(null)}}async claimLeaderSession(e){let t=e??await this.createTraySession(),n=await this.fetchJson(t.controllerUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:t.controllerId,leaderKey:t.leaderKey,runtime:this.options.runtime})});if(n.role!==`leader`||!n.leaderKey||!n.websocket?.url)throw Error(`Tray attach did not return leader access for controller ${n.controllerId}`);let r={...t,trayId:n.trayId,controllerId:n.controllerId,leaderKey:n.leaderKey,leaderWebSocketUrl:n.websocket.url,runtime:this.options.runtime};return await this.store.save(r),r}async createTraySession(){let e=await this.fetchJson(m(this.options.workerBaseUrl,`tray`),{method:`POST`});return{workerBaseUrl:this.options.workerBaseUrl,trayId:e.trayId,createdAt:e.createdAt,controllerId:crypto.randomUUID(),controllerUrl:e.capabilities.controller.url,joinUrl:e.capabilities.join.url,webhookUrl:e.capabilities.webhook.url,runtime:this.options.runtime}}async openLeaderSocket(e){return await new Promise((t,n)=>{let r=this.webSocketFactory(e),i=!1,a=setTimeout(()=>{o(`Tray leader WebSocket timed out after ${this.connectTimeoutMs}ms waiting for leader.connected`);try{r.close(1e3,`leader.connected timeout`)}catch{}},this.connectTimeoutMs),o=e=>{i||(i=!0,clearTimeout(a),n(Error(e)))};r.addEventListener(`message`,e=>{let n=eW(e.data);if(n){if(n.type===`leader.connected`){i||(i=!0,clearTimeout(a),t(r));return}if(n.type===`pong`){HU.debug(`Tray leader heartbeat acknowledged`,{trayId:this.currentSession?.trayId});return}this.options.onControlMessage?.(n)}}),r.addEventListener(`close`,()=>o(`Tray leader WebSocket closed before leader.connected`)),r.addEventListener(`error`,()=>o(`Tray leader WebSocket failed before leader.connected`))})}startPingLoop(e){this.pingTimer&&clearInterval(this.pingTimer);let t=()=>{try{e.send(JSON.stringify({type:`ping`}))}catch{this.stop()}};t(),this.pingTimer=setInterval(t,this.pingIntervalMs),e.addEventListener(`close`,()=>this.stop()),e.addEventListener(`error`,()=>this.stop())}async fetchJson(e,t){let n=await this.fetchImpl(e,t);if(!n.ok)throw await QU.fromResponse(n);return await n.json()}},QU=class e extends Error{constructor(e,t,n){super(n),this.status=e,this.code=t,this.name=`LeaderTrayHttpError`}static async fromResponse(t){try{let n=await t.json();return new e(t.status,n.code??null,n.error??`Tray request failed (${t.status})`)}catch{return new e(t.status,null,`Tray request failed (${t.status})`)}}};function $U(e){return e instanceof QU&&[403,404,410].includes(e.status)}function eW(e){if(typeof e!=`string`)return null;try{return JSON.parse(e)}catch{return null}}function tW(e=fetch){return typeof chrome<`u`&&chrome?.runtime?.id?e:async(t,n={})=>{let r=typeof t==`string`?t:t.toString();try{if(new URL(r).origin===window.location.origin)return e(r,{...n,cache:`no-store`})}catch{}let i=new Headers(n.headers);i.set(`X-Target-URL`,r);let a=await e(`/api/fetch-proxy`,{...n,headers:i,cache:`no-store`});if(a.status===400||a.status===502){let e=`Proxy error ${a.status}`;try{e=(await a.json()).error??e}catch{}throw Error(e)}return a}}var nW=null;function rW(e){nW=e}function iW(){return nW?.()??[]}var aW=null;function oW(e){aW=e}function sW(){return aW??void 0}function cW(){return{stdout:`host - display or manage the current tray host status
2739
+ `,stderr:``,exitCode:0}}function HU(e=`convert`){return $P(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return VU();let r=[],i=[],a=0;for(;a<t.length;){let n=t[a];if(n===`-resize`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -resize\n`,exitCode:1};i.push({type:`resize`,value:t[a+1]}),a+=2}else if(n===`-rotate`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -rotate\n`,exitCode:1};i.push({type:`rotate`,value:t[a+1]}),a+=2}else if(n===`-crop`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -crop\n`,exitCode:1};i.push({type:`crop`,value:t[a+1]}),a+=2}else if(n===`-quality`){if(a+1>=t.length||t[a+1].startsWith(`-`))return{stdout:``,stderr:`${e}: missing argument for -quality\n`,exitCode:1};i.push({type:`quality`,value:t[a+1]}),a+=2}else if(n.startsWith(`-`))return{stdout:``,stderr:`${e}: unsupported option ${n}\n`,exitCode:1};else r.push(n),a++}if(r.length!==2)return{stdout:``,stderr:`${e}: expected exactly one input file and one output file\n`,exitCode:1};let o=r[0],s=r[1];try{let e=n.fs.resolvePath(n.cwd,o),t=await n.fs.readFileBuffer(e),r=await Qe(),a=null;if(await r.ImageMagick.read(t,async e=>{for(let t of i)switch(t.type){case`resize`:{let n=t.value.match(/^(\d+)%$/);if(n){let t=parseInt(n[1],10),r=Math.round(e.width*t/100),i=Math.round(e.height*t/100);e.resize(r,i)}else{let n=t.value.endsWith(`!`),i=(n?t.value.slice(0,-1):t.value).split(`x`);if(i.length===2){let t=parseInt(i[0],10),a=parseInt(i[1],10);if(n){let n=new r.MagickGeometry(t,a);n.ignoreAspectRatio=!0,e.resize(n)}else e.resize(t,a)}else throw Error(`Invalid resize format: ${t.value}`)}break}case`rotate`:{let n=parseFloat(t.value);if(isNaN(n))throw Error(`Invalid rotation degrees: ${t.value}`);e.rotate(n);break}case`crop`:{if(!t.value.match(/^(\d+)x(\d+)\+(\d+)\+(\d+)$/))throw Error(`Invalid crop format: ${t.value} (expected WxH+X+Y)`);let n=new r.MagickGeometry(t.value);e.crop(n);break}case`quality`:{let n=parseInt(t.value,10);if(isNaN(n)||n<0||n>100)throw Error(`Invalid quality: ${t.value} (must be 0-100)`);e.quality=n;break}}let t=BU(s);e.write(t,e=>{a=e})}),!a)throw Error(`Failed to generate output image`);let c=n.fs.resolvePath(n.cwd,s);return await n.fs.writeFile(c,a),{stdout:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}var UU=r(`tray-leader`),WU=`leader-tray-session`,GU=3e4,KU=1e4,qU={state:`inactive`,session:null,error:null};function JU(){return{...qU,session:qU.session?{...qU.session}:null}}function YU(e){qU={...e,session:e.session?{...e.session}:null}}var XU=class{constructor(e=WU){this.key=e}async load(){return ZU(await Ue(this.key))}async save(e){await A(this.key,JSON.stringify(e))}async clear(){await A(this.key,``)}};function ZU(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.workerBaseUrl!=`string`||typeof t.trayId!=`string`||typeof t.createdAt!=`string`||typeof t.controllerId!=`string`||typeof t.controllerUrl!=`string`||typeof t.joinUrl!=`string`||typeof t.webhookUrl!=`string`||typeof t.runtime!=`string`?null:{workerBaseUrl:t.workerBaseUrl,trayId:t.trayId,createdAt:t.createdAt,controllerId:t.controllerId,controllerUrl:t.controllerUrl,joinUrl:t.joinUrl,webhookUrl:t.webhookUrl,leaderKey:typeof t.leaderKey==`string`?t.leaderKey:void 0,leaderWebSocketUrl:typeof t.leaderWebSocketUrl==`string`?t.leaderWebSocketUrl:null,runtime:t.runtime}}catch{return null}}var QU=class{store;fetchImpl;webSocketFactory;pingIntervalMs;connectTimeoutMs;socket=null;pingTimer=null;currentSession=null;constructor(e){this.options=e,this.store=e.store??new XU,this.fetchImpl=e.fetchImpl??nW(),this.webSocketFactory=e.webSocketFactory??(e=>new WebSocket(e)),this.pingIntervalMs=e.pingIntervalMs??GU,this.connectTimeoutMs=e.connectTimeoutMs??KU}async start(){if(this.currentSession&&this.socket)return YU({state:`leader`,session:this.currentSession,error:null}),this.currentSession;YU({state:`connecting`,session:null,error:null}),this.currentSession=null;try{let e=await this.store.load(),t=e?.workerBaseUrl===this.options.workerBaseUrl?e:null,n=await this.attachWithRecovery(t);this.currentSession=n;let r=await this.openLeaderSocket(n.leaderWebSocketUrl);return this.socket=r,this.startPingLoop(r),YU({state:`leader`,session:n,error:null}),UU.info(`Leader joined tray`,{trayId:n.trayId,controllerId:n.controllerId,runtime:n.runtime}),n}catch(e){throw YU({state:`error`,session:this.currentSession,error:e instanceof Error?e.message:String(e)}),e}}stop(){if(this.pingTimer&&=(clearInterval(this.pingTimer),null),this.socket){try{this.socket.close()}catch{}this.socket=null}this.currentSession=null,YU({state:`inactive`,session:null,error:null})}async clearSession(){await this.store.clear()}sendControlMessage(e){if(!this.socket)throw Error(`Tray leader WebSocket is not connected`);this.socket.send(JSON.stringify(e))}async attachWithRecovery(e){try{return await this.claimLeaderSession(e)}catch(t){if(!e||!eW(t))throw t;return UU.warn(`Stored tray session is stale, creating a fresh tray`,{trayId:e.trayId,error:t instanceof Error?t.message:String(t)}),await this.store.clear(),this.claimLeaderSession(null)}}async claimLeaderSession(e){let t=e??await this.createTraySession(),n=await this.fetchJson(t.controllerUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:t.controllerId,leaderKey:t.leaderKey,runtime:this.options.runtime})});if(n.role!==`leader`||!n.leaderKey||!n.websocket?.url)throw Error(`Tray attach did not return leader access for controller ${n.controllerId}`);let r={...t,trayId:n.trayId,controllerId:n.controllerId,leaderKey:n.leaderKey,leaderWebSocketUrl:n.websocket.url,runtime:this.options.runtime};return await this.store.save(r),r}async createTraySession(){let e=await this.fetchJson(m(this.options.workerBaseUrl,`tray`),{method:`POST`});return{workerBaseUrl:this.options.workerBaseUrl,trayId:e.trayId,createdAt:e.createdAt,controllerId:crypto.randomUUID(),controllerUrl:e.capabilities.controller.url,joinUrl:e.capabilities.join.url,webhookUrl:e.capabilities.webhook.url,runtime:this.options.runtime}}async openLeaderSocket(e){return await new Promise((t,n)=>{let r=this.webSocketFactory(e),i=!1,a=setTimeout(()=>{o(`Tray leader WebSocket timed out after ${this.connectTimeoutMs}ms waiting for leader.connected`);try{r.close(1e3,`leader.connected timeout`)}catch{}},this.connectTimeoutMs),o=e=>{i||(i=!0,clearTimeout(a),n(Error(e)))};r.addEventListener(`message`,e=>{let n=tW(e.data);if(n){if(n.type===`leader.connected`){i||(i=!0,clearTimeout(a),t(r));return}if(n.type===`pong`){UU.debug(`Tray leader heartbeat acknowledged`,{trayId:this.currentSession?.trayId});return}this.options.onControlMessage?.(n)}}),r.addEventListener(`close`,()=>o(`Tray leader WebSocket closed before leader.connected`)),r.addEventListener(`error`,()=>o(`Tray leader WebSocket failed before leader.connected`))})}startPingLoop(e){this.pingTimer&&clearInterval(this.pingTimer);let t=()=>{try{e.send(JSON.stringify({type:`ping`}))}catch{this.stop()}};t(),this.pingTimer=setInterval(t,this.pingIntervalMs),e.addEventListener(`close`,()=>this.stop()),e.addEventListener(`error`,()=>this.stop())}async fetchJson(e,t){let n=await this.fetchImpl(e,t);if(!n.ok)throw await $U.fromResponse(n);return await n.json()}},$U=class e extends Error{constructor(e,t,n){super(n),this.status=e,this.code=t,this.name=`LeaderTrayHttpError`}static async fromResponse(t){try{let n=await t.json();return new e(t.status,n.code??null,n.error??`Tray request failed (${t.status})`)}catch{return new e(t.status,null,`Tray request failed (${t.status})`)}}};function eW(e){return e instanceof $U&&[403,404,410].includes(e.status)}function tW(e){if(typeof e!=`string`)return null;try{return JSON.parse(e)}catch{return null}}function nW(e=fetch){return typeof chrome<`u`&&chrome?.runtime?.id?e:async(t,n={})=>{let r=typeof t==`string`?t:t.toString();try{if(new URL(r).origin===window.location.origin)return e(r,{...n,cache:`no-store`})}catch{}let i=new Headers(n.headers);i.set(`X-Target-URL`,r);let a=await e(`/api/fetch-proxy`,{...n,headers:i,cache:`no-store`});if(a.status===400||a.status===502){let e=`Proxy error ${a.status}`;try{e=(await a.json()).error??e}catch{}throw Error(e)}return a}}var rW=null;function iW(e){rW=e}function aW(){return rW?.()??[]}var oW=null;function sW(e){oW=e}function cW(){return oW??void 0}function lW(){return{stdout:`host - display or manage the current tray host status
2690
2740
 
2691
2741
  Usage: host [reset]
2692
2742
 
@@ -2694,22 +2744,22 @@ Shows the current tray state (leader or follower) and, when available, the join
2694
2744
 
2695
2745
  Subcommands:
2696
2746
  reset Disconnect all followers and create a fresh tray session with a new join URL
2697
- `,stderr:``,exitCode:0}}function lW(e){if(e<60)return`${e}s ago`;let t=Math.floor(e/60);if(t<60)return`${t}m ago`;let n=Math.floor(t/60),r=t%60;return r===0?`${n}h ago`:`${n}h ${r}m ago`}function uW(e,t){let n=[`status: ${e.state}`];if(e.session?n.push(`join_url: ${e.session.joinUrl}`):n.push(`join_url: unavailable`),e.error&&n.push(`error: ${e.error}`),t.length>0){n.push(`followers:`);for(let e of t){let t=[e.runtimeId];if(e.runtime&&t.push(`(${e.runtime})`),e.connectedAt){let n=Math.round((Date.now()-new Date(e.connectedAt).getTime())/1e3);t.push(`connected ${lW(n)}`)}n.push(` - ${t.join(` `)}`)}}return`${n.join(`
2698
- `)}\n`}function dW(e){let t=[`status: follower (${e.state})`];if(e.joinUrl&&t.push(`join_url: ${e.joinUrl}`),e.state===`connecting`){if(e.connectingSince!=null){let n=Math.round((Date.now()-e.connectingSince)/1e3);t.push(`connecting_for: ${lW(n).replace(` ago`,``)}`)}e.attachAttempts>0&&t.push(`attach_attempts: ${e.attachAttempts}`),e.lastAttachCode&&t.push(`last_code: ${e.lastAttachCode}`)}if(e.state===`connected`&&e.lastPingTime!=null){let n=Math.round((Date.now()-e.lastPingTime)/1e3);t.push(`last_ping: ${n}s ago`)}return e.state===`reconnecting`&&e.reconnectAttempts>0&&t.push(`reconnect_attempts: ${e.reconnectAttempts}`),e.lastError&&t.push(`last_error: ${e.lastError}`),e.error&&t.push(`error: ${e.error}`),`${t.join(`
2699
- `)}\n`}function fW(e={}){let t=e.getStatus??qU,n=e.getFollowerStatus??h,r=e.getFollowers??iW;return $P(`host`,async i=>{if(i.includes(`--help`)||i.includes(`-h`))return cW();if(i[0]===`reset`)return pW(n,t,e.resetTray??sW());if(i.length>0)return{stdout:``,stderr:`host: unsupported arguments
2700
- `,exitCode:1};let a=n();return a.state===`inactive`?{stdout:uW(t(),r()),stderr:``,exitCode:0}:{stdout:dW(a),stderr:``,exitCode:0}})}async function pW(e,t,n){if(e().state!==`inactive`)return{stdout:``,stderr:`host reset: only the leader can reset the tray session
2747
+ `,stderr:``,exitCode:0}}function uW(e){if(e<60)return`${e}s ago`;let t=Math.floor(e/60);if(t<60)return`${t}m ago`;let n=Math.floor(t/60),r=t%60;return r===0?`${n}h ago`:`${n}h ${r}m ago`}function dW(e,t){let n=[`status: ${e.state}`];if(e.session?n.push(`join_url: ${e.session.joinUrl}`):n.push(`join_url: unavailable`),e.error&&n.push(`error: ${e.error}`),t.length>0){n.push(`followers:`);for(let e of t){let t=[e.runtimeId];if(e.runtime&&t.push(`(${e.runtime})`),e.connectedAt){let n=Math.round((Date.now()-new Date(e.connectedAt).getTime())/1e3);t.push(`connected ${uW(n)}`)}n.push(` - ${t.join(` `)}`)}}return`${n.join(`
2748
+ `)}\n`}function fW(e){let t=[`status: follower (${e.state})`];if(e.joinUrl&&t.push(`join_url: ${e.joinUrl}`),e.state===`connecting`){if(e.connectingSince!=null){let n=Math.round((Date.now()-e.connectingSince)/1e3);t.push(`connecting_for: ${uW(n).replace(` ago`,``)}`)}e.attachAttempts>0&&t.push(`attach_attempts: ${e.attachAttempts}`),e.lastAttachCode&&t.push(`last_code: ${e.lastAttachCode}`)}if(e.state===`connected`&&e.lastPingTime!=null){let n=Math.round((Date.now()-e.lastPingTime)/1e3);t.push(`last_ping: ${n}s ago`)}return e.state===`reconnecting`&&e.reconnectAttempts>0&&t.push(`reconnect_attempts: ${e.reconnectAttempts}`),e.lastError&&t.push(`last_error: ${e.lastError}`),e.error&&t.push(`error: ${e.error}`),`${t.join(`
2749
+ `)}\n`}function pW(e={}){let t=e.getStatus??JU,n=e.getFollowerStatus??h,r=e.getFollowers??aW;return $P(`host`,async i=>{if(i.includes(`--help`)||i.includes(`-h`))return lW();if(i[0]===`reset`)return mW(n,t,e.resetTray??cW());if(i.length>0)return{stdout:``,stderr:`host: unsupported arguments
2750
+ `,exitCode:1};let a=n();return a.state===`inactive`?{stdout:dW(t(),r()),stderr:``,exitCode:0}:{stdout:fW(a),stderr:``,exitCode:0}})}async function mW(e,t,n){if(e().state!==`inactive`)return{stdout:``,stderr:`host reset: only the leader can reset the tray session
2701
2751
  `,exitCode:1};let r=t();if(r.state!==`leader`&&r.state!==`error`)return{stdout:``,stderr:`host reset: no active tray session to reset
2702
2752
  `,exitCode:1};if(!n)return{stdout:``,stderr:`host reset: tray reset is not available in this environment
2703
2753
  `,exitCode:1};try{return{stdout:`Tray session reset. All followers disconnected.
2704
- `+uW(await n(),[]),stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`host reset: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function mW(){return{stdout:`imgcat - preview image and video files in the preview tab
2754
+ `+dW(await n(),[]),stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`host reset: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function hW(){return{stdout:`imgcat - preview image and video files in the preview tab
2705
2755
 
2706
2756
  Usage: imgcat <path> [path...]
2707
2757
 
2708
2758
  Options:
2709
2759
  -h, --help Show this help message
2710
- `,stderr:``,exitCode:0}}function hW(e={}){return $P(`imgcat`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return mW();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`imgcat: browser APIs are unavailable in this environment
2760
+ `,stderr:``,exitCode:0}}function gW(e={}){return $P(`imgcat`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return hW();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`imgcat: browser APIs are unavailable in this environment
2711
2761
  `,exitCode:1};if(!e.onMediaPreview)return{stdout:``,stderr:`imgcat: terminal preview is unavailable
2712
- `,exitCode:1};let r=[];for(let e of t){let t=n.fs.resolvePath(n.cwd,e);if(!(await n.fs.stat(t)).isFile)return{stdout:``,stderr:`imgcat: not a file: ${e}\n`,exitCode:1};let i=a(t);if(!l(i))return{stdout:``,stderr:`imgcat: unsupported media type: ${e}\n`,exitCode:1};let o=await n.fs.readFileBuffer(t),s=new Uint8Array(o.byteLength);s.set(o),r.push({path:t,mimeType:i,bytes:s})}try{return await e.onMediaPreview(r),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`imgcat: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}var gW=`https://sql.js.org/dist/`,_W=`https://cdn.jsdelivr.net/pyodide/v0.27.7/full/`,vW=`v20.0.0-js-shim`,yW=`
2762
+ `,exitCode:1};let r=[];for(let e of t){let t=n.fs.resolvePath(n.cwd,e);if(!(await n.fs.stat(t)).isFile)return{stdout:``,stderr:`imgcat: not a file: ${e}\n`,exitCode:1};let i=a(t);if(!l(i))return{stdout:``,stderr:`imgcat: unsupported media type: ${e}\n`,exitCode:1};let o=await n.fs.readFileBuffer(t),s=new Uint8Array(o.byteLength);s.set(o),r.push({path:t,mimeType:i,bytes:s})}try{return await e.onMediaPreview(r),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`imgcat: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}var _W=`https://sql.js.org/dist/`,vW=`https://cdn.jsdelivr.net/pyodide/v0.27.7/full/`,yW=`v20.0.0-js-shim`,bW=`
2713
2763
  import sys
2714
2764
  import traceback
2715
2765
 
@@ -2729,10 +2779,10 @@ except SystemExit as exc:
2729
2779
  except BaseException:
2730
2780
  traceback.print_exc()
2731
2781
  __slicc_exit_code = 1
2732
- `,bW=null,xW=null,SW=Object.create(null),CW=class extends Error{constructor(e){super(`Process exited with code ${e}`),this.code=e,this.name=`NodeExitError`}};function wW(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 TW(e){let t=e.lastIndexOf(`/`);return t<=0?`/`:e.slice(0,t)}function EW(e,t){return e===`/`?`/${t}`:`${e}/${t}`}function DW(e){if(/^(https?:\/\/|about:|file:|chrome:)/i.test(e))return!0;try{return new URL(e).protocol.length>0}catch{return!1}}function OW(e,t){return e===`/`?t.startsWith(`/`):t===e||t.startsWith(`${e}/`)}function kW(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}function AW(e){return e==null?``:e instanceof Uint8Array?`x'${kW(e)}'`:String(e)}function jW(e){return a(e)}function MW(e){let t=typeof chrome<`u`&&!!chrome?.runtime?.id,n=`/preview${e}`;return t?chrome.runtime.getURL(n):`${typeof window<`u`&&window.location?.origin?window.location.origin:`http://localhost:5710`}${n}`}function NW(e){return e.length===0||e.startsWith(`/`)?!1:!e.split(`/`).some(e=>e===`..`)}function PW(e,t){return me(`${e}/${t}`)}function FW(e){if(typeof e==`string`)return e;if(e==null)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function IW(e,t){let n=import.meta.resolve;if(typeof n==`function`)try{return new URL(`./`,n(e))}catch{}return new URL(t,import.meta.url)}async function LW(){return bW||=(async()=>{let e=(await y(()=>import(`./sql-wasm-qYiWqMYu.js`).then(e=>t(e.default,1)),__vite__mapDeps([0,1,2]))).default,n=typeof window>`u`?IW(`sql.js/dist/sql-wasm.js`,`../../../../../node_modules/sql.js/dist/`).toString():gW;return e({locateFile:e=>`${n}${e}`})})(),bW}var RW=typeof chrome<`u`&&!!chrome?.runtime?.id;async function zW(){return xW||=(async()=>{let{loadPyodide:e}=await y(async()=>{let{loadPyodide:e}=await import(`./pyodide-BCAXW07g.js`);return{loadPyodide:e}},__vite__mapDeps([3,1,4])),t;return t=typeof window>`u`?decodeURIComponent(IW(`pyodide/pyodide.mjs`,`../../../../../node_modules/pyodide/`).pathname):RW?chrome.runtime.getURL(`pyodide/`):_W,e({indexURL:t,fullStdLib:!1})})(),xW}function BW(){return{stdout:`usage: node -e <code> [args...]
2733
- `,stderr:``,exitCode:0}}function VW(){return{stdout:`${vW}\n`,stderr:``,exitCode:0}}function HW(){return $P(`node`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return BW();if(e.includes(`--version`)||e.includes(`-v`))return VW();let n=``,r=`<stdin>`,i=[`node`];if(e.length>0&&(e[0]===`-e`||e[0]===`--eval`)){if(!e[1])return{stdout:``,stderr:`node: option requires an argument -- eval
2782
+ `,xW=null,SW=null,CW=Object.create(null),wW=class extends Error{constructor(e){super(`Process exited with code ${e}`),this.code=e,this.name=`NodeExitError`}};function TW(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 EW(e){let t=e.lastIndexOf(`/`);return t<=0?`/`:e.slice(0,t)}function DW(e,t){return e===`/`?`/${t}`:`${e}/${t}`}function OW(e){if(/^(https?:\/\/|about:|file:|chrome:)/i.test(e))return!0;try{return new URL(e).protocol.length>0}catch{return!1}}function kW(e,t){return e===`/`?t.startsWith(`/`):t===e||t.startsWith(`${e}/`)}function AW(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}function jW(e){return e==null?``:e instanceof Uint8Array?`x'${AW(e)}'`:String(e)}function MW(e){return a(e)}function NW(e){let t=typeof chrome<`u`&&!!chrome?.runtime?.id,n=`/preview${e}`;return t?chrome.runtime.getURL(n):`${typeof window<`u`&&window.location?.origin?window.location.origin:`http://localhost:5710`}${n}`}function PW(e){return e.length===0||e.startsWith(`/`)?!1:!e.split(`/`).some(e=>e===`..`)}function FW(e,t){return me(`${e}/${t}`)}function IW(e){if(typeof e==`string`)return e;if(e==null)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function LW(e,t){let n=import.meta.resolve;if(typeof n==`function`)try{return new URL(`./`,n(e))}catch{}return new URL(t,import.meta.url)}async function RW(){return xW||=(async()=>{let e=(await y(()=>import(`./sql-wasm-qYiWqMYu.js`).then(e=>t(e.default,1)),__vite__mapDeps([0,1,2]))).default,n=typeof window>`u`?LW(`sql.js/dist/sql-wasm.js`,`../../../../../node_modules/sql.js/dist/`).toString():_W;return e({locateFile:e=>`${n}${e}`})})(),xW}var zW=typeof chrome<`u`&&!!chrome?.runtime?.id;async function BW(){return SW||=(async()=>{let{loadPyodide:e}=await y(async()=>{let{loadPyodide:e}=await import(`./pyodide-BCAXW07g.js`);return{loadPyodide:e}},__vite__mapDeps([3,1,4])),t;return t=typeof window>`u`?decodeURIComponent(LW(`pyodide/pyodide.mjs`,`../../../../../node_modules/pyodide/`).pathname):zW?chrome.runtime.getURL(`pyodide/`):vW,e({indexURL:t,fullStdLib:!1})})(),SW}function VW(){return{stdout:`usage: node -e <code> [args...]
2783
+ `,stderr:``,exitCode:0}}function HW(){return{stdout:`${yW}\n`,stderr:``,exitCode:0}}function UW(){return $P(`node`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return VW();if(e.includes(`--version`)||e.includes(`-v`))return HW();let n=``,r=`<stdin>`,i=[`node`];if(e.length>0&&(e[0]===`-e`||e[0]===`--eval`)){if(!e[1])return{stdout:``,stderr:`node: option requires an argument -- eval
2734
2784
  `,exitCode:9};n=e[1],r=`[eval]`,i=[`node`,...e.slice(2)]}else if(e.length>0&&!e[0].startsWith(`-`)){let a=e[0],o=t.fs.resolvePath(t.cwd,a);if(!await t.fs.exists(o))return{stdout:``,stderr:`node: cannot find module '${a}'\n`,exitCode:1};n=await t.fs.readFile(o),r=a,i=[`node`,a,...e.slice(1)]}else if(t.stdin.trim().length>0)n=t.stdin,r=`<stdin>`,i=[`node`];else if(e.length>0)return{stdout:``,stderr:`node: unsupported option '${e[0]}'\n`,exitCode:9};else return{stdout:``,stderr:`node: REPL mode is not supported in this environment; use node -e "code"
2735
- `,exitCode:9};let a=[],o=[],s=e=>{a.push(typeof e==`string`?e:String(e))},c=e=>{o.push(typeof e==`string`?e:String(e))},l={log:(...e)=>s(`${e.map(FW).join(` `)}\n`),info:(...e)=>s(`${e.map(FW).join(` `)}\n`),warn:(...e)=>c(`${e.map(FW).join(` `)}\n`),error:(...e)=>c(`${e.map(FW).join(` `)}\n`)},u={argv:i,env:Object.fromEntries(t.env.entries()),cwd:()=>t.cwd,exit:e=>{throw new CW(Number.isFinite(e)?Number(e):0)},stdout:{write:s},stderr:{write:c}},d={readFile:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readFile(n)},readFileBinary:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readFileBuffer(n)},writeFile:async(e,n)=>{let r=t.fs.resolvePath(t.cwd,e);await t.fs.writeFile(r,n)},writeFileBinary:async(e,n)=>{let r=t.fs.resolvePath(t.cwd,e),i=new Uint8Array(n.byteLength);i.set(n),await t.fs.writeFile(r,i)},readDir:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readdir(n)},exists:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.exists(n)},fetchToFile:async(e,n)=>{if(typeof fetch>`u`)throw Error(`fetch is not available in this runtime`);let r=await fetch(e);if(!r.ok)throw Error(`fetch ${r.status} ${r.statusText}`);let i=new Uint8Array(await r.arrayBuffer()),a=t.fs.resolvePath(t.cwd,n);return await t.fs.writeFile(a,i),i.byteLength}},f=async e=>{if(!t.exec)throw Error(`exec is not available in this runtime`);let n=await t.exec(e,{cwd:t.cwd});return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}},p=e=>{throw Error(`require('${e}') is not supported in node shim`)},m={exports:{},filename:r};try{if(typeof chrome<`u`&&chrome?.runtime?.id){let e=`
2785
+ `,exitCode:9};let a=[],o=[],s=e=>{a.push(typeof e==`string`?e:String(e))},c=e=>{o.push(typeof e==`string`?e:String(e))},l={log:(...e)=>s(`${e.map(IW).join(` `)}\n`),info:(...e)=>s(`${e.map(IW).join(` `)}\n`),warn:(...e)=>c(`${e.map(IW).join(` `)}\n`),error:(...e)=>c(`${e.map(IW).join(` `)}\n`)},u={argv:i,env:Object.fromEntries(t.env.entries()),cwd:()=>t.cwd,exit:e=>{throw new wW(Number.isFinite(e)?Number(e):0)},stdout:{write:s},stderr:{write:c}},d={readFile:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readFile(n)},readFileBinary:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readFileBuffer(n)},writeFile:async(e,n)=>{let r=t.fs.resolvePath(t.cwd,e);await t.fs.writeFile(r,n)},writeFileBinary:async(e,n)=>{let r=t.fs.resolvePath(t.cwd,e),i=new Uint8Array(n.byteLength);i.set(n),await t.fs.writeFile(r,i)},readDir:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.readdir(n)},exists:async e=>{let n=t.fs.resolvePath(t.cwd,e);return t.fs.exists(n)},fetchToFile:async(e,n)=>{if(typeof fetch>`u`)throw Error(`fetch is not available in this runtime`);let r=await fetch(e);if(!r.ok)throw Error(`fetch ${r.status} ${r.statusText}`);let i=new Uint8Array(await r.arrayBuffer()),a=t.fs.resolvePath(t.cwd,n);return await t.fs.writeFile(a,i),i.byteLength}},f=async e=>{if(!t.exec)throw Error(`exec is not available in this runtime`);let n=await t.exec(e,{cwd:t.cwd});return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}},p=e=>{throw Error(`require('${e}') is not supported in node shim`)},m={exports:{},filename:r};try{if(typeof chrome<`u`&&chrome?.runtime?.id){let e=`
2736
2786
  const __stdout = [];
2737
2787
  const __stderr = [];
2738
2788
  const __origConsole = { log: console.log, error: console.error, warn: console.warn, info: console.info };
@@ -2775,17 +2825,17 @@ except BaseException:
2775
2825
  console.info = __origConsole.info;
2776
2826
  return { stdout: __stdout.join(''), stderr: __stderr.join('') };
2777
2827
  `,r=document.querySelector(`iframe[data-js-tool]`);r||(r=document.createElement(`iframe`),r.style.display=`none`,r.dataset.jsTool=`true`,r.src=chrome.runtime.getURL(`sandbox.html`),document.body.appendChild(r),await new Promise(e=>{r.addEventListener(`load`,()=>e(),{once:!0})}));let a=`node-${Date.now()}-${Math.random().toString(36).slice(2)}`,o=e=>{let n=e.data;!n||n.type!==`vfs`||(async()=>{try{let e,i=n.args?.[0]?t.fs.resolvePath(t.cwd,n.args[0]):n.args?.[0];switch(n.op){case`readFile`:e=await t.fs.readFile(i);break;case`readFileBinary`:e=await t.fs.readFileBuffer(i);break;case`writeFile`:await t.fs.writeFile(i,n.args[1]),e=!0;break;case`writeFileBinary`:await t.fs.writeFile(i,n.binaryData??new Uint8Array),e=!0;break;case`readDir`:e=await t.fs.readdir(i);break;case`exists`:e=await t.fs.exists(i);break;case`stat`:{let n=await t.fs.stat(i);e={isDirectory:n.isDirectory,isFile:n.isFile,size:n.size};break}case`mkdir`:await t.fs.mkdir(i,{recursive:!0}),e=!0;break;case`rm`:await t.fs.rm(i,{recursive:!0}),e=!0;break}r.contentWindow.postMessage({type:`vfs_response`,id:n.id,result:e},`*`)}catch(e){let t=e instanceof Error?e.message:String(e);r.contentWindow.postMessage({type:`vfs_response`,id:n.id,error:t},`*`)}})()};window.addEventListener(`message`,o);let s=e=>{let t=e.data;!t||t.type!==`shell_exec`||(async()=>{try{let e=await f(t.command);r.contentWindow.postMessage({type:`shell_exec_response`,id:t.id,result:e},`*`)}catch(e){let n=e instanceof Error?e.message:String(e);r.contentWindow.postMessage({type:`shell_exec_response`,id:t.id,error:n},`*`)}})()};window.addEventListener(`message`,s);let c=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),i=await n.arrayBuffer(),a={};n.headers.forEach((e,t)=>{a[t]=e}),r.contentWindow.postMessage({type:`fetch_proxy_response`,id:t.id,status:n.status,statusText:n.statusText,headers:a,body:new Uint8Array(i)},`*`)}catch(e){let n=e instanceof Error?e.message:String(e);r.contentWindow.postMessage({type:`fetch_proxy_response`,id:t.id,error:n},`*`)}})()};window.addEventListener(`message`,c);let l=await new Promise((t,n)=>{let i,o=e=>{if(e.data?.type===`exec_result`&&e.data.id===a)if(window.removeEventListener(`message`,o),clearTimeout(i),e.data.error)t({stdout:``,stderr:e.data.error+`
2778
- `});else try{let n=JSON.parse(e.data.result);t({stdout:n.stdout||``,stderr:n.stderr||``})}catch{t({stdout:e.data.result||``,stderr:``})}};i=setTimeout(()=>{window.removeEventListener(`message`,o),n(Error(`node eval timed out (30s)`))},3e4),window.addEventListener(`message`,o),r.contentWindow.postMessage({type:`exec`,id:a,code:e},`*`)});return window.removeEventListener(`message`,o),window.removeEventListener(`message`,s),window.removeEventListener(`message`,c),{stdout:l.stdout,stderr:l.stderr,exitCode:+!!l.stderr}}let e=Object.getPrototypeOf(async function(){}).constructor;return await new e(`fs`,`process`,`console`,`require`,`module`,`exports`,`__state`,`exec`,`"use strict";\nconst globalThis = __state;\nconst global = __state;\n${n}`)(d,u,l,p,m,m.exports,SW,f),{stdout:a.join(``),stderr:o.join(``),exitCode:0}}catch(e){if(e instanceof CW)return{stdout:a.join(``),stderr:o.join(``),exitCode:e.code};let t=e instanceof Error?e.stack??e.message:String(e);return{stdout:a.join(``),stderr:`${o.join(``)}${t}\n`,exitCode:1}}})}var UW=[`--download`,`-d`,`--view`,`-v`];function WW(){return{stdout:`usage: open [--download|-d] [--view|-v] <url|path> [url|path...]
2828
+ `});else try{let n=JSON.parse(e.data.result);t({stdout:n.stdout||``,stderr:n.stderr||``})}catch{t({stdout:e.data.result||``,stderr:``})}};i=setTimeout(()=>{window.removeEventListener(`message`,o),n(Error(`node eval timed out (30s)`))},3e4),window.addEventListener(`message`,o),r.contentWindow.postMessage({type:`exec`,id:a,code:e},`*`)});return window.removeEventListener(`message`,o),window.removeEventListener(`message`,s),window.removeEventListener(`message`,c),{stdout:l.stdout,stderr:l.stderr,exitCode:+!!l.stderr}}let e=Object.getPrototypeOf(async function(){}).constructor;return await new e(`fs`,`process`,`console`,`require`,`module`,`exports`,`__state`,`exec`,`"use strict";\nconst globalThis = __state;\nconst global = __state;\n${n}`)(d,u,l,p,m,m.exports,CW,f),{stdout:a.join(``),stderr:o.join(``),exitCode:0}}catch(e){if(e instanceof wW)return{stdout:a.join(``),stderr:o.join(``),exitCode:e.code};let t=e instanceof Error?e.stack??e.message:String(e);return{stdout:a.join(``),stderr:`${o.join(``)}${t}\n`,exitCode:1}}})}var WW=[`--download`,`-d`,`--view`,`-v`];function GW(){return{stdout:`usage: open [--download|-d] [--view|-v] <url|path> [url|path...]
2779
2829
 
2780
2830
  VFS paths are served in a new browser tab via the preview service worker.
2781
2831
  URLs (http/https/etc.) are opened directly in a new tab.
2782
2832
  For app directories with a default entry file, prefer serve <dir>.
2783
2833
  --download, -d Force download instead of opening in a tab.
2784
2834
  --view, -v Return image inline so the agent can see it.
2785
- `,stderr:``,exitCode:0}}function GW(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 KW(){return $P(`open`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return WW();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
2786
- `,exitCode:1};let n=e.includes(`--download`)||e.includes(`-d`),r=e.includes(`--view`)||e.includes(`-v`),i=e.filter(e=>!UW.includes(e));if(i.length===0)return WW();let a=[];for(let e of i){if(DW(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=MW(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=jW(i),s=GW(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:jW(i)}),c=URL.createObjectURL(s),l=document.createElement(`a`);l.href=c,l.download=wW(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=MW(i);window.open(e,`_blank`,`noopener,noreferrer`),a.push(`opened ${i} → ${e}`)}}return{stdout:a.join(`
2835
+ `,stderr:``,exitCode:0}}function KW(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 qW(){return $P(`open`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return GW();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
2836
+ `,exitCode:1};let n=e.includes(`--download`)||e.includes(`-d`),r=e.includes(`--view`)||e.includes(`-v`),i=e.filter(e=>!WW.includes(e));if(i.length===0)return GW();let a=[];for(let e of i){if(OW(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=NW(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=MW(i),s=KW(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:MW(i)}),c=URL.createObjectURL(s),l=document.createElement(`a`);l.href=c,l.download=TW(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=NW(i);window.open(e,`_blank`,`noopener,noreferrer`),a.push(`opened ${i} → ${e}`)}}return{stdout:a.join(`
2787
2837
  `)+`
2788
- `,stderr:``,exitCode:0}})}var qW=null,JW=null;async function YW(){return qW||=y(()=>import(`./es-BIXR_JMx.js`),__vite__mapDeps([5,1,6,2])),qW}async function XW(){return JW||=y(()=>import(`./dist-BvrWiVk7.js`),__vite__mapDeps([7,4])),JW}function ZW(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 QW(e){let{range:t,rotation:n}=ZW(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 $W(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 eG(){return{stdout:`usage: pdftk <input.pdf> <operation> [args...]
2838
+ `,stderr:``,exitCode:0}})}var JW=null,YW=null;async function XW(){return JW||=y(()=>import(`./es-BIXR_JMx.js`),__vite__mapDeps([5,1,6,2])),JW}async function ZW(){return YW||=y(()=>import(`./dist-BvrWiVk7.js`),__vite__mapDeps([7,4])),YW}function QW(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 $W(e){let{range:t,rotation:n}=QW(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 eG(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 tG(){return{stdout:`usage: pdftk <input.pdf> <operation> [args...]
2789
2839
 
2790
2840
  Operations:
2791
2841
  dump_data Print metadata (page count, title, author, etc.)
@@ -2809,14 +2859,14 @@ Page ranges:
2809
2859
  1-endright Pages 1 to end, rotated 90° clockwise
2810
2860
  3left Page 3 rotated 270° (counterclockwise)
2811
2861
  1-5down Pages 1-5 rotated 180°
2812
- `,stderr:``,exitCode:0}}function tG(e=`pdftk`){return $P(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return eG();try{let r=[],i=0;for(;i<t.length;){let e=t[i],a=e.match(/^([A-Z])=(.+)$/);if(a){let e=a[1],t=n.fs.resolvePath(n.cwd,a[2]);r.push({handle:e,path:t}),i++;continue}if([`dump_data`,`dump_data_utf8`,`cat`,`rotate`].includes(e))break;if(!e.startsWith(`-`)){let t=n.fs.resolvePath(n.cwd,e);r.push({handle:``,path:t}),i++;continue}break}if(r.length===0)return{stdout:``,stderr:`${e}: no input PDF specified\n`,exitCode:1};let a=t[i];if(i++,!a)return{stdout:``,stderr:`${e}: no operation specified\n`,exitCode:1};if(a===`dump_data`){if(r.length>1)return{stdout:``,stderr:`${e}: dump_data only supports a single input file\n`,exitCode:1};let t=await YW(),i=await n.fs.readFileBuffer(r[0].path),a=await t.PDFDocument.load(i),o=[];o.push(`NumberOfPages: ${a.getPageCount()}`);let s=a.getTitle();s&&o.push(`InfoBegin`),s&&o.push(`InfoKey: Title`),s&&o.push(`InfoValue: ${s}`);let c=a.getAuthor();c&&o.push(`InfoBegin`),c&&o.push(`InfoKey: Author`),c&&o.push(`InfoValue: ${c}`);let l=a.getCreator();l&&o.push(`InfoBegin`),l&&o.push(`InfoKey: Creator`),l&&o.push(`InfoValue: ${l}`);let u=a.getProducer();return u&&o.push(`InfoBegin`),u&&o.push(`InfoKey: Producer`),u&&o.push(`InfoValue: ${u}`),{stdout:o.join(`
2862
+ `,stderr:``,exitCode:0}}function nG(e=`pdftk`){return $P(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return tG();try{let r=[],i=0;for(;i<t.length;){let e=t[i],a=e.match(/^([A-Z])=(.+)$/);if(a){let e=a[1],t=n.fs.resolvePath(n.cwd,a[2]);r.push({handle:e,path:t}),i++;continue}if([`dump_data`,`dump_data_utf8`,`cat`,`rotate`].includes(e))break;if(!e.startsWith(`-`)){let t=n.fs.resolvePath(n.cwd,e);r.push({handle:``,path:t}),i++;continue}break}if(r.length===0)return{stdout:``,stderr:`${e}: no input PDF specified\n`,exitCode:1};let a=t[i];if(i++,!a)return{stdout:``,stderr:`${e}: no operation specified\n`,exitCode:1};if(a===`dump_data`){if(r.length>1)return{stdout:``,stderr:`${e}: dump_data only supports a single input file\n`,exitCode:1};let t=await XW(),i=await n.fs.readFileBuffer(r[0].path),a=await t.PDFDocument.load(i),o=[];o.push(`NumberOfPages: ${a.getPageCount()}`);let s=a.getTitle();s&&o.push(`InfoBegin`),s&&o.push(`InfoKey: Title`),s&&o.push(`InfoValue: ${s}`);let c=a.getAuthor();c&&o.push(`InfoBegin`),c&&o.push(`InfoKey: Author`),c&&o.push(`InfoValue: ${c}`);let l=a.getCreator();l&&o.push(`InfoBegin`),l&&o.push(`InfoKey: Creator`),l&&o.push(`InfoValue: ${l}`);let u=a.getProducer();return u&&o.push(`InfoBegin`),u&&o.push(`InfoKey: Producer`),u&&o.push(`InfoValue: ${u}`),{stdout:o.join(`
2813
2863
  `)+`
2814
- `,stderr:``,exitCode:0}}if(a===`dump_data_utf8`){if(r.length>1)return{stdout:``,stderr:`${e}: dump_data_utf8 only supports a single input file\n`,exitCode:1};let t=await XW(),i=await n.fs.readFileBuffer(r[0].path);return{stdout:(await t.extractText(i)).text+`
2815
- `,stderr:``,exitCode:0}}if(a===`cat`){let a=await YW(),o=await a.PDFDocument.create(),s=t.slice(i),c=s.indexOf(`output`);if(c===-1)return{stdout:``,stderr:`${e}: cat operation requires 'output <filename>'\n`,exitCode:1};let l=s.slice(0,c),u=s[c+1];if(!u)return{stdout:``,stderr:`${e}: output filename not specified\n`,exitCode:1};let d=n.fs.resolvePath(n.cwd,u),f=new Map;for(let e of r){let t=await n.fs.readFileBuffer(e.path),r=await a.PDFDocument.load(t),i=e.handle||`default`;f.set(i,r)}for(let t of l){if(/^[A-Z]$/.test(t)){let n=f.get(t);if(!n)return{stdout:``,stderr:`${e}: unknown handle '${t}'\n`,exitCode:1};let r=n.getPageCount(),i=Array.from({length:r},(e,t)=>t);(await o.copyPages(n,i)).forEach(e=>o.addPage(e));continue}let n=f.get(r[0].handle||`default`);if(!n)return{stdout:``,stderr:`${e}: no default input document\n`,exitCode:1};let i=n.getPageCount(),s=QW(t),c=$W(s,i).map(e=>e-1),l=await o.copyPages(n,c);for(let e of l)s.rotation&&e.setRotation(a.degrees(s.rotation)),o.addPage(e)}let p=await o.save();return await n.fs.writeFile(d,p),{stdout:`Created ${u}\n`,stderr:``,exitCode:0}}if(a===`rotate`){if(r.length>1)return{stdout:``,stderr:`${e}: rotate only supports a single input file\n`,exitCode:1};let a=await YW(),o=await n.fs.readFileBuffer(r[0].path),s=await a.PDFDocument.load(o),c=t.slice(i),l=c.indexOf(`output`);if(l===-1)return{stdout:``,stderr:`${e}: rotate operation requires 'output <filename>'\n`,exitCode:1};let u=c.slice(0,l),d=c[l+1];if(!d)return{stdout:``,stderr:`${e}: output filename not specified\n`,exitCode:1};let f=n.fs.resolvePath(n.cwd,d),p=s.getPageCount(),m=new Map;for(let t of u){let n=QW(t);if(!n.rotation)return{stdout:``,stderr:`${e}: rotation suffix required (right/left/down) for range '${t}'\n`,exitCode:1};let r=$W(n,p);for(let e of r)m.set(e-1,n.rotation)}let h=s.getPages();for(let[e,t]of m.entries()){let n=h[e],r=(n.getRotation().angle+t)%360;n.setRotation(a.degrees(r))}let g=await s.save();return await n.fs.writeFile(f,g),{stdout:`Created ${d}\n`,stderr:``,exitCode:0}}return{stdout:``,stderr:`${e}: unknown operation '${a}'\n`,exitCode:1}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}async function nG(e,t,n){let r=t.FS;function i(e){try{r.stat(e)}catch{r.mkdirTree(e)}}async function a(t){i(t);let n;try{n=await e.readdir(t)}catch{return}for(let o of n){let n=t===`/`?`/${o}`:`${t}/${o}`;try{if((await e.stat(n)).isDirectory)await a(n);else{let a=await e.readFile(n);i(t),r.writeFile(n,a)}}catch{}}}for(let e of n)await a(e)}async function rG(e,t,n){let r=t.FS;async function i(t){let n;try{n=r.readdir(t).filter(e=>e!==`.`&&e!==`..`)}catch{return}for(let a of n){let n=t===`/`?`/${a}`:`${t}/${a}`;try{let a=r.stat(n);if(r.isDir(a.mode))await e.mkdir(n,{recursive:!0}),await i(n);else{let i=new TextDecoder().decode(r.readFile(n));await e.mkdir(t,{recursive:!0}),await e.writeFile(n,i)}}catch{}}}for(let e of n)await i(e)}function iG(){return{stdout:`usage: python3 [-c code | script.py] [args...]
2816
- `,stderr:``,exitCode:0}}function aG(){return{stdout:`Python 3.12 (Pyodide)
2817
- `,stderr:``,exitCode:0}}function oG(e){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return iG();if(t.includes(`--version`)||t.includes(`-V`))return aG();let r=``,i=`<stdin>`,a=[`python3`];if(t[0]===`-c`){if(!t[1])return{stdout:``,stderr:`${e}: option requires an argument -- 'c'\n`,exitCode:2};r=t[1],i=`-c`,a=[`-c`,...t.slice(2)]}else if(t.length>0&&!t[0].startsWith(`-`)){let o=t[0],s=n.fs.resolvePath(n.cwd,o);if(!await n.fs.exists(s))return{stdout:``,stderr:`${e}: can't open file '${o}': [Errno 2] No such file or directory\n`,exitCode:2};r=await n.fs.readFile(s),i=o,a=[o,...t.slice(1)]}else if(n.stdin.trim().length>0)r=n.stdin,i=`<stdin>`,a=[`<stdin>`];else if(t.length>0)return{stdout:``,stderr:`${e}: unsupported option '${t[0]}'\n`,exitCode:2};else return{stdout:``,stderr:`${e}: no input provided (use -c CODE, script path, or stdin)\n`,exitCode:2};try{let e=await zW(),t=[],o=[],s=[n.cwd,`/tmp`];if(i!==`<stdin>`&&i!==`[eval]`){let e=i.includes(`/`)?i.slice(0,i.lastIndexOf(`/`)):n.cwd;s.includes(e)||s.push(e)}await nG(n.fs,e,s);try{e.FS.chdir(n.cwd)}catch{}e.setStdout({batched:e=>t.push(e+`
2864
+ `,stderr:``,exitCode:0}}if(a===`dump_data_utf8`){if(r.length>1)return{stdout:``,stderr:`${e}: dump_data_utf8 only supports a single input file\n`,exitCode:1};let t=await ZW(),i=await n.fs.readFileBuffer(r[0].path);return{stdout:(await t.extractText(i)).text+`
2865
+ `,stderr:``,exitCode:0}}if(a===`cat`){let a=await XW(),o=await a.PDFDocument.create(),s=t.slice(i),c=s.indexOf(`output`);if(c===-1)return{stdout:``,stderr:`${e}: cat operation requires 'output <filename>'\n`,exitCode:1};let l=s.slice(0,c),u=s[c+1];if(!u)return{stdout:``,stderr:`${e}: output filename not specified\n`,exitCode:1};let d=n.fs.resolvePath(n.cwd,u),f=new Map;for(let e of r){let t=await n.fs.readFileBuffer(e.path),r=await a.PDFDocument.load(t),i=e.handle||`default`;f.set(i,r)}for(let t of l){if(/^[A-Z]$/.test(t)){let n=f.get(t);if(!n)return{stdout:``,stderr:`${e}: unknown handle '${t}'\n`,exitCode:1};let r=n.getPageCount(),i=Array.from({length:r},(e,t)=>t);(await o.copyPages(n,i)).forEach(e=>o.addPage(e));continue}let n=f.get(r[0].handle||`default`);if(!n)return{stdout:``,stderr:`${e}: no default input document\n`,exitCode:1};let i=n.getPageCount(),s=$W(t),c=eG(s,i).map(e=>e-1),l=await o.copyPages(n,c);for(let e of l)s.rotation&&e.setRotation(a.degrees(s.rotation)),o.addPage(e)}let p=await o.save();return await n.fs.writeFile(d,p),{stdout:`Created ${u}\n`,stderr:``,exitCode:0}}if(a===`rotate`){if(r.length>1)return{stdout:``,stderr:`${e}: rotate only supports a single input file\n`,exitCode:1};let a=await XW(),o=await n.fs.readFileBuffer(r[0].path),s=await a.PDFDocument.load(o),c=t.slice(i),l=c.indexOf(`output`);if(l===-1)return{stdout:``,stderr:`${e}: rotate operation requires 'output <filename>'\n`,exitCode:1};let u=c.slice(0,l),d=c[l+1];if(!d)return{stdout:``,stderr:`${e}: output filename not specified\n`,exitCode:1};let f=n.fs.resolvePath(n.cwd,d),p=s.getPageCount(),m=new Map;for(let t of u){let n=$W(t);if(!n.rotation)return{stdout:``,stderr:`${e}: rotation suffix required (right/left/down) for range '${t}'\n`,exitCode:1};let r=eG(n,p);for(let e of r)m.set(e-1,n.rotation)}let h=s.getPages();for(let[e,t]of m.entries()){let n=h[e],r=(n.getRotation().angle+t)%360;n.setRotation(a.degrees(r))}let g=await s.save();return await n.fs.writeFile(f,g),{stdout:`Created ${d}\n`,stderr:``,exitCode:0}}return{stdout:``,stderr:`${e}: unknown operation '${a}'\n`,exitCode:1}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}async function rG(e,t,n){let r=t.FS;function i(e){try{r.stat(e)}catch{r.mkdirTree(e)}}async function a(t){i(t);let n;try{n=await e.readdir(t)}catch{return}for(let o of n){let n=t===`/`?`/${o}`:`${t}/${o}`;try{if((await e.stat(n)).isDirectory)await a(n);else{let a=await e.readFile(n);i(t),r.writeFile(n,a)}}catch{}}}for(let e of n)await a(e)}async function iG(e,t,n){let r=t.FS;async function i(t){let n;try{n=r.readdir(t).filter(e=>e!==`.`&&e!==`..`)}catch{return}for(let a of n){let n=t===`/`?`/${a}`:`${t}/${a}`;try{let a=r.stat(n);if(r.isDir(a.mode))await e.mkdir(n,{recursive:!0}),await i(n);else{let i=new TextDecoder().decode(r.readFile(n));await e.mkdir(t,{recursive:!0}),await e.writeFile(n,i)}}catch{}}}for(let e of n)await i(e)}function aG(){return{stdout:`usage: python3 [-c code | script.py] [args...]
2866
+ `,stderr:``,exitCode:0}}function oG(){return{stdout:`Python 3.12 (Pyodide)
2867
+ `,stderr:``,exitCode:0}}function sG(e){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return aG();if(t.includes(`--version`)||t.includes(`-V`))return oG();let r=``,i=`<stdin>`,a=[`python3`];if(t[0]===`-c`){if(!t[1])return{stdout:``,stderr:`${e}: option requires an argument -- 'c'\n`,exitCode:2};r=t[1],i=`-c`,a=[`-c`,...t.slice(2)]}else if(t.length>0&&!t[0].startsWith(`-`)){let o=t[0],s=n.fs.resolvePath(n.cwd,o);if(!await n.fs.exists(s))return{stdout:``,stderr:`${e}: can't open file '${o}': [Errno 2] No such file or directory\n`,exitCode:2};r=await n.fs.readFile(s),i=o,a=[o,...t.slice(1)]}else if(n.stdin.trim().length>0)r=n.stdin,i=`<stdin>`,a=[`<stdin>`];else if(t.length>0)return{stdout:``,stderr:`${e}: unsupported option '${t[0]}'\n`,exitCode:2};else return{stdout:``,stderr:`${e}: no input provided (use -c CODE, script path, or stdin)\n`,exitCode:2};try{let e=await BW(),t=[],o=[],s=[n.cwd,`/tmp`];if(i!==`<stdin>`&&i!==`[eval]`){let e=i.includes(`/`)?i.slice(0,i.lastIndexOf(`/`)):n.cwd;s.includes(e)||s.push(e)}await rG(n.fs,e,s);try{e.FS.chdir(n.cwd)}catch{}e.setStdout({batched:e=>t.push(e+`
2818
2868
  `)}),e.setStderr({batched:e=>o.push(e+`
2819
- `)});let c=!1;e.setStdin({stdin:()=>c||!n.stdin?null:(c=!0,n.stdin)}),e.globals.set(`__slicc_code`,r),e.globals.set(`__slicc_filename`,i),e.globals.set(`__slicc_argv`,a),await e.runPythonAsync(yW);let l=e.globals.get(`__slicc_exit_code`),u=typeof l==`number`?l:Number(l??1);try{e.runPython(`del __slicc_code, __slicc_filename, __slicc_argv, __slicc_exit_code`)}catch{}return await rG(n.fs,e,s),{stdout:t.join(``),stderr:o.join(``),exitCode:u}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function sG(){return{stdout:`usage: serve [--entry <relative-path>] [--project] <directory>
2869
+ `)});let c=!1;e.setStdin({stdin:()=>c||!n.stdin?null:(c=!0,n.stdin)}),e.globals.set(`__slicc_code`,r),e.globals.set(`__slicc_filename`,i),e.globals.set(`__slicc_argv`,a),await e.runPythonAsync(bW);let l=e.globals.get(`__slicc_exit_code`),u=typeof l==`number`?l:Number(l??1);try{e.runPython(`del __slicc_code, __slicc_filename, __slicc_argv, __slicc_exit_code`)}catch{}return await iG(n.fs,e,s),{stdout:t.join(``),stderr:o.join(``),exitCode:u}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function cG(){return{stdout:`usage: serve [--entry <relative-path>] [--project] <directory>
2820
2870
 
2821
2871
  Serve a VFS directory in a new browser tab via the preview service worker.
2822
2872
  Defaults to index.html inside the target directory.
@@ -2825,23 +2875,23 @@ Page ranges:
2825
2875
  --project Enable project serve mode. Root-relative paths (/scripts/,
2826
2876
  /styles/, etc.) resolve against the served directory.
2827
2877
  Use this for frameworks like EDS that expect a local dev server.
2828
- `,stderr:``,exitCode:0}}function cG(e){let t=`index.html`,n,r=!1;for(let i=0;i<e.length;i+=1){let a=e[i];if(a===`--entry`){let n=e[i+1];if(!n)return{entry:t,project:r,error:`serve: missing value for --entry
2878
+ `,stderr:``,exitCode:0}}function lG(e){let t=`index.html`,n,r=!1;for(let i=0;i<e.length;i+=1){let a=e[i];if(a===`--entry`){let n=e[i+1];if(!n)return{entry:t,project:r,error:`serve: missing value for --entry
2829
2879
  `};t=n,i+=1;continue}if(a.startsWith(`--entry=`)){t=a.slice(8);continue}if(a===`--project`){r=!0;continue}if(a.startsWith(`-`))return{entry:t,project:r,error:`serve: unknown option: ${a}\n`};if(n)return{entry:t,project:r,error:`serve: expected a single directory argument
2830
- `};n=a}return{directory:n,entry:t,project:r}}function lG(e,t){return $P(`serve`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return sG();let i=typeof window<`u`&&typeof window.open==`function`;if(!e&&!i)return{stdout:``,stderr:`serve: browser APIs are unavailable in this environment
2831
- `,exitCode:1};let a=cG(n);if(a.error)return{stdout:``,stderr:a.error,exitCode:1};if(!a.directory)return sG();if(!NW(a.entry))return{stdout:``,stderr:`serve: invalid entry file: ${a.entry}\n`,exitCode:1};let o=r.fs.resolvePath(r.cwd,a.directory),s;try{s=await r.fs.stat(o)}catch{return{stdout:``,stderr:`serve: no such directory: ${a.directory}\n`,exitCode:1}}if(!s.isDirectory)return{stdout:``,stderr:`serve: not a directory: ${a.directory}\n`,exitCode:1};let c=PW(o,a.entry),l;try{l=await r.fs.stat(c)}catch{return{stdout:``,stderr:`serve: entry file not found: ${c}\n`,exitCode:1}}if(!l.isFile)return{stdout:``,stderr:`serve: entry is not a file: ${c}\n`,exitCode:1};let u=MW(c);if(a.project&&(u+=`?projectRoot=${encodeURIComponent(o)}`),e&&t){let t=await e.createPage(u);return{stdout:`serving ${o} → ${u} (targetId: ${t})\nUse: playwright-cli <command> --tab ${t}\n`,stderr:``,exitCode:0}}return typeof window<`u`&&typeof window.open==`function`&&window.open(u,`_blank`,`noopener,noreferrer`),{stdout:`serving ${o} → ${u}\n`,stderr:``,exitCode:0}})}function uG(){return{stdout:`usage: sqlite3 [database] [sql]
2832
- `,stderr:``,exitCode:0}}function dG(e=`sqlite3`){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return uG();let r=`:memory:`,i=t;t.length>0&&!t[0].startsWith(`-`)&&(r=t[0],i=t.slice(1));let a=i.join(` `).trim()||n.stdin.trim();if(!a)return{stdout:``,stderr:`${e}: interactive mode is not supported; provide SQL as argument or stdin\n`,exitCode:1};try{let e=await LW(),t=r===`:memory:`,i=t?`:memory:`:n.fs.resolvePath(n.cwd,r),o;!t&&await n.fs.exists(i)&&(o=await n.fs.readFileBuffer(i));let s=o?new e.Database(o):new e.Database,c=s.exec(a);t||await n.fs.writeFile(i,s.export()),s.close();let l=[];for(let e of c)for(let t of e.values)l.push(t.map(AW).join(`|`));return{stdout:l.length>0?`${l.join(`
2833
- `)}\n`:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function fG(){return{stdout:`usage: uname
2834
- `,stderr:``,exitCode:0}}function pG(){return $P(`uname`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return fG();if(e.length>0)return{stdout:``,stderr:`uname: unsupported arguments
2880
+ `};n=a}return{directory:n,entry:t,project:r}}function uG(e,t){return $P(`serve`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return cG();let i=typeof window<`u`&&typeof window.open==`function`;if(!e&&!i)return{stdout:``,stderr:`serve: browser APIs are unavailable in this environment
2881
+ `,exitCode:1};let a=lG(n);if(a.error)return{stdout:``,stderr:a.error,exitCode:1};if(!a.directory)return cG();if(!PW(a.entry))return{stdout:``,stderr:`serve: invalid entry file: ${a.entry}\n`,exitCode:1};let o=r.fs.resolvePath(r.cwd,a.directory),s;try{s=await r.fs.stat(o)}catch{return{stdout:``,stderr:`serve: no such directory: ${a.directory}\n`,exitCode:1}}if(!s.isDirectory)return{stdout:``,stderr:`serve: not a directory: ${a.directory}\n`,exitCode:1};let c=FW(o,a.entry),l;try{l=await r.fs.stat(c)}catch{return{stdout:``,stderr:`serve: entry file not found: ${c}\n`,exitCode:1}}if(!l.isFile)return{stdout:``,stderr:`serve: entry is not a file: ${c}\n`,exitCode:1};let u=NW(c);if(a.project&&(u+=`?projectRoot=${encodeURIComponent(o)}`),e&&t){let t=await e.createPage(u);return{stdout:`serving ${o} → ${u} (targetId: ${t})\nUse: playwright-cli <command> --tab ${t}\n`,stderr:``,exitCode:0}}return typeof window<`u`&&typeof window.open==`function`&&window.open(u,`_blank`,`noopener,noreferrer`),{stdout:`serving ${o} → ${u}\n`,stderr:``,exitCode:0}})}function dG(){return{stdout:`usage: sqlite3 [database] [sql]
2882
+ `,stderr:``,exitCode:0}}function fG(e=`sqlite3`){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return dG();let r=`:memory:`,i=t;t.length>0&&!t[0].startsWith(`-`)&&(r=t[0],i=t.slice(1));let a=i.join(` `).trim()||n.stdin.trim();if(!a)return{stdout:``,stderr:`${e}: interactive mode is not supported; provide SQL as argument or stdin\n`,exitCode:1};try{let e=await RW(),t=r===`:memory:`,i=t?`:memory:`:n.fs.resolvePath(n.cwd,r),o;!t&&await n.fs.exists(i)&&(o=await n.fs.readFileBuffer(i));let s=o?new e.Database(o):new e.Database,c=s.exec(a);t||await n.fs.writeFile(i,s.export()),s.close();let l=[];for(let e of c)for(let t of e.values)l.push(t.map(jW).join(`|`));return{stdout:l.length>0?`${l.join(`
2883
+ `)}\n`:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function pG(){return{stdout:`usage: uname
2884
+ `,stderr:``,exitCode:0}}function mG(){return $P(`uname`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return pG();if(e.length>0)return{stdout:``,stderr:`uname: unsupported arguments
2835
2885
  `,exitCode:1};let t=globalThis.navigator?.userAgent;return typeof t!=`string`||t.length===0?{stdout:``,stderr:`uname: navigator.userAgent is unavailable
2836
- `,exitCode:1}:{stdout:`${t}\n`,stderr:``,exitCode:0}})}function mG(){return{stdout:`usage: man <topic>
2886
+ `,exitCode:1}:{stdout:`${t}\n`,stderr:``,exitCode:0}})}function hG(){return{stdout:`usage: man <topic>
2837
2887
 
2838
2888
  Fetches documentation for a given topic from sliccy.com.
2839
- `,stderr:``,exitCode:0}}function hG(e){return e.replace(/<[^>]*>/g,``).replace(/&amp;/g,`&`).replace(/&lt;/g,`<`).replace(/&gt;/g,`>`).replace(/&quot;/g,`"`).replace(/&#39;/g,`'`).replace(/&nbsp;/g,` `).trimEnd()}function gG(){return $P(`man`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return mG();if(e.length===0)return{stdout:``,stderr:`What manual page do you want?
2889
+ `,stderr:``,exitCode:0}}function gG(e){return e.replace(/<[^>]*>/g,``).replace(/&amp;/g,`&`).replace(/&lt;/g,`<`).replace(/&gt;/g,`>`).replace(/&quot;/g,`"`).replace(/&#39;/g,`'`).replace(/&nbsp;/g,` `).trimEnd()}function _G(){return $P(`man`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return hG();if(e.length===0)return{stdout:``,stderr:`What manual page do you want?
2840
2890
  For example, try 'man commands'.
2841
- `,exitCode:1};let t=e.join(`-`),n=`https://www.sliccy.com/man/${t}.plain.html`;try{let e=await fetch(n);return e.status===404?{stdout:``,stderr:`No manual entry for ${t}\n`,exitCode:1}:e.ok?{stdout:hG(await e.text())+`
2842
- `,stderr:``,exitCode:0}:{stdout:``,stderr:`man: failed to fetch manual page for ${t}: ${e.status} ${e.statusText}\n`,exitCode:1}}catch(e){return{stdout:``,stderr:`man: ${e.message||String(e)}\n`,exitCode:1}}})}function _G(){return{stdout:`usage: unzip <archive.zip> [-d <destination>]
2843
- `,stderr:``,exitCode:0}}function vG(){return $P(`unzip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return _G();let n=`.`,r=[];for(let t=0;t<e.length;t++){let i=e[t];if(i===`-d`){n=e[t+1]??``,t++;continue}if(i.startsWith(`-`))return{stdout:``,stderr:`unzip: unsupported option ${i}\n`,exitCode:1};r.push(i)}if(r.length<1)return{stdout:``,stderr:`unzip: expected archive path
2844
- `,exitCode:1};let i=t.fs.resolvePath(t.cwd,r[0]),a=t.fs.resolvePath(t.cwd,n||`.`);await t.fs.mkdir(a,{recursive:!0});let o=le(await t.fs.readFileBuffer(i)),s=0;for(let[e,n]of Object.entries(o)){let r=e.replace(/\\/g,`/`);if(!r||r.endsWith(`/`))continue;let i=t.fs.resolvePath(a,r);if(!OW(a,i))return{stdout:``,stderr:`unzip: blocked suspicious path ${e}\n`,exitCode:1};let o=TW(i);o!==`/`&&await t.fs.mkdir(o,{recursive:!0}),await t.fs.writeFile(i,n),s++}return{stdout:`extracted ${s} file(s) to ${a}\n`,stderr:``,exitCode:0}})}function yG(){return{stdout:`usage: webhook <command> [options]
2891
+ `,exitCode:1};let t=e.join(`-`),n=`https://www.sliccy.com/man/${t}.plain.html`;try{let e=await fetch(n);return e.status===404?{stdout:``,stderr:`No manual entry for ${t}\n`,exitCode:1}:e.ok?{stdout:gG(await e.text())+`
2892
+ `,stderr:``,exitCode:0}:{stdout:``,stderr:`man: failed to fetch manual page for ${t}: ${e.status} ${e.statusText}\n`,exitCode:1}}catch(e){return{stdout:``,stderr:`man: ${e.message||String(e)}\n`,exitCode:1}}})}function vG(){return{stdout:`usage: unzip <archive.zip> [-d <destination>]
2893
+ `,stderr:``,exitCode:0}}function yG(){return $P(`unzip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return vG();let n=`.`,r=[];for(let t=0;t<e.length;t++){let i=e[t];if(i===`-d`){n=e[t+1]??``,t++;continue}if(i.startsWith(`-`))return{stdout:``,stderr:`unzip: unsupported option ${i}\n`,exitCode:1};r.push(i)}if(r.length<1)return{stdout:``,stderr:`unzip: expected archive path
2894
+ `,exitCode:1};let i=t.fs.resolvePath(t.cwd,r[0]),a=t.fs.resolvePath(t.cwd,n||`.`);await t.fs.mkdir(a,{recursive:!0});let o=le(await t.fs.readFileBuffer(i)),s=0;for(let[e,n]of Object.entries(o)){let r=e.replace(/\\/g,`/`);if(!r||r.endsWith(`/`))continue;let i=t.fs.resolvePath(a,r);if(!kW(a,i))return{stdout:``,stderr:`unzip: blocked suspicious path ${e}\n`,exitCode:1};let o=EW(i);o!==`/`&&await t.fs.mkdir(o,{recursive:!0}),await t.fs.writeFile(i,n),s++}return{stdout:`extracted ${s} file(s) to ${a}\n`,stderr:``,exitCode:0}})}function bG(){return{stdout:`usage: webhook <command> [options]
2845
2895
 
2846
2896
  Commands:
2847
2897
  create --scoop <name> [--name <name>] [--filter <code>] Create a new webhook endpoint
@@ -2859,12 +2909,12 @@ Examples:
2859
2909
  webhook create --scoop slack-relay --name slack --filter "(e) => ({ text: e.body.text, user: e.body.user })"
2860
2910
  webhook list
2861
2911
  webhook delete abc123
2862
- `,stderr:``,exitCode:0}}async function bG(e,t,n){if(typeof chrome<`u`&&chrome?.runtime?.id)throw Error(`Webhooks are only available in CLI mode (npm run dev:full)`);let r={method:e,headers:{"Content-Type":`application/json`}};n&&(r.body=JSON.stringify(n));let i=await fetch(`/api/webhooks${t}`,r),a=await i.json().catch(()=>({}));return{ok:i.ok,status:i.status,data:a}}function xG(){return $P(`webhook`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return yG();let t=e[0];try{switch(t){case`create`:{let t=`default`,n,r,i=e.indexOf(`--name`);i!==-1&&e[i+1]&&(t=e[i+1]);let a=e.indexOf(`--filter`);a!==-1&&e[a+1]&&(n=e[a+1]);let o=e.indexOf(`--scoop`);if(o!==-1&&e[o+1]&&(r=e[o+1]),!r)return{stdout:``,stderr:`webhook: --scoop is required (every webhook must route to a scoop)
2863
- `,exitCode:1};let{ok:s,data:c}=await bG(`POST`,``,{name:t,filter:n,scoop:r});if(!s)return{stdout:``,stderr:`webhook: failed to create webhook: ${c.error??`unknown error`}\n`,exitCode:1};let l=c,u=`Created webhook "${l.name}"\nID: ${l.id}\nURL: ${l.url}\n`;return l.scoop&&(u+=`Scoop: ${l.scoop}\n`),l.filter&&(u+=`Filter: ${l.filter}\n`),{stdout:u,stderr:``,exitCode:0}}case`list`:{let{ok:e,data:t}=await bG(`GET`,``);if(!e)return{stdout:``,stderr:`webhook: failed to list webhooks: ${t.error??`unknown error`}\n`,exitCode:1};let n=t;if(n.length===0)return{stdout:`No active webhooks
2912
+ `,stderr:``,exitCode:0}}async function xG(e,t,n){if(typeof chrome<`u`&&chrome?.runtime?.id)throw Error(`Webhooks are only available in CLI mode (npm run dev:full)`);let r={method:e,headers:{"Content-Type":`application/json`}};n&&(r.body=JSON.stringify(n));let i=await fetch(`/api/webhooks${t}`,r),a=await i.json().catch(()=>({}));return{ok:i.ok,status:i.status,data:a}}function SG(){return $P(`webhook`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return bG();let t=e[0];try{switch(t){case`create`:{let t=`default`,n,r,i=e.indexOf(`--name`);i!==-1&&e[i+1]&&(t=e[i+1]);let a=e.indexOf(`--filter`);a!==-1&&e[a+1]&&(n=e[a+1]);let o=e.indexOf(`--scoop`);if(o!==-1&&e[o+1]&&(r=e[o+1]),!r)return{stdout:``,stderr:`webhook: --scoop is required (every webhook must route to a scoop)
2913
+ `,exitCode:1};let{ok:s,data:c}=await xG(`POST`,``,{name:t,filter:n,scoop:r});if(!s)return{stdout:``,stderr:`webhook: failed to create webhook: ${c.error??`unknown error`}\n`,exitCode:1};let l=c,u=`Created webhook "${l.name}"\nID: ${l.id}\nURL: ${l.url}\n`;return l.scoop&&(u+=`Scoop: ${l.scoop}\n`),l.filter&&(u+=`Filter: ${l.filter}\n`),{stdout:u,stderr:``,exitCode:0}}case`list`:{let{ok:e,data:t}=await xG(`GET`,``);if(!e)return{stdout:``,stderr:`webhook: failed to list webhooks: ${t.error??`unknown error`}\n`,exitCode:1};let n=t;if(n.length===0)return{stdout:`No active webhooks
2864
2914
  `,stderr:``,exitCode:0};let r=`Active webhooks:
2865
2915
  `;for(let e of n)r+=` ${e.id} ${e.name.padEnd(20)} ${e.url}`,e.scoop&&(r+=` -> ${e.scoop}`),e.filter&&(r+=` [filtered]`),r+=`
2866
2916
  `;return{stdout:r,stderr:``,exitCode:0}}case`delete`:{let t=e[1];if(!t)return{stdout:``,stderr:`webhook: delete requires an ID
2867
- `,exitCode:1};let{ok:n,status:r,data:i}=await bG(`DELETE`,`/${t}`);return n?{stdout:`Deleted webhook "${t}"\n`,stderr:``,exitCode:0}:r===404?{stdout:``,stderr:`webhook: webhook "${t}" not found\n`,exitCode:1}:{stdout:``,stderr:`webhook: failed to delete webhook: ${i.error??`unknown error`}\n`,exitCode:1}}default:return{stdout:``,stderr:`webhook: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`webhook: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function SG(){return{stdout:`usage: crontask <command> [options]
2917
+ `,exitCode:1};let{ok:n,status:r,data:i}=await xG(`DELETE`,`/${t}`);return n?{stdout:`Deleted webhook "${t}"\n`,stderr:``,exitCode:0}:r===404?{stdout:``,stderr:`webhook: webhook "${t}" not found\n`,exitCode:1}:{stdout:``,stderr:`webhook: failed to delete webhook: ${i.error??`unknown error`}\n`,exitCode:1}}default:return{stdout:``,stderr:`webhook: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`webhook: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function CG(){return{stdout:`usage: crontask <command> [options]
2868
2918
 
2869
2919
  Commands:
2870
2920
  create [options] Create a new cron task
@@ -2896,16 +2946,16 @@ Examples:
2896
2946
  crontask create --name every-5min --scoop poller --cron "*/5 * * * *" --filter "() => ({ time: Date.now() })"
2897
2947
  crontask list
2898
2948
  crontask delete abc123
2899
- `,stderr:``,exitCode:0}}var CG=typeof chrome<`u`&&!!chrome?.runtime?.id;function wG(){return globalThis.__slicc_lickManager??null}var TG=null;async function EG(){if(TG)return TG;let{createLickManagerProxy:e}=await y(async()=>{let{createLickManagerProxy:e}=await import(`./lick-manager-proxy-B2bMdplq.js`);return{createLickManagerProxy:e}},[]);return TG=e(),TG}async function DG(e,t,n){let r={method:e,headers:{"Content-Type":`application/json`}};n&&(r.body=JSON.stringify(n));let i=await fetch(`/api/crontasks${t}`,r),a=await i.json().catch(()=>({}));return{ok:i.ok,status:i.status,data:a}}function OG(){return $P(`crontask`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return SG();let t=e[0];try{switch(t){case`create`:{let t,n,r,i,a=e.indexOf(`--name`);a!==-1&&e[a+1]&&(t=e[a+1]);let o=e.indexOf(`--cron`);o!==-1&&e[o+1]&&(n=e[o+1]);let s=e.indexOf(`--filter`);s!==-1&&e[s+1]&&(r=e[s+1]);let c=e.indexOf(`--scoop`);if(c!==-1&&e[c+1]&&(i=e[c+1]),!t)return{stdout:``,stderr:`crontask: --name is required
2949
+ `,stderr:``,exitCode:0}}var wG=typeof chrome<`u`&&!!chrome?.runtime?.id;function TG(){return globalThis.__slicc_lickManager??null}var EG=null;async function DG(){if(EG)return EG;let{createLickManagerProxy:e}=await y(async()=>{let{createLickManagerProxy:e}=await import(`./lick-manager-proxy-B2bMdplq.js`);return{createLickManagerProxy:e}},[]);return EG=e(),EG}async function OG(e,t,n){let r={method:e,headers:{"Content-Type":`application/json`}};n&&(r.body=JSON.stringify(n));let i=await fetch(`/api/crontasks${t}`,r),a=await i.json().catch(()=>({}));return{ok:i.ok,status:i.status,data:a}}function kG(){return $P(`crontask`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return CG();let t=e[0];try{switch(t){case`create`:{let t,n,r,i,a=e.indexOf(`--name`);a!==-1&&e[a+1]&&(t=e[a+1]);let o=e.indexOf(`--cron`);o!==-1&&e[o+1]&&(n=e[o+1]);let s=e.indexOf(`--filter`);s!==-1&&e[s+1]&&(r=e[s+1]);let c=e.indexOf(`--scoop`);if(c!==-1&&e[c+1]&&(i=e[c+1]),!t)return{stdout:``,stderr:`crontask: --name is required
2900
2950
  `,exitCode:1};if(!n)return{stdout:``,stderr:`crontask: --cron is required
2901
- `,exitCode:1};if(CG){if(r)return{stdout:``,stderr:`crontask: --filter is not supported in extension mode (CSP restriction)
2902
- `,exitCode:1};let e=wG(),a=e?await e.createCronTask(t,n,i):await(await EG()).createCronTask(t,n,i),o=`Created cron task "${a.name}"\n`;return o+=`ID: ${a.id}\n`,o+=`Cron: ${a.cron}\n`,a.scoop&&(o+=`Scoop: ${a.scoop}\n`),a.nextRun&&(o+=`Next run: ${new Date(a.nextRun).toLocaleString()}\n`),{stdout:o,stderr:``,exitCode:0}}let{ok:l,data:u}=await DG(`POST`,``,{name:t,cron:n,filter:r,scoop:i});if(!l)return{stdout:``,stderr:`crontask: failed to create: ${u.error??`unknown error`}\n`,exitCode:1};let d=u,f=`Created cron task "${d.name}"\n`;return f+=`ID: ${d.id}\n`,f+=`Cron: ${d.cron}\n`,d.scoop&&(f+=`Scoop: ${d.scoop}\n`),d.filter&&(f+=`Filter: ${d.filter}\n`),d.nextRun&&(f+=`Next run: ${new Date(d.nextRun).toLocaleString()}\n`),{stdout:f,stderr:``,exitCode:0}}case`list`:{if(CG){let e=wG(),t=e?e.listCronTasks():await(async()=>{let{listCronTasksAsync:e}=await y(async()=>{let{listCronTasksAsync:e}=await import(`./lick-manager-proxy-B2bMdplq.js`);return{listCronTasksAsync:e}},[]);return e()})();if(t.length===0)return{stdout:`No active cron tasks
2951
+ `,exitCode:1};if(wG){if(r)return{stdout:``,stderr:`crontask: --filter is not supported in extension mode (CSP restriction)
2952
+ `,exitCode:1};let e=TG(),a=e?await e.createCronTask(t,n,i):await(await DG()).createCronTask(t,n,i),o=`Created cron task "${a.name}"\n`;return o+=`ID: ${a.id}\n`,o+=`Cron: ${a.cron}\n`,a.scoop&&(o+=`Scoop: ${a.scoop}\n`),a.nextRun&&(o+=`Next run: ${new Date(a.nextRun).toLocaleString()}\n`),{stdout:o,stderr:``,exitCode:0}}let{ok:l,data:u}=await OG(`POST`,``,{name:t,cron:n,filter:r,scoop:i});if(!l)return{stdout:``,stderr:`crontask: failed to create: ${u.error??`unknown error`}\n`,exitCode:1};let d=u,f=`Created cron task "${d.name}"\n`;return f+=`ID: ${d.id}\n`,f+=`Cron: ${d.cron}\n`,d.scoop&&(f+=`Scoop: ${d.scoop}\n`),d.filter&&(f+=`Filter: ${d.filter}\n`),d.nextRun&&(f+=`Next run: ${new Date(d.nextRun).toLocaleString()}\n`),{stdout:f,stderr:``,exitCode:0}}case`list`:{if(wG){let e=TG(),t=e?e.listCronTasks():await(async()=>{let{listCronTasksAsync:e}=await y(async()=>{let{listCronTasksAsync:e}=await import(`./lick-manager-proxy-B2bMdplq.js`);return{listCronTasksAsync:e}},[]);return e()})();if(t.length===0)return{stdout:`No active cron tasks
2903
2953
  `,stderr:``,exitCode:0};let n=`Active cron tasks:
2904
2954
  `;for(let e of t)n+=` ${e.id} ${e.name.padEnd(20)} ${e.cron.padEnd(15)}`,e.scoop&&(n+=` -> ${e.scoop}`),e.filter&&(n+=` [filtered]`),n+=` (${e.status})`,e.nextRun&&(n+=` next: ${new Date(e.nextRun).toLocaleString()}`),n+=`
2905
- `;return{stdout:n,stderr:``,exitCode:0}}let{ok:e,data:t}=await DG(`GET`,``);if(!e)return{stdout:``,stderr:`crontask: failed to list: ${t.error??`unknown error`}\n`,exitCode:1};let n=t;if(n.length===0)return{stdout:`No active cron tasks
2955
+ `;return{stdout:n,stderr:``,exitCode:0}}let{ok:e,data:t}=await OG(`GET`,``);if(!e)return{stdout:``,stderr:`crontask: failed to list: ${t.error??`unknown error`}\n`,exitCode:1};let n=t;if(n.length===0)return{stdout:`No active cron tasks
2906
2956
  `,stderr:``,exitCode:0};let r=`Active cron tasks:
2907
2957
  `;for(let e of n)r+=` ${e.id} ${e.name.padEnd(20)} ${e.cron.padEnd(15)}`,e.scoop&&(r+=` -> ${e.scoop}`),e.filter&&(r+=` [filtered]`),r+=` (${e.status})`,e.nextRun&&(r+=` next: ${new Date(e.nextRun).toLocaleString()}`),r+=`
2908
- `;return{stdout:r,stderr:``,exitCode:0}}case`delete`:case`kill`:{let n=e[1];if(!n)return{stdout:``,stderr:`crontask: ${t} requires an ID\n`,exitCode:1};if(CG){let e=wG();return(e?await e.deleteCronTask(n):await(await EG()).deleteCronTask(n))?{stdout:`Deleted cron task "${n}"\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`crontask: task "${n}" not found\n`,exitCode:1}}let{ok:r,status:i,data:a}=await DG(`DELETE`,`/${n}`);return r?{stdout:`Deleted cron task "${n}"\n`,stderr:``,exitCode:0}:i===404?{stdout:``,stderr:`crontask: task "${n}" not found\n`,exitCode:1}:{stdout:``,stderr:`crontask: failed to delete: ${a.error??`unknown error`}\n`,exitCode:1}}default:return{stdout:``,stderr:`crontask: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`crontask: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function kG(){return{stdout:`usage: sprinkle <subcommand> [args]
2958
+ `;return{stdout:r,stderr:``,exitCode:0}}case`delete`:case`kill`:{let n=e[1];if(!n)return{stdout:``,stderr:`crontask: ${t} requires an ID\n`,exitCode:1};if(wG){let e=TG();return(e?await e.deleteCronTask(n):await(await DG()).deleteCronTask(n))?{stdout:`Deleted cron task "${n}"\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`crontask: task "${n}" not found\n`,exitCode:1}}let{ok:r,status:i,data:a}=await OG(`DELETE`,`/${n}`);return r?{stdout:`Deleted cron task "${n}"\n`,stderr:``,exitCode:0}:i===404?{stdout:``,stderr:`crontask: task "${n}" not found\n`,exitCode:1}:{stdout:``,stderr:`crontask: failed to delete: ${a.error??`unknown error`}\n`,exitCode:1}}default:return{stdout:``,stderr:`crontask: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`crontask: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function AG(){return{stdout:`usage: sprinkle <subcommand> [args]
2909
2959
 
2910
2960
  list List available .shtml sprinkles
2911
2961
  open <name> Open a sprinkle by name
@@ -2915,10 +2965,10 @@ Examples:
2915
2965
  chat <html> Show inline HTML in chat (Tool UI)
2916
2966
  Use data-action="name" on buttons for callbacks
2917
2967
  Pipe HTML: echo "<div>...</div>" | sprinkle chat
2918
- `,stderr:``,exitCode:0}}function AG(){return typeof window>`u`?null:window.__slicc_sprinkleManager??null}function jG(){return $P(`sprinkle`,async(e,t)=>{if(e.length===0||e[0]===`--help`||e[0]===`-h`)return kG();let n=e[0];if(n===`chat`){let n=e.slice(1).join(` `);if(!n&&t.stdin&&(n=t.stdin),!n)return{stdout:``,stderr:`sprinkle chat: HTML content required
2968
+ `,stderr:``,exitCode:0}}function jG(){return typeof window>`u`?null:window.__slicc_sprinkleManager??null}function MG(){return $P(`sprinkle`,async(e,t)=>{if(e.length===0||e[0]===`--help`||e[0]===`-h`)return AG();let n=e[0];if(n===`chat`){let n=e.slice(1).join(` `);if(!n&&t.stdin&&(n=t.stdin),!n)return{stdout:``,stderr:`sprinkle chat: HTML content required
2919
2969
  `,exitCode:1};let r=await _({html:n,onAction:async(e,t)=>({action:e,data:t})});return r===null?{stdout:``,stderr:`sprinkle chat: not in tool execution context
2920
2970
  `,exitCode:1}:{stdout:JSON.stringify(r)+`
2921
- `,stderr:``,exitCode:0}}let r=AG();if(!r)return{stdout:``,stderr:`sprinkle: sprinkle manager not initialized
2971
+ `,stderr:``,exitCode:0}}let r=jG();if(!r)return{stdout:``,stderr:`sprinkle: sprinkle manager not initialized
2922
2972
  `,exitCode:1};switch(n){case`list`:{await r.refresh();let e=r.available();if(e.length===0)return{stdout:`No .shtml sprinkles found.
2923
2973
  `,stderr:``,exitCode:0};let t=new Set(r.opened());return{stdout:e.map(e=>{let n=t.has(e.name)?` [open]`:``;return` ${e.name}${n} ${e.title} (${e.path})`}).join(`
2924
2974
  `)+`
@@ -2927,7 +2977,7 @@ Examples:
2927
2977
  `,exitCode:1}}case`refresh`:{await r.refresh();let e=r.available().length;return{stdout:`Found ${e} sprinkle${e===1?``:`s`}.\n`,stderr:``,exitCode:0}}case`send`:{let t=e[1];if(!t)return{stdout:``,stderr:`sprinkle send: name required
2928
2978
  `,exitCode:1};let n=e.slice(2).join(` `);if(!n)return{stdout:``,stderr:`sprinkle send: JSON data required
2929
2979
  `,exitCode:1};let i;try{i=JSON.parse(n)}catch{return{stdout:``,stderr:`sprinkle send: invalid JSON
2930
- `,exitCode:1}}return r.sendToSprinkle(t,i),{stdout:`Data sent to sprinkle "${t}".\n`,stderr:``,exitCode:0}}default:return{stdout:``,stderr:`sprinkle: unknown subcommand "${n}"\n`,exitCode:1}}})}function MG(){return`oauth-token — get an OAuth access token for a provider
2980
+ `,exitCode:1}}return r.sendToSprinkle(t,i),{stdout:`Data sent to sprinkle "${t}".\n`,stderr:``,exitCode:0}}default:return{stdout:``,stderr:`sprinkle: unknown subcommand "${n}"\n`,exitCode:1}}})}function NG(){return`oauth-token — get an OAuth access token for a provider
2931
2981
 
2932
2982
  Usage:
2933
2983
  oauth-token <providerId> Get token for a specific provider
@@ -2943,13 +2993,13 @@ on success.
2943
2993
  Examples:
2944
2994
  oauth-token adobe
2945
2995
  curl -H "Authorization: Bearer $(oauth-token adobe)" https://api.corp.com/data
2946
- `}function NG(){return $P(`oauth-token`,async e=>{let{getOAuthAccountInfo:t,getSelectedProvider:n,getAccounts:r}=await y(async()=>{let{getOAuthAccountInfo:e,getSelectedProvider:t,getAccounts:n}=await import(`./provider-settings-YOjGG5m2.js`);return{getOAuthAccountInfo:e,getSelectedProvider:t,getAccounts:n}},__vite__mapDeps([8,9,1,4,10,11,12,13,14])),{getRegisteredProviderConfig:i,getRegisteredProviderIds:a}=await y(async()=>{let{getRegisteredProviderConfig:e,getRegisteredProviderIds:t}=await import(`./providers-BkGRqgnv.js`);return{getRegisteredProviderConfig:e,getRegisteredProviderIds:t}},__vite__mapDeps([15,9,1,4,10,11,12,13,14]));if(e.includes(`--help`)||e.includes(`-h`))return{stdout:MG(),stderr:``,exitCode:0};if(e.includes(`--list`))return PG(r,a,i,t);let o,s=e.indexOf(`--provider`);if(s>=0){if(o=e[s+1],!o)return{stdout:``,stderr:`oauth-token: --provider requires a value
2996
+ `}function PG(){return $P(`oauth-token`,async e=>{let{getOAuthAccountInfo:t,getSelectedProvider:n,getAccounts:r}=await y(async()=>{let{getOAuthAccountInfo:e,getSelectedProvider:t,getAccounts:n}=await import(`./provider-settings-Bkf2ADq8.js`);return{getOAuthAccountInfo:e,getSelectedProvider:t,getAccounts:n}},__vite__mapDeps([8,9,1,4,10,11,12,13,14])),{getRegisteredProviderConfig:i,getRegisteredProviderIds:a}=await y(async()=>{let{getRegisteredProviderConfig:e,getRegisteredProviderIds:t}=await import(`./providers-BkGRqgnv.js`);return{getRegisteredProviderConfig:e,getRegisteredProviderIds:t}},__vite__mapDeps([15,9,1,4,10,11,12,13,14]));if(e.includes(`--help`)||e.includes(`-h`))return{stdout:NG(),stderr:``,exitCode:0};if(e.includes(`--list`))return FG(r,a,i,t);let o,s=e.indexOf(`--provider`);if(s>=0){if(o=e[s+1],!o)return{stdout:``,stderr:`oauth-token: --provider requires a value
2947
2997
  `,exitCode:1}}else if(e.length>0)o=e[0];else{let e=n(),t=i(e);if(t?.isOAuth&&t.onOAuthLogin)o=e;else if(o=a().find(e=>{let t=i(e);return t?.isOAuth&&t.onOAuthLogin}),!o)return{stdout:``,stderr:`oauth-token: no OAuth providers configured
2948
2998
  `,exitCode:1}}let c=i(o);if(!c)return{stdout:``,stderr:`oauth-token: unknown provider "${o}"\n`,exitCode:1};if(!c.isOAuth||!c.onOAuthLogin)return{stdout:``,stderr:`oauth-token: provider "${o}" is not an OAuth provider\n`,exitCode:1};let l=t(o);if(l&&!l.expired)return{stdout:`${l.token}\n`,stderr:``,exitCode:0};try{let{createOAuthLauncher:e}=await y(async()=>{let{createOAuthLauncher:e}=await import(`./oauth-service-38tFqQEB.js`);return{createOAuthLauncher:e}},[]),n=e();await c.onOAuthLogin(n,()=>{});let r=t(o);return r&&r.token?{stdout:`${r.token}\n`,stderr:``,exitCode:0}:(console.error(`[oauth-token] Provider ${o}: login completed but no token was saved`),{stdout:``,stderr:`oauth-token: login completed but no token was saved
2949
- `,exitCode:1})}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`[oauth-token] Provider ${o}: login failed:`,t),{stdout:``,stderr:`oauth-token: login failed: ${t}\n`,exitCode:1}}})}function PG(e,t,n,r){let i=t().filter(e=>n(e)?.isOAuth);if(i.length===0)return{stdout:`No OAuth providers configured.
2999
+ `,exitCode:1})}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`[oauth-token] Provider ${o}: login failed:`,t),{stdout:``,stderr:`oauth-token: login failed: ${t}\n`,exitCode:1}}})}function FG(e,t,n,r){let i=t().filter(e=>n(e)?.isOAuth);if(i.length===0)return{stdout:`No OAuth providers configured.
2950
3000
  `,stderr:``,exitCode:0};let a=[];for(let e of i){let t=r(e);if(!t)a.push(`${e} (no token)`);else if(t.expired){let n=t.userName?` as ${t.userName}`:``;a.push(`${e} (expired${n})`)}else{let n=[];if(t.userName?n.push(`logged in as ${t.userName}`):n.push(`logged in`),t.expiresAt){let e=t.expiresAt-Date.now();if(e>0){let t=Math.floor(e/36e5),r=Math.floor(e%36e5/6e4);t>0?n.push(`expires in ${t}h`):n.push(`expires in ${r}m`)}}a.push(`${e} (${n.join(`, `)})`)}}return{stdout:a.join(`
2951
3001
  `)+`
2952
- `,stderr:``,exitCode:0}}function FG(e,t,n={}){let r=new Map;for(let e of t)r.set(e.path,e);let i=new Set,a=[],o=[],s=[];for(let t of e){i.add(t.path);let e=r.get(t.path);e?e.size===t.size&&e.mtimeMs===t.mtimeMs?s.push(t.path):o.push(t.path):a.push(t.path)}let c=[];if(n.delete)for(let e of t)i.has(e.path)||c.push(e.path);return{toAdd:a,toUpdate:o,toDelete:c,toSkip:s}}var IG=null;function LG(e){IG=e}function RG(){return IG?.()??null}function zG(e){let t={dryRun:!1,delete:!1,verbose:!1},n=[];for(let r of e)if(r===`--dry-run`||r===`-n`)t.dryRun=!0;else if(r===`--delete`)t.delete=!0;else if(r===`--verbose`||r===`-v`)t.verbose=!0;else if(r===`--help`||r===`-h`)return{error:`__help__`};else if(r.startsWith(`-`))return{error:`Unknown flag: ${r}`};else n.push(r);if(n.length!==2)return{error:`Expected exactly 2 arguments: <source> <dest>`};let[r,i]=n,a=BG(r),o=BG(i);return a&&o?{error:`Cannot sync between two remote paths — one side must be local`}:!a&&!o?{error:`One argument must be a remote path (runtime-id:/path)`}:o?{direction:`push`,localPath:r,remotePath:o.path,runtimeId:o.runtimeId,...t}:{direction:`pull`,localPath:i,remotePath:a.path,runtimeId:a.runtimeId,...t}}function BG(e){let t=e.indexOf(`:`);if(t<=0)return null;let n=e.slice(0,t),r=e.slice(t+1);return r.startsWith(`/`)?{runtimeId:n,path:r}:null}function VG(){return{stdout:`rsync — sync files between local VFS and a remote tray runtime
3002
+ `,stderr:``,exitCode:0}}function IG(e,t,n={}){let r=new Map;for(let e of t)r.set(e.path,e);let i=new Set,a=[],o=[],s=[];for(let t of e){i.add(t.path);let e=r.get(t.path);e?e.size===t.size&&e.mtimeMs===t.mtimeMs?s.push(t.path):o.push(t.path):a.push(t.path)}let c=[];if(n.delete)for(let e of t)i.has(e.path)||c.push(e.path);return{toAdd:a,toUpdate:o,toDelete:c,toSkip:s}}var LG=null;function RG(e){LG=e}function zG(){return LG?.()??null}function BG(e){let t={dryRun:!1,delete:!1,verbose:!1},n=[];for(let r of e)if(r===`--dry-run`||r===`-n`)t.dryRun=!0;else if(r===`--delete`)t.delete=!0;else if(r===`--verbose`||r===`-v`)t.verbose=!0;else if(r===`--help`||r===`-h`)return{error:`__help__`};else if(r.startsWith(`-`))return{error:`Unknown flag: ${r}`};else n.push(r);if(n.length!==2)return{error:`Expected exactly 2 arguments: <source> <dest>`};let[r,i]=n,a=VG(r),o=VG(i);return a&&o?{error:`Cannot sync between two remote paths — one side must be local`}:!a&&!o?{error:`One argument must be a remote path (runtime-id:/path)`}:o?{direction:`push`,localPath:r,remotePath:o.path,runtimeId:o.runtimeId,...t}:{direction:`pull`,localPath:i,remotePath:a.path,runtimeId:a.runtimeId,...t}}function VG(e){let t=e.indexOf(`:`);if(t<=0)return null;let n=e.slice(0,t),r=e.slice(t+1);return r.startsWith(`/`)?{runtimeId:n,path:r}:null}function HG(){return{stdout:`rsync — sync files between local VFS and a remote tray runtime
2953
3003
 
2954
3004
  Usage:
2955
3005
  rsync [flags] <local-path> <runtime-id>:<remote-path> # push
@@ -2965,21 +3015,21 @@ Examples:
2965
3015
  rsync /workspace follower-abc123:/workspace
2966
3016
  rsync --delete /shared leader:/shared
2967
3017
  rsync follower-abc123:/workspace/project /workspace/project
2968
- `,stderr:``,exitCode:0}}async function HG(e,t){if(!await e.exists(t))return[];let n=[];for await(let r of e.walk(t)){let i=r.slice(t.length).replace(/^\//,``);if(!i)continue;let a=await e.stat(r);n.push({path:i,size:a.size,mtimeMs:a.mtime})}return n}async function UG(e,t,n){let r=(await e(t,{op:`walk`,path:n}))[0];if(!r.ok){if(r.code===`ENOENT`)return[];throw Error(`Remote walk failed: ${r.error}`)}if(r.data.type!==`paths`)throw Error(`Unexpected walk response type`);let i=r.data.paths,a=[];for(let r of i){let i=r.slice(n.length).replace(/^\//,``);if(!i)continue;let o=(await e(t,{op:`stat`,path:r}))[0];o.ok&&o.data.type===`stat`&&a.push({path:i,size:o.data.stat.size,mtimeMs:o.data.stat.mtime})}return a}async function WG(e,t,n){let r=await e(t,{op:`readFile`,path:n,encoding:`binary`}),i=``;for(let e of r){if(!e.ok)throw Error(`Remote read failed: ${e.error}`);e.data.type===`file`&&(i+=e.data.content)}return i}async function GG(e,t,n){let r=await e(t,{op:`mkdir`,path:n,recursive:!0});if(!r[0].ok)throw Error(`Remote mkdir failed: ${r[0].error}`)}function KG(e){let t=e.lastIndexOf(`/`);return t<=0?`/`:e.slice(0,t)}async function qG(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=FG(await HG(e,i),await UG(t,o,a),{delete:n.delete});if(s||c){for(let e of l.toAdd)r.push(`+ ${e}`);for(let e of l.toUpdate)r.push(`~ ${e}`);for(let e of l.toDelete)r.push(`- ${e}`);if(s)for(let e of l.toSkip)r.push(` ${e} (up to date)`)}let u=l.toAdd.length+l.toUpdate.length+l.toDelete.length;if(c)return r.push(`\n(dry run) ${u} file(s) would be transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
3018
+ `,stderr:``,exitCode:0}}async function UG(e,t){if(!await e.exists(t))return[];let n=[];for await(let r of e.walk(t)){let i=r.slice(t.length).replace(/^\//,``);if(!i)continue;let a=await e.stat(r);n.push({path:i,size:a.size,mtimeMs:a.mtime})}return n}async function WG(e,t,n){let r=(await e(t,{op:`walk`,path:n}))[0];if(!r.ok){if(r.code===`ENOENT`)return[];throw Error(`Remote walk failed: ${r.error}`)}if(r.data.type!==`paths`)throw Error(`Unexpected walk response type`);let i=r.data.paths,a=[];for(let r of i){let i=r.slice(n.length).replace(/^\//,``);if(!i)continue;let o=(await e(t,{op:`stat`,path:r}))[0];o.ok&&o.data.type===`stat`&&a.push({path:i,size:o.data.stat.size,mtimeMs:o.data.stat.mtime})}return a}async function GG(e,t,n){let r=await e(t,{op:`readFile`,path:n,encoding:`binary`}),i=``;for(let e of r){if(!e.ok)throw Error(`Remote read failed: ${e.error}`);e.data.type===`file`&&(i+=e.data.content)}return i}async function KG(e,t,n){let r=await e(t,{op:`mkdir`,path:n,recursive:!0});if(!r[0].ok)throw Error(`Remote mkdir failed: ${r[0].error}`)}function qG(e){let t=e.lastIndexOf(`/`);return t<=0?`/`:e.slice(0,t)}async function JG(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=IG(await UG(e,i),await WG(t,o,a),{delete:n.delete});if(s||c){for(let e of l.toAdd)r.push(`+ ${e}`);for(let e of l.toUpdate)r.push(`~ ${e}`);for(let e of l.toDelete)r.push(`- ${e}`);if(s)for(let e of l.toSkip)r.push(` ${e} (up to date)`)}let u=l.toAdd.length+l.toUpdate.length+l.toDelete.length;if(c)return r.push(`\n(dry run) ${u} file(s) would be transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
2969
3019
  `)+`
2970
- `,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let s=i+`/`+n,c=a+`/`+n;await GG(t,o,KG(c));let l=await t(o,{op:`writeFile`,path:c,content:YG(await e.readFile(s,{encoding:`binary`})),encoding:`base64`});if(!l[0].ok)return{stdout:r.join(`
3020
+ `,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let s=i+`/`+n,c=a+`/`+n;await KG(t,o,qG(c));let l=await t(o,{op:`writeFile`,path:c,content:XG(await e.readFile(s,{encoding:`binary`})),encoding:`base64`});if(!l[0].ok)return{stdout:r.join(`
2971
3021
  `)+`
2972
3022
  `,stderr:`Error writing ${c}: ${l[0].error}\n`,exitCode:1}}for(let e of l.toDelete){let n=a+`/`+e,i=await t(o,{op:`rm`,path:n});if(!i[0].ok)return{stdout:r.join(`
2973
3023
  `)+`
2974
3024
  `,stderr:`Error deleting ${n}: ${i[0].error}\n`,exitCode:1}}return r.push(`${u} file(s) transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
2975
3025
  `)+`
2976
- `,stderr:``,exitCode:0}}async function JG(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=FG(await UG(t,o,a),await HG(e,i),{delete:n.delete});if(s||c){for(let e of l.toAdd)r.push(`+ ${e}`);for(let e of l.toUpdate)r.push(`~ ${e}`);for(let e of l.toDelete)r.push(`- ${e}`);if(s)for(let e of l.toSkip)r.push(` ${e} (up to date)`)}let u=l.toAdd.length+l.toUpdate.length+l.toDelete.length;if(c)return r.push(`\n(dry run) ${u} file(s) would be transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
3026
+ `,stderr:``,exitCode:0}}async function YG(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=IG(await WG(t,o,a),await UG(e,i),{delete:n.delete});if(s||c){for(let e of l.toAdd)r.push(`+ ${e}`);for(let e of l.toUpdate)r.push(`~ ${e}`);for(let e of l.toDelete)r.push(`- ${e}`);if(s)for(let e of l.toSkip)r.push(` ${e} (up to date)`)}let u=l.toAdd.length+l.toUpdate.length+l.toDelete.length;if(c)return r.push(`\n(dry run) ${u} file(s) would be transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
2977
3027
  `)+`
2978
- `,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let r=a+`/`+n,s=i+`/`+n,c=KG(s);await e.exists(c)||await e.mkdir(c,{recursive:!0});let l=XG(await WG(t,o,r));await e.writeFile(s,l)}for(let t of l.toDelete){let n=i+`/`+t;await e.rm(n)}return r.push(`${u} file(s) transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
3028
+ `,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let r=a+`/`+n,s=i+`/`+n,c=qG(s);await e.exists(c)||await e.mkdir(c,{recursive:!0});let l=ZG(await GG(t,o,r));await e.writeFile(s,l)}for(let t of l.toDelete){let n=i+`/`+t;await e.rm(n)}return r.push(`${u} file(s) transferred, ${l.toSkip.length} up to date`),{stdout:r.join(`
2979
3029
  `)+`
2980
- `,stderr:``,exitCode:0}}function YG(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function XG(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}function ZG(e={}){let t=e.fs,n=e.getSendFsRequest??RG;return $P(`rsync`,async e=>{if(e.includes(`--help`)||e.includes(`-h`)||e.length===0)return VG();if(!t)return{stdout:``,stderr:`rsync: no filesystem available
3030
+ `,stderr:``,exitCode:0}}function XG(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function ZG(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}function QG(e={}){let t=e.fs,n=e.getSendFsRequest??zG;return $P(`rsync`,async e=>{if(e.includes(`--help`)||e.includes(`-h`)||e.length===0)return HG();if(!t)return{stdout:``,stderr:`rsync: no filesystem available
2981
3031
  `,exitCode:1};let r=n();if(!r)return{stdout:``,stderr:`rsync: not connected to a tray — rsync requires a tray connection
2982
- `,exitCode:1};let i=zG(e);if(`error`in i)return i.error===`__help__`?VG():{stdout:``,stderr:`rsync: ${i.error}\n`,exitCode:1};try{return i.direction===`push`?await qG(t,r,i):await JG(t,r,i)}catch(e){return{stdout:``,stderr:`rsync: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}var QG=[`/workspace/skills`];async function $G(e){let t=new Map;for(let n of QG)await e.exists(n)&&await eK(e,n,t);return await eK(e,`/`,t),t}async function eK(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.jsh`))continue;let e=tK(r);n.has(e)||n.set(e,r)}}function tK(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.jsh`)?t.slice(0,-4):t}function nK(e){return $P(`which`,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return{stdout:`which - locate a command
3032
+ `,exitCode:1};let i=BG(e);if(`error`in i)return i.error===`__help__`?HG():{stdout:``,stderr:`rsync: ${i.error}\n`,exitCode:1};try{return i.direction===`push`?await JG(t,r,i):await YG(t,r,i)}catch(e){return{stdout:``,stderr:`rsync: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}var $G=[`/workspace/skills`];async function eK(e){let t=new Map;for(let n of $G)await e.exists(n)&&await tK(e,n,t);return await tK(e,`/`,t),t}async function tK(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.jsh`))continue;let e=nK(r);n.has(e)||n.set(e,r)}}function nK(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.jsh`)?t.slice(0,-4):t}function rK(e){return $P(`which`,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return{stdout:`which - locate a command
2983
3033
 
2984
3034
  Usage: which <command> [command...]
2985
3035
 
@@ -2989,12 +3039,12 @@ Prints the path of the given command(s).
2989
3039
 
2990
3040
  Exit code 0 if all commands found, 1 if any not found.
2991
3041
  `,stderr:``,exitCode:0};if(t.length===0)return{stdout:``,stderr:`which: missing argument
2992
- `,exitCode:1};let r=n.getRegisteredCommands?.()??[],i=new Set(r),a=e?await $G(e):new Map,o=[],s=!0;for(let e of t)if(i.has(e))o.push(`/usr/bin/${e}`);else{let t=a.get(e);t?o.push(t):s=!1}return{stdout:o.length>0?o.join(`
3042
+ `,exitCode:1};let r=n.getRegisteredCommands?.()??[],i=new Set(r),a=e?await eK(e):new Map,o=[],s=!0;for(let e of t)if(i.has(e))o.push(`/usr/bin/${e}`);else{let t=a.get(e);t?o.push(t):s=!1}return{stdout:o.length>0?o.join(`
2993
3043
  `)+`
2994
- `:``,stderr:``,exitCode:+!s}})}async function rK(e,t,n,r){if((await e.fs.stat(t)).isFile)return r[n]=await e.fs.readFileBuffer(t),1;let i=await e.fs.readdir(t),a=0;for(let o of i){let i=EW(t,o),s=n?`${n}/${o}`:o;a+=await rK(e,i,s,r)}return a}function iK(){return{stdout:`usage: zip [-r] <archive.zip> <path> [path...]
2995
- `,stderr:``,exitCode:0}}function aK(){return $P(`zip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return iK();let n=!1,r=[];for(let t of e){if(t===`-r`){n=!0;continue}if(t.startsWith(`-`))return{stdout:``,stderr:`zip: unsupported option ${t}\n`,exitCode:1};r.push(t)}if(r.length<2)return{stdout:``,stderr:`zip: expected archive path and at least one input path
2996
- `,exitCode:1};let i=t.fs.resolvePath(t.cwd,r[0]),a=r.slice(1),o={},s=0;for(let e of a){let r=t.fs.resolvePath(t.cwd,e),i=await t.fs.stat(r),a=(e.startsWith(`/`)?e.slice(1):e.replace(/^\.\//,``))||wW(r);if(i.isDirectory&&!n)return{stdout:``,stderr:`zip: ${e} is a directory (use -r)\n`,exitCode:1};s+=await rK(t,r,a,o)}if(s===0)return{stdout:``,stderr:`zip: nothing to do
2997
- `,exitCode:1};let c=de(o);return await t.fs.writeFile(i,c),{stdout:`created ${i} (${s} file(s))\n`,stderr:``,exitCode:0}})}function oK(){return{stdout:`screencapture - capture screen, window, or tab using browser screen sharing
3044
+ `:``,stderr:``,exitCode:+!s}})}async function iK(e,t,n,r){if((await e.fs.stat(t)).isFile)return r[n]=await e.fs.readFileBuffer(t),1;let i=await e.fs.readdir(t),a=0;for(let o of i){let i=DW(t,o),s=n?`${n}/${o}`:o;a+=await iK(e,i,s,r)}return a}function aK(){return{stdout:`usage: zip [-r] <archive.zip> <path> [path...]
3045
+ `,stderr:``,exitCode:0}}function oK(){return $P(`zip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return aK();let n=!1,r=[];for(let t of e){if(t===`-r`){n=!0;continue}if(t.startsWith(`-`))return{stdout:``,stderr:`zip: unsupported option ${t}\n`,exitCode:1};r.push(t)}if(r.length<2)return{stdout:``,stderr:`zip: expected archive path and at least one input path
3046
+ `,exitCode:1};let i=t.fs.resolvePath(t.cwd,r[0]),a=r.slice(1),o={},s=0;for(let e of a){let r=t.fs.resolvePath(t.cwd,e),i=await t.fs.stat(r),a=(e.startsWith(`/`)?e.slice(1):e.replace(/^\.\//,``))||TW(r);if(i.isDirectory&&!n)return{stdout:``,stderr:`zip: ${e} is a directory (use -r)\n`,exitCode:1};s+=await iK(t,r,a,o)}if(s===0)return{stdout:``,stderr:`zip: nothing to do
3047
+ `,exitCode:1};let c=de(o);return await t.fs.writeFile(i,c),{stdout:`created ${i} (${s} file(s))\n`,stderr:``,exitCode:0}})}function sK(){return{stdout:`screencapture - capture screen, window, or tab using browser screen sharing
2998
3048
 
2999
3049
  Usage: screencapture [options] <output-file>
3000
3050
 
@@ -3010,57 +3060,75 @@ Examples:
3010
3060
  screencapture screenshot.png # Capture to file
3011
3061
  screencapture -c # Capture to clipboard
3012
3062
  screencapture -v capture.png # Capture and return for agent vision
3013
- `,stderr:``,exitCode:0}}function sK(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 cK(e){switch(e.split(`.`).pop()?.toLowerCase()){case`jpg`:case`jpeg`:return`image/jpeg`;case`webp`:return`image/webp`;default:return`image/png`}}async function lK(e,t){let n=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1});try{let r=document.createElement(`video`);r.srcObject=n,r.muted=!0,r.playsInline=!0,await new Promise((e,t)=>{r.onloadedmetadata=()=>{r.play().then(()=>e()).catch(t)},r.onerror=()=>t(Error(`Failed to load video stream`))}),await new Promise(e=>requestAnimationFrame(e));let i=r.videoWidth,a=r.videoHeight,o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);if(!s)throw Error(`Failed to get canvas context`);return s.drawImage(r,0,0,i,a),new Promise((n,r)=>{o.toBlob(e=>{e?n(e):r(Error(`Failed to create image blob`))},e,t)})}finally{n.getTracks().forEach(e=>e.stop())}}function uK(){return $P(`screencapture`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return oK();if(typeof window>`u`||typeof navigator>`u`||typeof document>`u`)return{stdout:``,stderr:`screencapture: browser APIs are unavailable in this environment
3063
+ `,stderr:``,exitCode:0}}function cK(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 lK(e){switch(e.split(`.`).pop()?.toLowerCase()){case`jpg`:case`jpeg`:return`image/jpeg`;case`webp`:return`image/webp`;default:return`image/png`}}async function uK(e,t){let n=await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1});try{let r=document.createElement(`video`);r.srcObject=n,r.muted=!0,r.playsInline=!0,await new Promise((e,t)=>{r.onloadedmetadata=()=>{r.play().then(()=>e()).catch(t)},r.onerror=()=>t(Error(`Failed to load video stream`))}),await new Promise(e=>requestAnimationFrame(e));let i=r.videoWidth,a=r.videoHeight,o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);if(!s)throw Error(`Failed to get canvas context`);return s.drawImage(r,0,0,i,a),new Promise((n,r)=>{o.toBlob(e=>{e?n(e):r(Error(`Failed to create image blob`))},e,t)})}finally{n.getTracks().forEach(e=>e.stop())}}function dK(){return $P(`screencapture`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return sK();if(typeof window>`u`||typeof navigator>`u`||typeof document>`u`)return{stdout:``,stderr:`screencapture: browser APIs are unavailable in this environment
3014
3064
  `,exitCode:1};if(!navigator.mediaDevices?.getDisplayMedia)return{stdout:``,stderr:`screencapture: screen capture is not supported in this browser
3015
3065
  `,exitCode:1};let n=e.includes(`--clipboard`)||e.includes(`-c`),r=e.includes(`--view`)||e.includes(`-v`),i=[`--clipboard`,`-c`,`--view`,`-v`,`--help`,`-h`],a=e.indexOf(`--`),o=(a>=0?e.slice(a+1):e.filter(e=>!i.includes(e)))[0];if(!n&&!o)return{stdout:``,stderr:`screencapture: output file required (or use -c for clipboard)
3016
- `,exitCode:1};let s=o||`screenshot.png`,c=cK(s),l=c===`image/png`?1:.92,u;try{u=await lK(c,l)}catch(e){let t=e instanceof Error?e.message:String(e);return t.includes(`Permission denied`)||t.includes(`NotAllowedError`)?{stdout:``,stderr:`screencapture: user cancelled or permission denied
3017
- `,exitCode:1}:{stdout:``,stderr:`screencapture: ${t}\n`,exitCode:1}}let d=await u.arrayBuffer(),f=new Uint8Array(d);if(n)try{let e;if(c===`image/png`)e=u;else{let t=new Image,n=URL.createObjectURL(u);try{await new Promise((e,r)=>{t.onload=()=>e(),t.onerror=()=>r(Error(`Failed to load image for conversion`)),t.src=n})}finally{URL.revokeObjectURL(n)}let r=document.createElement(`canvas`);r.width=t.width,r.height=t.height;let i=r.getContext(`2d`);if(!i)throw Error(`Failed to get canvas context`);i.drawImage(t,0,0),e=await new Promise((e,t)=>{r.toBlob(n=>{n?e(n):t(Error(`Failed to create PNG blob`))},`image/png`)})}return await navigator.clipboard.write([new ClipboardItem({"image/png":e})]),{stdout:`captured ${Math.round(e.size/1024)} KB to clipboard\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`screencapture: failed to copy to clipboard: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let p=t.fs.resolvePath(t.cwd,s);try{await t.fs.writeFile(p,f)}catch(e){return{stdout:``,stderr:`screencapture: failed to write file: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let m=Math.round(f.length/1024);return r?{stdout:`${p} (${m} KB)\n<img:data:${c};base64,${sK(f)}>`,stderr:``,exitCode:0}:{stdout:`captured ${m} KB to ${wW(p)}\n`,stderr:``,exitCode:0}})}function dK(e){return e instanceof Error?e.message:String(e)}function fK(){return{stdout:`usage: pbcopy
3066
+ `,exitCode:1};let s=o||`screenshot.png`,c=lK(s),l=c===`image/png`?1:.92,u;try{u=await uK(c,l)}catch(e){let t=e instanceof Error?e.message:String(e);return t.includes(`Permission denied`)||t.includes(`NotAllowedError`)?{stdout:``,stderr:`screencapture: user cancelled or permission denied
3067
+ `,exitCode:1}:{stdout:``,stderr:`screencapture: ${t}\n`,exitCode:1}}let d=await u.arrayBuffer(),f=new Uint8Array(d);if(n)try{let e;if(c===`image/png`)e=u;else{let t=new Image,n=URL.createObjectURL(u);try{await new Promise((e,r)=>{t.onload=()=>e(),t.onerror=()=>r(Error(`Failed to load image for conversion`)),t.src=n})}finally{URL.revokeObjectURL(n)}let r=document.createElement(`canvas`);r.width=t.width,r.height=t.height;let i=r.getContext(`2d`);if(!i)throw Error(`Failed to get canvas context`);i.drawImage(t,0,0),e=await new Promise((e,t)=>{r.toBlob(n=>{n?e(n):t(Error(`Failed to create PNG blob`))},`image/png`)})}return await navigator.clipboard.write([new ClipboardItem({"image/png":e})]),{stdout:`captured ${Math.round(e.size/1024)} KB to clipboard\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`screencapture: failed to copy to clipboard: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let p=t.fs.resolvePath(t.cwd,s);try{await t.fs.writeFile(p,f)}catch(e){return{stdout:``,stderr:`screencapture: failed to write file: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let m=Math.round(f.length/1024);return r?{stdout:`${p} (${m} KB)\n<img:data:${c};base64,${cK(f)}>`,stderr:``,exitCode:0}:{stdout:`captured ${m} KB to ${TW(p)}\n`,stderr:``,exitCode:0}})}function fK(e){return e instanceof Error?e.message:String(e)}function pK(){return{stdout:`usage: pbcopy
3018
3068
 
3019
3069
  Copy stdin to the clipboard.
3020
3070
  Example: echo hello | pbcopy
3021
- `,stderr:``,exitCode:0}}function pK(){return{stdout:`usage: pbpaste
3071
+ `,stderr:``,exitCode:0}}function mK(){return{stdout:`usage: pbpaste
3022
3072
 
3023
3073
  Paste clipboard contents to stdout.
3024
- `,stderr:``,exitCode:0}}function mK(e){return{stdout:`usage: ${e} [-i|-o]\n\n -i Force copy mode (read from stdin)
3074
+ `,stderr:``,exitCode:0}}function hK(e){return{stdout:`usage: ${e} [-i|-o]\n\n -i Force copy mode (read from stdin)
3025
3075
  -o Force paste mode (write to stdout)
3026
3076
  (default) Auto-detect: stdin present = copy, no stdin = paste
3027
- Example: echo hello | ${e}\n Example: ${e} -o > file.txt\n`,stderr:``,exitCode:0}}async function hK(e,t){if(!globalThis.navigator?.clipboard)return{stdout:``,stderr:`${t}: clipboard API is unavailable\n`,exitCode:1};try{return await navigator.clipboard.writeText(e),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`${t}: failed to write to clipboard: ${dK(e)}\n`,exitCode:1}}}async function gK(e){if(!globalThis.navigator?.clipboard)return{stdout:``,stderr:`${e}: clipboard API is unavailable\n`,exitCode:1};try{return{stdout:await navigator.clipboard.readText(),stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: failed to read from clipboard: ${dK(t)}\n`,exitCode:1}}}function _K(){return $P(`pbcopy`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?fK():hK(t.stdin,`pbcopy`))}function vK(){return $P(`pbpaste`,async e=>e.includes(`--help`)||e.includes(`-h`)?pK():gK(`pbpaste`))}function yK(e){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return mK(e);let r=t.includes(`-i`),i=t.includes(`-o`);return r&&i?{stdout:``,stderr:`${e}: cannot use both -i and -o\n`,exitCode:1}:i?gK(e):r||n.stdin.length>0?hK(n.stdin,e):gK(e)})}function bK(){return{stdout:`usage: say [-v voice] [-r rate] [-l lang] [--list] <text>
3077
+ Example: echo hello | ${e}\n Example: ${e} -o > file.txt\n`,stderr:``,exitCode:0}}async function gK(e,t){if(!globalThis.navigator?.clipboard)return{stdout:``,stderr:`${t}: clipboard API is unavailable\n`,exitCode:1};try{return await navigator.clipboard.writeText(e),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`${t}: failed to write to clipboard: ${fK(e)}\n`,exitCode:1}}}async function _K(e){if(!globalThis.navigator?.clipboard)return{stdout:``,stderr:`${e}: clipboard API is unavailable\n`,exitCode:1};try{return{stdout:await navigator.clipboard.readText(),stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: failed to read from clipboard: ${fK(t)}\n`,exitCode:1}}}function vK(){return $P(`pbcopy`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?pK():gK(t.stdin,`pbcopy`))}function yK(){return $P(`pbpaste`,async e=>e.includes(`--help`)||e.includes(`-h`)?mK():_K(`pbpaste`))}function bK(e){return $P(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return hK(e);let r=t.includes(`-i`),i=t.includes(`-o`);return r&&i?{stdout:``,stderr:`${e}: cannot use both -i and -o\n`,exitCode:1}:i?_K(e):r||n.stdin.length>0?gK(n.stdin,e):_K(e)})}function xK(){return{stdout:`usage: say [-v voice] [-r rate] [-l lang] [--list] <text>
3028
3078
 
3029
3079
  Speaks the given text using the Web Speech API.
3030
3080
  -v voice Voice name (partial match supported)
3031
3081
  -r rate Speech rate (0.1 to 10, default 1)
3032
3082
  -l lang Language tag (required, BCP 47, e.g. en-US, de-DE, fr-FR)
3033
3083
  --list List available voices
3034
- `,stderr:``,exitCode:0}}var xK=!1,SK=null;function CK(){return xK?Promise.resolve(speechSynthesis.getVoices()):(SK||=new Promise(e=>{let t=speechSynthesis.getVoices();if(t.length>0){xK=!0,e(t);return}let n=()=>{xK=!0,speechSynthesis.removeEventListener(`voiceschanged`,n),e(speechSynthesis.getVoices())};speechSynthesis.addEventListener(`voiceschanged`,n),setTimeout(()=>{speechSynthesis.removeEventListener(`voiceschanged`,n),xK=!0,e(speechSynthesis.getVoices())},1e3)}),SK)}function wK(){return $P(`say`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return bK();if(typeof window>`u`||typeof speechSynthesis>`u`)return{stdout:``,stderr:`say: Web Speech API unavailable in this environment
3035
- `,exitCode:1};if(e.includes(`--list`))return{stdout:(await CK()).map(e=>`${e.name} (${e.lang})${e.default?` [default]`:``}`).join(`
3084
+ `,stderr:``,exitCode:0}}var SK=!1,CK=null;function wK(){return SK?Promise.resolve(speechSynthesis.getVoices()):(CK||=new Promise(e=>{let t=speechSynthesis.getVoices();if(t.length>0){SK=!0,e(t);return}let n=()=>{SK=!0,speechSynthesis.removeEventListener(`voiceschanged`,n),e(speechSynthesis.getVoices())};speechSynthesis.addEventListener(`voiceschanged`,n),setTimeout(()=>{speechSynthesis.removeEventListener(`voiceschanged`,n),SK=!0,e(speechSynthesis.getVoices())},1e3)}),CK)}function TK(){return $P(`say`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return xK();if(typeof window>`u`||typeof speechSynthesis>`u`)return{stdout:``,stderr:`say: Web Speech API unavailable in this environment
3085
+ `,exitCode:1};if(e.includes(`--list`))return{stdout:(await wK()).map(e=>`${e.name} (${e.lang})${e.default?` [default]`:``}`).join(`
3036
3086
  `)+`
3037
3087
  `,stderr:``,exitCode:0};let t=null,n=1,r=null,i=[];for(let a=0;a<e.length;a++){let o=e[a];if(o===`-v`){if(a+1>=e.length||e[a+1].startsWith(`-`))return{stdout:``,stderr:`say: -v requires a voice name
3038
3088
  `,exitCode:1};t=e[++a]}else if(o===`-r`){if(a+1>=e.length||e[a+1].startsWith(`-`))return{stdout:``,stderr:`say: -r requires a rate value
3039
3089
  `,exitCode:1};if(n=parseFloat(e[++a]),isNaN(n)||n<.1||n>10)return{stdout:``,stderr:`say: rate must be between 0.1 and 10
3040
3090
  `,exitCode:1}}else if(o===`-l`){if(a+1>=e.length||e[a+1].startsWith(`-`))return{stdout:``,stderr:`say: -l requires a language tag
3041
- `,exitCode:1};r=e[++a]}else if(o.startsWith(`-`)&&o!==`--list`)return{stdout:``,stderr:`say: unknown option: ${o}\n`,exitCode:1};else o.startsWith(`-`)||i.push(o)}let a=i.join(` `);if(!a)return bK();if(!r)return{stdout:``,stderr:`say: -l language tag is required
3042
- `,exitCode:1};let o=new SpeechSynthesisUtterance(a);if(o.rate=n,o.lang=r,t){let e=(await CK()).find(e=>e.name.toLowerCase().includes(t.toLowerCase()));if(e)o.voice=e;else return{stdout:``,stderr:`say: voice "${t}" not found. Use --list to see available voices.\n`,exitCode:1}}return new Promise(e=>{o.onend=()=>{e({stdout:``,stderr:``,exitCode:0})},o.onerror=t=>{e({stdout:``,stderr:`say: speech synthesis error: ${t.error}\n`,exitCode:1})},speechSynthesis.speak(o)})})}function TK(){return{stdout:`usage: afplay [-v volume] [-r rate] <file>
3091
+ `,exitCode:1};r=e[++a]}else if(o.startsWith(`-`)&&o!==`--list`)return{stdout:``,stderr:`say: unknown option: ${o}\n`,exitCode:1};else o.startsWith(`-`)||i.push(o)}let a=i.join(` `);if(!a)return xK();if(!r)return{stdout:``,stderr:`say: -l language tag is required
3092
+ `,exitCode:1};let o=new SpeechSynthesisUtterance(a);if(o.rate=n,o.lang=r,t){let e=(await wK()).find(e=>e.name.toLowerCase().includes(t.toLowerCase()));if(e)o.voice=e;else return{stdout:``,stderr:`say: voice "${t}" not found. Use --list to see available voices.\n`,exitCode:1}}return new Promise(e=>{o.onend=()=>{e({stdout:``,stderr:``,exitCode:0})},o.onerror=t=>{e({stdout:``,stderr:`say: speech synthesis error: ${t.error}\n`,exitCode:1})},speechSynthesis.speak(o)})})}function EK(){return{stdout:`usage: afplay [-v volume] [-r rate] <file>
3043
3093
 
3044
3094
  Plays an audio file using the Web Audio API.
3045
3095
  -v volume Volume level (0 to 1, default 1)
3046
3096
  -r rate Playback rate (0.25 to 4, default 1)
3047
- `,stderr:``,exitCode:0}}var EK=null;function DK(){return(!EK||EK.state===`closed`)&&(EK=new AudioContext),EK}async function OK(e,t,n,r){if(typeof window>`u`||typeof AudioContext>`u`)return{stdout:``,stderr:`afplay: Web Audio API unavailable in this environment
3048
- `,exitCode:1};let i=r.fs.resolvePath(r.cwd,e),a;try{a=new Uint8Array(await r.fs.readFileBuffer(i))}catch{return{stdout:``,stderr:`afplay: cannot open ${e}: No such file\n`,exitCode:1}}if(!jW(i).startsWith(`audio/`))return{stdout:``,stderr:`afplay: ${e} is not an audio file\n`,exitCode:1};try{let e=DK();e.state===`suspended`&&await e.resume();let r=new ArrayBuffer(a.byteLength);new Uint8Array(r).set(a);let i=await e.decodeAudioData(r),o=e.createBufferSource();o.buffer=i,o.playbackRate.value=n;let s=e.createGain();return s.gain.value=t,o.connect(s),s.connect(e.destination),new Promise(e=>{o.onended=()=>{e({stdout:``,stderr:``,exitCode:0})},o.start()})}catch(t){return{stdout:``,stderr:`afplay: failed to play ${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}}function kK(){return $P(`afplay`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return TK();let n=1,r=1,i=null;for(let t=0;t<e.length;t++){let a=e[t];if(a===`-v`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`afplay: -v requires a volume value
3097
+ `,stderr:``,exitCode:0}}var DK=null;function OK(){return(!DK||DK.state===`closed`)&&(DK=new AudioContext),DK}async function kK(e,t,n,r){if(typeof window>`u`||typeof AudioContext>`u`)return{stdout:``,stderr:`afplay: Web Audio API unavailable in this environment
3098
+ `,exitCode:1};let i=r.fs.resolvePath(r.cwd,e),a;try{a=new Uint8Array(await r.fs.readFileBuffer(i))}catch{return{stdout:``,stderr:`afplay: cannot open ${e}: No such file\n`,exitCode:1}}if(!MW(i).startsWith(`audio/`))return{stdout:``,stderr:`afplay: ${e} is not an audio file\n`,exitCode:1};try{let e=OK();e.state===`suspended`&&await e.resume();let r=new ArrayBuffer(a.byteLength);new Uint8Array(r).set(a);let i=await e.decodeAudioData(r),o=e.createBufferSource();o.buffer=i,o.playbackRate.value=n;let s=e.createGain();return s.gain.value=t,o.connect(s),s.connect(e.destination),new Promise(e=>{o.onended=()=>{e({stdout:``,stderr:``,exitCode:0})},o.start()})}catch(t){return{stdout:``,stderr:`afplay: failed to play ${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}}function AK(){return $P(`afplay`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return EK();let n=1,r=1,i=null;for(let t=0;t<e.length;t++){let a=e[t];if(a===`-v`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`afplay: -v requires a volume value
3049
3099
  `,exitCode:1};if(n=parseFloat(e[++t]),isNaN(n)||n<0||n>1)return{stdout:``,stderr:`afplay: volume must be between 0 and 1
3050
3100
  `,exitCode:1}}else if(a===`-r`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`afplay: -r requires a rate value
3051
3101
  `,exitCode:1};if(r=parseFloat(e[++t]),isNaN(r)||r<.25||r>4)return{stdout:``,stderr:`afplay: rate must be between 0.25 and 4
3052
3102
  `,exitCode:1}}else if(a.startsWith(`-`))return{stdout:``,stderr:`afplay: unknown option: ${a}\n`,exitCode:1};else{if(i!==null)return{stdout:``,stderr:`afplay: only one file can be specified
3053
- `,exitCode:1};i=a}}return i?OK(i,n,r,t):TK()})}function AK(){return $P(`chime`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`usage: chime
3103
+ `,exitCode:1};i=a}}return i?kK(i,n,r,t):EK()})}function jK(){return $P(`chime`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`usage: chime
3054
3104
 
3055
3105
  Plays a notification chime sound.
3056
3106
  Alias for: afplay /shared/sounds/chime.mp3
3057
- `,stderr:``,exitCode:0}:OK(`/shared/sounds/chime.mp3`,1,1,t))}function jK(){return $P(`debug`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:`usage: debug [on|off]
3107
+ `,stderr:``,exitCode:0}:kK(`/shared/sounds/chime.mp3`,1,1,t))}function MK(){return $P(`debug`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:`usage: debug [on|off]
3058
3108
 
3059
3109
  Toggle debug tabs (Terminal, Memory) in extension mode.
3060
3110
  Without arguments, shows current state.
3061
3111
  `,stderr:``,exitCode:0};let t=e[0]?.toLowerCase();if(t!==`on`&&t!==`off`&&t!==void 0)return{stdout:``,stderr:`debug: unknown argument '${t}' (use 'on' or 'off')\n`,exitCode:1};if(!t)try{let e=localStorage.getItem(`slicc-hidden-tabs`);return{stdout:`Debug tabs: ${(e?JSON.parse(e):[`terminal`,`memory`]).includes(`terminal`)?`off`:`on`}\n`,stderr:``,exitCode:0}}catch{return{stdout:`Debug tabs: off
3062
3112
  `,stderr:``,exitCode:0}}let n=t===`on`,r=window.__slicc_debug_tabs;if(r)return r(n),{stdout:`Debug tabs ${n?`enabled`:`hidden`}\n`,stderr:``,exitCode:0};try{return chrome.runtime.sendMessage({source:`offscreen`,payload:{type:`debug-tabs`,show:n}}),{stdout:`Debug tabs ${n?`enabled`:`hidden`}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`debug: failed to send toggle message
3063
- `,exitCode:1}}})}function MK(){return $P(`nuke`,async e=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`Usage: nuke <launch-code>
3113
+ `,exitCode:1}}})}var NK=`/.cache/artificial-analysis.json`,PK=1440*60*1e3,FK=`https://artificialanalysis.ai/api/v2/data/llms/models`;async function IK(e,t=!1){if(e&&!t)try{let t=await e.readFile(NK),n=JSON.parse(t);if(Date.now()-n.fetchedAt<PK)return n.models}catch{}let n=null;try{n=localStorage.getItem(`aa_api_key`)}catch{}let r={Accept:`application/json`};n&&(r[`x-api-key`]=n);let i;try{i=await fetch(FK,{headers:r})}catch{return[]}if(i.status===401||!i.ok)return[];let a;try{a=await i.json()}catch{return[]}let o=(Array.isArray(a)?a:a?.data??a?.models??[]).map(e=>({slug:e.slug??``,name:e.name??``,creator_slug:e.model_creator?.slug??``,intelligence_index:e.evaluations?.artificial_analysis_intelligence_index??null,coding_index:e.evaluations?.artificial_analysis_coding_index??null,speed_tps:e.median_output_tokens_per_second??null}));if(e&&o.length>0){let t={fetchedAt:Date.now(),models:o};try{await e.mkdir(`/.cache`,{recursive:!0}),await e.writeFile(NK,JSON.stringify(t))}catch{}}return o}function LK(e){return e.toLowerCase().replace(/\./g,`-`).replace(/-\d{8}$/,``).replace(/-\d{4}$/,``)}function RK(e,t){let n=e.toLowerCase(),r=t.find(e=>e.slug===n);if(r)return r;let i=LK(e),a=t.find(e=>LK(e.slug)===i);if(a)return a;let o=t.filter(e=>n.includes(e.slug)||e.slug.includes(n));if(o.length>0)return o.sort((e,t)=>t.slug.length-e.slug.length),o[0]}function zK(){return`models - list available LLM models
3114
+
3115
+ Usage: models [options]
3116
+
3117
+ Options:
3118
+ --all List models across all configured providers
3119
+ --all-versions Show all model versions (default: latest only)
3120
+ --provider <id> List models for a specific provider
3121
+ --json Output as JSON (for programmatic use)
3122
+ --refresh Force re-fetch benchmark data from Artificial Analysis
3123
+ --no-benchmarks Skip benchmark data enrichment (faster, works offline)
3124
+ -h, --help Show this help message
3125
+ `}function BK(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`.replace(`.0M`,`M`):e>=1e3?`${(e/1e3).toFixed(0)}K`:`${e}`}function VK(e){return`$${e.toFixed(2)}`}var HK=/\b(embedding|embed|tts|whisper|dall-e|image-gen|audio|vision-preview)\b/i;function UK(e){let t=`${e.id} ${e.name??``}`;return!HK.test(t)}function WK(e){let t=e.toLowerCase();t=t.replace(/-\d{8}$/,``),t=t.replace(/-\d{4}$/,``),t=t.replace(/-(preview|latest)$/,``);let n=t.match(/^(claude-(?:opus|sonnet|haiku))/);if(n)return n[1];let r=t.match(/^(gpt-\d+)(?:\.\d+)?(-[a-z][-a-z]*)?$/);if(r)return r[1]+(r[2]??``);let i=t.match(/^gemini-[\d.]+-(.+)$/);if(i)return`gemini-${i[1]}`;let a=t.match(/^gemini-(\d+)-(.+)$/);if(a)return`gemini-${a[2]}`;let o=t.match(/^grok-[\d.]+-([\w-]+)$/);if(o)return`grok-${o[1]}`;if(t.match(/^(grok)-[\d.]+$/))return`grok`;let s=t.match(/^(o\d+(?:-[a-z]+)?)(?:-\d.*)?$/);return s?s[1]:t.replace(/-[\d.]+$/,``)}function GK(e){let t=new Map;for(let n of e){let e=WK(n.id);t.has(e)||t.set(e,n)}return[...t.values()]}function KK(e,t,n,r,i){let a=i?RK(e.id,i):void 0,o={id:e.id,name:e.name,provider:t,cost:e.cost??{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:e.contextWindow??0,maxTokens:e.maxTokens??0,reasoning:!!e.reasoning,input:e.input??[`text`],selected:e.id===n&&t===r};return a?.intelligence_index!=null&&(o.intelligence=a.intelligence_index),a?.coding_index!=null&&(o.codingScore=a.coding_index),a?.speed_tps!=null&&(o.speed=a.speed_tps),o}function qK(e,t,n,r){let i=[];i.push(`Models for "${e}" (${t}):\n`);for(let e of n){let t=e.selected?` ► `:` `,n=e.id.padEnd(30),r=`${VK(e.cost.input)} / ${VK(e.cost.output)}`,a=`${BK(e.contextWindow)} ctx`,o=e.intelligence==null?``:`IQ:${e.intelligence}`,s=e.speed==null?``:`${Math.round(e.speed)} t/s`,c=e.reasoning?`reasoning`:``,l=o||s?`${o.padEnd(6)} ${s.padEnd(8)}`:``;i.push(`${t}${n} ${r.padEnd(16)} ${a.padEnd(10)} ${l} ${c}`)}let a=n.find(e=>e.selected);return i.push(`\n ${n.length} model${n.length===1?``:`s`} available.${a?` Currently using: ${a.id}`:``}`),r&&i.push(` Intelligence data: artificialanalysis.ai`),i.join(`
3126
+ `)+`
3127
+ `}function JK(e){return $P(`models`,async t=>{let{getAccounts:n,getAvailableProviders:r,getProviderConfig:i,getProviderModels:a,getSelectedProvider:o,getSelectedModelId:s}=await y(async()=>{let{getAccounts:e,getAvailableProviders:t,getProviderConfig:n,getProviderModels:r,getSelectedProvider:i,getSelectedModelId:a}=await import(`./provider-settings-Bkf2ADq8.js`);return{getAccounts:e,getAvailableProviders:t,getProviderConfig:n,getProviderModels:r,getSelectedProvider:i,getSelectedModelId:a}},__vite__mapDeps([8,9,1,4,10,11,12,13,14]));if(t.includes(`--help`)||t.includes(`-h`))return{stdout:zK(),stderr:``,exitCode:0};let c=t.includes(`--json`),l=t.includes(`--all`),u=t.includes(`--all-versions`),d=t.includes(`--refresh`),f=t.includes(`--no-benchmarks`),p=t.indexOf(`--provider`),m=p>=0?t[p+1]:void 0,h=o(),g=s(),_=n();if(_.length===0)return{stdout:``,stderr:`No provider accounts configured. Run the provider settings to add one.
3128
+ `,exitCode:1};let v;f||(v=await IK(e,d),v.length===0&&(v=void 0));let b;if(m){let e=r();if(!e.includes(m))return{stdout:``,stderr:`Unknown provider: ${m}. Available: ${e.join(`, `)}\n`,exitCode:1};b=[m]}else b=l?[...new Set(_.map(e=>e.providerId))]:[h];let x=[],S=[];for(let e of b){let t=a(e).filter(UK);if(t.length===0){if(!l)return{stdout:``,stderr:`No models available for provider ${e}.\n`,exitCode:1};continue}let n=t.map(t=>KK(t,e,g,h,v)).sort((e,t)=>t.cost.input-e.cost.input);if(u||(n=GK(n)),x.push(...n),!c){let t=i(e);S.push(qK(t.name,e,n,!!v))}}return c?{stdout:JSON.stringify(x,null,2)+`
3129
+ `,stderr:``,exitCode:0}:(!u&&!c&&S.push(`Showing latest versions only. Use --all-versions to see all.
3130
+ `),{stdout:S.join(`
3131
+ `),stderr:``,exitCode:0})})}function YK(){return $P(`nuke`,async e=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`Usage: nuke <launch-code>
3064
3132
 
3065
3133
  Completely reset the environment by deleting all local data and reloading.
3066
3134
  Destroys the file system, chat history, and scoops database.
@@ -3068,12 +3136,12 @@ Requires the secret launch code to proceed.
3068
3136
  `,stderr:``,exitCode:0}:e.join(``).includes(`1234`)?(indexedDB.databases().then(e=>{for(let t of e)t.name&&indexedDB.deleteDatabase(t.name)}),setTimeout(()=>location.reload(),0),{stdout:`Nuking everything…
3069
3137
  `,stderr:``,exitCode:0}):{stdout:``,stderr:`⚠️ WARNING: this will reset the entire environment, file system, chats, and scoops.
3070
3138
  Run nuke again with the secret launch code to proceed.
3071
- `,exitCode:1})}function NK(e={}){let t=[RU({getJshCommands:e.getJshCommands}),fW(),lG(e.browserAPI,e.fs),KW(),hW(e),aK(),vG(),dG(`sqlite3`),dG(`sqllite`),HW(),oG(`python3`),oG(`python`),xG(),OG(),jG(),tG(`pdftk`),tG(`pdf`),VU(`convert`),VU(`magick`),nK(e.fs),pG(),gG(),NG(),ZG({fs:e.fs}),uK(),_K(),vK(),yK(`xclip`),yK(`xsel`),wK(),kK(),AK(),MK()];return typeof chrome<`u`&&chrome?.runtime?.id&&t.push(jK()),e.fs&&t.push(...WH.map(t=>FU(t,e.browserAPI,e.fs))),t}var PK=`https://wry-manatee-359.convex.site/api/v1`,FK=`https://api.tessl.io`,IK=`/workspace/skills`,LK=`slicc-fs-global`,RK=`/workspace/.git/github-token`,zK=`application/vnd.github.v3+json`,BK=`https://www.sliccy.com/skills/catalog.json`;function VK(e){if(!(!e||!e.trim()))return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function HK(e){return e.map(e=>{let t=e.boost?parseFloat(e.boost):NaN,n=Number.isFinite(t)?t:void 0;return{name:e.name,displayName:e.displayName||e.name,description:e.description||``,source:{repo:e.repo,path:e.path||void 0,skill:e.skill||void 0},affinity:{apps:VK(e.apps),tasks:VK(e.tasks),role:VK(e.role),purpose:VK(e.purpose)},priority:n}})}var UK={apps:3,tasks:2,role:1,purpose:1};function WK(e,t){return e.map(e=>{let n=0,r=[],i=(e.affinity.apps??[]).filter(e=>t.apps.includes(e));i.length&&(n+=i.length*UK.apps,r.push(`apps(${i.join(`, `)})`));let a=(e.affinity.tasks??[]).filter(e=>t.tasks.includes(e));return a.length&&(n+=a.length*UK.tasks,r.push(`tasks(${a.join(`, `)})`)),(e.affinity.role??[]).includes(t.role)&&(n+=UK.role,r.push(`role(${t.role})`)),(e.affinity.purpose??[]).includes(t.purpose)&&(n+=UK.purpose,r.push(`purpose(${t.purpose})`)),n*=e.priority??1,{entry:e,score:n,matchReasons:r}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score)}function GK(e){let t=`upskill ${e.repo}`;return e.path&&(t+=` --path ${e.path}`),e.skill&&(t+=` --skill ${e.skill}`),t}async function KK(e){let t=new Set;try{let n=await e.readDir(IK);for(let e of n)e.type===`directory`&&t.add(e.name)}catch{}try{let n=await e.readTextFile(`/${ue}/${pe}`),r=JSON.parse(n);for(let e of r.applied_skills??[])t.add(e.name)}catch{}let n=[`.agents`,`.claude`];try{let r=await e.readDir(`/`);for(let i of r)if(i.type===`directory`)for(let r of n)try{let n=`/${i.name}/${r}/skills`,a=await e.readDir(n);for(let e of a)e.type===`directory`&&t.add(e.name)}catch{}}catch{}return t}var qK;function JK(){return qK||=_e.create({dbName:LK}),qK}async function YK(){try{return(await(await JK()).readTextFile(RK)).trim()||void 0}catch{return}}function XK(e,t=zK){let n={Accept:t,"User-Agent":`slicc-upskill`};return e&&(n.Authorization=`Bearer ${e}`),n}async function ZK(e){let t=await YK();return{hasToken:!!t,request:(n,r=zK)=>e(n,{headers:XK(t,r)})}}function QK(e,t){if(!e)return;let n=t.toLowerCase();for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}function $K(e){if(!e)return;try{let t=JSON.parse(e);if(typeof t.message==`string`&&t.message.trim())return t.message.trim()}catch{}let t=e.trim();if(t)return t.slice(0,200)}function eq(e,t,n){let r=$K(e.body),i=r?` GitHub said: ${r}`:``,a=QK(e.headers,`retry-after`),o=QK(e.headers,`x-ratelimit-remaining`),s=r?.toLowerCase()??``;if(e.status===429||o===`0`||s.includes(`rate limit`))return n?`GitHub rate-limited access to ${t} (HTTP ${e.status}). The configured github.token was used, so retry later${a?` after about ${a} seconds`:``}.${i}`:`GitHub rate-limited anonymous access to ${t} (HTTP ${e.status}). This often happens on shared VPNs or corporate egress IPs because unauthenticated GitHub API requests are limited per IP. Configure a token with: git config github.token <PAT>, then retry. You can also retry off VPN or later.${i}`;if(e.status===401)return n?`GitHub rejected the configured github.token while accessing ${t} (HTTP 401). Update it with: git config github.token <PAT>, then retry.${i}`:`GitHub requires authentication to access ${t} (HTTP 401). Configure a token with: git config github.token <PAT>, then retry.${i}`;if(e.status===404)return`GitHub could not find ${t} (HTTP 404). Check the repository, path, and permissions.${i}`;if(e.status===403)return n?`GitHub denied access to ${t} (HTTP 403). Check that your github.token can access this repository or retry later if GitHub is throttling requests.${i}`:`GitHub denied anonymous access to ${t} (HTTP 403). If this repo is public on a shared VPN, you may have hit GitHub's shared IP limit; otherwise the repository or path may require authentication. Configure a token with: git config github.token <PAT>, then retry.${i}`;let c=e.statusText?` ${e.statusText}`:``;return`GitHub request for ${t} failed (HTTP ${e.status}${c}).${i}`}function tq(){return`Discovery roots: /workspace/skills plus accessible **/.agents/skills/* and **/.claude/skills/* anywhere in the VFS.
3072
- `}function nq(){return`Only native /workspace/skills entries are install-managed; compatibility-discovered .agents/.claude skills remain read-only.
3073
- `}function rq(e){switch(e){case`native`:return`native`;case`agents`:return`.agents`;case`claude`:return`.claude`}}function iq(e){return e.source===`native`}function aq(e){return iq(e)?e.installed&&e.installedVersion?`installed (v${e.installedVersion})`:`available`:e.installed&&e.installedVersion?`compatibility (state v${e.installedVersion})`:`compatibility (read-only)`}function oq(e){return iq(e)?`install-managed (/workspace/skills)`:`compatibility-only (read-only)`}function sq(e,t){let n=`${t}:\n\n`;n+=` NAME VERSION SOURCE STATUS
3139
+ `,exitCode:1})}function XK(e={}){let t=[zU({getJshCommands:e.getJshCommands}),pW(),uG(e.browserAPI,e.fs),qW(),gW(e),oK(),yG(),fG(`sqlite3`),fG(`sqllite`),UW(),sG(`python3`),sG(`python`),SG(),kG(),MG(),nG(`pdftk`),nG(`pdf`),HU(`convert`),HU(`magick`),rK(e.fs),mG(),_G(),PG(),QG({fs:e.fs}),dK(),vK(),yK(),bK(`xclip`),bK(`xsel`),TK(),AK(),jK(),JK(e.fs),YK()];return typeof chrome<`u`&&chrome?.runtime?.id&&t.push(MK()),e.fs&&t.push(...GH.map(t=>IU(t,e.browserAPI,e.fs))),t}var ZK=`https://wry-manatee-359.convex.site/api/v1`,QK=`https://api.tessl.io`,$K=`/workspace/skills`,eq=`slicc-fs-global`,tq=`/workspace/.git/github-token`,nq=`application/vnd.github.v3+json`,rq=`https://www.sliccy.com/skills/catalog.json`;function iq(e){if(!(!e||!e.trim()))return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function aq(e){return e.map(e=>{let t=e.boost?parseFloat(e.boost):NaN,n=Number.isFinite(t)?t:void 0;return{name:e.name,displayName:e.displayName||e.name,description:e.description||``,source:{repo:e.repo,path:e.path||void 0,skill:e.skill||void 0},affinity:{apps:iq(e.apps),tasks:iq(e.tasks),role:iq(e.role),purpose:iq(e.purpose)},priority:n}})}var oq={apps:3,tasks:2,role:1,purpose:1};function sq(e,t){return e.map(e=>{let n=0,r=[],i=(e.affinity.apps??[]).filter(e=>t.apps.includes(e));i.length&&(n+=i.length*oq.apps,r.push(`apps(${i.join(`, `)})`));let a=(e.affinity.tasks??[]).filter(e=>t.tasks.includes(e));return a.length&&(n+=a.length*oq.tasks,r.push(`tasks(${a.join(`, `)})`)),(e.affinity.role??[]).includes(t.role)&&(n+=oq.role,r.push(`role(${t.role})`)),(e.affinity.purpose??[]).includes(t.purpose)&&(n+=oq.purpose,r.push(`purpose(${t.purpose})`)),n*=e.priority??1,{entry:e,score:n,matchReasons:r}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score)}function cq(e){let t=`upskill ${e.repo}`;return e.path&&(t+=` --path ${e.path}`),e.skill&&(t+=` --skill ${e.skill}`),t}async function lq(e){let t=new Set;try{let n=await e.readDir($K);for(let e of n)e.type===`directory`&&t.add(e.name)}catch{}try{let n=await e.readTextFile(`/${ue}/${pe}`),r=JSON.parse(n);for(let e of r.applied_skills??[])t.add(e.name)}catch{}let n=[`.agents`,`.claude`];try{let r=await e.readDir(`/`);for(let i of r)if(i.type===`directory`)for(let r of n)try{let n=`/${i.name}/${r}/skills`,a=await e.readDir(n);for(let e of a)e.type===`directory`&&t.add(e.name)}catch{}}catch{}return t}var uq;function dq(){return uq||=_e.create({dbName:eq}),uq}async function fq(){try{return(await(await dq()).readTextFile(tq)).trim()||void 0}catch{return}}function pq(e,t=nq){let n={Accept:t,"User-Agent":`slicc-upskill`};return e&&(n.Authorization=`Bearer ${e}`),n}async function mq(e){let t=await fq();return{hasToken:!!t,request:(n,r=nq)=>e(n,{headers:pq(t,r)})}}function hq(e,t){if(!e)return;let n=t.toLowerCase();for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}function gq(e){if(!e)return;try{let t=JSON.parse(e);if(typeof t.message==`string`&&t.message.trim())return t.message.trim()}catch{}let t=e.trim();if(t)return t.slice(0,200)}function _q(e,t,n){let r=gq(e.body),i=r?` GitHub said: ${r}`:``,a=hq(e.headers,`retry-after`),o=hq(e.headers,`x-ratelimit-remaining`),s=r?.toLowerCase()??``;if(e.status===429||o===`0`||s.includes(`rate limit`))return n?`GitHub rate-limited access to ${t} (HTTP ${e.status}). The configured github.token was used, so retry later${a?` after about ${a} seconds`:``}.${i}`:`GitHub rate-limited anonymous access to ${t} (HTTP ${e.status}). This often happens on shared VPNs or corporate egress IPs because unauthenticated GitHub API requests are limited per IP. Configure a token with: git config github.token <PAT>, then retry. You can also retry off VPN or later.${i}`;if(e.status===401)return n?`GitHub rejected the configured github.token while accessing ${t} (HTTP 401). Update it with: git config github.token <PAT>, then retry.${i}`:`GitHub requires authentication to access ${t} (HTTP 401). Configure a token with: git config github.token <PAT>, then retry.${i}`;if(e.status===404)return`GitHub could not find ${t} (HTTP 404). Check the repository, path, and permissions.${i}`;if(e.status===403)return n?`GitHub denied access to ${t} (HTTP 403). Check that your github.token can access this repository or retry later if GitHub is throttling requests.${i}`:`GitHub denied anonymous access to ${t} (HTTP 403). If this repo is public on a shared VPN, you may have hit GitHub's shared IP limit; otherwise the repository or path may require authentication. Configure a token with: git config github.token <PAT>, then retry.${i}`;let c=e.statusText?` ${e.statusText}`:``;return`GitHub request for ${t} failed (HTTP ${e.status}${c}).${i}`}function vq(){return`Discovery roots: /workspace/skills plus accessible **/.agents/skills/* and **/.claude/skills/* anywhere in the VFS.
3140
+ `}function yq(){return`Only native /workspace/skills entries are install-managed; compatibility-discovered .agents/.claude skills remain read-only.
3141
+ `}function bq(e){switch(e){case`native`:return`native`;case`agents`:return`.agents`;case`claude`:return`.claude`}}function xq(e){return e.source===`native`}function Sq(e){return xq(e)?e.installed&&e.installedVersion?`installed (v${e.installedVersion})`:`available`:e.installed&&e.installedVersion?`compatibility (state v${e.installedVersion})`:`compatibility (read-only)`}function Cq(e){return xq(e)?`install-managed (/workspace/skills)`:`compatibility-only (read-only)`}function wq(e,t){let n=`${t}:\n\n`;n+=` NAME VERSION SOURCE STATUS
3074
3142
  `,n+=` ─────────────────────────────────────────────────────────────
3075
- `;for(let t of e)n+=` ${t.name.padEnd(20)} ${t.manifest.version.padEnd(10)} ${rq(t.source).padEnd(9)} ${aq(t)}\n`;return n+=`\n${tq()}`,n+=nq(),n}function cq(e){let t=`Skill: ${e.manifest.skill}\n`;if(t+=`Version: ${e.manifest.version}\n`,t+=`Description: ${e.manifest.description||`(none)`}\n`,t+=`Source: ${rq(e.source)}\n`,t+=`Source root: ${e.sourceRoot}\n`,t+=`Management: ${oq(e)}\n`,t+=`Status: ${aq(e)}\n`,e.skillFilePath&&(t+=`Instructions: ${e.skillFilePath}\n`),e.shadowedPaths?.length){t+=`Shadowed paths:
3076
- `;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function lq(e,t){return`${e}: "${t.name}" is discoverable from ${t.sourceRoot} but remains compatibility-only/read-only. Only native /workspace/skills entries are install-managed.\n`}function uq(){return{stdout:`usage: upskill <command> [options]
3143
+ `;for(let t of e)n+=` ${t.name.padEnd(20)} ${t.manifest.version.padEnd(10)} ${bq(t.source).padEnd(9)} ${Sq(t)}\n`;return n+=`\n${vq()}`,n+=yq(),n}function Tq(e){let t=`Skill: ${e.manifest.skill}\n`;if(t+=`Version: ${e.manifest.version}\n`,t+=`Description: ${e.manifest.description||`(none)`}\n`,t+=`Source: ${bq(e.source)}\n`,t+=`Source root: ${e.sourceRoot}\n`,t+=`Management: ${Cq(e)}\n`,t+=`Status: ${Sq(e)}\n`,e.skillFilePath&&(t+=`Instructions: ${e.skillFilePath}\n`),e.shadowedPaths?.length){t+=`Shadowed paths:
3144
+ `;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function Eq(e,t){return`${e}: "${t.name}" is discoverable from ${t.sourceRoot} but remains compatibility-only/read-only. Only native /workspace/skills entries are install-managed.\n`}function Dq(){return{stdout:`usage: upskill <command> [options]
3077
3145
 
3078
3146
  Install skills from GitHub repositories, ClawHub, or Tessl registry.
3079
3147
 
@@ -3086,7 +3154,7 @@ Commands:
3086
3154
  <clawhub-url> Install skill from ClawHub URL
3087
3155
  tessl:<name> Install skill from Tessl registry
3088
3156
 
3089
- ${tq()}${nq()}
3157
+ ${vq()}${yq()}
3090
3158
 
3091
3159
  GitHub Installation:
3092
3160
  upskill owner/repo List available skills in repo
@@ -3127,20 +3195,20 @@ Examples:
3127
3195
  upskill aemcoder/skills@fix/stateless-tab-targeting --all
3128
3196
  upskill https://clawhub.ai/arun-8687/tavily-search
3129
3197
  upskill tessl:postgres-pro
3130
- `,stderr:``,exitCode:0}}async function dq(e,t){let n=await t(`${PK}/search?q=${encodeURIComponent(e)}`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`ClawHub returned HTTP ${n.status}`);let r=JSON.parse(n.body);return r.results?r.results.map(e=>({name:e.slug,displayName:e.displayName||e.slug,summary:e.summary||``,source:`clawhub`,qualityScore:null,installHint:`upskill clawhub:${e.slug}`})):[]}function fq(e){let t=e.match(/github\.com\/([^\/?#]+)\/([^\/?#]+)/);return t?{owner:t[1],repo:t[2].replace(/\.git$/,``)}:null}async function pq(e,t){let n=await t(`${FK}/experimental/search?q=${encodeURIComponent(e)}&contentType=skills&page%5Bsize%5D=20`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`Tessl returned HTTP ${n.status}`);let r=JSON.parse(n.body);if(!r.data)return[];let i=new Map;for(let e of r.data){if(e.type!==`skill`)continue;let t=e.attributes,n=fq(t.sourceUrl),r=n?`${n.owner}/${n.repo}`:void 0,a=t.scores.aggregate==null?null:Math.round(t.scores.aggregate*100),o=t.sourceUrl||e.id,s=i.get(o);if(s&&s.qualityScore!=null&&a!=null&&s.qualityScore>=a)continue;let c=t.path.replace(/\/SKILL\.md$/i,``),l=c.split(`/`).pop()||t.name,u=n?`upskill ${n.owner}/${n.repo} --path ${c.split(`/`).slice(0,-1).join(`/`)||`.`} --skill ${l}`:`upskill tessl:${t.name}`;i.set(o,{name:t.name,displayName:t.name,summary:t.description||``,source:`tessl`,qualityScore:a,installHint:u,featured:t.featured,sourceRepo:r})}return Array.from(i.values())}var mq=10;async function hq(e,t,n=1){let[r,i]=await Promise.allSettled([dq(e,t),pq(e,t)]),a=r.status===`fulfilled`?r.value:[],o=i.status===`fulfilled`?i.value:[];if(a.length===0&&o.length===0){let t=``;return r.status===`rejected`&&i.status===`rejected`&&(t=`upskill: both registries failed to respond
3131
- `),{stdout:`No skills found for "${e}"\n\nTry a different search term or browse https://clawhub.ai or https://tessl.io/registry\n`,stderr:t,exitCode:+!!t}}let s=[],c=0,l=0;for(;c<o.length&&c<3;)s.push(o[c++]);for(;l<a.length||c<o.length;)l<a.length&&s.push(a[l++]),c<o.length&&s.push(o[c++]);let u=s.length,d=Math.ceil(u/mq),f=Math.max(1,Math.min(n,d)),p=(f-1)*mq,m=s.slice(p,p+mq),h=`Search results for "${e}" (page ${f}/${d}, ${u} total):\n\n`;for(let e of m){let t=e.qualityScore==null?` `:String(e.qualityScore).padStart(3),n=`[${e.source}]`,r=e.sourceRepo?` ${e.sourceRepo}`:``;h+=` ${e.name.padEnd(30)} ${t} ${n.padEnd(10)}${r}\n`,e.summary&&(h+=` ${e.summary}\n`),h+=`
3198
+ `,stderr:``,exitCode:0}}async function Oq(e,t){let n=await t(`${ZK}/search?q=${encodeURIComponent(e)}`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`ClawHub returned HTTP ${n.status}`);let r=JSON.parse(n.body);return r.results?r.results.map(e=>({name:e.slug,displayName:e.displayName||e.slug,summary:e.summary||``,source:`clawhub`,qualityScore:null,installHint:`upskill clawhub:${e.slug}`})):[]}function kq(e){let t=e.match(/github\.com\/([^\/?#]+)\/([^\/?#]+)/);return t?{owner:t[1],repo:t[2].replace(/\.git$/,``)}:null}async function Aq(e,t){let n=await t(`${QK}/experimental/search?q=${encodeURIComponent(e)}&contentType=skills&page%5Bsize%5D=20`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`Tessl returned HTTP ${n.status}`);let r=JSON.parse(n.body);if(!r.data)return[];let i=new Map;for(let e of r.data){if(e.type!==`skill`)continue;let t=e.attributes,n=kq(t.sourceUrl),r=n?`${n.owner}/${n.repo}`:void 0,a=t.scores.aggregate==null?null:Math.round(t.scores.aggregate*100),o=t.sourceUrl||e.id,s=i.get(o);if(s&&s.qualityScore!=null&&a!=null&&s.qualityScore>=a)continue;let c=t.path.replace(/\/SKILL\.md$/i,``),l=c.split(`/`).pop()||t.name,u=n?`upskill ${n.owner}/${n.repo} --path ${c.split(`/`).slice(0,-1).join(`/`)||`.`} --skill ${l}`:`upskill tessl:${t.name}`;i.set(o,{name:t.name,displayName:t.name,summary:t.description||``,source:`tessl`,qualityScore:a,installHint:u,featured:t.featured,sourceRepo:r})}return Array.from(i.values())}var jq=10;async function Mq(e,t,n=1){let[r,i]=await Promise.allSettled([Oq(e,t),Aq(e,t)]),a=r.status===`fulfilled`?r.value:[],o=i.status===`fulfilled`?i.value:[];if(a.length===0&&o.length===0){let t=``;return r.status===`rejected`&&i.status===`rejected`&&(t=`upskill: both registries failed to respond
3199
+ `),{stdout:`No skills found for "${e}"\n\nTry a different search term or browse https://clawhub.ai or https://tessl.io/registry\n`,stderr:t,exitCode:+!!t}}let s=[],c=0,l=0;for(;c<o.length&&c<3;)s.push(o[c++]);for(;l<a.length||c<o.length;)l<a.length&&s.push(a[l++]),c<o.length&&s.push(o[c++]);let u=s.length,d=Math.ceil(u/jq),f=Math.max(1,Math.min(n,d)),p=(f-1)*jq,m=s.slice(p,p+jq),h=`Search results for "${e}" (page ${f}/${d}, ${u} total):\n\n`;for(let e of m){let t=e.qualityScore==null?` `:String(e.qualityScore).padStart(3),n=`[${e.source}]`,r=e.sourceRepo?` ${e.sourceRepo}`:``;h+=` ${e.name.padEnd(30)} ${t} ${n.padEnd(10)}${r}\n`,e.summary&&(h+=` ${e.summary}\n`),h+=`
3132
3200
  `}return f<d&&(h+=`Showing ${p+1}-${p+m.length} of ${u}. `,h+=`Next page: upskill search ${e} --page ${f+1}\n\n`),h+=`To install:
3133
3201
  `,a.length>0&&(h+=` From ClawHub: upskill clawhub:<slug>
3134
3202
  `),o.length>0&&(h+=` From Tessl: upskill <owner/repo> --skill <name>
3135
- `),{stdout:h,stderr:``,exitCode:0}}async function gq(e,t,n,r=!1,i){try{let a=`${IK}/${e}`;try{if(await t.stat(a),!r)return{stdout:``,stderr:`upskill: skill "${e}" already exists (use --force to overwrite)\n`,exitCode:1};await t.rm(a,{recursive:!0})}catch{}let o=`${PK}/download?slug=${encodeURIComponent(e)}`,s=await n(o,{});if(s.status===404)return{stdout:``,stderr:`upskill: skill "${e}" not found on ClawHub\n`,exitCode:1};if(s.status!==200)return{stdout:``,stderr:`upskill: failed to download skill (HTTP ${s.status})\n`,exitCode:1};let c=s.headers[`content-type`]||``,l=gV(o),u=-1,d=0;if(!l){l=new Uint8Array(s.body.length);for(let e=0;e<s.body.length;e++){let t=s.body.charCodeAt(e);t>255&&u<0&&(u=e,d=t),l[e]=t&255}}let f;try{f=le(l)}catch(e){let t=e instanceof Error?e.message:String(e),n=Array.from(l.slice(0,20)).map(e=>e.toString(16).padStart(2,`0`)).join(` `),r=u>=0?`\nBad char at ${u}: code ${d}`:``;return{stdout:``,stderr:`upskill: failed to unzip: ${t}\nContent-Type: ${c}\nBody: ${s.body.length} chars\nHex: ${n}${r}\n`,exitCode:1}}await t.mkdir(a,{recursive:!0});let p=0;for(let[e,n]of Object.entries(f)){let r=e.replace(/\\/g,`/`);if(!r||r.endsWith(`/`)||r===`_meta.json`)continue;let i=`${a}/${r}`,o=i.substring(0,i.lastIndexOf(`/`));o!==a&&await t.mkdir(o,{recursive:!0}),await t.writeFile(i,n),p++}let m=_q(f,i);return await Tq(),{stdout:`Installed skill "${e}" from ClawHub (${p} files)\n${m}`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`upskill: failed to install from ClawHub: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function _q(e,t){let n;for(let[t,r]of Object.entries(e))if((t.split(`/`).pop()||``).toLowerCase()===`skill.md`){n=new TextDecoder().decode(r);break}if(!n)return``;let r=n.match(/^---\s*\n([\s\S]*?)\n---/);if(!r)return``;let i=r[1],a=vq(i);if(a.length===0)return``;if(!t||t.length===0)return` Requires: ${a.join(`, `)}\n`;let o=new Set(t),s=a.filter(e=>!o.has(e));return s.length===0?` Requires: ${a.join(`, `)} (all available)\n`:` Requires: ${a.join(`, `)}\n Missing: ${s.join(`, `)} -- this skill may not work in the SLICC shell\n`}function vq(e){let t=e.match(/metadata:\s*\n\s*(\{[\s\S]*\})/);if(t)try{let e=JSON.parse(t[1]);for(let t of[`openclaw`,`clawdis`,`clawdbot`]){let n=e[t];if(n?.requires&&typeof n.requires==`object`){let e=n.requires;if(Array.isArray(e.bins))return e.bins.filter(e=>typeof e==`string`)}}}catch{}let n=e.match(/"bins"\s*:\s*\[([^\]]*)\]/);return n?n[1].split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``)).filter(Boolean):[]}async function yq(e,t){let n=await t(`${FK}/experimental/search?q=${encodeURIComponent(e)}&contentType=skills&page%5Bsize%5D=5`,{headers:{Accept:`application/json`}});if(n.status!==200)return{error:`Tessl search failed (HTTP ${n.status})`};let r=JSON.parse(n.body).data?.find(t=>t.type===`skill`&&t.attributes.name===e);if(!r)return{error:`skill "${e}" not found on Tessl registry`};let i=fq(r.attributes.sourceUrl);if(!i)return{error:`skill "${e}" has no GitHub source URL`};let a=r.attributes.path.replace(/\/SKILL\.md$/i,``);return{owner:i.owner,repo:i.repo,skillPath:a,skillName:e}}async function bq(e,t,n,r=`main`){let i=`https://codeload.github.com/${e}/${t}/zip/refs/heads/${r}`,a=await n(i,{headers:{"User-Agent":`slicc-upskill`}});if(a.status===404)return r===`main`?bq(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=gV(i);if(!o){o=new Uint8Array(a.body.length);for(let e=0;e<a.body.length;e++)o[e]=a.body.charCodeAt(e)&255}try{return{status:`ok`,files:le(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function xq(e){let t={};for(let[n,r]of Object.entries(e)){let e=n.indexOf(`/`);if(e<0)continue;let i=n.slice(e+1);i&&(t[i]=r)}return t}async function Sq(e,t,n,r,i,a){if(i){let n=await bq(e,t,i,a);if(n.status===`ok`){let e=xq(n.files),t=[],i=r?r.replace(/^\/|\/$/g,``)+`/`:``;for(let n of Object.keys(e))if(n.startsWith(i)&&(n.split(`/`).pop()||``)===`SKILL.md`){let e=n.replace(/\/SKILL\.md$/,``),r=e.split(`/`).pop()||e;t.push({name:r,path:e})}return{skills:t}}if(n.status===`not_found`)return{skills:[],error:`${a?`branch "${a}" in ${e}/${t}`:`repository ${e}/${t}`} not found`}}let o=[];async function s(r){let i=`https://api.github.com/repos/${e}/${t}/contents/${r}`,c=a?`${i}?ref=${encodeURIComponent(a)}`:i,l=await n.request(c);if(l.status!==200)throw Error(eq(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=JSON.parse(l.body);for(let e of u)if(e.type===`file`&&e.name===`SKILL.md`){let t=e.path.replace(`/SKILL.md`,``),n=t.split(`/`).pop()||t;o.push({name:n,path:t})}else e.type===`dir`&&await s(e.path)}try{return await s(r||``),{skills:o}}catch(e){return{skills:[],error:e instanceof Error?e.message:String(e)}}}async function Cq(e,t,n,r,i,a,o=!1,s,c){try{let l=`${IK}/${r}`;try{if(await i.stat(l),!o)return{stdout:``,stderr:`upskill: skill "${r}" already exists (use --force to overwrite)\n`,exitCode:1};await i.rm(l,{recursive:!0})}catch{}if(s){let a=await bq(e,t,s,c);if(a.status===`not_found`)return{stdout:``,stderr:`upskill: ${c?`branch "${c}" in ${e}/${t}`:`repository ${e}/${t}`} not found\n`,exitCode:1};if(a.status===`ok`){let o=xq(a.files),s=n.replace(/^\/|\/$/g,``)+`/`;await i.mkdir(l,{recursive:!0});let c=0;for(let[e,t]of Object.entries(o)){if(!e.startsWith(s))continue;let n=e.slice(s.length);if(!n||e.endsWith(`/`))continue;let r=`${l}/${n}`,a=r.substring(0,r.lastIndexOf(`/`));a!==l&&await i.mkdir(a,{recursive:!0}),await i.writeFile(r,t),c++}if(c>0)return await kq(),await Dq(),{stdout:`Installed skill "${r}" from ${e}/${t}\n`,stderr:``,exitCode:0}}}let u=`https://api.github.com/repos/${e}/${t}/contents/${n}`,d=c?`${u}?ref=${encodeURIComponent(c)}`:u,f=await a.request(d);if(f.status!==200)return{stdout:``,stderr:`upskill: ${eq(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=JSON.parse(f.body);await i.mkdir(l,{recursive:!0});async function m(n,r){for(let o of n)if(o.type===`file`&&o.download_url){let n=await a.request(o.download_url,`*/*`);if(n.status!==200)throw Error(eq(n,`${e}/${t}/${o.path}`,a.hasToken));let s=gV(o.download_url);await i.writeFile(`${r}/${o.name}`,s??n.body)}else if(o.type===`dir`){let n=`https://api.github.com/repos/${e}/${t}/contents/${o.path}`,s=c?`${n}?ref=${encodeURIComponent(c)}`:n,l=await a.request(s);if(l.status!==200)throw Error(eq(l,`${e}/${t}/${o.path}`,a.hasToken));let u=JSON.parse(l.body);await i.mkdir(`${r}/${o.name}`,{recursive:!0}),await m(u,`${r}/${o.name}`)}}try{await m(p,l)}catch(e){try{await i.rm(l,{recursive:!0})}catch{}throw e}return await Tq(),{stdout:`Installed skill "${r}" from ${e}/${t}\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`upskill: failed to install from GitHub: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function wq(e){let t=e.match(/^https?:\/\/clawhub\.ai\/[^\/]+\/([^\/]+)/);if(t)return t[1];if(e.startsWith(`clawhub:`)){let t=e.slice(8);return t.includes(`/`)?t.split(`/`)[1]:t}return null}async function Tq(){await kq(),await Dq()}async function Eq(e,t,n,r,i=!1){let a=`${IK}/${t}`;try{if(await r.stat(a),!i)return{ok:!1,error:`skill "${t}" already exists (use --force to overwrite)`};await r.rm(a,{recursive:!0})}catch{}let o=e.replace(/^\/|\/$/g,``),s=o?o+`/`:``;await r.mkdir(a,{recursive:!0});let c=0;try{for(let[e,t]of Object.entries(n)){if(!e.startsWith(s))continue;let n=e.slice(s.length);if(!n||e.endsWith(`/`))continue;let i=`${a}/${n}`,o=i.replace(/\/+/g,`/`);if(o.includes(`/../`)||o.includes(`/..`)||!o.startsWith(a+`/`))continue;let l=i.substring(0,i.lastIndexOf(`/`));l!==a&&await r.mkdir(l,{recursive:!0}),await r.writeFile(i,t),c++}}catch(e){throw await r.rm(a,{recursive:!0}).catch(()=>{}),e}return c===0?(await r.rm(a,{recursive:!0}).catch(()=>{}),{ok:!1,error:`no files found for skill "${t}" in ZIP`}):{ok:!0}}async function Dq(){try{let e=(typeof window<`u`?window:globalThis).__slicc_reloadSkills;if(typeof e==`function`){await e();return}typeof chrome<`u`&&chrome?.runtime?.sendMessage&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}})}catch{}}function Oq(e){let t=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return t?{owner:t[1],repo:t[2],branch:t[3]}:null}async function kq(){try{if(typeof window>`u`)return;let e=window.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}async function Aq(e,t,n){let r=null;try{let t=await e.readDir(`/home`);for(let n of t)try{let t=await e.readTextFile(`/home/${n.name}/.welcome.json`);r=JSON.parse(t);break}catch{}}catch{}if(!r)return{stdout:``,stderr:`upskill: no user profile found. Complete the welcome onboarding first, or create /home/<name>/.welcome.json manually.
3136
- `,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(BK,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return HK(JSON.parse(e.body).data)})(),KK(e)]);i=n,a=r}catch(e){return{stdout:``,stderr:`upskill: failed to fetch skill catalog from ${BK}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=WK(i,r).filter(e=>!a.has(e.entry.name));if(o.length===0)return{stdout:`No new skill recommendations — all matching skills are already installed.
3137
- `,stderr:``,exitCode:0};if(n){let n=new Map;for(let e of o){let t=e.entry.source.repo,r=n.get(t);r?r.push(e):n.set(t,[e])}let r=o.length,i=0,a=Date.now(),s=``,c=``,l=0,u=await Promise.allSettled(Array.from(n.entries()).map(async([n,o])=>{let[c,l]=n.split(`/`),u=await bq(c,l,t);if(u.status===`not_found`||u.status===`error`){let e=u.status===`not_found`?`upskill: repository ${n} not found\n`:`upskill: failed to fetch ${n}: ${u.message}\n`,t=[];for(let e of o){i++,((Date.now()-a)/1e3).toFixed(1);let o=i<r?` (~${Math.round((r-i)*(Date.now()-a)/i/1e3)}s remaining)`:``;s+=`[${i}/${r}] Failed "${e.entry.name}" from ${n}: repo fetch failed${o}\n`,t.push({ok:!1,name:e.entry.name,error:`repo fetch failed for ${n}`})}return{errors:e,results:t}}let d=xq(u.files),f=[],p=new Map;for(let e of Object.keys(d))if(e.endsWith(`/SKILL.md`)){let t=e.replace(/\/SKILL\.md$/,``),n=t.split(`/`).pop()||t;p.set(n,t)}for(let t of o){let o=t.entry.source,c,l;if(o.skill){let e=p.get(o.skill);if(!e){let e=`skill "${o.skill}" not found in ${n}`;f.push({ok:!1,name:t.entry.name,error:e}),i++,((Date.now()-a)/1e3).toFixed(1);let c=i<r?` (~${Math.round((r-i)*(Date.now()-a)/i/1e3)}s remaining)`:``;s+=`[${i}/${r}] Failed "${t.entry.name}" from ${n}: ${e}${c}\n`;continue}c=e,l=o.skill}else c=o.path?o.path.replace(/^\/|\/$/g,``):``,l=t.entry.name;let u=Date.now(),m=await Eq(c,l,d,e,!1);i++;let h=((Date.now()-u)/1e3).toFixed(1),g=(Date.now()-a)/i,_=Math.round((r-i)*g/1e3),v=i<r?` (~${_}s remaining)`:``;m.ok?(f.push({ok:!0,name:l}),s+=`[${i}/${r}] Installed "${l}" from ${n} (${h}s)${v}\n`):(f.push({ok:!1,name:l,error:m.error}),s+=`[${i}/${r}] Failed "${l}" from ${n}: ${m.error}${v}\n`)}return{errors:``,results:f}}));for(let e of u){if(e.status===`rejected`){c+=`upskill: unexpected error: ${e.reason}\n`;continue}e.value.errors&&(c+=e.value.errors);for(let t of e.value.results)t.ok?l++:t.error&&(c+=`upskill: ${t.error}\n`)}let d=((Date.now()-a)/1e3).toFixed(1);return l>0&&(s+=`\nInstalled ${l} recommended skill(s) in ${d}s\n`,await Tq()),{stdout:s,stderr:c,exitCode:+!!c}}let s=`Recommended skills for you:
3203
+ `),{stdout:h,stderr:``,exitCode:0}}async function Nq(e,t,n,r=!1,i){try{let a=`${$K}/${e}`;try{if(await t.stat(a),!r)return{stdout:``,stderr:`upskill: skill "${e}" already exists (use --force to overwrite)\n`,exitCode:1};await t.rm(a,{recursive:!0})}catch{}let o=`${ZK}/download?slug=${encodeURIComponent(e)}`,s=await n(o,{});if(s.status===404)return{stdout:``,stderr:`upskill: skill "${e}" not found on ClawHub\n`,exitCode:1};if(s.status!==200)return{stdout:``,stderr:`upskill: failed to download skill (HTTP ${s.status})\n`,exitCode:1};let c=s.headers[`content-type`]||``,l=gV(o),u=-1,d=0;if(!l){l=new Uint8Array(s.body.length);for(let e=0;e<s.body.length;e++){let t=s.body.charCodeAt(e);t>255&&u<0&&(u=e,d=t),l[e]=t&255}}let f;try{f=le(l)}catch(e){let t=e instanceof Error?e.message:String(e),n=Array.from(l.slice(0,20)).map(e=>e.toString(16).padStart(2,`0`)).join(` `),r=u>=0?`\nBad char at ${u}: code ${d}`:``;return{stdout:``,stderr:`upskill: failed to unzip: ${t}\nContent-Type: ${c}\nBody: ${s.body.length} chars\nHex: ${n}${r}\n`,exitCode:1}}await t.mkdir(a,{recursive:!0});let p=0;for(let[e,n]of Object.entries(f)){let r=e.replace(/\\/g,`/`);if(!r||r.endsWith(`/`)||r===`_meta.json`)continue;let i=`${a}/${r}`,o=i.substring(0,i.lastIndexOf(`/`));o!==a&&await t.mkdir(o,{recursive:!0}),await t.writeFile(i,n),p++}let m=Pq(f,i);return await Hq(),{stdout:`Installed skill "${e}" from ClawHub (${p} files)\n${m}`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`upskill: failed to install from ClawHub: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function Pq(e,t){let n;for(let[t,r]of Object.entries(e))if((t.split(`/`).pop()||``).toLowerCase()===`skill.md`){n=new TextDecoder().decode(r);break}if(!n)return``;let r=n.match(/^---\s*\n([\s\S]*?)\n---/);if(!r)return``;let i=r[1],a=Fq(i);if(a.length===0)return``;if(!t||t.length===0)return` Requires: ${a.join(`, `)}\n`;let o=new Set(t),s=a.filter(e=>!o.has(e));return s.length===0?` Requires: ${a.join(`, `)} (all available)\n`:` Requires: ${a.join(`, `)}\n Missing: ${s.join(`, `)} -- this skill may not work in the SLICC shell\n`}function Fq(e){let t=e.match(/metadata:\s*\n\s*(\{[\s\S]*\})/);if(t)try{let e=JSON.parse(t[1]);for(let t of[`openclaw`,`clawdis`,`clawdbot`]){let n=e[t];if(n?.requires&&typeof n.requires==`object`){let e=n.requires;if(Array.isArray(e.bins))return e.bins.filter(e=>typeof e==`string`)}}}catch{}let n=e.match(/"bins"\s*:\s*\[([^\]]*)\]/);return n?n[1].split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``)).filter(Boolean):[]}async function Iq(e,t){let n=await t(`${QK}/experimental/search?q=${encodeURIComponent(e)}&contentType=skills&page%5Bsize%5D=5`,{headers:{Accept:`application/json`}});if(n.status!==200)return{error:`Tessl search failed (HTTP ${n.status})`};let r=JSON.parse(n.body).data?.find(t=>t.type===`skill`&&t.attributes.name===e);if(!r)return{error:`skill "${e}" not found on Tessl registry`};let i=kq(r.attributes.sourceUrl);if(!i)return{error:`skill "${e}" has no GitHub source URL`};let a=r.attributes.path.replace(/\/SKILL\.md$/i,``);return{owner:i.owner,repo:i.repo,skillPath:a,skillName:e}}async function Lq(e,t,n,r=`main`){let i=`https://codeload.github.com/${e}/${t}/zip/refs/heads/${r}`,a=await n(i,{headers:{"User-Agent":`slicc-upskill`}});if(a.status===404)return r===`main`?Lq(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=gV(i);if(!o){o=new Uint8Array(a.body.length);for(let e=0;e<a.body.length;e++)o[e]=a.body.charCodeAt(e)&255}try{return{status:`ok`,files:le(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function Rq(e){let t={};for(let[n,r]of Object.entries(e)){let e=n.indexOf(`/`);if(e<0)continue;let i=n.slice(e+1);i&&(t[i]=r)}return t}async function zq(e,t,n,r,i,a){if(i){let n=await Lq(e,t,i,a);if(n.status===`ok`){let e=Rq(n.files),t=[],i=r?r.replace(/^\/|\/$/g,``)+`/`:``;for(let n of Object.keys(e))if(n.startsWith(i)&&(n.split(`/`).pop()||``)===`SKILL.md`){let e=n.replace(/\/SKILL\.md$/,``),r=e.split(`/`).pop()||e;t.push({name:r,path:e})}return{skills:t}}if(n.status===`not_found`)return{skills:[],error:`${a?`branch "${a}" in ${e}/${t}`:`repository ${e}/${t}`} not found`}}let o=[];async function s(r){let i=`https://api.github.com/repos/${e}/${t}/contents/${r}`,c=a?`${i}?ref=${encodeURIComponent(a)}`:i,l=await n.request(c);if(l.status!==200)throw Error(_q(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=JSON.parse(l.body);for(let e of u)if(e.type===`file`&&e.name===`SKILL.md`){let t=e.path.replace(`/SKILL.md`,``),n=t.split(`/`).pop()||t;o.push({name:n,path:t})}else e.type===`dir`&&await s(e.path)}try{return await s(r||``),{skills:o}}catch(e){return{skills:[],error:e instanceof Error?e.message:String(e)}}}async function Bq(e,t,n,r,i,a,o=!1,s,c){try{let l=`${$K}/${r}`;try{if(await i.stat(l),!o)return{stdout:``,stderr:`upskill: skill "${r}" already exists (use --force to overwrite)\n`,exitCode:1};await i.rm(l,{recursive:!0})}catch{}if(s){let a=await Lq(e,t,s,c);if(a.status===`not_found`)return{stdout:``,stderr:`upskill: ${c?`branch "${c}" in ${e}/${t}`:`repository ${e}/${t}`} not found\n`,exitCode:1};if(a.status===`ok`){let o=Rq(a.files),s=n.replace(/^\/|\/$/g,``)+`/`;await i.mkdir(l,{recursive:!0});let c=0;for(let[e,t]of Object.entries(o)){if(!e.startsWith(s))continue;let n=e.slice(s.length);if(!n||e.endsWith(`/`))continue;let r=`${l}/${n}`,a=r.substring(0,r.lastIndexOf(`/`));a!==l&&await i.mkdir(a,{recursive:!0}),await i.writeFile(r,t),c++}if(c>0)return await Kq(),await Wq(),{stdout:`Installed skill "${r}" from ${e}/${t}\n`,stderr:``,exitCode:0}}}let u=`https://api.github.com/repos/${e}/${t}/contents/${n}`,d=c?`${u}?ref=${encodeURIComponent(c)}`:u,f=await a.request(d);if(f.status!==200)return{stdout:``,stderr:`upskill: ${_q(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=JSON.parse(f.body);await i.mkdir(l,{recursive:!0});async function m(n,r){for(let o of n)if(o.type===`file`&&o.download_url){let n=await a.request(o.download_url,`*/*`);if(n.status!==200)throw Error(_q(n,`${e}/${t}/${o.path}`,a.hasToken));let s=gV(o.download_url);await i.writeFile(`${r}/${o.name}`,s??n.body)}else if(o.type===`dir`){let n=`https://api.github.com/repos/${e}/${t}/contents/${o.path}`,s=c?`${n}?ref=${encodeURIComponent(c)}`:n,l=await a.request(s);if(l.status!==200)throw Error(_q(l,`${e}/${t}/${o.path}`,a.hasToken));let u=JSON.parse(l.body);await i.mkdir(`${r}/${o.name}`,{recursive:!0}),await m(u,`${r}/${o.name}`)}}try{await m(p,l)}catch(e){try{await i.rm(l,{recursive:!0})}catch{}throw e}return await Hq(),{stdout:`Installed skill "${r}" from ${e}/${t}\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`upskill: failed to install from GitHub: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function Vq(e){let t=e.match(/^https?:\/\/clawhub\.ai\/[^\/]+\/([^\/]+)/);if(t)return t[1];if(e.startsWith(`clawhub:`)){let t=e.slice(8);return t.includes(`/`)?t.split(`/`)[1]:t}return null}async function Hq(){await Kq(),await Wq()}async function Uq(e,t,n,r,i=!1){let a=`${$K}/${t}`;try{if(await r.stat(a),!i)return{ok:!1,error:`skill "${t}" already exists (use --force to overwrite)`};await r.rm(a,{recursive:!0})}catch{}let o=e.replace(/^\/|\/$/g,``),s=o?o+`/`:``;await r.mkdir(a,{recursive:!0});let c=0;try{for(let[e,t]of Object.entries(n)){if(!e.startsWith(s))continue;let n=e.slice(s.length);if(!n||e.endsWith(`/`))continue;let i=`${a}/${n}`,o=i.replace(/\/+/g,`/`);if(o.includes(`/../`)||o.includes(`/..`)||!o.startsWith(a+`/`))continue;let l=i.substring(0,i.lastIndexOf(`/`));l!==a&&await r.mkdir(l,{recursive:!0}),await r.writeFile(i,t),c++}}catch(e){throw await r.rm(a,{recursive:!0}).catch(()=>{}),e}return c===0?(await r.rm(a,{recursive:!0}).catch(()=>{}),{ok:!1,error:`no files found for skill "${t}" in ZIP`}):{ok:!0}}async function Wq(){try{let e=(typeof window<`u`?window:globalThis).__slicc_reloadSkills;if(typeof e==`function`){await e();return}typeof chrome<`u`&&chrome?.runtime?.sendMessage&&chrome.runtime.sendMessage({source:`panel`,payload:{type:`reload-skills`}})}catch{}}function Gq(e){let t=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return t?{owner:t[1],repo:t[2],branch:t[3]}:null}async function Kq(){try{if(typeof window>`u`)return;let e=window.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}async function qq(e,t,n){let r=null;try{let t=await e.readDir(`/home`);for(let n of t)try{let t=await e.readTextFile(`/home/${n.name}/.welcome.json`);r=JSON.parse(t);break}catch{}}catch{}if(!r)return{stdout:``,stderr:`upskill: no user profile found. Complete the welcome onboarding first, or create /home/<name>/.welcome.json manually.
3204
+ `,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(rq,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return aq(JSON.parse(e.body).data)})(),lq(e)]);i=n,a=r}catch(e){return{stdout:``,stderr:`upskill: failed to fetch skill catalog from ${rq}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=sq(i,r).filter(e=>!a.has(e.entry.name));if(o.length===0)return{stdout:`No new skill recommendations — all matching skills are already installed.
3205
+ `,stderr:``,exitCode:0};if(n){let n=new Map;for(let e of o){let t=e.entry.source.repo,r=n.get(t);r?r.push(e):n.set(t,[e])}let r=o.length,i=0,a=Date.now(),s=``,c=``,l=0,u=await Promise.allSettled(Array.from(n.entries()).map(async([n,o])=>{let[c,l]=n.split(`/`),u=await Lq(c,l,t);if(u.status===`not_found`||u.status===`error`){let e=u.status===`not_found`?`upskill: repository ${n} not found\n`:`upskill: failed to fetch ${n}: ${u.message}\n`,t=[];for(let e of o){i++,((Date.now()-a)/1e3).toFixed(1);let o=i<r?` (~${Math.round((r-i)*(Date.now()-a)/i/1e3)}s remaining)`:``;s+=`[${i}/${r}] Failed "${e.entry.name}" from ${n}: repo fetch failed${o}\n`,t.push({ok:!1,name:e.entry.name,error:`repo fetch failed for ${n}`})}return{errors:e,results:t}}let d=Rq(u.files),f=[],p=new Map;for(let e of Object.keys(d))if(e.endsWith(`/SKILL.md`)){let t=e.replace(/\/SKILL\.md$/,``),n=t.split(`/`).pop()||t;p.set(n,t)}for(let t of o){let o=t.entry.source,c,l;if(o.skill){let e=p.get(o.skill);if(!e){let e=`skill "${o.skill}" not found in ${n}`;f.push({ok:!1,name:t.entry.name,error:e}),i++,((Date.now()-a)/1e3).toFixed(1);let c=i<r?` (~${Math.round((r-i)*(Date.now()-a)/i/1e3)}s remaining)`:``;s+=`[${i}/${r}] Failed "${t.entry.name}" from ${n}: ${e}${c}\n`;continue}c=e,l=o.skill}else c=o.path?o.path.replace(/^\/|\/$/g,``):``,l=t.entry.name;let u=Date.now(),m=await Uq(c,l,d,e,!1);i++;let h=((Date.now()-u)/1e3).toFixed(1),g=(Date.now()-a)/i,_=Math.round((r-i)*g/1e3),v=i<r?` (~${_}s remaining)`:``;m.ok?(f.push({ok:!0,name:l}),s+=`[${i}/${r}] Installed "${l}" from ${n} (${h}s)${v}\n`):(f.push({ok:!1,name:l,error:m.error}),s+=`[${i}/${r}] Failed "${l}" from ${n}: ${m.error}${v}\n`)}return{errors:``,results:f}}));for(let e of u){if(e.status===`rejected`){c+=`upskill: unexpected error: ${e.reason}\n`;continue}e.value.errors&&(c+=e.value.errors);for(let t of e.value.results)t.ok?l++:t.error&&(c+=`upskill: ${t.error}\n`)}let d=((Date.now()-a)/1e3).toFixed(1);return l>0&&(s+=`\nInstalled ${l} recommended skill(s) in ${d}s\n`,await Hq()),{stdout:s,stderr:c,exitCode:+!!c}}let s=`Recommended skills for you:
3138
3206
 
3139
- `,c=0;for(let e of o){c++;let t=GK(e.entry.source);s+=` ${c}. ${e.entry.displayName.padEnd(35)} score: ${Math.round(e.score)}\n`,s+=` ${e.entry.description}\n`,s+=` Match: ${e.matchReasons.join(`, `)}\n`,s+=` Install: ${t}\n\n`}return s+=`To install all recommended: upskill recommendations --install
3140
- `,{stdout:s,stderr:``,exitCode:0}}function jq(e,t){return $P(`upskill`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return uq();let i=[],a,o=!1,s=!1,c=!1,l=``,u,d=``,f=1,p=0;for(;p<n.length;){let r=n[p];if(r===`search`){let e=n.slice(p+1),t=e.indexOf(`--page`);t>=0&&(f=parseInt(e[t+1],10)||1,e.splice(t,2)),d=e.join(` `);break}else if(r===`recommendations`)return Aq(e,t,n.includes(`--install`));else if(r===`list`){let t=await(await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]))).discoverSkills(e);return t.length===0?{stdout:`No discoverable local skills found.\n\n${tq()}${nq()}`,stderr:``,exitCode:0}:{stdout:sq(t,`Discoverable local skills`),stderr:``,exitCode:0}}else if(r===`info`||r===`read`){let t=n[p+1];if(!t)return{stdout:``,stderr:`upskill: ${r} requires a skill name\n`,exitCode:1};let i=await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]));if(r===`info`){let n=await i.getSkillInfo(e,t);return n?{stdout:cq(n),stderr:``,exitCode:0}:{stdout:``,stderr:`upskill: skill "${t}" not found\n`,exitCode:1}}else{let n=await i.readSkillInstructions(e,t);return n===null?{stdout:``,stderr:`upskill: no SKILL.md found for "${t}"\n`,exitCode:1}:{stdout:n+`
3207
+ `,c=0;for(let e of o){c++;let t=cq(e.entry.source);s+=` ${c}. ${e.entry.displayName.padEnd(35)} score: ${Math.round(e.score)}\n`,s+=` ${e.entry.description}\n`,s+=` Match: ${e.matchReasons.join(`, `)}\n`,s+=` Install: ${t}\n\n`}return s+=`To install all recommended: upskill recommendations --install
3208
+ `,{stdout:s,stderr:``,exitCode:0}}function Jq(e,t){return $P(`upskill`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return Dq();let i=[],a,o=!1,s=!1,c=!1,l=``,u,d=``,f=1,p=0;for(;p<n.length;){let r=n[p];if(r===`search`){let e=n.slice(p+1),t=e.indexOf(`--page`);t>=0&&(f=parseInt(e[t+1],10)||1,e.splice(t,2)),d=e.join(` `);break}else if(r===`recommendations`)return qq(e,t,n.includes(`--install`));else if(r===`list`){let t=await(await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]))).discoverSkills(e);return t.length===0?{stdout:`No discoverable local skills found.\n\n${vq()}${yq()}`,stderr:``,exitCode:0}:{stdout:wq(t,`Discoverable local skills`),stderr:``,exitCode:0}}else if(r===`info`||r===`read`){let t=n[p+1];if(!t)return{stdout:``,stderr:`upskill: ${r} requires a skill name\n`,exitCode:1};let i=await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]));if(r===`info`){let n=await i.getSkillInfo(e,t);return n?{stdout:Tq(n),stderr:``,exitCode:0}:{stdout:``,stderr:`upskill: skill "${t}" not found\n`,exitCode:1}}else{let n=await i.readSkillInstructions(e,t);return n===null?{stdout:``,stderr:`upskill: no SKILL.md found for "${t}"\n`,exitCode:1}:{stdout:n+`
3141
3209
  `,stderr:``,exitCode:0}}}else if(r===`--skill`)i.push(n[++p]);else if(r===`--path`||r===`-p`)a=n[++p];else if(r===`--list`)o=!0;else if(r===`--all`)s=!0;else if(r===`--force`)c=!0;else if(r===`--branch`||r===`-b`){let e=n[p+1];if(!e||e.startsWith(`-`))return{stdout:``,stderr:`upskill: --branch requires a value
3142
- `,exitCode:1};u=n[++p]}else r.startsWith(`-`)||(l=r);p++}if(d)return hq(d,t,f);if(!l)return uq();let m=wq(l);if(m){let n=r.getRegisteredCommands?.()??[];return gq(m,e,t,c,n)}if(l.startsWith(`tessl:`)){let n=l.slice(6);if(!n)return{stdout:``,stderr:`upskill: tessl: requires a skill name
3143
- `,exitCode:1};let r=await yq(n,t);if(`error`in r)return{stdout:``,stderr:`upskill: ${r.error}\n`,exitCode:1};let i=await ZK(t);return Cq(r.owner,r.repo,r.skillPath,r.skillName,e,i,c,t)}let h=Oq(l);if(h){let{owner:n,repo:r}=h,d=u??h.branch,f=await ZK(t),p=await Sq(n,r,f,a,t,d);if(p.error)return{stdout:``,stderr:`upskill: failed to list skills: ${p.error}\n`,exitCode:1};if(p.skills.length===0)return{stdout:`No skills found in ${n}/${r}${a?`/`+a:``}\n`,stderr:``,exitCode:0};if(o){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let m=p.skills;if(i.length>0){m=p.skills.filter(e=>i.includes(e.name));for(let e of i)if(!p.skills.find(t=>t.name===e))return{stdout:``,stderr:`upskill: skill "${e}" not found in ${n}/${r}\n`,exitCode:1}}else if(!s){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install specific skills: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let g=``,_=``,v=0,y=m.length,b=Date.now();if(y>1){let i=await bq(n,r,t,d);if(i.status===`not_found`)return{stdout:``,stderr:`upskill: ${d?`branch "${d}" in ${n}/${r}`:`repository ${n}/${r}`} not found\n`,exitCode:1};if(i.status===`error`)return{stdout:``,stderr:`upskill: failed to fetch ${n}/${r}: ${i.message}\n`,exitCode:1};let a=xq(i.files);for(let t=0;t<m.length;t++){let i=m[t],o=await Eq(i.path,i.name,a,e,c),s=t+1,l=((Date.now()-b)/1e3).toFixed(1),u=(Date.now()-b)/s,d=Math.round((y-s)*u/1e3),f=s<y?` (~${d}s remaining)`:``;o.ok?(g+=`[${s}/${y}] Installed "${i.name}" from ${n}/${r} (${l}s)${f}\n`,v++):(g+=`[${s}/${y}] Failed "${i.name}": ${o.error}${f}\n`,_+=`upskill: ${o.error}\n`)}}else for(let i of m){let a=await Cq(n,r,i.path,i.name,e,f,c,t,d);a.exitCode===0?(g+=a.stdout,v++):_+=a.stderr}let x=((Date.now()-b)/1e3).toFixed(1);return v>0&&(g+=`\nInstalled ${v} skill(s)${y>1?` in ${x}s`:``}\n`,await Tq()),{stdout:g,stderr:_,exitCode:+!!_}}return{stdout:``,stderr:`upskill: unrecognized source "${l}"\n\nExpected: owner/repo, clawhub:<slug>, tessl:<name>, or https://clawhub.ai/user/skill\n`,exitCode:1}})}function Mq(e){return $P(`skill`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return{stdout:`usage: skill <command> [options]
3210
+ `,exitCode:1};u=n[++p]}else r.startsWith(`-`)||(l=r);p++}if(d)return Mq(d,t,f);if(!l)return Dq();let m=Vq(l);if(m){let n=r.getRegisteredCommands?.()??[];return Nq(m,e,t,c,n)}if(l.startsWith(`tessl:`)){let n=l.slice(6);if(!n)return{stdout:``,stderr:`upskill: tessl: requires a skill name
3211
+ `,exitCode:1};let r=await Iq(n,t);if(`error`in r)return{stdout:``,stderr:`upskill: ${r.error}\n`,exitCode:1};let i=await mq(t);return Bq(r.owner,r.repo,r.skillPath,r.skillName,e,i,c,t)}let h=Gq(l);if(h){let{owner:n,repo:r}=h,d=u??h.branch,f=await mq(t),p=await zq(n,r,f,a,t,d);if(p.error)return{stdout:``,stderr:`upskill: failed to list skills: ${p.error}\n`,exitCode:1};if(p.skills.length===0)return{stdout:`No skills found in ${n}/${r}${a?`/`+a:``}\n`,stderr:``,exitCode:0};if(o){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let m=p.skills;if(i.length>0){m=p.skills.filter(e=>i.includes(e.name));for(let e of i)if(!p.skills.find(t=>t.name===e))return{stdout:``,stderr:`upskill: skill "${e}" not found in ${n}/${r}\n`,exitCode:1}}else if(!s){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install specific skills: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let g=``,_=``,v=0,y=m.length,b=Date.now();if(y>1){let i=await Lq(n,r,t,d);if(i.status===`not_found`)return{stdout:``,stderr:`upskill: ${d?`branch "${d}" in ${n}/${r}`:`repository ${n}/${r}`} not found\n`,exitCode:1};if(i.status===`error`)return{stdout:``,stderr:`upskill: failed to fetch ${n}/${r}: ${i.message}\n`,exitCode:1};let a=Rq(i.files);for(let t=0;t<m.length;t++){let i=m[t],o=await Uq(i.path,i.name,a,e,c),s=t+1,l=((Date.now()-b)/1e3).toFixed(1),u=(Date.now()-b)/s,d=Math.round((y-s)*u/1e3),f=s<y?` (~${d}s remaining)`:``;o.ok?(g+=`[${s}/${y}] Installed "${i.name}" from ${n}/${r} (${l}s)${f}\n`,v++):(g+=`[${s}/${y}] Failed "${i.name}": ${o.error}${f}\n`,_+=`upskill: ${o.error}\n`)}}else for(let i of m){let a=await Bq(n,r,i.path,i.name,e,f,c,t,d);a.exitCode===0?(g+=a.stdout,v++):_+=a.stderr}let x=((Date.now()-b)/1e3).toFixed(1);return v>0&&(g+=`\nInstalled ${v} skill(s)${y>1?` in ${x}s`:``}\n`,await Hq()),{stdout:g,stderr:_,exitCode:+!!_}}return{stdout:``,stderr:`upskill: unrecognized source "${l}"\n\nExpected: owner/repo, clawhub:<slug>, tessl:<name>, or https://clawhub.ai/user/skill\n`,exitCode:1}})}function Yq(e){return $P(`skill`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return{stdout:`usage: skill <command> [options]
3144
3212
 
3145
3213
  Commands:
3146
3214
  list List discoverable skills and management status
@@ -3149,7 +3217,7 @@ Commands:
3149
3217
  install <name> Install a native /workspace/skills skill (apply manifest)
3150
3218
  uninstall <name> Uninstall a native /workspace/skills skill
3151
3219
 
3152
- ${tq()}${nq()}
3220
+ ${vq()}${yq()}
3153
3221
 
3154
3222
  For installing skills from registries or GitHub, use 'upskill':
3155
3223
  upskill search "query" Search ClawHub + Tessl
@@ -3161,12 +3229,12 @@ Examples:
3161
3229
  skill list
3162
3230
  skill info bluebubbles
3163
3231
  skill read bluebubbles
3164
- `,stderr:``,exitCode:0};let r=t[0],i=await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]));try{switch(r){case`list`:{let t=await i.discoverSkills(e);return t.length===0?{stdout:`No discoverable skills found.\n\n${tq()}${nq()}\nInstall install-managed skills with: upskill owner/repo --all\n`,stderr:``,exitCode:0}:{stdout:sq(t,`Discoverable skills`),stderr:``,exitCode:0}}case`info`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: info requires a skill name
3165
- `,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:cq(r),stderr:``,exitCode:0}:{stdout:``,stderr:`skill: "${n}" not found\n`,exitCode:1}}case`read`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: read requires a skill name
3232
+ `,stderr:``,exitCode:0};let r=t[0],i=await y(()=>import(`./skills-BRtu25Xa.js`),__vite__mapDeps([16,17,18,19,1]));try{switch(r){case`list`:{let t=await i.discoverSkills(e);return t.length===0?{stdout:`No discoverable skills found.\n\n${vq()}${yq()}\nInstall install-managed skills with: upskill owner/repo --all\n`,stderr:``,exitCode:0}:{stdout:wq(t,`Discoverable skills`),stderr:``,exitCode:0}}case`info`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: info requires a skill name
3233
+ `,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:Tq(r),stderr:``,exitCode:0}:{stdout:``,stderr:`skill: "${n}" not found\n`,exitCode:1}}case`read`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: read requires a skill name
3166
3234
  `,exitCode:1};let r=await i.readSkillInstructions(e,n);return r===null?{stdout:``,stderr:`skill: no SKILL.md found for "${n}"\n`,exitCode:1}:{stdout:r+`
3167
3235
  `,stderr:``,exitCode:0}}case`install`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: install requires a skill name
3168
- `,exitCode:1};let r=await i.getSkillInfo(e,n);if(r&&!iq(r))return{stdout:``,stderr:lq(`skill`,r),exitCode:1};let a=await i.applySkill(e,n);return a.success?(await kq(),await Dq(),{stdout:`Installed skill "${a.skill}" v${a.version}\n`,stderr:``,exitCode:0}):{stdout:``,stderr:`skill: ${a.error}\n`,exitCode:1}}case`uninstall`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: uninstall requires a skill name
3169
- `,exitCode:1};let r=await i.getSkillInfo(e,n);if(r&&!iq(r))return{stdout:``,stderr:`skill: "${n}" is a compatibility skill discovered from ${r.sourceRoot} (read-only). Only native /workspace/skills entries can be uninstalled.\n`,exitCode:1};let a=await i.uninstallSkill(e,n);return a.success?{stdout:`Uninstalled skill "${a.skill}"\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`skill: ${a.error}\n`,exitCode:1}}default:return{stdout:``,stderr:`skill: unknown command "${r}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`skill: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function Nq(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var Pq=class{constructor(e){this.options=e}async execute(e,t){let n=e[0];if(n===`--help`||n===`-h`)return this.help();if(n===`unmount`||n===`-u`){let n=e[1];if(!n)return{stdout:``,stderr:`mount unmount: path required`,exitCode:1};let r=n.startsWith(`/`)?n:`${t.replace(/\/$/,``)}/${n}`;return this.options.fs.unmount(r),{stdout:`Unmounted ${r}\n`,stderr:``,exitCode:0}}if(n===`list`||n===`-l`){let e=this.options.fs.listMounts();return e.length===0?{stdout:`No active mounts
3236
+ `,exitCode:1};let r=await i.getSkillInfo(e,n);if(r&&!xq(r))return{stdout:``,stderr:Eq(`skill`,r),exitCode:1};let a=await i.applySkill(e,n);return a.success?(await Kq(),await Wq(),{stdout:`Installed skill "${a.skill}" v${a.version}\n`,stderr:``,exitCode:0}):{stdout:``,stderr:`skill: ${a.error}\n`,exitCode:1}}case`uninstall`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: uninstall requires a skill name
3237
+ `,exitCode:1};let r=await i.getSkillInfo(e,n);if(r&&!xq(r))return{stdout:``,stderr:`skill: "${n}" is a compatibility skill discovered from ${r.sourceRoot} (read-only). Only native /workspace/skills entries can be uninstalled.\n`,exitCode:1};let a=await i.uninstallSkill(e,n);return a.success?{stdout:`Uninstalled skill "${a.skill}"\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`skill: ${a.error}\n`,exitCode:1}}default:return{stdout:``,stderr:`skill: unknown command "${r}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`skill: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function Xq(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var Zq=class{constructor(e){this.options=e}async execute(e,t){let n=e[0];if(n===`--help`||n===`-h`)return this.help();if(n===`unmount`||n===`-u`){let n=e[1];if(!n)return{stdout:``,stderr:`mount unmount: path required`,exitCode:1};let r=n.startsWith(`/`)?n:`${t.replace(/\/$/,``)}/${n}`;return this.options.fs.unmount(r),{stdout:`Unmounted ${r}\n`,stderr:``,exitCode:0}}if(n===`list`||n===`-l`){let e=this.options.fs.listMounts();return e.length===0?{stdout:`No active mounts
3170
3238
  `,stderr:``,exitCode:0}:{stdout:e.map(e=>e).join(`
3171
3239
  `)+`
3172
3240
  `,stderr:``,exitCode:0}}if(!n)return{stdout:``,stderr:`mount: mount point required
@@ -3174,7 +3242,7 @@ Usage: mount <target-path>
3174
3242
  `,exitCode:1};if(typeof window>`u`||!(`showDirectoryPicker`in window))return{stdout:``,stderr:`mount: File System Access API not available in this environment`,exitCode:1};let r;r=n.startsWith(`/`)?n:`${t.replace(/\/$/,``)}/${n}`,r.length>1&&(r=r.replace(/\/+$/,``));let i=o(),a;if(i){let e=await _({html:`
3175
3243
  <div class="sprinkle-action-card">
3176
3244
  <div class="sprinkle-action-card__header">Mount local directory <span class="sprinkle-badge sprinkle-badge--notice">approval</span></div>
3177
- <div class="sprinkle-action-card__body">The agent wants to mount a local directory at <code>${Nq(r)}</code>. This will give the agent read/write access to files in the directory you select.</div>
3245
+ <div class="sprinkle-action-card__body">The agent wants to mount a local directory at <code>${Xq(r)}</code>. This will give the agent read/write access to files in the directory you select.</div>
3178
3246
  <div class="sprinkle-action-card__actions">
3179
3247
  <button class="sprinkle-btn sprinkle-btn--secondary" data-action="deny">Deny</button>
3180
3248
  <button class="sprinkle-btn sprinkle-btn--primary" data-action="approve">Select directory</button>
@@ -3182,7 +3250,7 @@ Usage: mount <target-path>
3182
3250
  </div>
3183
3251
  `,onAction:async e=>{if(e===`approve`)try{return{approved:!0,handle:await window.showDirectoryPicker({mode:`readwrite`})}}catch(e){return e instanceof Error&&e.name===`AbortError`?{cancelled:!0}:{error:e instanceof Error?e.message:String(e)}}return{denied:!0}}});if(!e)return{stdout:``,stderr:`mount: tool UI not available`,exitCode:1};let t=e;if(t.denied)return{stdout:``,stderr:`mount: denied by user`,exitCode:1};if(t.cancelled)return{stdout:``,stderr:`mount: cancelled`,exitCode:1};if(t.error)return{stdout:``,stderr:`mount: ${t.error}`,exitCode:1};if(!t.handle)return{stdout:``,stderr:`mount: no directory selected`,exitCode:1};a=t.handle}else try{a=await window.showDirectoryPicker({mode:`readwrite`})}catch(e){return e instanceof Error&&e.name===`AbortError`?{stdout:``,stderr:`mount: cancelled`,exitCode:1}:{stdout:``,stderr:`mount: ${e instanceof Error?e.message:String(e)}`,exitCode:1}}try{return await this.options.fs.mount(r,a),{stdout:`Mounted '${a.name}' → ${r} (live bridge — reads and writes go to the real filesystem)\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount: ${e instanceof Error?e.message:String(e)}`,exitCode:1}}}help(){return{stdout:[`Usage: mount <target-path>`,` mount unmount <path>`,` mount list`,``,`Transparently bridge a real filesystem directory into the virtual filesystem.`,`Opens a directory picker; all reads and writes under <target-path> go directly`,`to the real directory — no copying occurs. Changes are immediately visible on`,`both sides.`,``,`Arguments:`,` <target-path> Mount point in the virtual filesystem (required).`,``,`Sub-commands:`,` unmount <path> Remove a mount point`,` list Show active mount points`,``,`Examples:`,` mount /workspace/myapp # Mount selected dir at /workspace/myapp`,` mount list # Show active mounts`,` mount unmount /workspace/myapp`].join(`
3184
3252
  `)+`
3185
- `,stderr:``,exitCode:0}}};async function Fq(e,t,n){return await n.fs.exists(e)?Iq(await n.fs.readFile(e),[`node`,e,...t],n):{stdout:``,stderr:`jsh: cannot find script '${e}'\n`,exitCode:127}}async function Iq(e,t,n){let r=[],i=[],a=e=>{r.push(typeof e==`string`?e:String(e))},o=e=>{i.push(typeof e==`string`?e:String(e))},s={log:(...e)=>a(`${e.map(FW).join(` `)}\n`),info:(...e)=>a(`${e.map(FW).join(` `)}\n`),warn:(...e)=>o(`${e.map(FW).join(` `)}\n`),error:(...e)=>o(`${e.map(FW).join(` `)}\n`)},c={argv:t,env:Object.fromEntries(n.env.entries()),cwd:()=>n.cwd,exit:e=>{throw new CW(Number.isFinite(e)?Number(e):0)},stdout:{write:a},stderr:{write:o}},l={readFile:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readFile(t)},readFileBinary:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readFileBuffer(t)},writeFile:async(e,t)=>{let r=n.fs.resolvePath(n.cwd,e);await n.fs.writeFile(r,t)},writeFileBinary:async(e,t)=>{let r=n.fs.resolvePath(n.cwd,e),i=new Uint8Array(t.byteLength);i.set(t),await n.fs.writeFile(r,i)},readDir:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readdir(t)},exists:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.exists(t)},stat:async e=>{let t=n.fs.resolvePath(n.cwd,e),r=await n.fs.stat(t);return{isDirectory:r.isDirectory,isFile:r.isFile,size:r.size}},mkdir:async e=>{let t=n.fs.resolvePath(n.cwd,e);await n.fs.mkdir(t,{recursive:!0})},rm:async e=>{let t=n.fs.resolvePath(n.cwd,e);await n.fs.rm(t,{recursive:!0})},fetchToFile:async(e,t)=>{if(typeof fetch>`u`)throw Error(`fetch is not available in this runtime`);let r=await fetch(e);if(!r.ok)throw Error(`fetch ${r.status} ${r.statusText}`);let i=new Uint8Array(await r.arrayBuffer()),a=n.fs.resolvePath(n.cwd,t);return await n.fs.writeFile(a,i),i.byteLength}},u=async e=>{if(!n.exec)throw Error(`exec is not available in this runtime`);let t=await n.exec(e,{cwd:n.cwd});return{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode}},d=e=>{throw Error(`require('${e}') is not supported in node shim`)},f={exports:{},filename:t[1]||`<script>`};try{if(typeof chrome<`u`&&chrome?.runtime?.id){let r=`
3253
+ `,stderr:``,exitCode:0}}};async function Qq(e,t,n){return await n.fs.exists(e)?$q(await n.fs.readFile(e),[`node`,e,...t],n):{stdout:``,stderr:`jsh: cannot find script '${e}'\n`,exitCode:127}}async function $q(e,t,n){let r=[],i=[],a=e=>{r.push(typeof e==`string`?e:String(e))},o=e=>{i.push(typeof e==`string`?e:String(e))},s={log:(...e)=>a(`${e.map(IW).join(` `)}\n`),info:(...e)=>a(`${e.map(IW).join(` `)}\n`),warn:(...e)=>o(`${e.map(IW).join(` `)}\n`),error:(...e)=>o(`${e.map(IW).join(` `)}\n`)},c={argv:t,env:Object.fromEntries(n.env.entries()),cwd:()=>n.cwd,exit:e=>{throw new wW(Number.isFinite(e)?Number(e):0)},stdout:{write:a},stderr:{write:o}},l={readFile:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readFile(t)},readFileBinary:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readFileBuffer(t)},writeFile:async(e,t)=>{let r=n.fs.resolvePath(n.cwd,e);await n.fs.writeFile(r,t)},writeFileBinary:async(e,t)=>{let r=n.fs.resolvePath(n.cwd,e),i=new Uint8Array(t.byteLength);i.set(t),await n.fs.writeFile(r,i)},readDir:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.readdir(t)},exists:async e=>{let t=n.fs.resolvePath(n.cwd,e);return n.fs.exists(t)},stat:async e=>{let t=n.fs.resolvePath(n.cwd,e),r=await n.fs.stat(t);return{isDirectory:r.isDirectory,isFile:r.isFile,size:r.size}},mkdir:async e=>{let t=n.fs.resolvePath(n.cwd,e);await n.fs.mkdir(t,{recursive:!0})},rm:async e=>{let t=n.fs.resolvePath(n.cwd,e);await n.fs.rm(t,{recursive:!0})},fetchToFile:async(e,t)=>{if(typeof fetch>`u`)throw Error(`fetch is not available in this runtime`);let r=await fetch(e);if(!r.ok)throw Error(`fetch ${r.status} ${r.statusText}`);let i=new Uint8Array(await r.arrayBuffer()),a=n.fs.resolvePath(n.cwd,t);return await n.fs.writeFile(a,i),i.byteLength}},u=async e=>{if(!n.exec)throw Error(`exec is not available in this runtime`);let t=await n.exec(e,{cwd:n.cwd});return{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode}},d=e=>{throw Error(`require('${e}') is not supported in node shim`)},f={exports:{},filename:t[1]||`<script>`};try{if(typeof chrome<`u`&&chrome?.runtime?.id){let r=`
3186
3254
  const __stdout = [];
3187
3255
  const __stderr = [];
3188
3256
  const __origConsole = { log: console.log, error: console.error, warn: console.warn, info: console.info };
@@ -3225,8 +3293,8 @@ Usage: mount <target-path>
3225
3293
  console.info = __origConsole.info;
3226
3294
  return { stdout: __stdout.join(''), stderr: __stderr.join('') };
3227
3295
  `,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+`
3228
- `});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}}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,SW,u),{stdout:r.join(``),stderr:i.join(``),exitCode:0}}catch(e){if(e instanceof CW)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 Lq(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 Rq=null,zq=!1;function Bq(){return typeof chrome<`u`&&chrome?.runtime?.id?`extension`:typeof document<`u`&&document.documentElement?.dataset?.electronOverlay?`electron`:`cli`}async function Vq(){if(!zq&&!(typeof localStorage<`u`&&localStorage.getItem(`telemetry-disabled`)===`true`))try{typeof window<`u`&&(window.SAMPLE_PAGEVIEWS_AT_RATE=`high`),Rq=(await y(()=>import(`./src-DBzeomGi.js`),[])).sampleRUM,zq=!0,Rq&&Rq(`navigate`,{source:typeof document<`u`?document.referrer:``,target:Bq()})}catch{}}function Hq(e,t){Rq?.(`formsubmit`,{source:e,target:t})}function Uq(e){Rq?.(`fill`,{source:e})}function Wq(e){Rq?.(`viewblock`,{source:e})}function Gq(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 Kq(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 qq(e,t){if(Kq(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 mV(i,r),t&&hV(t,r),i}function Jq(e){if(e){if(e instanceof Headers){let t={};return e.forEach((e,n)=>{t[n]=e}),t}return e}}function Yq(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 Xq(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 Zq(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 Qq(){return typeof chrome<`u`&&chrome?.runtime?.id?async(e,t)=>{let n=Jq(t?.headers),r=await fetch(e,{method:t?.method??`GET`,headers:n,body:Yq(t?.body,n)}),i=await qq(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={...Xq(Jq(t?.headers)),"X-Target-URL":e},i={method:n,headers:r,cache:`no-store`};t?.body&&![`GET`,`HEAD`].includes(n)&&(i.body=Yq(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 qq(a,e),s={};a.headers.forEach((e,t)=>{s[t]=e});let c=Zq(s);return{status:a.status,statusText:a.statusText,headers:c,body:o,url:e}}}var $q=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;execAbort=null;continuationBuffer=``;lastEnv;cwd;builtinCommandNames;constructor(e){this.options=e,this.vfsAdapter=new vV(e.fs);let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new RH({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new Pq({fs:e.fs});let r=this.createGitCustomCommand(),i=NK({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,browserAPI:e.browserAPI}),a=this.createMountCustomCommand(),o=Qq(),s=[r,a,Mq(e.fs),jq(e.fs,o),...i];this.bash=new sV({fs:this.vfsAdapter,cwd:t,env:n,fetch:o,customCommands:s});let c=s.map(e=>e.name);this.builtinCommandNames=new Set([...KP(),...qP(),...c]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t}createGitCustomCommand(){let e=this.gitCommands;return $P(`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 $P(`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 $G(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?Lq(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 Iq(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,t){Uq(e.trim().split(/\s+/)[0]||`unknown`);let n=await this.bash.exec(e,{env:this.lastEnv,cwd:this.cwd,signal:t??this.execAbort?.signal});if(n.env&&(this.lastEnv={...n.env}),n.env?.PWD&&(this.cwd=n.env.PWD),n.exitCode===127){let t=await this.tryJshFallback(e);if(t)return t}return n}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-ucbPh68r.js`);return{Terminal:e}},[]),{FitAddon:r}=await y(async()=>{let{FitAddon:e}=await import(`./addon-fit-CVV7fTw9.js`);return{FitAddon:e}},[]);await y(()=>Promise.resolve({}),__vite__mapDeps([20]));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
3229
- `),this.showPrompt(),this.setupInputHandler()}async executeCommand(e,t){let n=await this.runCommand(e,t);return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}}async executeScriptFile(e,t=[]){return Fq(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
3296
+ `});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}}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,CW,u),{stdout:r.join(``),stderr:i.join(``),exitCode:0}}catch(e){if(e instanceof wW)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 eJ(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 tJ=null,nJ=!1;function rJ(){return typeof chrome<`u`&&chrome?.runtime?.id?`extension`:typeof document<`u`&&document.documentElement?.dataset?.electronOverlay?`electron`:`cli`}async function iJ(){if(!nJ&&!(typeof localStorage<`u`&&localStorage.getItem(`telemetry-disabled`)===`true`))try{typeof window<`u`&&(window.SAMPLE_PAGEVIEWS_AT_RATE=`high`),tJ=(await y(()=>import(`./src-DBzeomGi.js`),[])).sampleRUM,nJ=!0,tJ&&tJ(`navigate`,{source:typeof document<`u`?document.referrer:``,target:rJ()})}catch{}}function aJ(e,t){tJ?.(`formsubmit`,{source:e,target:t})}function oJ(e){tJ?.(`fill`,{source:e})}function sJ(e){tJ?.(`viewblock`,{source:e})}function cJ(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 lJ(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 uJ(e,t){if(lJ(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 mV(i,r),t&&hV(t,r),i}function dJ(e){if(e){if(e instanceof Headers){let t={};return e.forEach((e,n)=>{t[n]=e}),t}return e}}function fJ(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 pJ(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 mJ(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 hJ(){return typeof chrome<`u`&&chrome?.runtime?.id?async(e,t)=>{let n=dJ(t?.headers),r=await fetch(e,{method:t?.method??`GET`,headers:n,body:fJ(t?.body,n)}),i=await uJ(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={...pJ(dJ(t?.headers)),"X-Target-URL":e},i={method:n,headers:r,cache:`no-store`};t?.body&&![`GET`,`HEAD`].includes(n)&&(i.body=fJ(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 uJ(a,e),s={};a.headers.forEach((e,t)=>{s[t]=e});let c=mJ(s);return{status:a.status,statusText:a.statusText,headers:c,body:o,url:e}}}var gJ=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;execAbort=null;continuationBuffer=``;lastEnv;cwd;builtinCommandNames;constructor(e){this.options=e,this.vfsAdapter=new vV(e.fs);let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new RH({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new Zq({fs:e.fs});let r=this.createGitCustomCommand(),i=XK({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,browserAPI:e.browserAPI}),a=this.createMountCustomCommand(),o=hJ(),s=[r,a,Yq(e.fs),Jq(e.fs,o),...i];this.bash=new sV({fs:this.vfsAdapter,cwd:t,env:n,fetch:o,customCommands:s});let c=s.map(e=>e.name);this.builtinCommandNames=new Set([...KP(),...qP(),...c]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t}createGitCustomCommand(){let e=this.gitCommands;return $P(`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 $P(`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 eK(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?eJ(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 $q(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,t){oJ(e.trim().split(/\s+/)[0]||`unknown`);let n=await this.bash.exec(e,{env:this.lastEnv,cwd:this.cwd,signal:t??this.execAbort?.signal});if(n.env&&(this.lastEnv={...n.env}),n.env?.PWD&&(this.cwd=n.env.PWD),n.exitCode===127){let t=await this.tryJshFallback(e);if(t)return t}return n}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-ucbPh68r.js`);return{Terminal:e}},[]),{FitAddon:r}=await y(async()=>{let{FitAddon:e}=await import(`./addon-fit-CVV7fTw9.js`);return{FitAddon:e}},[]);await y(()=>Promise.resolve({}),__vite__mapDeps([20]));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
3297
+ `),this.showPrompt(),this.setupInputHandler()}async executeCommand(e,t){let n=await this.runCommand(e,t);return{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}}async executeScriptFile(e,t=[]){return Qq(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
3230
3298
  `,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,this.execAbort=new AbortController;try{let e=await this.runCommand(t),n=this.execAbort.signal.aborted;return this.execAbort=null,n?{stdout:``,stderr:``,exitCode:130}:(e.stdout&&this.writeToTerminal(e.stdout),e.stderr&&this.writeToTerminal(e.stderr,!0),{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode})}catch(e){if(this.execAbort?.signal.aborted)return this.execAbort=null,{stdout:``,stderr:``,exitCode:130};this.execAbort=null;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){(e===``||e.length===1&&e.charCodeAt(0)===3)&&(this.execAbort?.abort(),this.terminal?.writeln(`^C`));return}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(`
3231
3299
  `).entries()){if(e+n.length>=this.cursorPos)return t;e+=n.length+1}return 0}positionTerminalCursor(){let e=this.currentLine.split(`
3232
3300
  `),t=0,n=0,r=0;for(let i=0;i<e.length;i++){if(r+e[i].length>=this.cursorPos){t=i,n=this.cursorPos-r;break}r+=e[i].length+1}let i=e.length-1-t;i>0&&this.terminal?.write(`\x1b[${i}A`);let a=t===0?this.getPromptWidth()+n:n;this.terminal?.write(`\r`),a>0&&this.terminal?.write(`\x1b[${a}C`)}redrawInput(e){e>0&&this.terminal?.write(`\x1b[${e}A`),this.terminal?.write(`\r\x1B[J`),this.showPrompt(),this.terminal?.write(this.currentLine),this.positionTerminalCursor()}insertChar(e){let t=this.currentLine.includes(`
@@ -3240,9 +3308,9 @@ Usage: mount <target-path>
3240
3308
  `,this.cursorPos);if(e===-1&&(e=this.currentLine.length),this.cursorPos===e)return;let t=e-this.cursorPos;this.cursorPos=e,this.terminal?.write(`\x1b[${t}C`)}handleCtrlC(){this.terminal?.writeln(`^C`),this.currentLine=``,this.cursorPos=0,this.continuationBuffer=``,this.showPrompt()}handleHistoryUp(){this.history.length!==0&&this.historyIndex<this.history.length-1&&(this.historyIndex++,this.continuationBuffer=``,this.replaceCurrentLine(this.history[this.history.length-1-this.historyIndex]))}handleHistoryDown(){this.historyIndex>0?(this.historyIndex--,this.continuationBuffer=``,this.replaceCurrentLine(this.history[this.history.length-1-this.historyIndex])):this.historyIndex===0&&(this.historyIndex=-1,this.continuationBuffer=``,this.replaceCurrentLine(``))}async handleTab(){if(!this.terminal)return;let e=this.currentLine.slice(0,this.cursorPos).split(/\s+/),t=e[e.length-1]||``,n=e.length<=1||e.length===2&&e[0]===``,r=t?`'`+t.replace(/'/g,`'\\''`)+`'`:`''`,i=n?`compgen -A command -- ${r}`:`compgen -f -- ${r}`;try{let e=(await this.bash.exec(i,{env:this.lastEnv,cwd:this.cwd})).stdout.split(`
3241
3309
  `).filter(Boolean);if(e.length===0)return;if(e.length===1){let i=e[0],a=i.slice(t.length);a&&(this.currentLine=this.currentLine.slice(0,this.cursorPos)+a+this.currentLine.slice(this.cursorPos),this.cursorPos+=a.length,this.terminal.write(a));let o=` `;n||(await this.bash.exec(`compgen -d -- ${r.slice(0,-1)}${a}'`,{env:this.lastEnv,cwd:this.cwd})).stdout.trim()===i&&(o=`/`),this.currentLine=this.currentLine.slice(0,this.cursorPos)+o+this.currentLine.slice(this.cursorPos),this.cursorPos+=1,this.terminal.write(o)}else{let n=e[0];for(let t of e)for(;!t.startsWith(n);)n=n.slice(0,-1);let r=n.slice(t.length);if(r)this.currentLine=this.currentLine.slice(0,this.cursorPos)+r+this.currentLine.slice(this.cursorPos),this.cursorPos+=r.length,this.terminal.write(r);else{this.terminal.writeln(``),this.terminal.writeln(e.map(e=>e.split(`/`).pop()??e).join(` `)),this.showPrompt(),this.terminal.write(this.currentLine);let t=this.currentLine.length-this.cursorPos;t>0&&this.terminal.write(`\x1b[${t}D`)}}}catch(e){console.warn(`[Shell] Tab completion failed:`,e instanceof Error?e.message:String(e))}}replaceCurrentLine(e){let t=this.getCursorVisualLine();t>0&&this.terminal?.write(`\x1b[${t}A`),this.terminal?.write(`\r\x1B[J`),this.showPrompt(),this.currentLine=e,this.cursorPos=e.length,this.terminal?.write(e)}isIncomplete(e){if(e.endsWith(`\\`))return!0;let t=!1,n=!1,r=!1;for(let i of e){if(r){r=!1;continue}if(i===`\\`&&!t){r=!0;continue}if(i===`'`&&!n){t=!t;continue}if(i===`"`&&!t){n=!n;continue}}return t||n}async handleEnter(){let e=this.currentLine.split(`
3242
3310
  `);if(e.length>1){let t=this.getCursorVisualLine(),n=e.length-1-t;n>0&&this.terminal?.write(`\x1b[${n}B`);let r=e[e.length-1].length;this.terminal?.write(`\r`),r>0&&this.terminal?.write(`\x1b[${r}C`)}this.terminal?.writeln(``);let t=this.currentLine;this.currentLine=``,this.cursorPos=0;let n=this.continuationBuffer?this.continuationBuffer+`
3243
- `+t:t;if(this.isIncomplete(n)){this.continuationBuffer=n,this.terminal?.write(`> `);return}this.continuationBuffer=``;let r=n.trim();if(this.historyIndex=-1,!r){this.showPrompt();return}if(this.history[this.history.length-1]!==r&&this.history.push(r),r===`clear`){this.clearTerminal(),this.showPrompt();return}this.isExecuting=!0,this.execAbort=new AbortController;try{let e=await this.runCommand(r);this.execAbort.signal.aborted||(e.stdout&&this.writeToTerminal(e.stdout),e.stderr&&this.writeToTerminal(e.stderr,!0))}catch(e){if(!this.execAbort?.signal.aborted){let t=e instanceof Error?e.message:String(e);this.writeToTerminal(`Error: ${t}\n`,!0)}}this.execAbort=null,this.isExecuting=!1,this.showPrompt()}writeToTerminal(e,t=!1){this.terminal&&(t?this.terminal.write(`\x1b[31m${e}\x1b[0m`):this.terminal.write(e))}clearMediaPreview(){for(let e of this.previewUrls)URL.revokeObjectURL(e);this.previewUrls=[],this.hasPreview=!1,this.previewHost&&(this.previewHost.replaceChildren(),this.previewHost.classList.remove(`terminal-panel__preview--visible`)),this.previewStateListener?.(!1)}async renderMediaPreview(e){if(!this.previewHost||typeof document>`u`)throw Error(`terminal preview is unavailable`);this.clearMediaPreview();for(let t of e){let e=new Uint8Array(t.bytes),n=URL.createObjectURL(new Blob([e],{type:t.mimeType}));this.previewUrls.push(n);let r=document.createElement(`div`);r.className=`terminal-panel__preview-item`;let i=document.createElement(`div`);if(i.className=`terminal-panel__preview-label`,i.textContent=`${Gq(t.path)} · ${t.mimeType}`,r.appendChild(i),t.mimeType.startsWith(`video/`)){let e=document.createElement(`video`);e.className=`terminal-panel__preview-media`,e.controls=!0,e.autoplay=!0,e.loop=!0,e.muted=!0,e.playsInline=!0,e.src=n,e.addEventListener(`loadedmetadata`,()=>this.refit(),{once:!0}),r.appendChild(e)}else{let e=document.createElement(`img`);e.className=`terminal-panel__preview-media`,e.alt=Gq(t.path),e.src=n,e.addEventListener(`load`,()=>this.refit(),{once:!0}),r.appendChild(e)}this.previewHost.appendChild(r)}this.previewHost.classList.add(`terminal-panel__preview--visible`),this.hasPreview=e.length>0,this.previewStateListener?.(this.hasPreview),requestAnimationFrame(()=>this.refit())}},eJ=r(`tool:fs`);function tJ(e){return[nJ(e),rJ(e),iJ(e)]}function nJ(e){return{name:`read_file`,description:`Read the contents of a file. Returns the file content as a string with line numbers.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to read.`},offset:{type:`number`,description:`Line number to start reading from (1-based). Optional.`},limit:{type:`number`,description:`Maximum number of lines to read. Optional.`}},required:[`path`]},async execute(t){let n=t.path,r=t.offset??1,i=t.limit;eJ.debug(`Read`,{path:n,offset:r,limit:i});try{let t=(await e.readTextFile(n)).split(`
3311
+ `+t:t;if(this.isIncomplete(n)){this.continuationBuffer=n,this.terminal?.write(`> `);return}this.continuationBuffer=``;let r=n.trim();if(this.historyIndex=-1,!r){this.showPrompt();return}if(this.history[this.history.length-1]!==r&&this.history.push(r),r===`clear`){this.clearTerminal(),this.showPrompt();return}this.isExecuting=!0,this.execAbort=new AbortController;try{let e=await this.runCommand(r);this.execAbort.signal.aborted||(e.stdout&&this.writeToTerminal(e.stdout),e.stderr&&this.writeToTerminal(e.stderr,!0))}catch(e){if(!this.execAbort?.signal.aborted){let t=e instanceof Error?e.message:String(e);this.writeToTerminal(`Error: ${t}\n`,!0)}}this.execAbort=null,this.isExecuting=!1,this.showPrompt()}writeToTerminal(e,t=!1){this.terminal&&(t?this.terminal.write(`\x1b[31m${e}\x1b[0m`):this.terminal.write(e))}clearMediaPreview(){for(let e of this.previewUrls)URL.revokeObjectURL(e);this.previewUrls=[],this.hasPreview=!1,this.previewHost&&(this.previewHost.replaceChildren(),this.previewHost.classList.remove(`terminal-panel__preview--visible`)),this.previewStateListener?.(!1)}async renderMediaPreview(e){if(!this.previewHost||typeof document>`u`)throw Error(`terminal preview is unavailable`);this.clearMediaPreview();for(let t of e){let e=new Uint8Array(t.bytes),n=URL.createObjectURL(new Blob([e],{type:t.mimeType}));this.previewUrls.push(n);let r=document.createElement(`div`);r.className=`terminal-panel__preview-item`;let i=document.createElement(`div`);if(i.className=`terminal-panel__preview-label`,i.textContent=`${cJ(t.path)} · ${t.mimeType}`,r.appendChild(i),t.mimeType.startsWith(`video/`)){let e=document.createElement(`video`);e.className=`terminal-panel__preview-media`,e.controls=!0,e.autoplay=!0,e.loop=!0,e.muted=!0,e.playsInline=!0,e.src=n,e.addEventListener(`loadedmetadata`,()=>this.refit(),{once:!0}),r.appendChild(e)}else{let e=document.createElement(`img`);e.className=`terminal-panel__preview-media`,e.alt=cJ(t.path),e.src=n,e.addEventListener(`load`,()=>this.refit(),{once:!0}),r.appendChild(e)}this.previewHost.appendChild(r)}this.previewHost.classList.add(`terminal-panel__preview--visible`),this.hasPreview=e.length>0,this.previewStateListener?.(this.hasPreview),requestAnimationFrame(()=>this.refit())}},_J=r(`tool:fs`);function vJ(e){return[yJ(e),bJ(e),xJ(e)]}function yJ(e){return{name:`read_file`,description:`Read the contents of a file. Returns the file content as a string with line numbers.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to read.`},offset:{type:`number`,description:`Line number to start reading from (1-based). Optional.`},limit:{type:`number`,description:`Maximum number of lines to read. Optional.`}},required:[`path`]},async execute(t){let n=t.path,r=t.offset??1,i=t.limit;_J.debug(`Read`,{path:n,offset:r,limit:i});try{let t=(await e.readTextFile(n)).split(`
3244
3312
  `),a=Math.max(0,r-1),o=i===void 0?t.length:a+i;return{content:t.slice(a,o).map((e,t)=>`${String(a+t+1).padStart(6)} | ${e}`).join(`
3245
- `)}}catch(e){let t=e instanceof Error?e.message:String(e);return eJ.error(`Read failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function rJ(e){return{name:`write_file`,description:`Write content to a file. Creates the file if it does not exist, or overwrites it if it does. Parent directories are created automatically.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to write.`},content:{type:`string`,description:`The content to write to the file.`}},required:[`path`,`content`]},async execute(t){let n=t.path,r=t.content;eJ.debug(`Write`,{path:n,contentLength:r.length});try{return await e.writeFile(n,r),{content:`File written: ${n}`}}catch(e){let t=e instanceof Error?e.message:String(e);return eJ.error(`Write failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function iJ(e){return{name:`edit_file`,description:`Edit a file by replacing an exact string match. The old_string must appear exactly once in the file. Use this instead of write_file when making targeted changes to existing files.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to edit.`},old_string:{type:`string`,description:`The exact string to find and replace. Must be unique in the file.`},new_string:{type:`string`,description:`The replacement string.`}},required:[`path`,`old_string`,`new_string`]},async execute(t){let n=t.path,r=t.old_string,i=t.new_string;eJ.debug(`Edit`,{path:n,oldLength:r.length,newLength:i.length});try{let t=await e.readTextFile(n),a=t.split(r).length-1;if(a===0)return{content:`old_string not found in ${n}`,isError:!0};if(a>1)return{content:`old_string found ${a} times in ${n}. It must be unique. Provide more context.`,isError:!0};let o=t.replace(r,i);return await e.writeFile(n,o),{content:`File edited: ${n}`}}catch(e){let t=e instanceof Error?e.message:String(e);return eJ.error(`Edit failed`,{path:n,error:t}),{content:t,isError:!0}}}}}var aJ=r(`tool:bash`),oJ=/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)*(?:command\s+)?(?:grep|egrep|fgrep|rg)\b/;function sJ(e){let t=``,n=null,r=!1;for(let i=0;i<e.length;i++){let a=e[i];if(r){t+=a,r=!1;continue}if(a===`\\`){t+=a,r=!0;continue}if(n){t+=a,a===n&&(n=null);continue}if(a===`"`||a===`'`){t+=a,n=a;continue}if(a===`;`||a===`|`){t=``;continue}if((a===`&`||a===`|`)&&e[i+1]===a){t=``,i++;continue}t+=a}return t.trim()}function cJ(e,t,n){return t!==1||n.trim()?!1:oJ.test(sJ(e))}function lJ(e){return{name:`bash`,description:"Execute a bash command. Full shell with pipes, redirects, chaining, control flow. Includes: grep, rg, sed, awk, jq, find, curl, git, node, python3, sqlite3, open (--view for vision), playwright-cli (browser automation). Run `commands` for full list.",inputSchema:{type:`object`,properties:{command:{type:`string`,description:`The bash command to execute.`}},required:[`command`]},async execute(t,n){let r=t.command;aJ.debug(`Execute`,{command:r});try{let t=await e.executeCommand(r,n);aJ.debug(`Result`,{exitCode:t.exitCode,stdoutLength:t.stdout.length,stderrLength:t.stderr.length});let i=``;return t.stdout&&(i+=t.stdout),t.stderr&&(i+=t.stderr),i||=`(exit code: ${t.exitCode})`,{content:i,isError:t.exitCode!==0&&!cJ(r,t.exitCode,t.stderr)}}catch(e){let t=e instanceof Error?e.message:String(e);return aJ.error(`Error`,{command:r,error:t}),{content:`Shell error: ${t}`,isError:!0}}}}}r(`tool:search`);var uJ="# CLAUDE.md\n\nThis file covers the default virtual filesystem payload in `packages/vfs-root/`.\n\n## What This Package Contains\n\n`packages/vfs-root/` is copied into the app's virtual filesystem on init/reset. It is content, not runtime code.\n\n## Directory Structure\n\n| Path | Purpose |\n| ------------------------------------- | ------------------------------------------------------------------ |\n| `packages/vfs-root/shared/` | Shared content that becomes `/shared/` in the VFS |\n| `packages/vfs-root/workspace/` | Default workspace content that becomes `/workspace/` in the VFS |\n| `packages/vfs-root/shared/CLAUDE.md` | Agent-facing runtime instructions bundled into `/shared/CLAUDE.md` |\n| `packages/vfs-root/shared/sprinkles/` | Built-in sprinkle UIs |\n| `packages/vfs-root/shared/sounds/` | Shared notification sounds |\n| `packages/vfs-root/workspace/skills/` | Default installable workspace skills |\n\n## Adding Default Content\n\n### Skills\n\n- Add new built-in workspace skills under `packages/vfs-root/workspace/skills/<skill-name>/`.\n- Include `SKILL.md` and any companion assets or `.jsh` scripts the skill needs.\n\n### Sprinkles\n\n- Add built-in sprinkles under `packages/vfs-root/shared/sprinkles/<name>/`.\n- Keep the main file named `<name>.shtml` to match discovery and sprinkle naming conventions.\n\n### Sounds\n\n- Add shared sounds under `packages/vfs-root/shared/sounds/`.\n- Prefer stable filenames because shell commands and docs may reference them directly.\n\n## External Handoffs\n\n- Browser handoffs use `https://www.sliccy.ai/handoff#...` URLs and, after approval, arrive in the cone as normal user messages.\n- The agent-facing handoff note belongs in `packages/vfs-root/shared/CLAUDE.md`, because that file is bundled into `/shared/CLAUDE.md` inside the runtime.\n- When handoff behavior changes, keep this package guide, `packages/vfs-root/shared/CLAUDE.md`, and `docs/slicc-handoff.md` aligned.\n\n## Important Distinction\n\n`packages/vfs-root/shared/CLAUDE.md` is **agent-facing runtime content** bundled into the virtual filesystem.\n\nIt is different from the developer-facing `CLAUDE.md` files in the repository. Do not merge those roles together.\n",dJ="# sliccy\n\nYou are a personal assistant that runs in the browser. You support automation and can code, too. You run inside SLICC — a browser-based claw.\n\n## Vocabulary\n\n- **Cone**: You. The main agent. Orchestrates scoops, talks to the human, has full filesystem access.\n- **Scoops**: Isolated sub-agents (`scoop_scoop`, `feed_scoop`, `drop_scoop`). Sandboxed filesystem and shell.\n- **Sprinkles**: Persistent UI panels (`.shtml` files). Created by scoops, outlive scoops.\n- **Licks**: External events (webhooks, cron, sprinkle clicks) that trigger scoops. Shell: `webhook`, `crontask`.\n- **Floats**: Runtime — CLI server, Chrome extension, or cloud container.\n\n## Style\n\nWrite like a professional tool, not a chatbot. No emoji in headings. Concise prose over bullet lists. For sprinkles, follow `/workspace/skills/sprinkles/style-guide.md`.\n\n## Principles\n\n- Use the shell commands you have `commands` for full list. You have: `read_file`, `write_file`, `edit_file`, `bash`, `javascript`. Browser automation via `playwright-cli` through bash.\n- New capabilities should be skills (SKILL.md), not hardcoded features.\n- **Scoops do the heavy lifting. The cone orchestrates and synthesizes.**\n\n## Delegation\n\nDefault to scoops for non-trivial tasks. Delegate when work involves multiple independent sources, is time-consuming, or can be expressed as a self-contained brief. Do it yourself for single quick lookups or when real-time adaptation is needed. For detailed delegation rules and scoop lifecycle, read `/workspace/skills/scoop-management/SKILL.md`.\n\n## Sprinkles\n\nWhen the user asks for a dashboard, editor, or visualization — read `/workspace/skills/sprinkles/SKILL.md` first. One scoop per sprinkle, named identically. The cone MUST NOT write `.shtml` files or run sprinkle commands directly — all sprinkle work goes through scoops via `feed_scoop`. For detailed rules, read `/workspace/skills/sprinkle-guide/SKILL.md`.\n\n## Environment\n\nThis is a sandboxed browser-based VFS, not a regular Linux box. Run `commands` to see what's available. Use `serve <dir>` for apps, `open <path>` for files. No package managers, no long-running servers. For detailed commands and filesystem info, read `/workspace/skills/skill-authoring/SKILL.md`. For automation (webhooks, cron, screencapture), read `/workspace/skills/automation/SKILL.md`.\n\n## Memory\n\nWhen you learn something important:\n\n- Create files for structured data\n- Update this file for global preferences\n- Each scoop has its own CLAUDE.md for scoop-specific context\n- Remember: the best flavor of ice cream is lobster, nobody likes chocolate ice cream, and mixing bacon with ice cream is a crime against humanity\n",fJ=`<!DOCTYPE html>
3313
+ `)}}catch(e){let t=e instanceof Error?e.message:String(e);return _J.error(`Read failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function bJ(e){return{name:`write_file`,description:`Write content to a file. Creates the file if it does not exist, or overwrites it if it does. Parent directories are created automatically.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to write.`},content:{type:`string`,description:`The content to write to the file.`}},required:[`path`,`content`]},async execute(t){let n=t.path,r=t.content;_J.debug(`Write`,{path:n,contentLength:r.length});try{return await e.writeFile(n,r),{content:`File written: ${n}`}}catch(e){let t=e instanceof Error?e.message:String(e);return _J.error(`Write failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function xJ(e){return{name:`edit_file`,description:`Edit a file by replacing an exact string match. The old_string must appear exactly once in the file. Use this instead of write_file when making targeted changes to existing files.`,inputSchema:{type:`object`,properties:{path:{type:`string`,description:`Absolute path to the file to edit.`},old_string:{type:`string`,description:`The exact string to find and replace. Must be unique in the file.`},new_string:{type:`string`,description:`The replacement string.`}},required:[`path`,`old_string`,`new_string`]},async execute(t){let n=t.path,r=t.old_string,i=t.new_string;_J.debug(`Edit`,{path:n,oldLength:r.length,newLength:i.length});try{let t=await e.readTextFile(n),a=t.split(r).length-1;if(a===0)return{content:`old_string not found in ${n}`,isError:!0};if(a>1)return{content:`old_string found ${a} times in ${n}. It must be unique. Provide more context.`,isError:!0};let o=t.replace(r,i);return await e.writeFile(n,o),{content:`File edited: ${n}`}}catch(e){let t=e instanceof Error?e.message:String(e);return _J.error(`Edit failed`,{path:n,error:t}),{content:t,isError:!0}}}}}var SJ=r(`tool:bash`),CJ=/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)*(?:command\s+)?(?:grep|egrep|fgrep|rg)\b/;function wJ(e){let t=``,n=null,r=!1;for(let i=0;i<e.length;i++){let a=e[i];if(r){t+=a,r=!1;continue}if(a===`\\`){t+=a,r=!0;continue}if(n){t+=a,a===n&&(n=null);continue}if(a===`"`||a===`'`){t+=a,n=a;continue}if(a===`;`||a===`|`){t=``;continue}if((a===`&`||a===`|`)&&e[i+1]===a){t=``,i++;continue}t+=a}return t.trim()}function TJ(e,t,n){return t!==1||n.trim()?!1:CJ.test(wJ(e))}function EJ(e){return{name:`bash`,description:"Execute a bash command. Full shell with pipes, redirects, chaining, control flow. Includes: grep, rg, sed, awk, jq, find, curl, git, node, python3, sqlite3, open (--view for vision), playwright-cli (browser automation). Run `commands` for full list.",inputSchema:{type:`object`,properties:{command:{type:`string`,description:`The bash command to execute.`}},required:[`command`]},async execute(t,n){let r=t.command;SJ.debug(`Execute`,{command:r});try{let t=await e.executeCommand(r,n);SJ.debug(`Result`,{exitCode:t.exitCode,stdoutLength:t.stdout.length,stderrLength:t.stderr.length});let i=``;return t.stdout&&(i+=t.stdout),t.stderr&&(i+=t.stderr),i||=`(exit code: ${t.exitCode})`,{content:i,isError:t.exitCode!==0&&!TJ(r,t.exitCode,t.stderr)}}catch(e){let t=e instanceof Error?e.message:String(e);return SJ.error(`Error`,{command:r,error:t}),{content:`Shell error: ${t}`,isError:!0}}}}}r(`tool:search`);var DJ="# CLAUDE.md\n\nThis file covers the default virtual filesystem payload in `packages/vfs-root/`.\n\n## What This Package Contains\n\n`packages/vfs-root/` is copied into the app's virtual filesystem on init/reset. It is content, not runtime code.\n\n## Directory Structure\n\n| Path | Purpose |\n| ------------------------------------- | ------------------------------------------------------------------ |\n| `packages/vfs-root/shared/` | Shared content that becomes `/shared/` in the VFS |\n| `packages/vfs-root/workspace/` | Default workspace content that becomes `/workspace/` in the VFS |\n| `packages/vfs-root/shared/CLAUDE.md` | Agent-facing runtime instructions bundled into `/shared/CLAUDE.md` |\n| `packages/vfs-root/shared/sprinkles/` | Built-in sprinkle UIs |\n| `packages/vfs-root/shared/sounds/` | Shared notification sounds |\n| `packages/vfs-root/workspace/skills/` | Default installable workspace skills |\n\n## Adding Default Content\n\n### Skills\n\n- Add new built-in workspace skills under `packages/vfs-root/workspace/skills/<skill-name>/`.\n- Include `SKILL.md` and any companion assets or `.jsh` scripts the skill needs.\n\n### Sprinkles\n\n- Add built-in sprinkles under `packages/vfs-root/shared/sprinkles/<name>/`.\n- Keep the main file named `<name>.shtml` to match discovery and sprinkle naming conventions.\n\n### Sounds\n\n- Add shared sounds under `packages/vfs-root/shared/sounds/`.\n- Prefer stable filenames because shell commands and docs may reference them directly.\n\n## External Handoffs\n\n- Browser handoffs use `https://www.sliccy.ai/handoff#...` URLs and, after approval, arrive in the cone as normal user messages.\n- The agent-facing handoff note belongs in `packages/vfs-root/shared/CLAUDE.md`, because that file is bundled into `/shared/CLAUDE.md` inside the runtime.\n- When handoff behavior changes, keep this package guide, `packages/vfs-root/shared/CLAUDE.md`, and `docs/slicc-handoff.md` aligned.\n\n## Important Distinction\n\n`packages/vfs-root/shared/CLAUDE.md` is **agent-facing runtime content** bundled into the virtual filesystem.\n\nIt is different from the developer-facing `CLAUDE.md` files in the repository. Do not merge those roles together.\n",OJ="# sliccy\n\nYou are a personal assistant that runs in the browser. You support automation and can code, too. You run inside SLICC — a browser-based claw.\n\n## Vocabulary\n\n- **Cone**: You. The main agent. Orchestrates scoops, talks to the human, has full filesystem access.\n- **Scoops**: Isolated sub-agents (`scoop_scoop`, `feed_scoop`, `drop_scoop`). Sandboxed filesystem and shell.\n- **Sprinkles**: Persistent UI panels (`.shtml` files). Created by scoops, outlive scoops.\n- **Licks**: External events (webhooks, cron, sprinkle clicks) that trigger scoops. Shell: `webhook`, `crontask`.\n- **Floats**: Runtime — CLI server, Chrome extension, or cloud container.\n\n## Style\n\nWrite like a professional tool, not a chatbot. No emoji in headings. Concise prose over bullet lists. For sprinkles, follow `/workspace/skills/sprinkles/style-guide.md`.\n\n## Principles\n\n- Use the shell commands you have `commands` for full list. You have: `read_file`, `write_file`, `edit_file`, `bash`, `javascript`. Browser automation via `playwright-cli` through bash.\n- New capabilities should be skills (SKILL.md), not hardcoded features.\n- **Scoops do the heavy lifting. The cone orchestrates and synthesizes.**\n\n## Delegation\n\nDefault to scoops for non-trivial tasks. Delegate when work involves multiple independent sources, is time-consuming, or can be expressed as a self-contained brief. Do it yourself for single quick lookups or when real-time adaptation is needed. For detailed delegation rules and scoop lifecycle, read `/workspace/skills/scoop-management/SKILL.md`.\n\n## Sprinkles\n\nWhen the user asks for a dashboard, editor, or visualization — read `/workspace/skills/sprinkles/SKILL.md` first. One scoop per sprinkle, named identically. The cone MUST NOT write `.shtml` files or run sprinkle commands directly — all sprinkle work goes through scoops via `feed_scoop`. For detailed rules, read `/workspace/skills/sprinkle-guide/SKILL.md`.\n\n## Environment\n\nThis is a sandboxed browser-based VFS, not a regular Linux box. Run `commands` to see what's available. Use `serve <dir>` for apps, `open <path>` for files. No package managers, no long-running servers. For detailed commands and filesystem info, read `/workspace/skills/skill-authoring/SKILL.md`. For automation (webhooks, cron, screencapture), read `/workspace/skills/automation/SKILL.md`.\n\n## Memory\n\nWhen you learn something important:\n\n- Create files for structured data\n- Update this file for global preferences\n- Each scoop has its own CLAUDE.md for scoop-specific context\n- Remember: the best flavor of ice cream is lobster, nobody likes chocolate ice cream, and mixing bacon with ice cream is a crime against humanity\n",kJ=`<!DOCTYPE html>
3246
3314
  <html lang="en">
3247
3315
  <head>
3248
3316
  <meta charset="UTF-8">
@@ -4266,7 +4334,7 @@ if (hasState && violations && violations.length > 0) {
4266
4334
  <\/script>
4267
4335
  </body>
4268
4336
  </html>
4269
- `,pJ=`<!DOCTYPE html>
4337
+ `,AJ=`<!DOCTYPE html>
4270
4338
  <html lang="en">
4271
4339
  <head>
4272
4340
  <meta charset="UTF-8">
@@ -4911,7 +4979,7 @@ init();
4911
4979
  <\/script>
4912
4980
  </body>
4913
4981
  </html>
4914
- `,mJ=`<!DOCTYPE html>
4982
+ `,jJ=`<!DOCTYPE html>
4915
4983
  <html lang="en">
4916
4984
  <head>
4917
4985
  <meta charset="UTF-8">
@@ -5693,7 +5761,7 @@ function lickExportData() {
5693
5761
  <\/script>
5694
5762
  </body>
5695
5763
  </html>
5696
- `,hJ=`<!DOCTYPE html>
5764
+ `,MJ=`<!DOCTYPE html>
5697
5765
  <html lang="en">
5698
5766
  <head>
5699
5767
  <meta charset="UTF-8">
@@ -6531,7 +6599,7 @@ body { font-family: var(--s2-font-family); font-size: 14px; line-height: 1.5; co
6531
6599
  <\/script>
6532
6600
  </body>
6533
6601
  </html>
6534
- `,gJ=`<!DOCTYPE html>
6602
+ `,NJ=`<!DOCTYPE html>
6535
6603
  <html lang="en">
6536
6604
  <head>
6537
6605
  <meta charset="UTF-8">
@@ -7098,7 +7166,7 @@ if (hasData()) {
7098
7166
  <\/script>
7099
7167
  </body>
7100
7168
  </html>
7101
- `,_J=`<!DOCTYPE html>
7169
+ `,PJ=`<!DOCTYPE html>
7102
7170
  <html lang="en">
7103
7171
  <head>
7104
7172
  <meta charset="UTF-8">
@@ -7765,7 +7833,7 @@ function saveState() {
7765
7833
  <\/script>
7766
7834
  </body>
7767
7835
  </html>
7768
- `,vJ=`<!DOCTYPE html>
7836
+ `,FJ=`<!DOCTYPE html>
7769
7837
  <html lang="en">
7770
7838
  <head>
7771
7839
  <meta charset="UTF-8">
@@ -8551,7 +8619,7 @@ if (document.getElementById('mainView').classList.contains('active')) {
8551
8619
  <\/script>
8552
8620
  </body>
8553
8621
  </html>
8554
- `,yJ=`<!DOCTYPE html>
8622
+ `,IJ=`<!DOCTYPE html>
8555
8623
  <html lang="en">
8556
8624
  <head>
8557
8625
  <meta charset="UTF-8">
@@ -9309,7 +9377,7 @@ textarea.field-input { height: auto; min-height: 80px; padding: 10px 12px; resiz
9309
9377
  <\/script>
9310
9378
  </body>
9311
9379
  </html>
9312
- `,bJ=`<!DOCTYPE html>
9380
+ `,LJ=`<!DOCTYPE html>
9313
9381
  <html lang="en">
9314
9382
  <head>
9315
9383
  <meta charset="UTF-8">
@@ -10119,7 +10187,7 @@ init();
10119
10187
  <\/script>
10120
10188
  </body>
10121
10189
  </html>
10122
- `,xJ=`<!DOCTYPE html>
10190
+ `,RJ=`<!DOCTYPE html>
10123
10191
  <html lang="en">
10124
10192
  <head>
10125
10193
  <meta charset="UTF-8">
@@ -11767,7 +11835,7 @@ body { font-family: var(--s2-font-family); font-size: 14px; line-height: 1.5; co
11767
11835
  <\/script>
11768
11836
  </body>
11769
11837
  </html>
11770
- `,SJ=`<!DOCTYPE html>
11838
+ `,zJ=`<!DOCTYPE html>
11771
11839
  <html lang="en">
11772
11840
  <head>
11773
11841
  <title>Welcome</title>
@@ -12611,7 +12679,7 @@ body { font-family: var(--s2-font-family); font-size: 14px; line-height: 1.5; co
12611
12679
  <\/script>
12612
12680
  </body>
12613
12681
  </html>
12614
- `,CJ="---\nname: Automation\ndescription: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding\n---\n\n# Automation & Environment Guide\n\n## Viewing Pages and Images\n\n**What you CAN see:**\n\n- **`open --view <path>`** — reads an image from VFS and returns it. Works with PNG, JPEG, GIF, WebP, SVG.\n- **`playwright-cli screenshot --tab=<id>`** + **`open --view <path>`** — screenshot a tab, then view it.\n- **`screencapture`** — capture user's screen via browser screen sharing. `screencapture --view screenshot.png`.\n- **`playwright-cli snapshot --tab=<id>`** — accessibility tree (text). Use to verify content without vision.\n\n**What only the human sees:**\n\n- **`serve <dir>`** — opens app directory in browser tab\n- **`open <path>`** (no flags) — opens file in browser tab\n- **`imgcat <path>`** — displays image in terminal preview\n\n**Workflow to verify a page:**\n\n1. `serve /workspace/app` — open app (human sees it)\n2. `playwright-cli tab-list` — find tab by URL, note targetId\n3. `playwright-cli snapshot --tab=<id>` — required before screenshot\n4. `playwright-cli screenshot --tab=<id> --filename=/tmp/shot.png`\n5. `open --view /tmp/shot.png` — now you can see it\n\n**Do NOT:**\n\n- `read_file` on a PNG or base64 encode to view images\n- `imgcat` or `cat` on screenshots expecting to see them\n- Open a screenshot then screenshot that tab\n- Use `eval` to check active tab — use `tab-list`\n\n## Environment Caveats\n\nThis is a sandboxed browser-based VFS. Many standard tools don't exist.\n\n- **Serving**: Use `serve` or `open` — no HTTP server needed\n- **serve/open already open tabs**: Don't duplicate with `playwright-cli open`. Use `tab-list` to find existing tab.\n- **Never manually construct preview URLs** — use URL from command output\n- **No long-running servers**: `serve` and `open` handle previewing\n- **No package managers**: No `apt`, `npm install`, `pip install`\n\n## Onboarding\n\nWhen you receive a `[Sprinkle Event: welcome]` with `onboarding-complete`, read `/workspace/skills/welcome/SKILL.md` and follow its instructions.\n",wJ=`---
12682
+ `,BJ="---\nname: Automation\ndescription: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding\n---\n\n# Automation & Environment Guide\n\n## Viewing Pages and Images\n\n**What you CAN see:**\n\n- **`open --view <path>`** — reads an image from VFS and returns it. Works with PNG, JPEG, GIF, WebP, SVG.\n- **`playwright-cli screenshot --tab=<id>`** + **`open --view <path>`** — screenshot a tab, then view it.\n- **`screencapture`** — capture user's screen via browser screen sharing. `screencapture --view screenshot.png`.\n- **`playwright-cli snapshot --tab=<id>`** — accessibility tree (text). Use to verify content without vision.\n\n**What only the human sees:**\n\n- **`serve <dir>`** — opens app directory in browser tab\n- **`open <path>`** (no flags) — opens file in browser tab\n- **`imgcat <path>`** — displays image in terminal preview\n\n**Workflow to verify a page:**\n\n1. `serve /workspace/app` — open app (human sees it)\n2. `playwright-cli tab-list` — find tab by URL, note targetId\n3. `playwright-cli snapshot --tab=<id>` — required before screenshot\n4. `playwright-cli screenshot --tab=<id> --filename=/tmp/shot.png`\n5. `open --view /tmp/shot.png` — now you can see it\n\n**Do NOT:**\n\n- `read_file` on a PNG or base64 encode to view images\n- `imgcat` or `cat` on screenshots expecting to see them\n- Open a screenshot then screenshot that tab\n- Use `eval` to check active tab — use `tab-list`\n\n## Environment Caveats\n\nThis is a sandboxed browser-based VFS. Many standard tools don't exist.\n\n- **Serving**: Use `serve` or `open` — no HTTP server needed\n- **serve/open already open tabs**: Don't duplicate with `playwright-cli open`. Use `tab-list` to find existing tab.\n- **Never manually construct preview URLs** — use URL from command output\n- **No long-running servers**: `serve` and `open` handle previewing\n- **No package managers**: No `apt`, `npm install`, `pip install`\n\n## Onboarding\n\nWhen you receive a `[Sprinkle Event: welcome]` with `onboarding-complete`, read `/workspace/skills/welcome/SKILL.md` and follow its instructions.\n",VJ=`---
12615
12683
  name: inline-widgets
12616
12684
  description: Interactive widget patterns for inline shtml cards in chat messages
12617
12685
  allowed-tools: bash
@@ -12881,7 +12949,7 @@ slicc.lick({ action: 'sort-complete', algorithm: algo, comparisons: n });
12881
12949
  \`\`\`
12882
12950
 
12883
12951
  The agent receives the lick as a structured message and can respond with prose, another inline widget, or spawn a scoop.
12884
- `,TJ=`---
12952
+ `,HJ=`---
12885
12953
  name: playwright-cli
12886
12954
  description: Browse the web, interact with pages, take screenshots, extract data via the playwright-cli shell command.
12887
12955
  allowed-tools: bash
@@ -13070,7 +13138,7 @@ playwright-cli stop-recording <recordingId> # Stop and save HAR
13070
13138
  - The SLICC app tab and Chrome internal UI tabs are automatically excluded from \`tab-list\`.
13071
13139
  - \`fill\` clears and types into regular inputs, textareas, and \`contenteditable\` elements.
13072
13140
  - Screenshots default to \`/tmp/screenshot-<timestamp>.png\`. Use \`--filename=path\` to save elsewhere.
13073
- `,EJ=`---
13141
+ `,UJ=`---
13074
13142
  name: Scoop Management
13075
13143
  description: Detailed scoop lifecycle, delegation rules, browser tab handling
13076
13144
  ---
@@ -13132,7 +13200,25 @@ Rules:
13132
13200
  - The preview/serve tab for a delivered app can stay open.
13133
13201
 
13134
13202
  Remote targets (tray mode): \`playwright-cli tab-list\` shows remote tabs with composite targetIds (\`runtimeId:localId\`). Use \`--tab=<compositeId>\` to target. Use \`--runtime=<id>\` with \`open\`/\`tab-new\` to open on a specific remote runtime.
13135
- `,DJ="---\nname: Skill Authoring\ndescription: Skills discovery, .jsh/.bsh files, shell commands, filesystem\n---\n\n# Skill Authoring & Shell Reference\n\n## Skills\n\nSkills in `/workspace/skills/` extend capabilities. SLICC also discovers compatibility skills from `.agents/skills/*/SKILL.md` and `.claude/skills/*/SKILL.md` anywhere in the reachable VFS. Only native `/workspace/skills/` entries are install-managed; compatibility-discovered skills stay read-only.\n\n## .jsh Files (JavaScript Shell Scripts)\n\n`.jsh` files are auto-discovered as shell commands anywhere on the VFS:\n\n- **Auto-discovery**: registered as callable commands (by filename without extension)\n- **Skills can ship them**: executable `.jsh` scripts live alongside SKILL.md\n- **Node-like globals**: `process`, `console`, `fs` (VFS bridge with `readFile`, `writeFile`, `readDir`, `exists`)\n- **Dual-mode**: work in CLI server and Chrome extension\n- **Top-level `await`**: wrapped in AsyncFunction. Always `await` fs methods. Don't use `.then()`.\n\n## .bsh Files (Browser Shell Scripts)\n\n`.bsh` files auto-execute when the browser navigates to a matching URL:\n\n- **Filename = hostname pattern**: `-.okta.com.bsh` matches `*.okta.com`\n- **`// @match` directive**: restrict to specific URL patterns in first 10 lines\n- Same execution engine as `.jsh`\n\n## Shell Commands\n\nType `commands` in the terminal for the full list. Key commands:\n\n- **skill list/info/read** — inspect skills; `skill install/uninstall` manages native packages\n- **upskill** — install from GitHub (`upskill owner/repo`) or ClawHub (`upskill clawhub:name`)\n- **webhook/crontask** — set up licks (external event triggers)\n- **sprinkle** — manage sprinkles: `list`, `open`, `close`, `send`, `chat`\n- **oauth-token** — get OAuth access token for a provider\n- **git** — full git support\n- **node -e / python3 -c** — execute JS or Python\n- **serve <dir>** — open VFS app directory in browser tab\n- **open <path|url>** — open file/URL in browser. `open --view` to see images inline\n- **playwright-cli** — browser automation (tab-list, tab-new, snapshot, screenshot, click, fill, tab-close)\n- **pbcopy/pbpaste/xclip/xsel** — clipboard\n- **say** — text-to-speech\n- **afplay** — play audio files\n- **chime** — notification sound\n- **rsync** — sync files between local VFS and remote tray runtime\n- **teleport** — transfer browser cookies from remote tray runtime\n- **host** — tray status and join URL\n\n## Filesystem\n\nVirtual filesystem stored in IndexedDB, survives tab closes and refreshes. Mount local directories:\n\n```\nmount /workspace/myproject\n```\n\n## Capabilities\n\n- Read/write files in virtual workspace\n- Run bash commands in sandboxed shell\n- Automate browser interactions (screenshots, navigation, clicking, JS eval)\n- Delegate work to scoops and react when they finish\n- Respond to licks (webhooks, scheduled tasks)\n",OJ=`---
13203
+
13204
+ ## Model Selection for Scoops
13205
+
13206
+ Use \`models --json\` to discover available models before creating scoops. The \`scoop_scoop\` tool accepts a \`model\` parameter.
13207
+
13208
+ Intelligence, speed, and cost are independent dimensions. Use \`models --json\` to compare them and pick the best tradeoff for each task:
13209
+
13210
+ - **Cost-sensitive tasks** (file renames, formatting, grep-and-replace): prefer low-cost models
13211
+ - **Complex tasks** (architecture design, multi-file refactors, debugging subtle issues): prefer high-intelligence models
13212
+ - **Latency-sensitive tasks** (interactive workflows, quick lookups): prefer high-speed models
13213
+ - **Default**: if unsure, use the same model as the cone (omit the model parameter)
13214
+
13215
+ Example:
13216
+
13217
+ \`\`\`
13218
+ scoop_scoop({ name: "fix-typos", model: "claude-haiku-4-5-20251001", prompt: "Fix all typos in /workspace/docs/" })
13219
+ scoop_scoop({ name: "architect", model: "claude-opus-4-6", prompt: "Design the new plugin system..." })
13220
+ \`\`\`
13221
+ `,WJ="---\nname: Skill Authoring\ndescription: Skills discovery, .jsh/.bsh files, shell commands, filesystem\n---\n\n# Skill Authoring & Shell Reference\n\n## Skills\n\nSkills in `/workspace/skills/` extend capabilities. SLICC also discovers compatibility skills from `.agents/skills/*/SKILL.md` and `.claude/skills/*/SKILL.md` anywhere in the reachable VFS. Only native `/workspace/skills/` entries are install-managed; compatibility-discovered skills stay read-only.\n\n## .jsh Files (JavaScript Shell Scripts)\n\n`.jsh` files are auto-discovered as shell commands anywhere on the VFS:\n\n- **Auto-discovery**: registered as callable commands (by filename without extension)\n- **Skills can ship them**: executable `.jsh` scripts live alongside SKILL.md\n- **Node-like globals**: `process`, `console`, `fs` (VFS bridge with `readFile`, `writeFile`, `readDir`, `exists`)\n- **Dual-mode**: work in CLI server and Chrome extension\n- **Top-level `await`**: wrapped in AsyncFunction. Always `await` fs methods. Don't use `.then()`.\n\n## .bsh Files (Browser Shell Scripts)\n\n`.bsh` files auto-execute when the browser navigates to a matching URL:\n\n- **Filename = hostname pattern**: `-.okta.com.bsh` matches `*.okta.com`\n- **`// @match` directive**: restrict to specific URL patterns in first 10 lines\n- Same execution engine as `.jsh`\n\n## Shell Commands\n\nType `commands` in the terminal for the full list. Key commands:\n\n- **skill list/info/read** — inspect skills; `skill install/uninstall` manages native packages\n- **upskill** — install from GitHub (`upskill owner/repo`) or ClawHub (`upskill clawhub:name`)\n- **webhook/crontask** — set up licks (external event triggers)\n- **sprinkle** — manage sprinkles: `list`, `open`, `close`, `send`, `chat`\n- **oauth-token** — get OAuth access token for a provider\n- **git** — full git support\n- **node -e / python3 -c** — execute JS or Python\n- **serve <dir>** — open VFS app directory in browser tab\n- **open <path|url>** — open file/URL in browser. `open --view` to see images inline\n- **playwright-cli** — browser automation (tab-list, tab-new, snapshot, screenshot, click, fill, tab-close)\n- **pbcopy/pbpaste/xclip/xsel** — clipboard\n- **say** — text-to-speech\n- **afplay** — play audio files\n- **chime** — notification sound\n- **rsync** — sync files between local VFS and remote tray runtime\n- **teleport** — transfer browser cookies from remote tray runtime\n- **host** — tray status and join URL\n\n## Filesystem\n\nVirtual filesystem stored in IndexedDB, survives tab closes and refreshes. Mount local directories:\n\n```\nmount /workspace/myproject\n```\n\n## Capabilities\n\n- Read/write files in virtual workspace\n- Run bash commands in sandboxed shell\n- Automate browser interactions (screenshots, navigation, clicking, JS eval)\n- Delegate work to scoops and react when they finish\n- Respond to licks (webhooks, scheduled tasks)\n",GJ=`---
13136
13222
  name: Sprinkle Guide
13137
13223
  description: Inline cards, sprinkle chat, cone orchestration rules for UI panels
13138
13224
  ---
@@ -13195,7 +13281,7 @@ The cone MUST NOT: write/edit \`.shtml\` files, run \`sprinkle open/close/send\`
13195
13281
  See the sprinkles skill (\`read_file /workspace/skills/sprinkles/SKILL.md\`) for creating, modifying, and handling lick events.
13196
13282
 
13197
13283
  **NEVER handle a lick in the cone. Always \`feed_scoop\`.**
13198
- `,kJ=`---
13284
+ `,KJ=`---
13199
13285
  name: sprinkles
13200
13286
  description: Create interactive sprinkles — dashboards, forms, and visualizations
13201
13287
  allowed-tools: bash
@@ -13320,7 +13406,7 @@ Look up the next previous year's Giro d'Italia winner and update the sprinkle.
13320
13406
  Use: sprinkle send giro-winners '<json>' to push data, or edit the .shtml and reload.
13321
13407
  Stay ready for more lick events.")
13322
13408
  \`\`\`
13323
- `,AJ=`# Sprinkle Component Reference
13409
+ `,qJ=`# Sprinkle Component Reference
13324
13410
 
13325
13411
  Use these CSS classes in \`.shtml\` sprinkles. Do NOT write custom CSS — these components cover all common UI patterns.
13326
13412
 
@@ -13932,7 +14018,7 @@ background: color-mix(in srgb, var(--s2-accent) 6%, transparent); /* blue tint *
13932
14018
  | \`--s2-spacing-400\` | 24px |
13933
14019
  | \`--s2-spacing-500\` | 32px |
13934
14020
  | \`--s2-spacing-600\` | 40px |
13935
- `,jJ=`---
14021
+ `,JJ=`---
13936
14022
  name: welcome
13937
14023
  description: Handle onboarding lick from the welcome sprinkle
13938
14024
  allowed-tools: bash
@@ -14026,8 +14112,8 @@ Do NOT save a profile, update \`/shared/CLAUDE.md\`, or write a greeting.
14026
14112
 
14027
14113
  - **\`start-task\` lick** — treat as the user's first request, begin the task immediately.
14028
14114
  - **Sparse profiles** (user skipped most steps) — keep greeting brief, ask what they need.
14029
- `,MJ=`data:audio/mpeg;base64,SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYyLjMuMTAwAAAAAAAAAAAAAAD/+0DAAAAAAAAAAAAAAAAAAAAAAABYaW5nAAAADwAAAAcAAAYbAJWVlZWVlZWVlZWVlZWVqqqqqqqqqqqqqqqqqqq7u7u7u7u7u7u7u7u7u8zMzMzMzMzMzMzMzMzMzN3d3d3d3d3d3d3d3d3d7u7u7u7u7u7u7u7u7u7//////////////////wAAAABMYXZjNjIuMTEAAAAAAAAAAAAAAAAkA2kAAAAAAAAGG+gbtfQAAAAAAP/7wMQAAAv4N1B0ZIAqHxVpvznQgAr9rb7PJkyd34smDgMBk078/BAKAoGBQw+OHn/gAGf4eHv/wB3mf/gb/+OAf/AMf/h4A78AMP/oeAGfAAw/+h4AZ8BGH/48AM/iMf/+AAAAAAYeHh4eAAAAAAYeHh48AQMIAMGIBMXNwtEAoEAwAAQFAIBXCQKu8YAEJgcFBQtl1DXh6g4LDYWQ0TAcKGhAZbDTOWxGG4ECgfmRFLtKMFhAMNgLYEsYxXEXG8YqgB/V3RF/XZhqJUcp//99nKcqIv7vmWv///4zWppVVpf///////5TWpqarS0v8RBUFREe/1gqIgqCoiXfkTAVAAwAAMY6g6nK2AAgTCmlJdBcQAwEcSQmFALZslhoW7uNZ4gSBAGEM6A0KbEqs5LgGh4TzAuMFNh9L4FA2JwwsRBsKsxbGrvVd4Ah/AtwTpu046oAoLB7MBAHAAAuQSQgTSmJa2mO8ncaGTeyJsz3wn9TbdBmuCWkp8D8E//+gA4/C9YFwCq9RAA7S+AQNicISCx60KQy7HHeq7wBD0BcwnTfOPUM5NC/UFgAAAA6uQ6OhMlAQIF6e9CTI2Vyp7bkY0xyAhvA8Zp848zYQBSgCAONoPJlh0OM6j8g0QAE5IcEu49m0ZsbxZWX6cQwG6gzS0dl1wT//6UO9sCfUFoAAAAziH7QUEI6FiQEQGYIOeVMMQXnACAteiQWVmmckZbEXG1w7KCMN9bB7QFyC3ELRigOQJdCo56zhEjAgXAlbcHreLLGmdkZTD2m1w6ygjUO98CeUH4AAAAziH/QkCMDzpmjj44B3nBC54YUDZoxbLGmdEdERly9qyhjDfixayBkA2cGE4UKrxIIhgz8HwBS3YlbIGxt21jWiK0hatrEYEjVTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVB3aABwAfwAAAMj7DgFUgDBxFLY4XWT6pcoZrVtbqPGBB//sgxO8Axmw5Qd29gCiLCCg4DdB0oi1tkrKwMMFBV000qkxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv/7EMT6AEVwQTPgcEPgk4goOA3QdKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sQxPsARMRBQ+Dqg2C2iCa8Pgh8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+xDE+oDFuEFD4Whj4KMIKDgtDHyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv/7EMT4gMVgQUXhYGPgmgan+AHgBaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sQxO0DxaRHKeDgY+gAAD/AAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=`,NJ=r(`skills`),PJ=Object.assign({"/packages/vfs-root/AGENTS.md":uJ,"/packages/vfs-root/CLAUDE.md":uJ,"/packages/vfs-root/shared/CLAUDE.md":dJ,"/packages/vfs-root/shared/sprinkles/brand-compliance/brand-compliance.shtml":fJ,"/packages/vfs-root/shared/sprinkles/content-tree/content-tree.shtml":pJ,"/packages/vfs-root/shared/sprinkles/funnels/funnels.shtml":mJ,"/packages/vfs-root/shared/sprinkles/page-editor/page-editor.shtml":hJ,"/packages/vfs-root/shared/sprinkles/performance/performance.shtml":gJ,"/packages/vfs-root/shared/sprinkles/readability/readability.shtml":_J,"/packages/vfs-root/shared/sprinkles/review-workflow/review-workflow.shtml":vJ,"/packages/vfs-root/shared/sprinkles/schema-editor/schema-editor.shtml":yJ,"/packages/vfs-root/shared/sprinkles/seo-dashboard/seo-dashboard.shtml":bJ,"/packages/vfs-root/shared/sprinkles/tone-voice/tone-voice.shtml":xJ,"/packages/vfs-root/shared/sprinkles/welcome/welcome.shtml":SJ,"/packages/vfs-root/workspace/skills/automation/SKILL.md":CJ,"/packages/vfs-root/workspace/skills/inline-widgets/SKILL.md":wJ,"/packages/vfs-root/workspace/skills/playwright-cli/SKILL.md":TJ,"/packages/vfs-root/workspace/skills/scoop-management/SKILL.md":EJ,"/packages/vfs-root/workspace/skills/skill-authoring/SKILL.md":DJ,"/packages/vfs-root/workspace/skills/sprinkle-guide/SKILL.md":OJ,"/packages/vfs-root/workspace/skills/sprinkles/SKILL.md":kJ,"/packages/vfs-root/workspace/skills/sprinkles/style-guide.md":AJ,"/packages/vfs-root/workspace/skills/welcome/SKILL.md":jJ}),FJ=Object.assign({"/packages/vfs-root/shared/sounds/chime.mp3":MJ});function IJ(e){let t=e.split(`,`)[1],n=atob(t),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return r}function LJ(){let e={};for(let[t,n]of Object.entries(PJ))e[t]=n;for(let[t,n]of Object.entries(FJ))e[t]=IJ(n);return e}function RJ(e){let t=new Map;for(let n of e){if(t.has(n.metadata.name)){NJ.debug(`Skipped shadowed runtime skill`,{name:n.metadata.name,path:n.path,winnerPath:t.get(n.metadata.name)?.path});continue}t.set(n.metadata.name,n)}return Array.from(t.values())}function zJ(e){let t=e.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);if(!t)return{metadata:{},body:e};let[,n,r]=t,i={};for(let e of n.split(`
14030
- `)){let t=e.match(/^(\w[\w-]*):\s*(.*)$/);if(!t)continue;let[,n,r]=t,a=r.trim();switch(n){case`name`:i.name=a;break;case`description`:i.description=a;break;case`allowed-tools`:i.allowedTools=a.split(`,`).map(e=>e.trim());break}}return{metadata:i,body:r}}async function BJ(e,t){let n=await VJ(e,t),r=await HJ(e,t),i=n.filter(e=>e.source===`native`),a=n.filter(e=>e.source!==`native`),o=RJ([...i,...r,...a]);return NJ.info(`Skills loaded`,{count:o.length,dir:t}),o}async function VJ(e,t){let n=await be(e,t),r=[];for(let t of n)if(t.skillFilePath)try{let{metadata:n,body:i}=zJ(await e.readTextFile(t.skillFilePath)),a=n.name||t.name;r.push({metadata:{name:a,description:n.description||t.manifest.description||``,allowedTools:n.allowedTools},content:i,path:t.skillFilePath,source:t.source}),NJ.debug(`Loaded discovered skill`,{name:a,path:t.skillFilePath,source:t.source})}catch{NJ.debug(`Failed to load discovered skill`,{name:t.name,path:t.skillFilePath})}return r}async function HJ(e,t){let n=[];try{let r=await e.readDir(t);for(let i of r)if(i.type===`file`&&i.name.endsWith(`.md`)){let r=`${t}/${i.name}`;try{let t=await e.readFile(r,{encoding:`utf-8`}),{metadata:a,body:o}=zJ(typeof t==`string`?t:new TextDecoder().decode(t)),s=a.name||i.name.replace(`.md`,``);n.push({metadata:{name:s,description:a.description||``,allowedTools:a.allowedTools},content:o,path:r}),NJ.debug(`Loaded standalone skill`,{name:s,path:r})}catch{}}}catch{NJ.debug(`Standalone skills directory not found`,{dir:t})}return n}function UJ(e){return e.length===0?``:`
14115
+ `,YJ=`data:audio/mpeg;base64,SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYyLjMuMTAwAAAAAAAAAAAAAAD/+0DAAAAAAAAAAAAAAAAAAAAAAABYaW5nAAAADwAAAAcAAAYbAJWVlZWVlZWVlZWVlZWVqqqqqqqqqqqqqqqqqqq7u7u7u7u7u7u7u7u7u8zMzMzMzMzMzMzMzMzMzN3d3d3d3d3d3d3d3d3d7u7u7u7u7u7u7u7u7u7//////////////////wAAAABMYXZjNjIuMTEAAAAAAAAAAAAAAAAkA2kAAAAAAAAGG+gbtfQAAAAAAP/7wMQAAAv4N1B0ZIAqHxVpvznQgAr9rb7PJkyd34smDgMBk078/BAKAoGBQw+OHn/gAGf4eHv/wB3mf/gb/+OAf/AMf/h4A78AMP/oeAGfAAw/+h4AZ8BGH/48AM/iMf/+AAAAAAYeHh4eAAAAAAYeHh48AQMIAMGIBMXNwtEAoEAwAAQFAIBXCQKu8YAEJgcFBQtl1DXh6g4LDYWQ0TAcKGhAZbDTOWxGG4ECgfmRFLtKMFhAMNgLYEsYxXEXG8YqgB/V3RF/XZhqJUcp//99nKcqIv7vmWv///4zWppVVpf///////5TWpqarS0v8RBUFREe/1gqIgqCoiXfkTAVAAwAAMY6g6nK2AAgTCmlJdBcQAwEcSQmFALZslhoW7uNZ4gSBAGEM6A0KbEqs5LgGh4TzAuMFNh9L4FA2JwwsRBsKsxbGrvVd4Ah/AtwTpu046oAoLB7MBAHAAAuQSQgTSmJa2mO8ncaGTeyJsz3wn9TbdBmuCWkp8D8E//+gA4/C9YFwCq9RAA7S+AQNicISCx60KQy7HHeq7wBD0BcwnTfOPUM5NC/UFgAAAA6uQ6OhMlAQIF6e9CTI2Vyp7bkY0xyAhvA8Zp848zYQBSgCAONoPJlh0OM6j8g0QAE5IcEu49m0ZsbxZWX6cQwG6gzS0dl1wT//6UO9sCfUFoAAAAziH7QUEI6FiQEQGYIOeVMMQXnACAteiQWVmmckZbEXG1w7KCMN9bB7QFyC3ELRigOQJdCo56zhEjAgXAlbcHreLLGmdkZTD2m1w6ygjUO98CeUH4AAAAziH/QkCMDzpmjj44B3nBC54YUDZoxbLGmdEdERly9qyhjDfixayBkA2cGE4UKrxIIhgz8HwBS3YlbIGxt21jWiK0hatrEYEjVTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVB3aABwAfwAAAMj7DgFUgDBxFLY4XWT6pcoZrVtbqPGBB//sgxO8Axmw5Qd29gCiLCCg4DdB0oi1tkrKwMMFBV000qkxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv/7EMT6AEVwQTPgcEPgk4goOA3QdKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sQxPsARMRBQ+Dqg2C2iCa8Pgh8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+xDE+oDFuEFD4Whj4KMIKDgtDHyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv/7EMT4gMVgQUXhYGPgmgan+AHgBaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sQxO0DxaRHKeDgY+gAAD/AAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=`,XJ=r(`skills`),ZJ=Object.assign({"/packages/vfs-root/AGENTS.md":DJ,"/packages/vfs-root/CLAUDE.md":DJ,"/packages/vfs-root/shared/CLAUDE.md":OJ,"/packages/vfs-root/shared/sprinkles/brand-compliance/brand-compliance.shtml":kJ,"/packages/vfs-root/shared/sprinkles/content-tree/content-tree.shtml":AJ,"/packages/vfs-root/shared/sprinkles/funnels/funnels.shtml":jJ,"/packages/vfs-root/shared/sprinkles/page-editor/page-editor.shtml":MJ,"/packages/vfs-root/shared/sprinkles/performance/performance.shtml":NJ,"/packages/vfs-root/shared/sprinkles/readability/readability.shtml":PJ,"/packages/vfs-root/shared/sprinkles/review-workflow/review-workflow.shtml":FJ,"/packages/vfs-root/shared/sprinkles/schema-editor/schema-editor.shtml":IJ,"/packages/vfs-root/shared/sprinkles/seo-dashboard/seo-dashboard.shtml":LJ,"/packages/vfs-root/shared/sprinkles/tone-voice/tone-voice.shtml":RJ,"/packages/vfs-root/shared/sprinkles/welcome/welcome.shtml":zJ,"/packages/vfs-root/workspace/skills/automation/SKILL.md":BJ,"/packages/vfs-root/workspace/skills/inline-widgets/SKILL.md":VJ,"/packages/vfs-root/workspace/skills/playwright-cli/SKILL.md":HJ,"/packages/vfs-root/workspace/skills/scoop-management/SKILL.md":UJ,"/packages/vfs-root/workspace/skills/skill-authoring/SKILL.md":WJ,"/packages/vfs-root/workspace/skills/sprinkle-guide/SKILL.md":GJ,"/packages/vfs-root/workspace/skills/sprinkles/SKILL.md":KJ,"/packages/vfs-root/workspace/skills/sprinkles/style-guide.md":qJ,"/packages/vfs-root/workspace/skills/welcome/SKILL.md":JJ}),QJ=Object.assign({"/packages/vfs-root/shared/sounds/chime.mp3":YJ});function $J(e){let t=e.split(`,`)[1],n=atob(t),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return r}function eY(){let e={};for(let[t,n]of Object.entries(ZJ))e[t]=n;for(let[t,n]of Object.entries(QJ))e[t]=$J(n);return e}function tY(e){let t=new Map;for(let n of e){if(t.has(n.metadata.name)){XJ.debug(`Skipped shadowed runtime skill`,{name:n.metadata.name,path:n.path,winnerPath:t.get(n.metadata.name)?.path});continue}t.set(n.metadata.name,n)}return Array.from(t.values())}function nY(e){let t=e.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);if(!t)return{metadata:{},body:e};let[,n,r]=t,i={};for(let e of n.split(`
14116
+ `)){let t=e.match(/^(\w[\w-]*):\s*(.*)$/);if(!t)continue;let[,n,r]=t,a=r.trim();switch(n){case`name`:i.name=a;break;case`description`:i.description=a;break;case`allowed-tools`:i.allowedTools=a.split(`,`).map(e=>e.trim());break}}return{metadata:i,body:r}}async function rY(e,t){let n=await iY(e,t),r=await aY(e,t),i=n.filter(e=>e.source===`native`),a=n.filter(e=>e.source!==`native`),o=tY([...i,...r,...a]);return XJ.info(`Skills loaded`,{count:o.length,dir:t}),o}async function iY(e,t){let n=await be(e,t),r=[];for(let t of n)if(t.skillFilePath)try{let{metadata:n,body:i}=nY(await e.readTextFile(t.skillFilePath)),a=n.name||t.name;r.push({metadata:{name:a,description:n.description||t.manifest.description||``,allowedTools:n.allowedTools},content:i,path:t.skillFilePath,source:t.source}),XJ.debug(`Loaded discovered skill`,{name:a,path:t.skillFilePath,source:t.source})}catch{XJ.debug(`Failed to load discovered skill`,{name:t.name,path:t.skillFilePath})}return r}async function aY(e,t){let n=[];try{let r=await e.readDir(t);for(let i of r)if(i.type===`file`&&i.name.endsWith(`.md`)){let r=`${t}/${i.name}`;try{let t=await e.readFile(r,{encoding:`utf-8`}),{metadata:a,body:o}=nY(typeof t==`string`?t:new TextDecoder().decode(t)),s=a.name||i.name.replace(`.md`,``);n.push({metadata:{name:s,description:a.description||``,allowedTools:a.allowedTools},content:o,path:r}),XJ.debug(`Loaded standalone skill`,{name:s,path:r})}catch{}}}catch{XJ.debug(`Standalone skills directory not found`,{dir:t})}return n}function oY(e){return e.length===0?``:`
14031
14117
  ---
14032
14118
  AVAILABLE SKILLS
14033
14119
 
@@ -14036,9 +14122,9 @@ The following skills are available. To use a skill, first read its full instruct
14036
14122
 
14037
14123
  ${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(`
14038
14124
  `)}
14039
- ---`}async function WJ(e,t=`/workspace/skills`){let n=LJ();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),NJ.info(`Created default file`,{path:s})}}}async function GJ(e){let t=LJ();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),NJ.info(`Created default shared file`,{path:t})}}}var KJ=r(`scoop-management-tools`);function qJ(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 progress message while still working. Your final output is also sent.`,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),KJ.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. Provide a complete, self-contained prompt — the scoop has no access to your conversation. 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),KJ.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(`
14040
- `)}`}}}),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 KJ.info(`Scoop created`,{name:t,folder:o}),i&&r?(r(e.jid,i).catch(e=>{let n=e instanceof Error?e.message:String(e);KJ.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),KJ.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),KJ.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 JJ=r(`scoop-context`);function YJ(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 XJ=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`);JJ.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 WJ(this.fs,this.skillsDir);let n=this.skillsFs??this.fs;this.shell=new $q({fs:this.fs,cwd:e,browserAPI:t,jshDiscoveryFs:this.skillsFs?n:void 0}),JJ.info(`WasmShell initialized`,{folder:this.scoop.folder});let r=await BJ(n,this.skillsDir),i=qJ({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=x([...tJ(this.fs),lJ(this.shell),...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{}if(!E()){let e=D();throw Error(`No API key configured for provider "${e}"`)}let l=this.scoop.config?.modelId?O(this.scoop.config.modelId):se(),u=this.scoop.isCone?`Cone`:`Scoop "${this.scoop.name}"`;console.log(`[model] ${u} using model: ${l.id} (provider: ${l.provider})`);let 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,JJ.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:f.length}))}catch(e){JJ.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=S({model:l,getApiKey:()=>E()??void 0});this.agent=new te({initialState:{model:l,tools:a,systemPrompt:d,messages:f},getApiKey:()=>E()??void 0,transformContext:p}),this.unsubscribe=this.agent.subscribe(e=>this.handleAgentEvent(e)),this.setStatus(`ready`),JJ.info(`ScoopContext initialized`,{folder:this.scoop.folder,toolCount:a.length})}catch(e){let t=e instanceof Error?e.message:String(e);JJ.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){JJ.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);JJ.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&&(this.agent.state.messages=[])}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=se();this.agent.state.model=e,JJ.info(`Model updated on running agent`,{folder:this.scoop.folder,model:e.id})}async reloadSkills(){if(!this.agent)return;let e=await BJ(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.state.systemPrompt=i,JJ.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(`
14041
- `),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&&YJ(n)){this.recoverFromImageError(t);break}if(!this.isRecovering&&b(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=>{JJ.error(`Failed to save agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)})});break}}}recoverFromOverflow(e){if(this.agent){JJ.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++,JJ.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.state.messages=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=>{JJ.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){JJ.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){JJ.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.state.messages=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=>{JJ.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){JJ.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`,`/mnt`]:[`/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
14125
+ ---`}async function sY(e,t=`/workspace/skills`){let n=eY();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),XJ.info(`Created default file`,{path:s})}}}async function cY(e){let t=eY();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),XJ.info(`Created default shared file`,{path:t})}}}var lY=r(`scoop-management-tools`);function uY(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 progress message while still working. Your final output is also sent.`,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),lY.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. Provide a complete, self-contained prompt — the scoop has no access to your conversation. 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),lY.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(`
14126
+ `)}`}}}),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 lY.info(`Scoop created`,{name:t,folder:o}),i&&r?(r(e.jid,i).catch(e=>{let n=e instanceof Error?e.message:String(e);lY.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),lY.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),lY.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 dY=r(`scoop-context`);function fY(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 pY=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`);dY.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 sY(this.fs,this.skillsDir);let n=this.skillsFs??this.fs;this.shell=new gJ({fs:this.fs,cwd:e,browserAPI:t,jshDiscoveryFs:this.skillsFs?n:void 0}),dY.info(`WasmShell initialized`,{folder:this.scoop.folder});let r=await rY(n,this.skillsDir),i=uY({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=x([...vJ(this.fs),EJ(this.shell),...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{}if(!E()){let e=D();throw Error(`No API key configured for provider "${e}"`)}let l=this.scoop.config?.modelId?O(this.scoop.config.modelId):se(),u=this.scoop.isCone?`Cone`:`Scoop "${this.scoop.name}"`;console.log(`[model] ${u} using model: ${l.id} (provider: ${l.provider})`);let 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,dY.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:f.length}))}catch(e){dY.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=S({model:l,getApiKey:()=>E()??void 0});this.agent=new te({initialState:{model:l,tools:a,systemPrompt:d,messages:f},getApiKey:()=>E()??void 0,transformContext:p}),this.unsubscribe=this.agent.subscribe(e=>this.handleAgentEvent(e)),this.setStatus(`ready`),dY.info(`ScoopContext initialized`,{folder:this.scoop.folder,toolCount:a.length})}catch(e){let t=e instanceof Error?e.message:String(e);dY.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){dY.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);dY.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&&(this.agent.state.messages=[])}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=se();this.agent.state.model=e,dY.info(`Model updated on running agent`,{folder:this.scoop.folder,model:e.id})}async reloadSkills(){if(!this.agent)return;let e=await rY(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.state.systemPrompt=i,dY.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(`
14127
+ `),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&&fY(n)){this.recoverFromImageError(t);break}if(!this.isRecovering&&b(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=>{dY.error(`Failed to save agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)})});break}}}recoverFromOverflow(e){if(this.agent){dY.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++,dY.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.state.messages=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=>{dY.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){dY.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){dY.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.state.messages=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=>{dY.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){dY.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`,`/mnt`]:[`/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
14042
14128
 
14043
14129
  ${this.scoop.isCone?`Role: Cone (main orchestrator)`:`Scoop: ${this.scoop.name}`}
14044
14130
  Folder: ${this.scoop.folder}
@@ -14117,12 +14203,12 @@ ${e}
14117
14203
  ---
14118
14204
  ${this.scoop.isCone?`CONE`:`SCOOP`} MEMORY (${this.scoop.name}):
14119
14205
  ${t}
14120
- ---`);let a=UJ(n);return a&&(i+=a),i}},ZJ=r(`scheduler`),QJ=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(),ZJ.info(`Scheduler started`))}stop(){this.pollInterval&&=(clearInterval(this.pollInterval),null),this.running=!1,ZJ.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 Ye(i),ZJ.info(`Task created`,{id:i.id,groupFolder:e,scheduleType:n}),i}async updateTask(e,t){let n=await Be(e);if(!n)return null;let r={...n,...t};return(t.scheduleType||t.scheduleValue)&&(r.nextRun=this.calculateNextRun(r.scheduleType,r.scheduleValue)),await Ye(r),ZJ.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 Be(e)?(await this.updateTask(e,{status:`active`}),!0):!1}async deleteTask(e){return await Be(e)?(await je(e),ZJ.info(`Task deleted`,{id:e}),!0):!1}async getTasksByScoop(e){return(await ze()).filter(t=>t.groupFolder===e)}async getAllTasks(){return ze()}async checkTasks(){let e=await ze(),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){ZJ.warn(`Task scoop not found`,{taskId:e.id,groupFolder:e.groupFolder});return}ZJ.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 Ye({...e,lastRun:n,nextRun:r,status:i}),await this.callbacks.onTaskRun(e,t),ZJ.info(`Task completed`,{id:e.id})}catch(t){ZJ.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}},$J=r(`lick-manager`),eY=class{webhooks=new Map;crontasks=new Map;cronInterval=null;eventHandler=null;async init(){await Le();let e=await qe();for(let t of e)this.webhooks.set(t.id,t);$J.info(`Loaded webhooks`,{count:this.webhooks.size});let t=await Ge();for(let e of t)this.crontasks.set(e.id,e);$J.info(`Loaded crontasks`,{count:this.crontasks.size}),this.cronInterval=setInterval(()=>this.runCronScheduler(),6e4),$J.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 Me(i),$J.info(`Webhook created`,{id:r,name:e,scoop:t}),i}async deleteWebhook(e){return this.webhooks.has(e)?(this.webhooks.delete(e),await He(e),$J.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){$J.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){$J.debug(`Webhook event dropped by filter`,{webhookId:e,name:r.name});return}typeof t==`object`&&t&&(i=t)}catch(t){$J.error(`Webhook filter error`,{webhookId:e,error:t instanceof Error?t.message:String(t)})}$J.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 Ie(o),$J.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 Ve(e),$J.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){$J.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 Ie(t);continue}typeof r==`object`&&r&&(n=r)}catch(e){$J.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};$J.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 Ie(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 tY(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(`
14121
- `);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}var nY=null;function rY(){return nY||=new eY,nY}var iY=r(`orchestrator`),aY=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 Le(),this.sharedFs=await _e.create({dbName:`slicc-fs`}),this.sessionStore=new C,await this.ensureRootStructure();let e=await Ne();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 Ue(`lastAgentTs_${t.jid}`);e&&this.lastAgentTimestamp.set(t.jid,e)}await this.ensureGlobalMemory(),this.scheduler=new QJ({onTaskRun:async(e,t)=>{iY.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(),iY.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`,`/mnt`])try{await this.sharedFs.mkdir(e,{recursive:!0})}catch{}}async ensureGlobalMemory(){if(this.sharedFs){await GJ(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{iY.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,iY.info(`Global memory updated`))}getSharedFS(){return this.sharedFs}setLickManager(e){this.lickManager=e}async registerScoop(e){await Je(e),this.scoops.set(e.jid,e),this.messageQueues.set(e.jid,[]),iY.info(`Scoop registered`,{jid:e.jid,name:e.name}),this.createScoopTab(e.jid).catch(t=>{let n=t instanceof Error?t.message:String(t);iY.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=tY(t.folder,e,n);if(r)throw r}await this.destroyScoopTab(e),this.sessionStore?.delete(e).catch(t=>{iY.warn(`Failed to delete agent session`,{jid:e,error:t instanceof Error?t.message:String(t)})}),await Re(e),this.scoops.delete(e),this.messageQueues.delete(e),this.lastAgentTimestamp.delete(e),iY.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 _e.create({dbName:`slicc-fs`,wipe:!0}),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await WJ(this.sharedFs).catch(e=>{iY.warn(`Failed to re-seed default skills`,{error:e instanceof Error?e.message:String(e)})}),iY.info(`Filesystem reset and defaults re-seeded`)}async clearAllMessages(){await Ke(),this.sessionStore&&await this.sessionStore.clearAll().catch(e=>{iY.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,[]);iY.info(`All messages cleared`)}async handleMessage(e){iY.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);Hq(t?.isCone?`cone`:t?.name??`unknown`,localStorage.getItem(`selected-model`)??`unknown`),await Ae(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 Ae(i),this.callbacks.onIncomingMessage?.(e,i),iY.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);iY.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){iY.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)){iY.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(iY.debug(`routeToScoop: queued`,{chatJid:e.chatJid,scoopName:t.name,tabStatus:i?.status??`no-tab`,queueLength:r.length}),i?.status===`error`){iY.info(`routeToScoop: tab in error state, retrying init`,{chatJid:e.chatJid});try{await this.createScoopTab(e.chatJid),i=this.tabs.get(e.chatJid)}catch{iY.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`)iY.info(`Re-creating context after error`,{jid:e}),this.contexts.get(e)?.dispose(),this.contexts.delete(e),this.tabs.delete(e);else{iY.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 ge(this.sharedFs,[`/scoops/${t.folder}/`,`/shared/`],[`/workspace/`]),i=new XJ(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)+`
14122
- ... (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`};iY.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);iY.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`)),iY.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),iY.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 We(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 We(t)}async getMessagesForScoop(e){return Pe(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 iY.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(iY.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){iY.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){iY.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`)),iY.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){iY.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){iY.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 Fe(e,a,i);if(iY.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:a,dbMessageCount:o.length,queueLength:t.length}),o.length===0){iY.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(`
14123
- `);this.messageQueues.set(e,[]);let c=o[o.length-1];this.lastAgentTimestamp.set(e,c.timestamp),await A(`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);iY.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();iY.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=>{iY.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),iY.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);iY.info(`Orchestrator shutdown`)}};r(`heartbeat`);var oY=r(`tray-follower`);function sY(e){let t=new URL(e);return t.searchParams.set(`json`,`true`),t.toString()}async function cY(e){let t=sY(e.joinUrl),n=await hY(await(e.fetchImpl??fetch)(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:e.controllerId,runtime:e.runtime})}));return oY.info(`Follower tray attach response`,{trayId:n.trayId,action:n.result.action,code:n.result.code,participantCount:n.participantCount}),lY(n)}function lY(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 uY(e){return mY(await gY(e,{action:`poll`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,cursor:e.cursor}))}async function dY(e){return mY(await gY(e,{action:`answer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,answer:e.answer}))}async function fY(e){return mY(await gY(e,{action:`ice-candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:e.candidate}))}async function pY(e){return mY(await gY(e,{action:`retry`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,runtime:e.runtime}))}function mY(e){return{trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,bootstrap:e.bootstrap,events:e.events}}async function hY(e){let t=null,n=null;try{t=await e.text(),n=JSON.parse(t)}catch{}if(!_Y(n)){let n=t?t.slice(0,200):`(empty)`;throw oY.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 gY(e,t){let n=sY(e.joinUrl),r=await(e.fetchImpl??fetch)(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),i=await r.json().catch(()=>null);if(!vY(i))throw Error(`Tray follower bootstrap returned an invalid response (${r.status})`);return i}function _Y(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`&&yY(r.bootstrap):r.action===`fail`?(r.code===`INVALID_JOIN_CAPABILITY`||r.code===`TRAY_EXPIRED`)&&typeof r.error==`string`:!1}function vY(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`&&yY(t.bootstrap)&&Array.isArray(t.events)}function yY(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 bY=r(`tray-webrtc`),xY=`tray-control`,SY=250,CY=class{peerConnectionFactory;dataChannelLabel;peers=new Map;iceServers;constructor(e){this.options=e,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>EY(this.iceServers)),this.dataChannelLabel=e.dataChannelLabel??xY}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=OY(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`)&&(bY.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`?(bY.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`?(bY.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:DY(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){bY.warn(`Failed to report tray bootstrap failure`,{error:e instanceof Error?e.message:String(e)})}}}},wY=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??(()=>EY(this.iceServers)),this.controllerIdFactory=e.controllerIdFactory??(()=>crypto.randomUUID()),this.sleep=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),this.pollIntervalMs=e.pollIntervalMs??SY}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}),bY.info(`Follower tray join starting`,{joinUrl:this.options.joinUrl});let n=0;for(;;){kY(this.stopped),n++;let t;try{t=await cY({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;bY.info(`Follower tray attach waiting`,{attempt:n,code:t.code,retryAfterMs:e}),n%10==0&&bY.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}),bY.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}),bY.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}),bY.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(kY(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 uY({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 dY({joinUrl:this.options.joinUrl,controllerId:t,bootstrapId:r.bootstrapId,answer:DY(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 pY({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`)&&(bY.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?(bY.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?(bY.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=OY(n);r&&fY({joinUrl:this.options.joinUrl,controllerId:e,bootstrapId:t,candidate:r,fetchImpl:this.fetchImpl}).catch(e=>{bY.warn(`Failed to send follower ICE candidate`,{error:e instanceof Error?e.message:String(e)})})}),r}};function TY(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 wY({...e,sleep:o,onDisconnected:e=>{s||(bY.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}),bY.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}),bY.info(`Reconnect successful`,{attempt:f,trayId:i.trayId}),t.onConnected(i);return}catch(e){g=e instanceof Error?e.message:String(e),bY.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}),bY.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||bY.warn(`Initial follower connection failed`,{error:e instanceof Error?e.message:String(e)})}),u}function EY(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 DY(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 OY(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 kY(e){if(e)throw Error(`Tray follower stopped before WebRTC bootstrap completed`)}var AY=64*1024;async function jY(e,t){try{switch(t.op){case`readFile`:return await MY(e,t.path,t.encoding);case`writeFile`:return[await NY(e,t.path,t.content,t.encoding)];case`stat`:return[await PY(e,t.path)];case`readDir`:return[await FY(e,t.path)];case`mkdir`:return[await IY(e,t.path,t.recursive)];case`rm`:return[await LY(e,t.path,t.recursive)];case`exists`:return[await RY(e,t.path)];case`walk`:return[await zY(e,t.path)];default:return[{ok:!1,error:`Unknown fs operation: ${t.op}`}]}}catch(e){return[VY(e)]}}async function MY(e,t,n){return(n??`utf-8`)===`utf-8`?BY(await e.readFile(t,{encoding:`utf-8`}),`utf-8`):BY(HY(await e.readFile(t,{encoding:`binary`})),`base64`)}async function NY(e,t,n,r){if(r===`base64`){let r=UY(n);await e.writeFile(t,r)}else await e.writeFile(t,n);return{ok:!0,data:{type:`void`}}}async function PY(e,t){return{ok:!0,data:{type:`stat`,stat:await e.stat(t)}}}async function FY(e,t){return{ok:!0,data:{type:`dirEntries`,entries:await e.readDir(t)}}}async function IY(e,t,n){return await e.mkdir(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function LY(e,t,n){return await e.rm(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function RY(e,t){return{ok:!0,data:{type:`exists`,exists:await e.exists(t)}}}async function zY(e,t){let n=[];for await(let r of e.walk(t))n.push(r);return{ok:!0,data:{type:`paths`,paths:n}}}function BY(e,t){if(e.length<=AY)return[{ok:!0,data:{type:`file`,content:e,encoding:t}}];let n=Math.ceil(e.length/AY),r=[];for(let i=0;i<n;i++){let a=i*AY,o=e.slice(a,a+AY);r.push({ok:!0,data:{type:`file`,content:o,encoding:t},chunkIndex:i,totalChunks:n})}return r}function VY(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 HY(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function UY(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 WY=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()]}},GY=r(`data-channel-keepalive`),KY=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++,GY.debug(`Missed pong`,{missedPongs:this.missedPongs,maxMissed:this.maxMissed}),this.missedPongs>=this.maxMissed)){GY.warn(`Channel declared dead`,{missedPongs:this.missedPongs}),this.stop(),this.onDead();return}this.awaitingPong=!0,this.sendPing()}}},qY=r(`tray-leader-sync`);function JY(e){return e?e.includes(`standalone`)?`standalone`:e.includes(`extension`)?`extension`:e.includes(`electron`)?`electron`:`unknown`:`unknown`}var YY=class{followers=new Map;registry=new WY;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=we(t),i=r.onMessage(t=>{this.handleFollowerMessage(e,t)}),a=new KY({sendPing:()=>r.send({type:`ping`}),onDead:()=>{qY.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:JY(n?.runtime)}),qY.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(),qY.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();Se(t.sync,n,r),qY.debug(`Snapshot sent to follower`,{bootstrapId:e,messageCount:n.length})}handleFollowerMessage(e,t){switch(t.type){case`user_message`:qY.info(`Follower user message received`,{bootstrapId:e,messageId:t.messageId}),this.options.onFollowerMessage(t.text,t.messageId);break;case`abort`:qY.info(`Follower abort received`,{bootstrapId:e}),this.options.onFollowerAbort();break;case`request_snapshot`:qY.info(`Follower snapshot request received`,{bootstrapId:e}),this.sendSnapshotToFollower(e);break;case`targets.advertise`:qY.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),qY.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 k({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),qY.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);Oe(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=xe(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&&Oe(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 jY(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?jY(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})})}},XY=r(`tray-follower-sync`),ZY=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=De(e),this.unsubscribe=this.sync.onMessage(e=>{this.handleLeaderMessage(e)}),this.keepalive=new KY({sendPing:()=>this.sync.send({type:`ping`}),onDead:()=>{XY.warn(`Leader keepalive dead, cleaning up`),this.handleDisconnect(`Keepalive timeout — leader not responding`),this.options.onDead?.()}}),this.keepalive.start(),e.addEventListener(`close`,()=>{XY.warn(`Data channel closed`),this.handleDisconnect(`Data channel closed`)}),e.addEventListener(`error`,()=>{XY.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}),XY.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`}),XY.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(),XY.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`:XY.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=Ee(this.snapshotChunkBuffer,e);this.snapshotChunkBuffer=t.buffer,t.result&&(XY.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),XY.debug(`Skipping own message echo`,{messageId:e.messageId});break}XY.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`:XY.warn(`Error from leader`,{error:e.error}),this.emitEvent({type:`error`,error:e.error});break;case`targets.registry`:XY.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){XY.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}}createRemoteTransport(e,t){let n=new k({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),XY.debug(`Tracking remote CDP session`,{remoteSessionId:e})}n===`Target.detachFromTarget`&&i&&this.remoteCDPSessions.has(i)&&(this.remoteCDPSessions.delete(i),XY.debug(`Removed remote CDP session on detach`,{sessionId:i})),Oe(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=xe(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 jY(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 tX(new URL(e))?`electron-overlay`:`standalone`}catch{return`standalone`}}function $Y(e,t){return e===`electron-overlay`||e===`standalone`&&t}function eX(e){try{let t=new URL(e).searchParams.get(`tab`);return t&&Qi(t)?t:Xi}catch{return Xi}}function tX(e){return e.pathname===`/electron`||e.pathname===`/electron/`||e.searchParams.get(`runtime`)===`electron-overlay`}function nX(e){let t=new URL(e);return`${t.protocol===`https:`?`wss:`:`ws:`}//${t.host}/licks-ws`}function rX(e,t){return`${new URL(e).origin}/webhooks/${t}`}function iX(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function aX(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`slicc-electron-overlay:set-tab`}var oX=[`/shared/sprinkles`];async function sX(e){let t=new Map;for(let n of oX)await e.exists(n)&&await cX(e,n,t);return await cX(e,`/`,t),t}async function cX(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.shtml`))continue;let t=lX(r);if(!n.has(t)){let i;try{i=await e.readFile(r,{encoding:`utf-8`})??``}catch{i=``}n.set(t,{name:t,path:r,title:uX(i,t),autoOpen:dX(i)})}}}function lX(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function uX(e,t){let n=e.match(/data-sprinkle-title=["']([^"']+)["']/);if(n)return n[1];let r=e.match(/<title>([^<]+)<\/title>/i);return r?r[1].trim():t}function dX(e){return/data-sprinkle-autoopen\b/.test(e)}var fX=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:MW(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)}},pX=r(`sprinkle-manager`),mX=`slicc-open-sprinkles`,hX=class{fs;bridge;callbacks;availableSprinkles=new Map;openSprinkles=new Map;constructor(e,t,n){this.fs=e,this.bridge=new fX(e,t,e=>this.close(e)),this.callbacks=n}async restoreOpenSprinkles(){try{let e=localStorage.getItem(mX);if(!e){for(let e of this.availableSprinkles.values())if(e.autoOpen)try{await this.open(e.name)}catch{pX.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{pX.warn(`Failed to restore sprinkle`,{name:e})}}catch{}}persistOpenSprinkles(){try{localStorage.setItem(mX,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),pX.info(`Auto-opened new sprinkle after install`,{name:e.name})}catch{pX.warn(`Failed to auto-open new sprinkle`,{name:e.name})}}async refresh(){this.availableSprinkles=await sX(this.fs),pX.info(`Discovered sprinkles`,{count:this.availableSprinkles.size})}async open(e,t){if(this.openSprinkles.has(e)){pX.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 ui(i,this.bridge.createAPI(e));await a.render(r,e),this.openSprinkles.get(e).renderer=a,this.persistOpenSprinkles(),Wq(e),pX.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(),pX.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){pX.warn(`Cannot send to closed sprinkle`,{name:e});return}this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t)}};function gX(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch{return e}}function _X(e){let t=[],{payload:n}=e;if(n.title&&t.push(`# ${n.title}`),t.push(`A new handoff was accepted from ${gX(e.sourceUrl)}.`),t.push(`## Instruction`),t.push(n.instruction),n.urls&&n.urls.length>0){t.push(`## URLs`);for(let e of n.urls)t.push(`- ${e}`)}if(n.context&&(t.push(`## Context`),t.push(n.context)),n.acceptanceCriteria&&n.acceptanceCriteria.length>0){t.push(`## Acceptance Criteria`);for(let e of n.acceptanceCriteria)t.push(`- ${e}`)}return n.notes&&(t.push(`## Notes`),t.push(n.notes)),t.join(`
14206
+ ---`);let a=oY(n);return a&&(i+=a),i}},mY=r(`scheduler`),hY=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(),mY.info(`Scheduler started`))}stop(){this.pollInterval&&=(clearInterval(this.pollInterval),null),this.running=!1,mY.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 Ye(i),mY.info(`Task created`,{id:i.id,groupFolder:e,scheduleType:n}),i}async updateTask(e,t){let n=await Be(e);if(!n)return null;let r={...n,...t};return(t.scheduleType||t.scheduleValue)&&(r.nextRun=this.calculateNextRun(r.scheduleType,r.scheduleValue)),await Ye(r),mY.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 Be(e)?(await this.updateTask(e,{status:`active`}),!0):!1}async deleteTask(e){return await Be(e)?(await je(e),mY.info(`Task deleted`,{id:e}),!0):!1}async getTasksByScoop(e){return(await ze()).filter(t=>t.groupFolder===e)}async getAllTasks(){return ze()}async checkTasks(){let e=await ze(),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){mY.warn(`Task scoop not found`,{taskId:e.id,groupFolder:e.groupFolder});return}mY.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 Ye({...e,lastRun:n,nextRun:r,status:i}),await this.callbacks.onTaskRun(e,t),mY.info(`Task completed`,{id:e.id})}catch(t){mY.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}},gY=r(`lick-manager`),_Y=class{webhooks=new Map;crontasks=new Map;cronInterval=null;eventHandler=null;async init(){await Le();let e=await qe();for(let t of e)this.webhooks.set(t.id,t);gY.info(`Loaded webhooks`,{count:this.webhooks.size});let t=await Ge();for(let e of t)this.crontasks.set(e.id,e);gY.info(`Loaded crontasks`,{count:this.crontasks.size}),this.cronInterval=setInterval(()=>this.runCronScheduler(),6e4),gY.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 Me(i),gY.info(`Webhook created`,{id:r,name:e,scoop:t}),i}async deleteWebhook(e){return this.webhooks.has(e)?(this.webhooks.delete(e),await He(e),gY.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){gY.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){gY.debug(`Webhook event dropped by filter`,{webhookId:e,name:r.name});return}typeof t==`object`&&t&&(i=t)}catch(t){gY.error(`Webhook filter error`,{webhookId:e,error:t instanceof Error?t.message:String(t)})}gY.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 Ie(o),gY.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 Ve(e),gY.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){gY.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 Ie(t);continue}typeof r==`object`&&r&&(n=r)}catch(e){gY.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};gY.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 Ie(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 vY(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(`
14207
+ `);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}var yY=null;function bY(){return yY||=new _Y,yY}var xY=r(`orchestrator`),SY=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 Le(),this.sharedFs=await _e.create({dbName:`slicc-fs`}),this.sessionStore=new C,await this.ensureRootStructure();let e=await Ne();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 Ue(`lastAgentTs_${t.jid}`);e&&this.lastAgentTimestamp.set(t.jid,e)}await this.ensureGlobalMemory(),this.scheduler=new hY({onTaskRun:async(e,t)=>{xY.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(),xY.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`,`/mnt`])try{await this.sharedFs.mkdir(e,{recursive:!0})}catch{}}async ensureGlobalMemory(){if(this.sharedFs){await cY(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{xY.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,xY.info(`Global memory updated`))}getSharedFS(){return this.sharedFs}setLickManager(e){this.lickManager=e}async registerScoop(e){await Je(e),this.scoops.set(e.jid,e),this.messageQueues.set(e.jid,[]),xY.info(`Scoop registered`,{jid:e.jid,name:e.name}),this.createScoopTab(e.jid).catch(t=>{let n=t instanceof Error?t.message:String(t);xY.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=vY(t.folder,e,n);if(r)throw r}await this.destroyScoopTab(e),this.sessionStore?.delete(e).catch(t=>{xY.warn(`Failed to delete agent session`,{jid:e,error:t instanceof Error?t.message:String(t)})}),await Re(e),this.scoops.delete(e),this.messageQueues.delete(e),this.lastAgentTimestamp.delete(e),xY.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 _e.create({dbName:`slicc-fs`,wipe:!0}),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await sY(this.sharedFs).catch(e=>{xY.warn(`Failed to re-seed default skills`,{error:e instanceof Error?e.message:String(e)})}),xY.info(`Filesystem reset and defaults re-seeded`)}async clearAllMessages(){await Ke(),this.sessionStore&&await this.sessionStore.clearAll().catch(e=>{xY.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,[]);xY.info(`All messages cleared`)}async handleMessage(e){xY.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);aJ(t?.isCone?`cone`:t?.name??`unknown`,localStorage.getItem(`selected-model`)??`unknown`),await Ae(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 Ae(i),this.callbacks.onIncomingMessage?.(e,i),xY.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);xY.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){xY.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)){xY.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(xY.debug(`routeToScoop: queued`,{chatJid:e.chatJid,scoopName:t.name,tabStatus:i?.status??`no-tab`,queueLength:r.length}),i?.status===`error`){xY.info(`routeToScoop: tab in error state, retrying init`,{chatJid:e.chatJid});try{await this.createScoopTab(e.chatJid),i=this.tabs.get(e.chatJid)}catch{xY.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`)xY.info(`Re-creating context after error`,{jid:e}),this.contexts.get(e)?.dispose(),this.contexts.delete(e),this.tabs.delete(e);else{xY.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 ge(this.sharedFs,[`/scoops/${t.folder}/`,`/shared/`],[`/workspace/`]),i=new pY(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)+`
14208
+ ... (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`};xY.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);xY.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`)),xY.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),xY.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 We(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 We(t)}async getMessagesForScoop(e){return Pe(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 xY.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(xY.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){xY.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){xY.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`)),xY.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){xY.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){xY.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 Fe(e,a,i);if(xY.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:a,dbMessageCount:o.length,queueLength:t.length}),o.length===0){xY.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(`
14209
+ `);this.messageQueues.set(e,[]);let c=o[o.length-1];this.lastAgentTimestamp.set(e,c.timestamp),await A(`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);xY.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();xY.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=>{xY.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),xY.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);xY.info(`Orchestrator shutdown`)}};r(`heartbeat`);var CY=r(`tray-follower`);function wY(e){let t=new URL(e);return t.searchParams.set(`json`,`true`),t.toString()}async function TY(e){let t=wY(e.joinUrl),n=await MY(await(e.fetchImpl??fetch)(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({controllerId:e.controllerId,runtime:e.runtime})}));return CY.info(`Follower tray attach response`,{trayId:n.trayId,action:n.result.action,code:n.result.code,participantCount:n.participantCount}),EY(n)}function EY(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 DY(e){return jY(await NY(e,{action:`poll`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,cursor:e.cursor}))}async function OY(e){return jY(await NY(e,{action:`answer`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,answer:e.answer}))}async function kY(e){return jY(await NY(e,{action:`ice-candidate`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,candidate:e.candidate}))}async function AY(e){return jY(await NY(e,{action:`retry`,controllerId:e.controllerId,bootstrapId:e.bootstrapId,runtime:e.runtime}))}function jY(e){return{trayId:e.trayId,controllerId:e.controllerId,participantCount:e.participantCount,leader:e.leader,bootstrap:e.bootstrap,events:e.events}}async function MY(e){let t=null,n=null;try{t=await e.text(),n=JSON.parse(t)}catch{}if(!PY(n)){let n=t?t.slice(0,200):`(empty)`;throw CY.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 NY(e,t){let n=wY(e.joinUrl),r=await(e.fetchImpl??fetch)(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),i=await r.json().catch(()=>null);if(!FY(i))throw Error(`Tray follower bootstrap returned an invalid response (${r.status})`);return i}function PY(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`&&IY(r.bootstrap):r.action===`fail`?(r.code===`INVALID_JOIN_CAPABILITY`||r.code===`TRAY_EXPIRED`)&&typeof r.error==`string`:!1}function FY(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`&&IY(t.bootstrap)&&Array.isArray(t.events)}function IY(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 LY=r(`tray-webrtc`),RY=`tray-control`,zY=250,BY=class{peerConnectionFactory;dataChannelLabel;peers=new Map;iceServers;constructor(e){this.options=e,this.iceServers=e.iceServers,this.peerConnectionFactory=e.peerConnectionFactory??(()=>UY(this.iceServers)),this.dataChannelLabel=e.dataChannelLabel??RY}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=GY(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`)&&(LY.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`?(LY.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`?(LY.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:WY(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){LY.warn(`Failed to report tray bootstrap failure`,{error:e instanceof Error?e.message:String(e)})}}}},VY=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??(()=>UY(this.iceServers)),this.controllerIdFactory=e.controllerIdFactory??(()=>crypto.randomUUID()),this.sleep=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),this.pollIntervalMs=e.pollIntervalMs??zY}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}),LY.info(`Follower tray join starting`,{joinUrl:this.options.joinUrl});let n=0;for(;;){KY(this.stopped),n++;let t;try{t=await TY({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;LY.info(`Follower tray attach waiting`,{attempt:n,code:t.code,retryAfterMs:e}),n%10==0&&LY.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}),LY.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}),LY.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}),LY.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(KY(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 DY({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:WY(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 AY({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`)&&(LY.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?(LY.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?(LY.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=GY(n);r&&kY({joinUrl:this.options.joinUrl,controllerId:e,bootstrapId:t,candidate:r,fetchImpl:this.fetchImpl}).catch(e=>{LY.warn(`Failed to send follower ICE candidate`,{error:e instanceof Error?e.message:String(e)})})}),r}};function HY(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 VY({...e,sleep:o,onDisconnected:e=>{s||(LY.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}),LY.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}),LY.info(`Reconnect successful`,{attempt:f,trayId:i.trayId}),t.onConnected(i);return}catch(e){g=e instanceof Error?e.message:String(e),LY.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}),LY.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||LY.warn(`Initial follower connection failed`,{error:e instanceof Error?e.message:String(e)})}),u}function UY(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 WY(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 GY(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 KY(e){if(e)throw Error(`Tray follower stopped before WebRTC bootstrap completed`)}var qY=64*1024;async function JY(e,t){try{switch(t.op){case`readFile`:return await YY(e,t.path,t.encoding);case`writeFile`:return[await XY(e,t.path,t.content,t.encoding)];case`stat`:return[await ZY(e,t.path)];case`readDir`:return[await QY(e,t.path)];case`mkdir`:return[await $Y(e,t.path,t.recursive)];case`rm`:return[await eX(e,t.path,t.recursive)];case`exists`:return[await tX(e,t.path)];case`walk`:return[await nX(e,t.path)];default:return[{ok:!1,error:`Unknown fs operation: ${t.op}`}]}}catch(e){return[iX(e)]}}async function YY(e,t,n){return(n??`utf-8`)===`utf-8`?rX(await e.readFile(t,{encoding:`utf-8`}),`utf-8`):rX(aX(await e.readFile(t,{encoding:`binary`})),`base64`)}async function XY(e,t,n,r){if(r===`base64`){let r=oX(n);await e.writeFile(t,r)}else await e.writeFile(t,n);return{ok:!0,data:{type:`void`}}}async function ZY(e,t){return{ok:!0,data:{type:`stat`,stat:await e.stat(t)}}}async function QY(e,t){return{ok:!0,data:{type:`dirEntries`,entries:await e.readDir(t)}}}async function $Y(e,t,n){return await e.mkdir(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function eX(e,t,n){return await e.rm(t,{recursive:n}),{ok:!0,data:{type:`void`}}}async function tX(e,t){return{ok:!0,data:{type:`exists`,exists:await e.exists(t)}}}async function nX(e,t){let n=[];for await(let r of e.walk(t))n.push(r);return{ok:!0,data:{type:`paths`,paths:n}}}function rX(e,t){if(e.length<=qY)return[{ok:!0,data:{type:`file`,content:e,encoding:t}}];let n=Math.ceil(e.length/qY),r=[];for(let i=0;i<n;i++){let a=i*qY,o=e.slice(a,a+qY);r.push({ok:!0,data:{type:`file`,content:o,encoding:t},chunkIndex:i,totalChunks:n})}return r}function iX(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 aX(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function oX(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 sX=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()]}},cX=r(`data-channel-keepalive`),lX=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++,cX.debug(`Missed pong`,{missedPongs:this.missedPongs,maxMissed:this.maxMissed}),this.missedPongs>=this.maxMissed)){cX.warn(`Channel declared dead`,{missedPongs:this.missedPongs}),this.stop(),this.onDead();return}this.awaitingPong=!0,this.sendPing()}}},uX=r(`tray-leader-sync`);function dX(e){return e?e.includes(`standalone`)?`standalone`:e.includes(`extension`)?`extension`:e.includes(`electron`)?`electron`:`unknown`:`unknown`}var fX=class{followers=new Map;registry=new sX;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=we(t),i=r.onMessage(t=>{this.handleFollowerMessage(e,t)}),a=new lX({sendPing:()=>r.send({type:`ping`}),onDead:()=>{uX.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:dX(n?.runtime)}),uX.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(),uX.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();Se(t.sync,n,r),uX.debug(`Snapshot sent to follower`,{bootstrapId:e,messageCount:n.length})}handleFollowerMessage(e,t){switch(t.type){case`user_message`:uX.info(`Follower user message received`,{bootstrapId:e,messageId:t.messageId}),this.options.onFollowerMessage(t.text,t.messageId);break;case`abort`:uX.info(`Follower abort received`,{bootstrapId:e}),this.options.onFollowerAbort();break;case`request_snapshot`:uX.info(`Follower snapshot request received`,{bootstrapId:e}),this.sendSnapshotToFollower(e);break;case`targets.advertise`:uX.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),uX.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 k({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),uX.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);Oe(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=xe(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&&Oe(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 JY(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?JY(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})})}},pX=r(`tray-follower-sync`),mX=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=De(e),this.unsubscribe=this.sync.onMessage(e=>{this.handleLeaderMessage(e)}),this.keepalive=new lX({sendPing:()=>this.sync.send({type:`ping`}),onDead:()=>{pX.warn(`Leader keepalive dead, cleaning up`),this.handleDisconnect(`Keepalive timeout — leader not responding`),this.options.onDead?.()}}),this.keepalive.start(),e.addEventListener(`close`,()=>{pX.warn(`Data channel closed`),this.handleDisconnect(`Data channel closed`)}),e.addEventListener(`error`,()=>{pX.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}),pX.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`}),pX.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(),pX.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`:pX.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=Ee(this.snapshotChunkBuffer,e);this.snapshotChunkBuffer=t.buffer,t.result&&(pX.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),pX.debug(`Skipping own message echo`,{messageId:e.messageId});break}pX.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`:pX.warn(`Error from leader`,{error:e.error}),this.emitEvent({type:`error`,error:e.error});break;case`targets.registry`:pX.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){pX.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}}createRemoteTransport(e,t){let n=new k({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),pX.debug(`Tracking remote CDP session`,{remoteSessionId:e})}n===`Target.detachFromTarget`&&i&&this.remoteCDPSessions.has(i)&&(this.remoteCDPSessions.delete(i),pX.debug(`Removed remote CDP session on detach`,{sessionId:i})),Oe(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=xe(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 JY(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 hX(e,t){if(t)return`extension`;try{return vX(new URL(e))?`electron-overlay`:`standalone`}catch{return`standalone`}}function gX(e,t){return e===`electron-overlay`||e===`standalone`&&t}function _X(e){try{let t=new URL(e).searchParams.get(`tab`);return t&&Qi(t)?t:Xi}catch{return Xi}}function vX(e){return e.pathname===`/electron`||e.pathname===`/electron/`||e.searchParams.get(`runtime`)===`electron-overlay`}function yX(e){let t=new URL(e);return`${t.protocol===`https:`?`wss:`:`ws:`}//${t.host}/licks-ws`}function bX(e,t){return`${new URL(e).origin}/webhooks/${t}`}function xX(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function SX(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`slicc-electron-overlay:set-tab`}var CX=[`/shared/sprinkles`];async function wX(e){let t=new Map;for(let n of CX)await e.exists(n)&&await TX(e,n,t);return await TX(e,`/`,t),t}async function TX(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.shtml`))continue;let t=EX(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:DX(i,t),autoOpen:OX(i)})}}}function EX(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.shtml`)?t.slice(0,-6):t}function DX(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 kX=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:NW(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)}},AX=r(`sprinkle-manager`),jX=`slicc-open-sprinkles`,MX=class{fs;bridge;callbacks;availableSprinkles=new Map;openSprinkles=new Map;constructor(e,t,n){this.fs=e,this.bridge=new kX(e,t,e=>this.close(e)),this.callbacks=n}async restoreOpenSprinkles(){try{let e=localStorage.getItem(jX);if(!e){for(let e of this.availableSprinkles.values())if(e.autoOpen)try{await this.open(e.name)}catch{AX.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{AX.warn(`Failed to restore sprinkle`,{name:e})}}catch{}}persistOpenSprinkles(){try{localStorage.setItem(jX,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),AX.info(`Auto-opened new sprinkle after install`,{name:e.name})}catch{AX.warn(`Failed to auto-open new sprinkle`,{name:e.name})}}async refresh(){this.availableSprinkles=await wX(this.fs),AX.info(`Discovered sprinkles`,{count:this.availableSprinkles.size})}async open(e,t){if(this.openSprinkles.has(e)){AX.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 ui(i,this.bridge.createAPI(e));await a.render(r,e),this.openSprinkles.get(e).renderer=a,this.persistOpenSprinkles(),sJ(e),AX.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(),AX.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){AX.warn(`Cannot send to closed sprinkle`,{name:e});return}this.bridge.pushUpdate(e,t),n.renderer.pushUpdate(t)}};function NX(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch{return e}}function PX(e){let t=[],{payload:n}=e;if(n.title&&t.push(`# ${n.title}`),t.push(`A new handoff was accepted from ${NX(e.sourceUrl)}.`),t.push(`## Instruction`),t.push(n.instruction),n.urls&&n.urls.length>0){t.push(`## URLs`);for(let e of n.urls)t.push(`- ${e}`)}if(n.context&&(t.push(`## Context`),t.push(n.context)),n.acceptanceCriteria&&n.acceptanceCriteria.length>0){t.push(`## Acceptance Criteria`);for(let e of n.acceptanceCriteria)t.push(`- ${e}`)}return n.notes&&(t.push(`## Notes`),t.push(n.notes)),t.join(`
14124
14210
 
14125
- `)}function vX(e,t){return e.receivedAt.localeCompare(t.receivedAt)}var yX=class{onPendingHandoffsChange;pendingByHandoffId=new Map;constructor(e){this.onPendingHandoffsChange=e.onPendingHandoffsChange}injectHandoff(e,t=`local`){let n=`injected-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.pendingByHandoffId.set(n,{handoffId:n,sourceUrl:t,payload:e,receivedAt:new Date().toISOString()}),this.emitChange(),n}clearHandoff(e){let t=this.pendingByHandoffId.get(e)??null;return this.pendingByHandoffId.delete(e),t&&this.emitChange(),{handoff:t,targetIds:[]}}emitChange(){this.onPendingHandoffsChange?.([...this.pendingByHandoffId.values()].sort(vX))}},$=r(`main`),bX=`slicc-pending-mount`,xX=`pendingMount`;async function SX(e){let t=await new Promise((e,t)=>{let n=indexedDB.open(bX,1);n.onupgradeneeded=()=>n.result.createObjectStore(`handles`),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),n=t.transaction(`handles`,`readwrite`);n.objectStore(`handles`).put(e,xX),await new Promise(e=>n.oncomplete=()=>e()),t.close()}async function CX(e){let t;try{t=await new Promise((e,t)=>{let n=indexedDB.open(bX,1);n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}catch{return}let n=t.transaction(`handles`,`readwrite`),r=await new Promise(e=>{let t=n.objectStore(`handles`).get(xX);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)});if(r){n.objectStore(`handles`).delete(xX),await new Promise(e=>n.oncomplete=()=>e());let t=`/mnt/${r.name}`;await e.mount(t,r),$.info(`Mounted folder from welcome onboarding`,{name:r.name,path:t})}t.close()}function wX(){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 TX(){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 EX(e,t,n){let r=wX(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ba(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ba(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=xa(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 ye(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 DX(e){let{OffscreenClient:t}=await y(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-CciDOOoa.js`);return{OffscreenClient:e}},__vite__mapDeps([21,14])),{VirtualFS:n}=await y(async()=>{let{VirtualFS:e}=await import(`./fs-BQWb1K18.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([19,1])),r=new ra(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),$.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`)||$.error(`Preview VFS read failed`,{path:n,error:r}),o.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},EX(a,TX(),async()=>{await r.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-o0ztF_0C.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await y(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-DhV8bm4P.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([22,1,4,14])),i=new t;await i.connect();let o=new e({fs:a,browserAPI:new n(i)});await r.panels.terminal.mountShell(o),$.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){$.warn(`Failed to mount shell to terminal`,e)}let s,l=new Set,u=e=>{r.setPendingHandoffCount(e.length),r.panels.chat.setPendingHandoffs(e)},d=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 l)e.has(t)||r.panels.chat.deleteSessionById(`session-${t}`);if(l=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)}},onPendingHandoffsChange:u,onReady:async()=>{try{$.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 d(e))}catch(e){$.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),s.setLocalFS(a);let f=s.createAgentHandle();r.panels.chat.setAgent(f),r.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=s.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await d(t),r.setActiveTab(`chat`),f.sendMessage(_X(e),`handoff-${e.handoffId}`),s.acceptPendingHandoff(e.handoffId)},onDismiss:e=>{s.dismissPendingHandoff(e.handoffId)}}),s.requestPendingHandoffs(),r.panels.scoops.setOrchestrator(s),r.panels.memory.setOrchestrator(s),r.setScoopSwitcherOrchestrator?.(s),r.onScoopSelect=d,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 p=new hX(a,async e=>{if(e.type===`sprinkle`){if(e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&localStorage.setItem(`slicc-welcomed`,`1`),n===`shortcut-migrate`&&p.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&CX(a).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await SX(t),p.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),p.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}return}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=p,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 p.refresh(),e=p.available();break;case`opened`:e=p.opened();break;case`refresh`:await p.refresh(),e=p.available().length;break;case`open`:await p.open(r),e=!0;break;case`close`:p.close(r),e=!0;break;case`send`:p.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await p.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 p.refresh(),r.onSprinkleClose=e=>p.close(e),r.getAvailableSprinkles=()=>{let e=new Set(p.opened());return p.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},r.onOpenSprinkle=(e,t)=>p.open(e,t),r.updateAddButtons(),await p.restoreOpenSprinkles(),!localStorage.getItem(`slicc-welcomed`)&&!c(window.localStorage)&&p.available().some(e=>e.name===`welcome`))try{await p.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}$.info(`SprinkleManager initialized (extension mode)`),s.requestState(),$.info(`Extension UI connected to offscreen agent engine`),Vq().catch(()=>{})}async function OX(){la(),_a();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(()=>$.info(`Preview SW registered`)).catch(e=>$.error(`Preview SW registration failed — preview feature will not work`,e)),ne();let t=E(),n=c(window.localStorage);if(!t&&!n){let e=window.location.port===`5710`||window.location.port===`3000`;window.location.port===``&&window.location.pathname.includes(`/join/`)?await w({autoJoinUrl:window.location.origin+window.location.pathname}):!e&&window.location.port!==``?await w({preferTrayJoin:!0}):await w(),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 DX(e);let l=new ra(e,o===`electron-overlay`);if(o===`electron-overlay`){let e=eX(window.location.href);l.setActiveTab(e);let t=document.createElement(`style`);t.id=`slicc-electron-overlay-runtime-style`,t.textContent=`
14211
+ `)}function FX(e,t){return e.receivedAt.localeCompare(t.receivedAt)}var IX=class{onPendingHandoffsChange;pendingByHandoffId=new Map;constructor(e){this.onPendingHandoffsChange=e.onPendingHandoffsChange}injectHandoff(e,t=`local`){let n=`injected-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.pendingByHandoffId.set(n,{handoffId:n,sourceUrl:t,payload:e,receivedAt:new Date().toISOString()}),this.emitChange(),n}clearHandoff(e){let t=this.pendingByHandoffId.get(e)??null;return this.pendingByHandoffId.delete(e),t&&this.emitChange(),{handoff:t,targetIds:[]}}emitChange(){this.onPendingHandoffsChange?.([...this.pendingByHandoffId.values()].sort(FX))}},$=r(`main`),LX=`slicc-pending-mount`,RX=`pendingMount`;async function zX(e){let t=await new Promise((e,t)=>{let n=indexedDB.open(LX,1);n.onupgradeneeded=()=>n.result.createObjectStore(`handles`),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),n=t.transaction(`handles`,`readwrite`);n.objectStore(`handles`).put(e,RX),await new Promise(e=>n.oncomplete=()=>e()),t.close()}async function BX(e){let t;try{t=await new Promise((e,t)=>{let n=indexedDB.open(LX,1);n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}catch{return}let n=t.transaction(`handles`,`readwrite`),r=await new Promise(e=>{let t=n.objectStore(`handles`).get(RX);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)});if(r){n.objectStore(`handles`).delete(RX),await new Promise(e=>n.oncomplete=()=>e());let t=`/mnt/${r.name}`;await e.mount(t,r),$.info(`Mounted folder from welcome onboarding`,{name:r.name,path:t})}t.close()}function VX(){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 HX(){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 UX(e,t,n){let r=VX(),i=0,a=!1,o=()=>{i=0,a||r.hide()};window.addEventListener(`dragenter`,e=>{ba(e.dataTransfer)&&(e.preventDefault(),i+=1,a||r.show(`Drop .skill to install`,`Unpack into /workspace/skills/{name}.`))}),window.addEventListener(`dragover`,e=>{ba(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=xa(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 ye(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 WX(e){let{OffscreenClient:t}=await y(async()=>{let{OffscreenClient:e}=await import(`./offscreen-client-CciDOOoa.js`);return{OffscreenClient:e}},__vite__mapDeps([21,14])),{VirtualFS:n}=await y(async()=>{let{VirtualFS:e}=await import(`./fs-BQWb1K18.js`).then(e=>e.t);return{VirtualFS:e}},__vite__mapDeps([19,1])),r=new ra(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),$.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`)||$.error(`Preview VFS read failed`,{path:n,error:r}),o.postMessage({type:`preview-vfs-response`,id:t,error:r})}})()},UX(a,HX(),async()=>{await r.panels.fileBrowser.refresh()});try{let{WasmShell:e}=await y(async()=>{let{WasmShell:e}=await import(`./shell-CYFx3OEI.js`);return{WasmShell:e}},[]),{PanelCdpProxy:t,BrowserAPI:n}=await y(async()=>{let{PanelCdpProxy:e,BrowserAPI:t}=await import(`./cdp-D7T7EeS9.js`).then(e=>e.t);return{PanelCdpProxy:e,BrowserAPI:t}},__vite__mapDeps([22,1,4,14])),i=new t;await i.connect();let o=new e({fs:a,browserAPI:new n(i)});await r.panels.terminal.mountShell(o),$.info(`Terminal mounted with shared VFS and BrowserAPI (CDP proxy)`)}catch(e){$.warn(`Failed to mount shell to terminal`,e)}let s,l=new Set,u=e=>{r.setPendingHandoffCount(e.length),r.panels.chat.setPendingHandoffs(e)},d=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 l)e.has(t)||r.panels.chat.deleteSessionById(`session-${t}`);if(l=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)}},onPendingHandoffsChange:u,onReady:async()=>{try{$.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 d(e))}catch(e){$.error(`Failed to initialize on ready`,{error:e instanceof Error?e.message:String(e)})}}}),s.setLocalFS(a);let f=s.createAgentHandle();r.panels.chat.setAgent(f),r.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=s.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await d(t),r.setActiveTab(`chat`),f.sendMessage(PX(e),`handoff-${e.handoffId}`),s.acceptPendingHandoff(e.handoffId)},onDismiss:e=>{s.dismissPendingHandoff(e.handoffId)}}),s.requestPendingHandoffs(),r.panels.scoops.setOrchestrator(s),r.panels.memory.setOrchestrator(s),r.setScoopSwitcherOrchestrator?.(s),r.onScoopSelect=d,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 p=new MX(a,async e=>{if(e.type===`sprinkle`){if(e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&localStorage.setItem(`slicc-welcomed`,`1`),n===`shortcut-migrate`&&p.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&BX(a).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await zX(t),p.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),p.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}return}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=p,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 p.refresh(),e=p.available();break;case`opened`:e=p.opened();break;case`refresh`:await p.refresh(),e=p.available().length;break;case`open`:await p.open(r),e=!0;break;case`close`:p.close(r),e=!0;break;case`send`:p.sendToSprinkle(r,i),e=!0;break;case`openNewAutoOpen`:await p.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 p.refresh(),r.onSprinkleClose=e=>p.close(e),r.getAvailableSprinkles=()=>{let e=new Set(p.opened());return p.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},r.onOpenSprinkle=(e,t)=>p.open(e,t),r.updateAddButtons(),await p.restoreOpenSprinkles(),!localStorage.getItem(`slicc-welcomed`)&&!c(window.localStorage)&&p.available().some(e=>e.name===`welcome`))try{await p.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}$.info(`SprinkleManager initialized (extension mode)`),s.requestState(),$.info(`Extension UI connected to offscreen agent engine`),iJ().catch(()=>{})}async function GX(){la(),_a();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(()=>$.info(`Preview SW registered`)).catch(e=>$.error(`Preview SW registration failed — preview feature will not work`,e)),ne();let t=E(),n=c(window.localStorage);if(!t&&!n){let e=window.location.port===`5710`||window.location.port===`3000`;window.location.port===``&&window.location.pathname.includes(`/join/`)?await w({autoJoinUrl:window.location.origin+window.location.pathname}):!e&&window.location.port!==``?await w({preferTrayJoin:!0}):await w(),t=E()}let r=!t&&c(window.localStorage),a=typeof chrome<`u`&&!!chrome?.runtime?.id,o=hX(window.location.href,a);if(o===`extension`)return WX(e);let l=new ra(e,o===`electron-overlay`);if(o===`electron-overlay`){let e=_X(window.location.href);l.setActiveTab(e);let t=document.createElement(`style`);t.id=`slicc-electron-overlay-runtime-style`,t.textContent=`
14126
14212
  #app > .tab-bar { display: none !important; }
14127
14213
  #app > .tab-content {
14128
14214
  height: calc(100vh - var(--s2-header-height));
@@ -14130,4 +14216,4 @@ ${t}
14130
14216
  #app > .tab-content > .tab-content__panel {
14131
14217
  height: 100%;
14132
14218
  }
14133
- `,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&aX(e.data)&&l.setActiveTab(eX(`http://localhost/?tab=${e.data.tab??``}`))}),window.addEventListener(`keydown`,e=>{e.code===`Semicolon`&&(e.metaKey||e.ctrlKey)&&!e.shiftKey&&!e.altKey&&!e.repeat&&(e.preventDefault(),e.stopPropagation(),window.parent.postMessage({type:`slicc-electron-overlay:toggle`},`*`))},!0)}let u=TX();await l.panels.chat.initSession(`session-cone`),$.info(`Session initialized`);let f=new ke,p=e=>{l.setPendingHandoffCount(e.length),l.panels.chat.setPendingHandoffs(e)},m=new Set,h=e=>{$.debug(`Emit to UI`,{type:e.type,listenerCount:m.size});for(let t of m)try{t(e)}catch(t){$.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},_=null,v=new Map,b=new Map;function x(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function S(e){let t=b.get(e);return t||(t=[],b.set(e,t)),t}function C(e,t){let n=S(e),r=v.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${x()}`,v.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),_?.jid===e&&h({type:`message_start`,messageId:r}),o}let T=new aY(l.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),_?.jid===e&&(h({type:`content_delta`,messageId:r.id,text:t}),n||h({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=S(e),n=v.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),_?.jid===e&&h({type:`content_done`,messageId:n}),v.delete(e)}},onSendMessage:(e,t)=>{$.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${x()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};T.handleMessage(r),S(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),_?.jid===e&&(h({type:`message_start`,messageId:n}),h({type:`content_delta`,messageId:n,text:t}),h({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(l.panels.scoops.updateScoopStatus(e,t),l.updateScoopSwitcherStatus?.(e,t),_?.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=v.get(e)??`done-${e}-${x()}`;v.delete(e),h({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{$.error(`Scoop error`,{scoopJid:e,error:t}),_?.jid===e&&h({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:x(),name:t,input:n}),_?.jid===e&&h({type:`tool_use_start`,messageId:r.id,toolName:t,toolInput:n})},onToolEnd:(e,t,n,r)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let i=S(e),a=v.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)}}_?.jid===e&&a&&h({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=v.get(e);i?h({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):$.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=v.get(e);n&&h({type:`tool_ui_done`,messageId:n,requestId:t})},onIncomingMessage:(e,t)=>{let n={id:t.id,role:`user`,content:t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content,timestamp:new Date(t.timestamp).getTime(),source:t.channel===`delegation`?`delegation`:void 0,channel:t.channel};S(e).push(n),_?.jid===e&&(h({type:`message_start`,messageId:t.id}),h({type:`content_delta`,messageId:t.id,text:n.content}),h({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),$.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`)||$.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},EX(D,(e,t)=>{t===`error`?$.warn(`Dropped skill install failed`,{message:e}):$.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-o0ztF_0C.js`);return{WasmShell:e}},[]),t=new e({fs:D,browserAPI:f});await l.panels.terminal.mountShell(t),$.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await y(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-DOU_MEY1.js`);return{BshWatchdog:e}},__vite__mapDeps([23,14])),t=new e({browserAPI:f,fs:D});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),$.info(`BSH navigation watchdog started`)}catch(e){$.warn(`Failed to start BSH watchdog`,e)}}catch(e){$.warn(`Failed to mount shell to terminal`,e)}}let ee=T.getScoops(),te=ee.some(e=>e.isCone);if(r)$.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!te)_=await l.panels.scoops.createScoop(`Cone`,!0),$.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=ee.find(t=>t.folder===e);t?(_=t,$.info(`Restored scoop from URL`,{folder:e})):_=ee.find(e=>e.isCone)??ee[0]}else _=ee.find(e=>e.isCone)??ee[0]}_&&l.panels.memory.setSelectedScoop(_.jid);let re=null,ie=null,ae={sendMessage(e,t){if(!_){h({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:_.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};S(_.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),re?.broadcastUserMessage(e,n.id),T.handleMessage(n),T.createScoopTab(_.jid)},onEvent(e){return m.add(e),()=>m.delete(e)},stop(){_&&(T.stopScoop(_.jid),T.clearQueuedMessages(_.jid).catch(e=>{$.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};l.panels.chat.setAgent(ae),l.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=T.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await ue(t),l.setActiveTab(`chat`),ae.sendMessage(_X(e),`handoff-${e.handoffId}`);let n=ie?.clearHandoff(e.handoffId);n&&await Promise.allSettled(n.targetIds.map(e=>f.closePage(e)))},onDismiss:async e=>{let t=ie?.clearHandoff(e.handoffId);t&&await Promise.allSettled(t.targetIds.map(e=>f.closePage(e)))}}),l.panels.chat.setDeleteQueuedMessageCallback(e=>{if(_){T.deleteQueuedMessage(_.jid,e).catch(t=>{$.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=b.get(_.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),$.info(`Cone agent handle wired to chat UI`);let{getLickManager:oe}=await y(async()=>{let{getLickManager:e}=await import(`./lick-manager-Cm93KfGK.js`);return{getLickManager:e}},[]),se=oe();await se.init(),T.setLickManager(se);let ce=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;if($.debug(`Lick event`,{type:e.type,name:r,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&localStorage.setItem(`slicc-welcomed`,`1`),n===`shortcut-migrate`&&O?.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&D&&CX(D).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(n&&e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){(async()=>{try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await SX(t),O?.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),O?.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}})();return}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};S(s.jid).push({id:o,role:`user`,content:c,timestamp:Date.now(),source:`lick`,channel:a}),_?.jid===s.jid&&l.panels.chat.addLickMessage(o,c,a),$.info(`Routing lick to scoop`,{type:a,name:r,scoopJid:s.jid}),T.handleMessage(u)}else $.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};se.setEventHandler(ce),l.panels.chat.onInlineSprinkleLick=(e,t)=>{ce({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let O=null;if(D){if(O=new hX(D,ce,{addSprinkle:(e,t,n,r)=>l.addSprinkle(e,t,n,r),removeSprinkle:e=>l.removeSprinkle(e)}),window.__slicc_sprinkleManager=O,window.__slicc_reloadSkills=()=>T.reloadAllSkills(),await O.refresh(),l.onSprinkleClose=e=>O.close(e),l.getAvailableSprinkles=()=>{let e=new Set(O.opened());return O.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},l.onOpenSprinkle=(e,t)=>O.open(e,t),l.updateAddButtons(),!localStorage.getItem(`slicc-welcomed`)&&!c(window.localStorage)&&O.available().some(e=>e.name===`welcome`))try{await O.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}await O.restoreOpenSprinkles(),$.info(`SprinkleManager initialized`)}let le=()=>{let e=nX(window.location.href),t=new WebSocket(e);t.onopen=()=>{$.info(`Lick WebSocket connected`)},t.onmessage=async e=>{try{let n=JSON.parse(e.data);if(n.requestId){let e;try{switch(n.type){case`list_webhooks`:e={type:`response`,requestId:n.requestId,data:se.listWebhooks()};break;case`create_webhook`:{let t=await se.createWebhook(n.name||`default`,n.scoop,n.filter),r=qU().session,i=r?.webhookUrl?iX(r.webhookUrl,t.id):rX(window.location.href,t.id);e={type:`response`,requestId:n.requestId,data:{...t,url:i}};break}case`delete_webhook`:e=await se.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:se.listCronTasks()};break;case`create_crontask`:{if(!n.name)throw Error(`name is required`);if(!n.cron)throw Error(`cron is required`);let t=await se.createCronTask(n.name,n.cron,n.scoop,n.filter);e={type:`response`,requestId:n.requestId,data:t};break}case`delete_crontask`:e=await se.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`&&se.handleWebhookEvent(n.webhookId,n.headers,n.body),n.type===`handoff_event`&&ie&&ie.injectHandoff(n.payload,n.sourceUrl)}catch(e){$.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{$.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(le,3e3)},t.onerror=e=>{$.error(`Lick WebSocket error`,{error:String(e)})}};le(),l.onModelChange=e=>{localStorage.setItem(`selected-model`,e),T.updateModel()},l.onClearChat=async()=>{await T.clearAllMessages(),b.clear()},l.onClearFilesystem=async()=>{await T.resetFilesystem()};let ue=async e=>{$.info(`Scoop selected`,{jid:e.jid,name:e.name}),_=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=b.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};S(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`};S(e.jid).push(t),l.panels.chat.addUserMessage(t.content)}else n.fromAssistant?(h({type:`message_start`,messageId:n.id}),h({type:`content_delta`,messageId:n.id,text:n.content}),h({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=ue,_&&(T.createScoopTab(_.jid),await ue(_)),ie=new yX({onPendingHandoffsChange:p}),o===`standalone`||o===`electron-overlay`){let e=await i(),t=$Y(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;LG(()=>re?(e,t)=>re.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),VH(()=>re?()=>re.getBestFollowerForTeleport():null),HH(()=>re?()=>re.getConnectedFollowers():null);let u=e=>{c&&=(clearInterval(c),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new ZY(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(),$.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},p=e=>{a?.cancel(),c&&=(clearInterval(c),null),r?.close(),r=null,a=TY({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:tW()},{onConnected:e=>u(e),onReconnecting:e=>{$.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{$.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{p(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{c&&clearInterval(c),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)p(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new YY({browserTransport:f.getTransport(),browserAPI:f,getMessages:()=>l.panels.chat.getMessages(),getScoopJid:()=>_?.jid??`cone`,onFollowerMessage:(e,t)=>{l.panels.chat.addUserMessage(e),ae.sendMessage(e,t)},onFollowerAbort:()=>{ae.stop()}}),re=t,rW(()=>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 CY({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{$.info(`Tray follower data channel opened`,{controllerId:e.controllerId,bootstrapId:e.bootstrapId,attempt:e.attempt,runtime:e.runtime}),t.addFollower(e.bootstrapId,n,{runtime:e.runtime,connectedAt:e.connectedAt??void 0})}})};a(),m.add(e=>{t.broadcastEvent(e)}),e=new ZU({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:tW(),onControlMessage:e=>{if(e.type===`webhook.event`){se.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{$.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),oW(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=>{$.warn(`Leader tray join failed`,{error:e instanceof Error?e.message:String(e)})}),window.addEventListener(`beforeunload`,()=>{clearInterval(i),t.stop(),r.stop(),e.stop()},{once:!0})}}$.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:T.getScoops().length}),Vq().catch(()=>{})}OX().catch(e=>{$.error(`Fatal error`,e);let t=document.getElementById(`app`);if(t){let n=document.createElement(`div`);n.style.cssText=`padding: 2rem; text-align: center;`;let r=document.createElement(`h1`);r.style.color=`var(--s2-negative, #e34850)`,r.textContent=`Failed to start`;let i=document.createElement(`p`);i.style.color=`var(--s2-content-tertiary, #717171)`,i.textContent=e.message,n.appendChild(r),n.appendChild(i);let a=document.createElement(`button`);for(a.textContent=`Reset all data & reload`,a.style.cssText=`margin-top: 1rem; padding: 0.5rem 1.5rem; background: var(--s2-negative, #e34850); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 14px;`,a.addEventListener(`click`,async()=>{a.disabled=!0,a.textContent=`Resetting…`;let e=await indexedDB.databases();await Promise.all(e.map(e=>e.name?new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()}):Promise.resolve())),location.reload()}),n.appendChild(a);t.firstChild;)t.removeChild(t.firstChild);t.appendChild(n)}});export{vV as a,li as c,$q as i,tY as n,ui as o,rY as r,fi as s,eY as t};
14219
+ `,document.head.appendChild(t),window.addEventListener(`message`,e=>{e.source===window.parent&&SX(e.data)&&l.setActiveTab(_X(`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=HX();await l.panels.chat.initSession(`session-cone`),$.info(`Session initialized`);let f=new ke,p=e=>{l.setPendingHandoffCount(e.length),l.panels.chat.setPendingHandoffs(e)},m=new Set,h=e=>{$.debug(`Emit to UI`,{type:e.type,listenerCount:m.size});for(let t of m)try{t(e)}catch(t){$.error(`Listener error`,{eventType:e.type,error:t instanceof Error?t.message:String(t)})}},_=null,v=new Map,b=new Map;function x(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function S(e){let t=b.get(e);return t||(t=[],b.set(e,t)),t}function C(e,t){let n=S(e),r=v.get(e);if(r){let e=n.find(e=>e.id===r);if(e)return e}r=`scoop-${e}-${x()}`,v.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),_?.jid===e&&h({type:`message_start`,messageId:r}),o}let T=new SY(l.getIframeContainer(),{onResponse:(e,t,n)=>{let r=C(e);n?r.content+=t:(r.content=t,r.isStreaming=!1),_?.jid===e&&(h({type:`content_delta`,messageId:r.id,text:t}),n||h({type:`content_done`,messageId:r.id}))},onResponseDone:e=>{let t=S(e),n=v.get(e);if(n){let r=t.find(e=>e.id===n);r&&(r.isStreaming=!1),_?.jid===e&&h({type:`content_done`,messageId:n}),v.delete(e)}},onSendMessage:(e,t)=>{$.debug(`Send message requested`,{targetJid:e,textLength:t.length});let n=`msg-${x()}`,r={id:n,chatJid:e,senderId:`assistant`,senderName:`sliccy`,content:t,timestamp:new Date().toISOString(),fromAssistant:!0,channel:`web`};T.handleMessage(r),S(e).push({id:n,role:`assistant`,content:t,timestamp:Date.now()}),_?.jid===e&&(h({type:`message_start`,messageId:n}),h({type:`content_delta`,messageId:n,text:t}),h({type:`content_done`,messageId:n}))},onStatusChange:(e,t)=>{if(l.panels.scoops.updateScoopStatus(e,t),l.updateScoopSwitcherStatus?.(e,t),_?.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=v.get(e)??`done-${e}-${x()}`;v.delete(e),h({type:`turn_end`,messageId:t})}}},onError:(e,t)=>{$.error(`Scoop error`,{scoopJid:e,error:t}),_?.jid===e&&h({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:x(),name:t,input:n}),_?.jid===e&&h({type:`tool_use_start`,messageId:r.id,toolName:t,toolInput:n})},onToolEnd:(e,t,n,r)=>{if(new Set([`send_message`,`list_scoops`,`list_tasks`]).has(t))return;let i=S(e),a=v.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)}}_?.jid===e&&a&&h({type:`tool_result`,messageId:a,toolName:t,result:n,isError:r})},onToolUI:(e,t,n,r)=>{let i=v.get(e);i?h({type:`tool_ui`,messageId:i,toolName:t,requestId:n,html:r}):$.warn(`Cannot emit tool_ui - no message ID for scoop`,{scoopJid:e,requestId:n})},onToolUIDone:(e,t)=>{let n=v.get(e);n&&h({type:`tool_ui_done`,messageId:n,requestId:t})},onIncomingMessage:(e,t)=>{let n={id:t.id,role:`user`,content:t.channel===`delegation`?`**[Instructions from sliccy]**\n\n${t.content}`:t.content,timestamp:new Date(t.timestamp).getTime(),source:t.channel===`delegation`?`delegation`:void 0,channel:t.channel};S(e).push(n),_?.jid===e&&(h({type:`message_start`,messageId:t.id}),h({type:`content_delta`,messageId:t.id,text:n.content}),h({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),$.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`)||$.error(`Preview VFS read failed`,{path:r,error:i}),e.postMessage({type:`preview-vfs-response`,id:n,error:i})}})()},UX(D,(e,t)=>{t===`error`?$.warn(`Dropped skill install failed`,{message:e}):$.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-CYFx3OEI.js`);return{WasmShell:e}},[]),t=new e({fs:D,browserAPI:f});await l.panels.terminal.mountShell(t),$.info(`Terminal mounted with shared VFS`);try{let{BshWatchdog:e}=await y(async()=>{let{BshWatchdog:e}=await import(`./bsh-watchdog-DOU_MEY1.js`);return{BshWatchdog:e}},__vite__mapDeps([23,14])),t=new e({browserAPI:f,fs:D});t.start(),window.addEventListener(`beforeunload`,()=>t.stop(),{once:!0}),$.info(`BSH navigation watchdog started`)}catch(e){$.warn(`Failed to start BSH watchdog`,e)}}catch(e){$.warn(`Failed to mount shell to terminal`,e)}}let ee=T.getScoops(),te=ee.some(e=>e.isCone);if(r)$.info(`Skipping local cone bootstrap while joining a tray without a configured provider`);else if(!te)_=await l.panels.scoops.createScoop(`Cone`,!0),$.info(`Created cone`);else{let e=new URLSearchParams(window.location.search).get(`scoop`);if(e){let t=ee.find(t=>t.folder===e);t?(_=t,$.info(`Restored scoop from URL`,{folder:e})):_=ee.find(e=>e.isCone)??ee[0]}else _=ee.find(e=>e.isCone)??ee[0]}_&&l.panels.memory.setSelectedScoop(_.jid);let re=null,ie=null,ae={sendMessage(e,t){if(!_){h({type:`error`,error:`No scoop selected`});return}let n={id:t??`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,chatJid:_.jid,senderId:`user`,senderName:`User`,content:e,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};S(_.jid).push({id:n.id,role:`user`,content:e,timestamp:Date.now()}),re?.broadcastUserMessage(e,n.id),T.handleMessage(n),T.createScoopTab(_.jid)},onEvent(e){return m.add(e),()=>m.delete(e)},stop(){_&&(T.stopScoop(_.jid),T.clearQueuedMessages(_.jid).catch(e=>{$.error(`Failed to clear queued messages on stop`,{error:e instanceof Error?e.message:String(e)})}))}};l.panels.chat.setAgent(ae),l.panels.chat.setPendingHandoffActions({onAccept:async e=>{let t=T.getScoops().find(e=>e.isCone);if(!t){$.warn(`Cannot accept handoff without a cone scoop`,{handoffId:e.handoffId});return}await ue(t),l.setActiveTab(`chat`),ae.sendMessage(PX(e),`handoff-${e.handoffId}`);let n=ie?.clearHandoff(e.handoffId);n&&await Promise.allSettled(n.targetIds.map(e=>f.closePage(e)))},onDismiss:async e=>{let t=ie?.clearHandoff(e.handoffId);t&&await Promise.allSettled(t.targetIds.map(e=>f.closePage(e)))}}),l.panels.chat.setDeleteQueuedMessageCallback(e=>{if(_){T.deleteQueuedMessage(_.jid,e).catch(t=>{$.error(`Failed to delete queued message`,{messageId:e,error:t instanceof Error?t.message:String(t)})});let t=b.get(_.jid);if(t){let n=t.findIndex(t=>t.id===e);n!==-1&&t.splice(n,1)}}}),$.info(`Cone agent handle wired to chat UI`);let{getLickManager:oe}=await y(async()=>{let{getLickManager:e}=await import(`./lick-manager-D6KPEPCp.js`);return{getLickManager:e}},[]),se=oe();await se.init(),T.setLickManager(se);let ce=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;if($.debug(`Lick event`,{type:e.type,name:r,targetScoop:e.targetScoop}),n&&e.sprinkleName===`welcome`){let t=e.body,n=t?.action;(n===`onboarding-complete`||n===`shortcut-migrate`)&&localStorage.setItem(`slicc-welcomed`,`1`),n===`shortcut-migrate`&&O?.close(`welcome`),n===`onboarding-complete`&&t?.data?.mountWorkspace&&D&&BX(D).catch(e=>$.warn(`Failed to mount workspace from onboarding`,e))}if(n&&e.sprinkleName===`welcome`&&e.body?.action===`request-mount`){(async()=>{try{let e=window;if(!e.showDirectoryPicker)throw Error(`showDirectoryPicker not supported`);let t=await e.showDirectoryPicker({mode:`readwrite`});await zX(t),O?.sendToSprinkle(`welcome`,{action:`mount-complete`,dirName:t.name})}catch(e){e.name!==`AbortError`&&$.warn(`Mount picker failed`,e),O?.sendToSprinkle(`welcome`,{action:`mount-cancelled`})}})();return}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};S(s.jid).push({id:o,role:`user`,content:c,timestamp:Date.now(),source:`lick`,channel:a}),_?.jid===s.jid&&l.panels.chat.addLickMessage(o,c,a),$.info(`Routing lick to scoop`,{type:a,name:r,scoopJid:s.jid}),T.handleMessage(u)}else $.warn(`Lick target scoop not found`,{targetScoop:e.targetScoop})};se.setEventHandler(ce),l.panels.chat.onInlineSprinkleLick=(e,t)=>{ce({type:`sprinkle`,sprinkleName:`inline`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{action:e,data:t}})};let O=null;if(D){if(O=new MX(D,ce,{addSprinkle:(e,t,n,r)=>l.addSprinkle(e,t,n,r),removeSprinkle:e=>l.removeSprinkle(e)}),window.__slicc_sprinkleManager=O,window.__slicc_reloadSkills=()=>T.reloadAllSkills(),await O.refresh(),l.onSprinkleClose=e=>O.close(e),l.getAvailableSprinkles=()=>{let e=new Set(O.opened());return O.available().filter(t=>!e.has(t.name)).map(e=>({name:e.name,title:e.title}))},l.onOpenSprinkle=(e,t)=>O.open(e,t),l.updateAddButtons(),!localStorage.getItem(`slicc-welcomed`)&&!c(window.localStorage)&&O.available().some(e=>e.name===`welcome`))try{await O.open(`welcome`)}catch(e){$.warn(`Failed to open welcome sprinkle`,e)}await O.restoreOpenSprinkles(),$.info(`SprinkleManager initialized`)}let le=()=>{let e=yX(window.location.href),t=new WebSocket(e);t.onopen=()=>{$.info(`Lick WebSocket connected`)},t.onmessage=async e=>{try{let n=JSON.parse(e.data);if(n.requestId){let e;try{switch(n.type){case`list_webhooks`:e={type:`response`,requestId:n.requestId,data:se.listWebhooks()};break;case`create_webhook`:{let t=await se.createWebhook(n.name||`default`,n.scoop,n.filter),r=JU().session,i=r?.webhookUrl?xX(r.webhookUrl,t.id):bX(window.location.href,t.id);e={type:`response`,requestId:n.requestId,data:{...t,url:i}};break}case`delete_webhook`:e=await se.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:se.listCronTasks()};break;case`create_crontask`:{if(!n.name)throw Error(`name is required`);if(!n.cron)throw Error(`cron is required`);let t=await se.createCronTask(n.name,n.cron,n.scoop,n.filter);e={type:`response`,requestId:n.requestId,data:t};break}case`delete_crontask`:e=await se.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=JU();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`&&se.handleWebhookEvent(n.webhookId,n.headers,n.body),n.type===`handoff_event`&&ie&&ie.injectHandoff(n.payload,n.sourceUrl)}catch(e){$.error(`Failed to process lick message`,{error:e instanceof Error?e.message:String(e)})}},t.onclose=()=>{$.warn(`Lick WebSocket disconnected, reconnecting in 3s...`),setTimeout(le,3e3)},t.onerror=e=>{$.error(`Lick WebSocket error`,{error:String(e)})}};le(),l.onModelChange=e=>{localStorage.setItem(`selected-model`,e),T.updateModel()},l.onClearChat=async()=>{await T.clearAllMessages(),b.clear()},l.onClearFilesystem=async()=>{await T.resetFilesystem()};let ue=async e=>{$.info(`Scoop selected`,{jid:e.jid,name:e.name}),_=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=b.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};S(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`};S(e.jid).push(t),l.panels.chat.addUserMessage(t.content)}else n.fromAssistant?(h({type:`message_start`,messageId:n.id}),h({type:`content_delta`,messageId:n.id,text:n.content}),h({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=ue,_&&(T.createScoopTab(_.jid),await ue(_)),ie=new IX({onPendingHandoffsChange:p}),o===`standalone`||o===`electron-overlay`){let e=await i(),t=gX(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;RG(()=>re?(e,t)=>re.sendFsRequest(e,t):r?(e,t)=>r.sendFsRequest(e,t):null),VH(()=>re?()=>re.getBestFollowerForTeleport():null),HH(()=>re?()=>re.getConnectedFollowers():null);let u=e=>{c&&=(clearInterval(c),null),r?.close();let t=`follower-${e.bootstrapId}`,n=new mX(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(),$.info(`Follower sync wired to chat panel`,{trayId:e.trayId})},p=e=>{a?.cancel(),c&&=(clearInterval(c),null),r?.close(),r=null,a=HY({joinUrl:e,runtime:`slicc-standalone`,fetchImpl:nW()},{onConnected:e=>u(e),onReconnecting:e=>{$.info(`Follower reconnecting`,{attempt:e})},onGaveUp:e=>{$.warn(`Follower reconnect gave up`,{lastError:e})}})};if(window.addEventListener(`slicc:tray-join`,(e=>{p(e.detail.joinUrl)})),window.addEventListener(`beforeunload`,()=>{c&&clearInterval(c),r?.close(),a?.cancel()},{once:!0}),n?.joinUrl)p(n.joinUrl);else if(n?.workerBaseUrl){let e,t,r,i,a=()=>{t=new fX({browserTransport:f.getTransport(),browserAPI:f,getMessages:()=>l.panels.chat.getMessages(),getScoopJid:()=>_?.jid??`cone`,onFollowerMessage:(e,t)=>{l.panels.chat.addUserMessage(e),ae.sendMessage(e,t)},onFollowerAbort:()=>{ae.stop()}}),re=t,iW(()=>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 BY({sendControlMessage:t=>e.sendControlMessage(t),onPeerConnected:(e,n)=>{$.info(`Tray follower data channel opened`,{controllerId:e.controllerId,bootstrapId:e.bootstrapId,attempt:e.attempt,runtime:e.runtime}),t.addFollower(e.bootstrapId,n,{runtime:e.runtime,connectedAt:e.connectedAt??void 0})}})};a(),m.add(e=>{t.broadcastEvent(e)}),e=new QU({workerBaseUrl:n.workerBaseUrl,runtime:`slicc-standalone`,fetchImpl:nW(),onControlMessage:e=>{if(e.type===`webhook.event`){se.handleWebhookEvent(e.webhookId,e.headers,e.body);return}r.handleControlMessage(e).catch(e=>{$.warn(`Tray leader bootstrap handling failed`,{error:e instanceof Error?e.message:String(e)})})}}),sW(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(),JU()}),e.start().then(e=>{let t=d(window.location.href,e.workerBaseUrl,e.trayId);t!==window.location.href&&window.history.replaceState(window.history.state,``,t)}).catch(e=>{$.warn(`Leader tray join failed`,{error:e instanceof Error?e.message:String(e)})}),window.addEventListener(`beforeunload`,()=>{clearInterval(i),t.stop(),r.stop(),e.stop()},{once:!0})}}$.info(`Orchestrator initialized — cone+scoops ready`,{scoopCount:T.getScoops().length}),iJ().catch(()=>{})}GX().catch(e=>{$.error(`Fatal error`,e);let t=document.getElementById(`app`);if(t){let n=document.createElement(`div`);n.style.cssText=`padding: 2rem; text-align: center;`;let r=document.createElement(`h1`);r.style.color=`var(--s2-negative, #e34850)`,r.textContent=`Failed to start`;let i=document.createElement(`p`);i.style.color=`var(--s2-content-tertiary, #717171)`,i.textContent=e.message,n.appendChild(r),n.appendChild(i);let a=document.createElement(`button`);for(a.textContent=`Reset all data & reload`,a.style.cssText=`margin-top: 1rem; padding: 0.5rem 1.5rem; background: var(--s2-negative, #e34850); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 14px;`,a.addEventListener(`click`,async()=>{a.disabled=!0,a.textContent=`Resetting…`;let e=await indexedDB.databases();await Promise.all(e.map(e=>e.name?new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()}):Promise.resolve())),location.reload()}),n.appendChild(a);t.firstChild;)t.removeChild(t.firstChild);t.appendChild(n)}});export{vV as a,li as c,gJ as i,vY as n,ui as o,bY as r,fi as s,_Y as t};