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.
- package/dist/ui/assets/{cdp-DhV8bm4P.js → cdp-D7T7EeS9.js} +14 -2
- package/dist/ui/assets/{index-GgBfVMPy.js → index-uTGW51Kt.js} +279 -193
- package/dist/ui/assets/lick-manager-D6KPEPCp.js +1 -0
- package/dist/ui/assets/provider-settings-Bkf2ADq8.js +1 -0
- package/dist/ui/assets/shell-CYFx3OEI.js +1 -0
- package/dist/ui/assets/sprinkle-renderer-9SeK_akJ.js +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/ui/packages/webapp/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/lick-manager-Cm93KfGK.js +0 -1
- package/dist/ui/assets/provider-settings-YOjGG5m2.js +0 -1
- package/dist/ui/assets/shell-o0ztF_0C.js +0 -1
- package/dist/ui/assets/sprinkle-renderer-Dlqdvfe5.js +0 -1
|
@@ -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-
|
|
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-
|
|
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={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},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
|
|
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
|
-
}`,
|
|
2410
|
+
}`,QH=`function() {
|
|
2411
2411
|
const el = this;
|
|
2412
2412
|
if (el.isContentEditable) return el.textContent || '';
|
|
2413
2413
|
return el.value ?? '';
|
|
2414
|
-
}
|
|
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
|
|
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-${
|
|
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
|
|
2443
|
-
`)
|
|
2444
|
-
`)
|
|
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}),
|
|
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
|
|
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
|
|
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
|
|
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: ${
|
|
2571
|
-
`}}function
|
|
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}=
|
|
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=
|
|
2577
|
-
`,stderr:``,exitCode:0};break}let e=
|
|
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}),
|
|
2580
|
-
`,exitCode:1};break}let e=
|
|
2581
|
-
`,stderr:``,exitCode:0};break}case`
|
|
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=
|
|
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=
|
|
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=
|
|
2596
|
-
`,exitCode:1};break}let e=
|
|
2597
|
-
|
|
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 (${
|
|
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(
|
|
2622
|
+
const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
|
|
2604
2623
|
if (!el) return '';
|
|
2605
|
-
return (${
|
|
2624
|
+
return (${QH}).call(el);
|
|
2606
2625
|
})()`)!==r&&await t.evaluate(`(function() {
|
|
2607
|
-
const el = document.querySelector(${JSON.stringify(
|
|
2626
|
+
const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
|
|
2608
2627
|
if (!el) return;
|
|
2609
|
-
(${
|
|
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=
|
|
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=
|
|
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=
|
|
2617
|
-
`,stderr:``,exitCode:0};break}case`go-forward`:{let e=
|
|
2618
|
-
`,stderr:``,exitCode:0};break}case`reload`:{let e=
|
|
2619
|
-
`,stderr:``,exitCode:0};break}case`tab-list`:{let e=await
|
|
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=
|
|
2623
|
-
`,exitCode:1};break}let e=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
2637
|
-
`,stderr:``,exitCode:0};break}case`cookie-list`:{let e=
|
|
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=
|
|
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=
|
|
2644
|
-
`,exitCode:1};break}let e=
|
|
2645
|
-
`,stderr:``,exitCode:0};break}case`localstorage-list`:{let e=
|
|
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=
|
|
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=
|
|
2651
|
-
`,exitCode:1};break}let e=
|
|
2652
|
-
`,stderr:``,exitCode:0};break}case`sessionstorage-list`:{let e=
|
|
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=
|
|
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=
|
|
2658
|
-
`,exitCode:1};break}let e=
|
|
2659
|
-
`,stderr:``,exitCode:0};break}case`record`:{let e=c[0]||`about:blank`,r=l.filter;await
|
|
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;
|
|
2661
|
-
`);let i=[];for(let[e,t]of
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
2698
|
-
`)}\n`}function
|
|
2699
|
-
`)}\n`}function
|
|
2700
|
-
`,exitCode:1};let a=n();return a.state===`inactive`?{stdout:
|
|
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
|
-
`+
|
|
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
|
|
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
|
|
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
|
-
`,
|
|
2733
|
-
`,stderr:``,exitCode:0}}function
|
|
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(
|
|
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,
|
|
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
|
|
2786
|
-
`,exitCode:1};let n=e.includes(`--download`)||e.includes(`-d`),r=e.includes(`--view`)||e.includes(`-v`),i=e.filter(e=>!
|
|
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
|
|
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
|
|
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
|
|
2815
|
-
`,stderr:``,exitCode:0}}if(a===`cat`){let a=await
|
|
2816
|
-
`,stderr:``,exitCode:0}}function
|
|
2817
|
-
`,stderr:``,exitCode:0}}function
|
|
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(
|
|
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
|
|
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
|
|
2831
|
-
`,exitCode:1};let a=
|
|
2832
|
-
`,stderr:``,exitCode:0}}function
|
|
2833
|
-
`)}\n`:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function
|
|
2834
|
-
`,stderr:``,exitCode:0}}function
|
|
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
|
|
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
|
|
2889
|
+
`,stderr:``,exitCode:0}}function gG(e){return e.replace(/<[^>]*>/g,``).replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`).replace(/ /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:
|
|
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
|
|
2843
|
-
`,stderr:``,exitCode:0}}function
|
|
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(!
|
|
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
|
|
2863
|
-
`,exitCode:1};let{ok:s,data:c}=await
|
|
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
|
|
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
|
|
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(
|
|
2902
|
-
`,exitCode:1};let e=
|
|
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
|
|
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(
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
2995
|
-
`,stderr:``,exitCode:0}}function
|
|
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(/^\.\//,``))||
|
|
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
|
|
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
|
|
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=
|
|
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,${
|
|
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
|
|
3071
|
+
`,stderr:``,exitCode:0}}function mK(){return{stdout:`usage: pbpaste
|
|
3022
3072
|
|
|
3023
3073
|
Paste clipboard contents to stdout.
|
|
3024
|
-
`,stderr:``,exitCode:0}}function
|
|
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
|
|
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
|
|
3035
|
-
`,exitCode:1};if(e.includes(`--list`))return{stdout:(await
|
|
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
|
|
3042
|
-
`,exitCode:1};let o=new SpeechSynthesisUtterance(a);if(o.rate=n,o.lang=r,t){let e=(await
|
|
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
|
|
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(!
|
|
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?
|
|
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}:
|
|
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
|
|
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
|
|
3072
|
-
`}function
|
|
3073
|
-
`}function
|
|
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)} ${
|
|
3076
|
-
`;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function
|
|
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
|
-
${
|
|
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
|
|
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/
|
|
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
|
|
3136
|
-
`,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(
|
|
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
|
|
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=
|
|
3140
|
-
`,{stdout:s,stderr:``,exitCode:0}}function
|
|
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
|
|
3143
|
-
`,exitCode:1};let r=await
|
|
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
|
-
${
|
|
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${
|
|
3165
|
-
`,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:
|
|
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&&!
|
|
3169
|
-
`,exitCode:1};let r=await i.getSkillInfo(e,n);if(r&&!
|
|
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,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}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>${
|
|
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
|
|
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,
|
|
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
|
|
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=`${
|
|
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
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
|
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
|
|
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
|
|
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&&
|
|
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=
|
|
14121
|
-
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}var
|
|
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`};
|
|
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};
|