sliccy 2.56.0 → 3.0.1
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/adobe-D7FAx1Pl.js +2 -0
- package/dist/ui/assets/adobe-DDmxwGXD.js +1 -0
- package/dist/ui/assets/{agent-bridge-DxRah7QA.js → agent-bridge-BK6W3qJh.js} +1 -1
- package/dist/ui/assets/{agent-message-to-chat-BpcmXkzt.js → agent-message-to-chat-BVeCeF6Q.js} +1 -1
- package/dist/ui/assets/{azure-openai-PWmjqnnu.js → azure-openai-7pTcClzw.js} +1 -1
- package/dist/ui/assets/{azure-openai-C3jQCjj8.js → azure-openai-bWhlMin-.js} +1 -1
- package/dist/ui/assets/{bedrock-camp-DChwr7KC.js → bedrock-camp-Bds6qFqf.js} +1 -1
- package/dist/ui/assets/bedrock-camp-uPFt7YMZ.js +5 -0
- package/dist/ui/assets/{cdp-DWT2l8bP.js → cdp-BuJISenS.js} +1 -1
- package/dist/ui/assets/cost-command-Bt8tDgf-.js +1 -0
- package/dist/ui/assets/{es-DNsspHsb.js → es-DuN0Jsb9.js} +1 -1
- package/dist/ui/assets/{fs-DSB_5PK0.js → fs-DDc-eOO2.js} +1 -1
- package/dist/ui/assets/{fs-C9P3Nfvq.js → fs-DJesPCjN.js} +2 -2
- package/dist/ui/assets/{github-BthdVOch.js → github-Be-voIch.js} +1 -1
- package/dist/ui/assets/github-G9n4Zw-j.js +2 -0
- package/dist/ui/assets/{index-CTzhOMSf.js → index-C4J34n8d.js} +5 -5
- package/dist/ui/assets/{kernel-worker-DQl_BcO3.js → kernel-worker-DkfabjjT.js} +344 -329
- package/dist/ui/assets/{local-llm-CjP7smbg.js → local-llm-BdgJqTmS.js} +1 -1
- package/dist/ui/assets/{local-llm-4QCHSjR3.js → local-llm-Bz5hi9oX.js} +1 -1
- package/dist/ui/assets/{mount-D1VXEtPM.js → mount-CPqnWW5n.js} +2 -2
- package/dist/ui/assets/{mount-D7zeWCcE.js → mount-D2PnDqUD.js} +1 -1
- package/dist/ui/assets/{nuke-command-6iDUjrgH.js → nuke-command-h2Qa6iv1.js} +1 -1
- package/dist/ui/assets/{oauth-bootstrap-CCaF1mhA.js → oauth-bootstrap-R3f3d8xI.js} +1 -1
- package/dist/ui/assets/{offscreen-client-BZIuqCtj.js → offscreen-client-CX6UYAF6.js} +1 -1
- package/dist/ui/assets/{onboarding-orchestrator-wblO8A6r.js → onboarding-orchestrator-Cr3CYPo4.js} +1 -1
- package/dist/ui/assets/{panel-rpc-handlers-C7GqtNpD.js → panel-rpc-handlers-Dgo2AAUu.js} +1 -1
- package/dist/ui/assets/provider-settings-C7vl_UXi.js +28 -0
- package/dist/ui/assets/provider-settings-CRaSBF8A.js +63 -0
- package/dist/ui/assets/{providers-DSe5NWr6.js → providers-wxzKgKGa.js} +1 -1
- package/dist/ui/assets/{spawn-Cg0_PKqL.js → spawn-htSrwEAJ.js} +1 -1
- package/dist/ui/assets/upgrade-detection-DonNu3ys.js +1 -0
- package/dist/ui/assets/{xai-grok-cGh8uXu4.js → xai-grok-CdzXrygZ.js} +1 -1
- package/dist/ui/assets/{xai-grok-CiMn_9LI.js → xai-grok-DA45ToJz.js} +1 -1
- package/dist/ui/index.html +5 -5
- package/dist/ui/packages/webapp/index.html +5 -5
- package/package.json +1 -1
- package/dist/ui/assets/adobe-NRB0tB6W.js +0 -1
- package/dist/ui/assets/adobe-QXZCy565.js +0 -2
- package/dist/ui/assets/bedrock-camp-prTmQ4PG.js +0 -5
- package/dist/ui/assets/cost-command-G_pajegS.js +0 -1
- package/dist/ui/assets/github-CR01A3Pd.js +0 -2
- package/dist/ui/assets/provider-settings-C_bHAv6F.js +0 -63
- package/dist/ui/assets/provider-settings-CyRPUAEx.js +0 -28
- package/dist/ui/assets/upgrade-detection-DSxLFlVR.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e,o as t,r as n,t as r}from"./chunk-jRWAZmH_.js";import{t as i}from"./logger-BHrAkMIS.js";import{S as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,l as h,m as g,n as _,o as v,p as y,r as b,s as x,t as S,u as C,v as w,x as T,y as E}from"./db-DPvmo9md.js";import{C as D,S as O,_ as ee,b as te,c as ne,d as k,g as re,h as ie,m as ae,n as oe,p as se,r as ce,u as le,v as ue,x as de,y as fe}from"./provider-settings-
|
|
1
|
+
import{i as e,o as t,r as n,t as r}from"./chunk-jRWAZmH_.js";import{t as i}from"./logger-BHrAkMIS.js";import{S as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,l as h,m as g,n as _,o as v,p as y,r as b,s as x,t as S,u as C,v as w,x as T,y as E}from"./db-DPvmo9md.js";import{C as D,S as O,_ as ee,b as te,c as ne,d as k,g as re,h as ie,m as ae,n as oe,p as se,r as ce,u as le,v as ue,x as de,y as fe}from"./provider-settings-CRaSBF8A.js";import{a as A,o as pe,t as me}from"./tool-ui-D9h6SJkp.js";import{i as he,n as ge,r as _e}from"./fs-DDc-eOO2.js";import{i as ve,n as ye,r as be,t as xe}from"./backend-local-BTd37iLF.js";import{n as j,t as Se}from"./path-utils-CgbXfwyO.js";import{t as Ce}from"./mount-id-Ccy4_G8i.js";import{n as we}from"./mount-table-store-BDnU4NqG.js";import{a as Te,i as Ee,r as M,t as De}from"./git-config-CxvDN7N3.js";import{n as N,t as P}from"./panel-rpc-uLhnFoXD.js";import{n as Oe,t as ke}from"./mime-types-4JXpZe6p.js";import{_ as Ae,a as je,c as Me,d as Ne,f as Pe,g as Fe,h as Ie,i as Le,l as Re,m as ze,o as Be,p as Ve,r as He,s as Ue,t as We,u as Ge,v as Ke}from"./magick-wasm-BMFWa7e1.js";import{a as qe,s as Je}from"./bedrock-camp-uPFt7YMZ.js";import{f as Ye}from"./simple-options-CVJdKrCb.js";import{i as Xe}from"./providers-wxzKgKGa.js";import{t as Ze}from"./local-llm-BdgJqTmS.js";import{a as Qe,i as $e,n as et,r as tt}from"./mount-D2PnDqUD.js";import{t as nt}from"./remote-cache-Cd8CL8Mo.js";const rt=i(`cdp`);var it=class{ws=null;nextId=1;pending=new Map;listeners=new Map;_state=`disconnected`;get state(){return this._state}async connect(e){if(this._state!==`disconnected`)throw Error(`Cannot connect: state is ${this._state}`);if(!e?.url)throw Error(`CDPClient.connect() requires a WebSocket URL`);let{url:t,timeout:n=5e3}=e;return this._state=`connecting`,new Promise((e,r)=>{let i=setTimeout(()=>{this.cleanup(),r(Error(`CDP connection timed out after ${n}ms`))},n);try{this.ws=new WebSocket(t)}catch(e){clearTimeout(i),this._state=`disconnected`,r(e);return}this.ws.onopen=()=>{clearTimeout(i),this._state=`connected`,rt.info(`Connected`,{url:t}),e()},this.ws.onerror=e=>{clearTimeout(i),this._state===`connecting`&&(rt.error(`Connection failed`,{url:t}),this.cleanup(),r(Error(`CDP WebSocket connection failed`)))},this.ws.onmessage=e=>{this.handleMessage(e.data)},this.ws.onclose=()=>{this.handleClose()}})}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close()),this.cleanup(),rt.info(`Disconnected`)}async send(e,t,n,r=3e4){if(this._state!==`connected`||!this.ws)throw Error(`CDP client is not connected`);let i=this.nextId++,a={id:i,method:e};return t&&(a.params=t),n&&(a.sessionId=n),rt.debug(`Send`,{method:e,id:i,sessionId:n}),new Promise((t,n)=>{let o=setTimeout(()=>{this.pending.delete(i),n(Error(`CDP command timed out after ${r}ms: ${e}`))},r);this.pending.set(i,{resolve:e=>{clearTimeout(o),t(e)},reject:e=>{clearTimeout(o),n(e)}}),this.ws.send(JSON.stringify(a))})}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t=3e4){return new Promise((n,r)=>{let i=setTimeout(()=>{this.off(e,a),r(Error(`Timed out waiting for event: ${e}`))},t),a=t=>{clearTimeout(i),this.off(e,a),n(t)};this.on(e,a)})}handleMessage(e){let t;try{t=JSON.parse(e)}catch{return}if(`id`in t&&typeof t.id==`number`){let e=t;rt.debug(`Response`,{id:e.id,hasError:!!e.error});let n=this.pending.get(e.id);n&&(this.pending.delete(e.id),e.error?(rt.error(`Command error`,{id:e.id,code:e.error.code,message:e.error.message}),n.reject(Error(`CDP error: ${e.error.message} (${e.error.code})`))):n.resolve(e.result??{}));return}if(`method`in t){let e=t;rt.debug(`Event`,{method:e.method,sessionId:e.sessionId});let n=this.listeners.get(e.method);if(n){let t=e.sessionId?{...e.params,sessionId:e.sessionId}:e.params??{};for(let e of n)try{e(t)}catch{}}}}handleClose(){rt.error(`Connection closed unexpectedly`,{pendingCommands:this.pending.size});for(let[,e]of this.pending)e.reject(Error(`CDP connection closed`));this.cleanup()}cleanup(){this.ws=null,this._state=`disconnected`,this.pending.clear()}};function at(e,t=``){if(e==null)return t;if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)??t}catch{return String(e)}}const ot=`(function() {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
// ===== DOM Utilities =====
|
|
@@ -876,7 +876,7 @@ import{i as e,o as t,r as n,t as r}from"./chunk-jRWAZmH_.js";import{t as i}from"
|
|
|
876
876
|
this.scrollIntoView({ block: 'center', inline: 'center' });
|
|
877
877
|
const r = this.getBoundingClientRect();
|
|
878
878
|
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
879
|
-
}`,returnByValue:!0},this.sessionId)).result?.value;if(!n||n.width===0||n.height===0)throw Error(`Element with backend node ${e} has no dimensions`);return{x:n.x+n.width/2,y:n.y+n.height/2}}async ensureLocalConnected(){this.localClient.state===`disconnected`&&await this.localClient.connect({url:ct()})}async ensureConnected(){this.client.state===`disconnected`&&(this.remoteTargetInfo&&this.trayTargetProvider?.removeRemoteTransport&&(this.trayTargetProvider.removeRemoteTransport(this.remoteTargetInfo.runtimeId,this.remoteTargetInfo.localTargetId),this.setClient(this.localClient),this.remoteTargetInfo=null),this.sessionId=null,this.attachedTargetId=null,this.client.state===`disconnected`&&await this.connect())}ensureAttached(){if(!this.sessionId)throw Error(`Not attached to a page. Call attachToPage(targetId) first.`)}addDialogListener(e){e.on(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}removeDialogListener(e){e.off(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}setClient(e){this.client!==e&&(this.removeDialogListener(this.client),this.client=e,this.addDialogListener(this.client))}async boundingBox(e){await this.client.send(`DOM.enable`,{},this.sessionId);let t=(await this.client.send(`DOM.getDocument`,{depth:0},this.sessionId)).root.nodeId,n;try{n=(await this.client.send(`DOM.querySelector`,{nodeId:t,selector:e},this.sessionId)).nodeId}catch{return null}if(!n)return null;let r=(await this.client.send(`DOM.getBoxModel`,{nodeId:n},this.sessionId)).model;if(!r)return null;let i=r.content;return{x:i[0],y:i[1],width:r.width,height:r.height}}};function ut(e){let t={role:at(e.role,`unknown`),name:at(e.name)},n=at(e.value);n!==``&&(t.value=n);let r=at(e.description);return r!==``&&(t.description=r),Array.isArray(e.children)&&e.children.length>0&&(t.children=e.children.map(e=>ut(e)).filter(e=>e.role!==`unknown`)),t}function dt(e){return e.headers.get(`x-proxy-error`)===`1`}async function ft(e){let t=`Proxy error ${e.status}`,n;try{n=await e.text()}catch{return t}return pt(n,t)}function pt(e,t){let n;try{n=JSON.parse(e)}catch{return t}if(!n||typeof n!=`object`)return t;let r=n.error;if(typeof r==`string`&&r.length>0)return r;if(r&&typeof r==`object`){let e=r.message;if(typeof e==`string`&&e.length>0)return e;try{return JSON.stringify(r)}catch{return t}}return t}i(`tray-leader`);let mt={state:`inactive`,session:null,error:null};function ht(){return{...mt,session:mt.session?{...mt.session}:null}}const gt=new Set;function _t(e){return gt.add(e),()=>{gt.delete(e)}}const vt=new Set([`send_message`,`list_scoops`,`list_tasks`]),yt=`sessions`;function bt(){return new Promise((e,t)=>{let n=indexedDB.open(`browser-coding-agent`,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(yt)||e.createObjectStore(yt,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}var xt=class{db=null;async init(){this.db=await bt()}ensureDb(){if(!this.db)throw Error(`SessionStore not initialized. Call init() first.`);return this.db}async save(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readwrite`);i.objectStore(yt).put(e),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})}async load(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readonly`).objectStore(yt).get(e);i.onsuccess=()=>n(i.result??null),i.onerror=()=>r(i.error)})}async list(){let e=this.ensureDb();return new Promise((t,n)=>{let r=e.transaction(yt,`readonly`).objectStore(yt).getAll();r.onsuccess=()=>{t(r.result.sort((e,t)=>t.updatedAt-e.updatedAt).map(e=>e.id))},r.onerror=()=>n(r.error)})}async delete(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readwrite`);i.objectStore(yt).delete(e),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})}async saveMessages(e,t){let n=await this.load(e),r=n?{...n,messages:t,updatedAt:Date.now()}:{id:e,messages:t,createdAt:Date.now(),updatedAt:Date.now()};await this.save(r)}};const St=i(`panel-transport`);function Ct(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function wt(){return{onMessage:e=>{let t=(t,n,r)=>(Ct(t)&&e(t),!1);return chrome.runtime.onMessage.addListener(t),()=>chrome.runtime.onMessage.removeListener(t)},send:e=>{chrome.runtime.sendMessage({source:`offscreen`,payload:e}).catch(e=>{let t=e instanceof Error?e.message:String(e);/receiving end does not exist/i.test(t)||St.error(`Offscreen → panel transport send failed`,{error:t})})}}}var Tt=class{orchestrator=null;browserAPI=null;messageBuffers=new Map;currentMessageId=new Map;scoopStatuses=new Map;sessionStore=null;followerSync=null;_transport;transportUnsubscribe=null;constructor(e){this._transport=e??null}get transport(){return this._transport||=wt(),this._transport}async bind(e,t){this.orchestrator=e,this.browserAPI=t??null,this.transportUnsubscribe?.(),this.transportUnsubscribe=this.setupMessageListener();let n=new xt;await n.init(),this.sessionStore=n}static createCallbacks(e){return{onResponse:(t,n,r)=>{let i=e.getOrCreateAssistantMsg(t);r?i.content+=n:(i.content=n,i.isStreaming=!1),e.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:n})},onResponseDone:t=>{let n=e.currentMessageId.get(t);if(n){let r=e.getBuffer(t).find(e=>e.id===n);r&&(r.isStreaming=!1),e.currentMessageId.delete(t)}e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`})},onSendMessage:(t,n)=>{let r=e.getBuffer(t),i=`msg-${Et()}`;r.push({id:i,role:`assistant`,content:n,timestamp:Date.now()}),e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:n}),e.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`})},onStatusChange:(t,n)=>{e.scoopStatuses.set(t,n),n===`ready`&&e.currentMessageId.delete(t),e.emit({type:`scoop-status`,scoopJid:t,status:n}),e.emitScoopList()},onCompactionStateChange:(t,n)=>{e.emit({type:`compaction-state`,scoopJid:t,state:n})},onError:(t,n)=>{e.emit({type:`error`,scoopJid:t,error:n})},onToolStart:(t,n,r)=>{if(vt.has(n))return;let i=e.getOrCreateAssistantMsg(t);i.toolCalls||=[],i.toolCalls.push({id:Et(),name:n,input:r}),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:n,toolInput:r})},onToolEnd:(t,n,r,i)=>{if(vt.has(n))return;let a=e.currentMessageId.get(t);if(a){let o=e.getBuffer(t).find(e=>e.id===a);if(o?.toolCalls){let e=[...o.toolCalls].reverse().find(e=>e.name===n&&e.result===void 0);e&&(e.result=r,e.isError=i)}}e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_end`,toolName:n,toolResult:r,isError:i})},onToolUI:(t,n,r,i)=>{e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_ui`,toolName:n,requestId:r,html:i})},onToolUIDone:(t,n)=>{e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_ui_done`,requestId:n})},onIncomingMessage:(t,n)=>{let r={id:n.id,role:`user`,content:n.channel===`delegation`?`**[Instructions from sliccy]**\n\n${n.content}`:n.content,attachments:n.attachments,timestamp:new Date(n.timestamp).getTime(),source:n.channel===`delegation`?`delegation`:void 0,channel:n.channel};e.getBuffer(t).push(r),e.persistScoop(t),e.emit({type:`incoming-message`,scoopJid:t,message:{id:n.id,content:n.content,attachments:n.attachments,channel:n.channel,senderName:n.senderName,fromAssistant:n.fromAssistant,timestamp:n.timestamp}})}}}toScoopSnapshot(e){let t=e.config&&(e.config.modelId!==void 0||e.config.thinkingLevel!==void 0)?{...e.config.modelId===void 0?{}:{modelId:e.config.modelId},...e.config.thinkingLevel===void 0?{}:{thinkingLevel:e.config.thinkingLevel}}:void 0;return{jid:e.jid,name:e.name,folder:e.folder,isCone:e.isCone,assistantLabel:e.assistantLabel,status:this.scoopStatuses.get(e.jid)??`ready`,...t?{config:t}:{}}}buildStateSnapshot(){let e=this.orchestrator?.getScoops().map(e=>this.toScoopSnapshot(e))??[];return{type:`state-snapshot`,scoops:e,activeScoopJid:e.find(e=>e.isCone)?.jid??null,trayRuntimeStatus:this.buildTrayRuntimeStatus()}}emitTrayRuntimeStatus(){let e=this.buildTrayRuntimeStatus(),t={type:`tray-runtime-status`,leader:e.leader,follower:e.follower};this.emit(t)}buildTrayRuntimeStatus(){let e=ht(),t=O();return{leader:{state:e.state,session:e.session,error:e.error??null,reconnectAttempts:e.reconnectAttempts??0},follower:{state:t.state,joinUrl:t.joinUrl,trayId:t.trayId,error:t.error,lastError:t.lastError,reconnectAttempts:t.reconnectAttempts,attachAttempts:t.attachAttempts,lastAttachCode:t.lastAttachCode,connectingSince:t.connectingSince,lastPingTime:t.lastPingTime}}}setFollowerSync(e){this.followerSync=e}applyFollowerSnapshot(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoops().find(e=>e.isCone);if(!t)return;let n=e.map(e=>({id:e.id,role:e.role,content:e.content,attachments:e.attachments,timestamp:e.timestamp,source:e.source,channel:e.channel,toolCalls:e.toolCalls?.map(e=>({id:e.id,name:e.name,input:e.input,result:e.result,isError:e.isError})),isStreaming:e.isStreaming}));if(this.messageBuffers.set(t.jid,n),this.currentMessageId.delete(t.jid),this.sessionStore){let n=t.isCone?`session-cone`:`session-${t.folder}`;this.sessionStore.saveMessages(n,e).catch(e=>{console.warn(`[offscreen-bridge] applyFollowerSnapshot persist failed:`,e)})}this.emit({type:`scoop-messages-replaced`,scoopJid:t.jid,messages:n})}getConeJid(){return this.orchestrator?.getScoops().find(e=>e.isCone)?.jid??null}emitFollowerAgentEvent(e){let t=this.getConeJid();if(t)switch(e.type){case`content_delta`:this.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:e.text});break;case`content_done`:this.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`});break;case`tool_use_start`:this.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:e.toolName,toolInput:e.toolInput});break;case`tool_result`:this.emit({type:`agent-event`,scoopJid:t,eventType:`tool_end`,toolName:e.toolName,toolResult:e.result,isError:e.isError});break;case`turn_end`:this.emit({type:`agent-event`,scoopJid:t,eventType:`turn_end`});break;case`error`:this.emit({type:`error`,scoopJid:t,error:e.error});break}}emitFollowerIncomingMessage(e,t){let n=this.getConeJid();n&&this.emit({type:`incoming-message`,scoopJid:n,message:{id:e,content:t,channel:`web`,senderName:`User`,fromAssistant:!1,timestamp:new Date().toISOString()}})}emitFollowerStatus(e){let t=this.getConeJid();if(!t)return;let n=e===`processing`?`processing`:`ready`;this.scoopStatuses.set(t,n),this.emit({type:`scoop-status`,scoopJid:t,status:n})}async handleRequestScoopMessages(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoops().find(t=>t.jid===e);if(!t)return;let n=this.messageBuffers.get(e);if(n&&n.length>0){this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:n});return}let r=this.orchestrator.getScoopContext(e);if(r){let{agentMessagesToChatMessages:n}=await import(`./agent-message-to-chat-BpcmXkzt.js`),i=r.getAgentMessages();if(i.length>0){let r=n(i,{source:t.isCone?`cone`:t.name??t.folder}).map(e=>({id:e.id,role:e.role,content:e.content,attachments:e.attachments,timestamp:e.timestamp,source:e.source,channel:e.channel,toolCalls:e.toolCalls?.map(e=>({id:e.id,name:e.name,input:e.input,result:e.result,isError:e.isError})),isStreaming:!1}));this.messageBuffers.set(e,r),this.currentMessageId.delete(e),this.persistScoop(e),this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:r});return}}if(this.sessionStore){let n=t.isCone?`session-cone`:`session-${t.folder}`;try{let t=(await this.sessionStore.load(n))?.messages??[];t.length>0&&(this.messageBuffers.set(e,t),this.currentMessageId.delete(e),this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:t}))}catch(e){console.warn(`[offscreen-bridge] sessionStore load failed:`,n,e)}}}persistScoop(e){if(!this.sessionStore||!this.orchestrator)return;let t=this.orchestrator.getScoops().find(t=>t.jid===e);if(!t)return;let n=t.isCone?`session-cone`:`session-${t.folder}`,r=this.messageBuffers.get(e);!r||r.length===0||this.sessionStore.saveMessages(n,r).catch(e=>{console.warn(`[offscreen-bridge] persistScoop failed:`,n,e)})}getBuffer(e){let t=this.messageBuffers.get(e);return t||(t=[],this.messageBuffers.set(e,t)),t}getOrCreateAssistantMsg(e){let t=this.getBuffer(e),n=this.currentMessageId.get(e);if(n){let e=t.find(e=>e.id===n);if(e)return e}n=`scoop-${e}-${Et()}`,this.currentMessageId.set(e,n);let r=(this.orchestrator?.getScoops()??[]).find(t=>t.jid===e),i=r?.isCone?`cone`:r?.name??`unknown`,a={id:n,role:`assistant`,content:``,timestamp:Date.now(),toolCalls:[],isStreaming:!0,source:i};return t.push(a),a}setupMessageListener(){return this.transport.onMessage(e=>{if(e.source===`panel`){if(e.payload?.type===`sprinkle-op-response`){import(`./sprinkle-proxy-CgcbIA81.js`).then(({handleSprinkleOpResponse:t})=>{t(e.payload)});return}this.handlePanelMessage(e.payload).catch(t=>{console.error(`[offscreen-bridge] handlePanelMessage error:`,t);let n=e.payload.scoopJid;n&&this.emit({type:`error`,scoopJid:n,error:t instanceof Error?t.message:String(t)})})}})}async handlePanelMessage(e){if(this.orchestrator)switch(e.type){case`user-message`:{if(this.followerSync){this.getBuffer(e.scoopJid).push({id:e.messageId,role:`user`,content:e.text,attachments:e.attachments,timestamp:Date.now()}),this.persistScoop(e.scoopJid),this.followerSync.sendMessage(e.text,e.messageId,e.attachments);break}let t={id:e.messageId,chatJid:e.scoopJid,senderId:`user`,senderName:`User`,content:e.text,attachments:e.attachments,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};this.getBuffer(e.scoopJid).push({id:e.messageId,role:`user`,content:e.text,attachments:e.attachments,timestamp:Date.now()}),this.persistScoop(e.scoopJid),await this.orchestrator.handleMessage(t),this.orchestrator.createScoopTab(e.scoopJid);break}case`cone-create`:{let t={jid:`cone_${Date.now()}`,name:e.name,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()};await this.orchestrator.registerScoop(t),this.emit({type:`scoop-created`,scoop:this.toScoopSnapshot(t)});break}case`scoop-feed`:await this.orchestrator.delegateToScoop(e.scoopJid,e.prompt,`sliccy`);break;case`scoop-drop`:{let t=this.orchestrator.getScoops().find(t=>t.jid===e.scoopJid);if(await this.orchestrator.unregisterScoop(e.scoopJid),this.messageBuffers.delete(e.scoopJid),this.currentMessageId.delete(e.scoopJid),this.scoopStatuses.delete(e.scoopJid),t&&this.sessionStore){let e=t.isCone?`session-cone`:`session-${t.folder}`;this.sessionStore.delete(e).catch(t=>{console.warn(`[offscreen-bridge] Failed to delete session on scoop drop:`,e,t)})}this.emitScoopList();break}case`abort`:this.orchestrator.stopScoop(e.scoopJid),this.orchestrator.clearQueuedMessages(e.scoopJid).catch(e=>{console.warn(`[offscreen-bridge] Failed to clear queued messages on abort:`,e)});break;case`set-model`:this.orchestrator.updateModel();break;case`request-state`:this.emit(this.buildStateSnapshot());break;case`request-scoop-messages`:await this.handleRequestScoopMessages(e.scoopJid);break;case`clear-chat`:{let t=this.orchestrator.getScoops().find(e=>e.isCone)?.jid;t&&await this.orchestrator.clearScoopMessages(t),this.sessionStore&&await this.sessionStore.delete(`session-cone`),t&&(this.messageBuffers.delete(t),this.currentMessageId.delete(t)),this.emit({type:`clear-chat-ack`,requestId:e.requestId});break}case`clear-filesystem`:try{await this.orchestrator.resetFilesystem()}catch(e){console.error(`[offscreen-bridge] clear-filesystem failed:`,e)}break;case`refresh-model`:this.orchestrator.updateModel();break;case`set-thinking-level`:{let t=e;try{await this.orchestrator.setScoopThinkingLevel(t.scoopJid,t.level)}catch(e){console.error(`[offscreen-bridge] set-thinking-level failed:`,e)}break}case`sprinkle-lick`:{let t=this.orchestrator.getScoops(),n=e,r=n.targetScoop?t.find(e=>e.name===n.targetScoop||e.folder===n.targetScoop||e.folder===`${n.targetScoop}-scoop`):void 0;if(r||=t.find(e=>e.isCone),r){let e=`sprinkle-${n.sprinkleName}-${Date.now()}`,t=`[Sprinkle Event: ${n.sprinkleName}]\n\`\`\`json\n${JSON.stringify(n.body,null,2)}\n\`\`\``,i={id:e,chatJid:r.jid,senderId:`sprinkle`,senderName:`sprinkle:${n.sprinkleName}`,content:t,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`sprinkle`};this.getBuffer(r.jid).push({id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:`sprinkle`}),this.persistScoop(r.jid),await this.orchestrator.handleMessage(i)}break}case`lick-webhook-event`:this.orchestrator.handleWebhookEvent(e.webhookId,e.headers,e.body);break;case`reload-skills`:this.orchestrator.reloadAllSkills().catch(e=>{console.warn(`[offscreen-bridge] Skill reload failed:`,e)});break;case`panel-cdp-command`:{let{id:t,method:n,params:r,sessionId:i}=e;if(!this.browserAPI){console.warn(`[offscreen-bridge] Panel CDP command received but BrowserAPI is null`),this.emit({type:`panel-cdp-response`,id:t,error:`BrowserAPI not available`});break}try{let e=await this.browserAPI.getTransport().send(n,r,i);this.emit({type:`panel-cdp-response`,id:t,result:e})}catch(e){this.emit({type:`panel-cdp-response`,id:t,error:e instanceof Error?e.message:String(e)})}break}case`tool-ui-action`:{let{requestId:t,action:n,data:r}=e;try{await pe.handleAction(t,{action:n,data:r})}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`[offscreen-bridge] Tool UI action failed`,{requestId:t,action:n,error:r}),pe.cancel(t,`Action failed: ${r}`)}break}case`local-storage-set`:try{globalThis.localStorage?.setItem(e.key,e.value)}catch(e){console.warn(`[offscreen-bridge] local-storage-set failed:`,e)}break;case`local-storage-remove`:try{globalThis.localStorage?.removeItem(e.key)}catch(e){console.warn(`[offscreen-bridge] local-storage-remove failed:`,e)}break;case`local-storage-clear`:try{globalThis.localStorage?.clear()}catch(e){console.warn(`[offscreen-bridge] local-storage-clear failed:`,e)}break}}emitScoopList(){let e=this.orchestrator?.getScoops().map(e=>this.toScoopSnapshot(e))??[];this.emit({type:`scoop-list`,scoops:e})}emit(e){this.transport.send(e)}};function Et(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}const Dt=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`];function Ot(e){return typeof e==`string`&&Dt.includes(e)}var kt=r((e=>{(function(){var t={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function n(e){return i(o(e),arguments)}function r(e,t){return n.apply(null,[e].concat(t||[]))}function i(e,r){var i=1,a=e.length,o,s=``,c,l,u,d,f,p,m,h;for(c=0;c<a;c++)if(typeof e[c]==`string`)s+=e[c];else if(typeof e[c]==`object`){if(u=e[c],u.keys)for(o=r[i],l=0;l<u.keys.length;l++){if(o==null)throw Error(n(`[sprintf] Cannot access property "%s" of undefined value "%s"`,u.keys[l],u.keys[l-1]));o=o[u.keys[l]]}else o=u.param_no?r[u.param_no]:r[i++];if(t.not_type.test(u.type)&&t.not_primitive.test(u.type)&&o instanceof Function&&(o=o()),t.numeric_arg.test(u.type)&&typeof o!=`number`&&isNaN(o))throw TypeError(n(`[sprintf] expecting number but found %T`,o));switch(t.number.test(u.type)&&(m=o>=0),u.type){case`b`:o=parseInt(o,10).toString(2);break;case`c`:o=String.fromCharCode(parseInt(o,10));break;case`d`:case`i`:o=parseInt(o,10);break;case`j`:o=JSON.stringify(o,null,u.width?parseInt(u.width):0);break;case`e`:o=u.precision?parseFloat(o).toExponential(u.precision):parseFloat(o).toExponential();break;case`f`:o=u.precision?parseFloat(o).toFixed(u.precision):parseFloat(o);break;case`g`:o=u.precision?String(Number(o.toPrecision(u.precision))):parseFloat(o);break;case`o`:o=(parseInt(o,10)>>>0).toString(8);break;case`s`:o=String(o),o=u.precision?o.substring(0,u.precision):o;break;case`t`:o=String(!!o),o=u.precision?o.substring(0,u.precision):o;break;case`T`:o=Object.prototype.toString.call(o).slice(8,-1).toLowerCase(),o=u.precision?o.substring(0,u.precision):o;break;case`u`:o=parseInt(o,10)>>>0;break;case`v`:o=o.valueOf(),o=u.precision?o.substring(0,u.precision):o;break;case`x`:o=(parseInt(o,10)>>>0).toString(16);break;case`X`:o=(parseInt(o,10)>>>0).toString(16).toUpperCase();break}t.json.test(u.type)?s+=o:(t.number.test(u.type)&&(!m||u.sign)?(h=m?`+`:`-`,o=o.toString().replace(t.sign,``)):h=``,f=u.pad_char?u.pad_char===`0`?`0`:u.pad_char.charAt(1):` `,p=u.width-(h+o).length,d=u.width&&p>0?f.repeat(p):``,s+=u.align?h+o+d:f===`0`?h+d+o:d+h+o)}return s}var a=Object.create(null);function o(e){if(a[e])return a[e];for(var n=e,r,i=[],o=0;n;){if((r=t.text.exec(n))!==null)i.push(r[0]);else if((r=t.modulo.exec(n))!==null)i.push(`%`);else if((r=t.placeholder.exec(n))!==null){if(r[2]){o|=1;var s=[],c=r[2],l=[];if((l=t.key.exec(c))!==null)for(s.push(l[1]);(c=c.substring(l[0].length))!==``;)if((l=t.key_access.exec(c))!==null)s.push(l[1]);else if((l=t.index_access.exec(c))!==null)s.push(l[1]);else throw SyntaxError(`[sprintf] failed to parse named argument key`);else throw SyntaxError(`[sprintf] failed to parse named argument key`);r[2]=s}else o|=2;if(o===3)throw Error(`[sprintf] mixing positional and named placeholders is not (yet) supported`);i.push({placeholder:r[0],param_no:r[1],keys:r[2],sign:r[3],pad_char:r[4],align:r[5],width:r[6],precision:r[7],type:r[8]})}else throw SyntaxError(`[sprintf] unexpected placeholder`);n=n.substring(r[0].length)}return a[e]=i}e!==void 0&&(e.sprintf=n,e.vsprintf=r),typeof window<`u`&&(window.sprintf=n,window.vsprintf=r,typeof define==`function`&&define.amd&&define(function(){return{sprintf:n,vsprintf:r}}))})()}))();const At=(e,t,n)=>{let r=e instanceof RegExp?jt(e,n):e,i=t instanceof RegExp?jt(t,n):t,a=r!==null&&i!=null&&Mt(r,i,n);return a&&{start:a[0],end:a[1],pre:n.slice(0,a[0]),body:n.slice(a[0]+r.length,a[1]),post:n.slice(a[1]+i.length)}},jt=(e,t)=>{let n=t.match(e);return n?n[0]:null},Mt=(e,t,n)=>{let r,i,a,o,s,c=n.indexOf(e),l=n.indexOf(t,c+1),u=c;if(c>=0&&l>0){if(e===t)return[c,l];for(r=[],a=n.length;u>=0&&!s;){if(u===c)r.push(u),c=n.indexOf(e,u+1);else if(r.length===1){let e=r.pop();e!==void 0&&(s=[e,l])}else i=r.pop(),i!==void 0&&i<a&&(a=i,o=l),l=n.indexOf(t,u+1);u=c<l&&c>=0?c:l}r.length&&o!==void 0&&(s=[a,o])}return s},Nt=`\0SLASH`+Math.random()+`\0`,Pt=`\0OPEN`+Math.random()+`\0`,Ft=`\0CLOSE`+Math.random()+`\0`,It=`\0COMMA`+Math.random()+`\0`,Lt=`\0PERIOD`+Math.random()+`\0`,Rt=new RegExp(Nt,`g`),zt=new RegExp(Pt,`g`),Bt=new RegExp(Ft,`g`),Vt=new RegExp(It,`g`),Ht=new RegExp(Lt,`g`),Ut=/\\\\/g,Wt=/\\{/g,Gt=/\\}/g,Kt=/\\,/g,qt=/\\\./g;function Jt(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function Yt(e){return e.replace(Ut,Nt).replace(Wt,Pt).replace(Gt,Ft).replace(Kt,It).replace(qt,Lt)}function Xt(e){return e.replace(Rt,`\\`).replace(zt,`{`).replace(Bt,`}`).replace(Vt,`,`).replace(Ht,`.`)}function Zt(e){if(!e)return[``];let t=[],n=At(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=Zt(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function Qt(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),rn(Yt(e),n,!0).map(Xt)}function $t(e){return`{`+e+`}`}function en(e){return/^-?0\d/.test(e)}function tn(e,t){return e<=t}function nn(e,t){return e>=t}function rn(e,t,n){let r=[],i=At(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?rn(i.post,t,!1):[``];if(/\$$/.test(i.pre))for(let e=0;e<o.length&&e<t;e++){let t=a+`{`+i.body+`}`+o[e];r.push(t)}else{let s=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(i.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(i.body),l=s||c,u=i.body.indexOf(`,`)>=0;if(!l&&!u)return i.post.match(/,(?!,).*\}/)?(e=i.pre+`{`+i.body+Ft+i.post,rn(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=Zt(i.body),d.length===1&&d[0]!==void 0&&(d=rn(d[0],t,!1).map($t),d.length===1))return o.map(e=>i.pre+d[0]+e);let f;if(l&&d[0]!==void 0&&d[1]!==void 0){let e=Jt(d[0]),t=Jt(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.abs(Jt(d[2])):1,i=tn;t<e&&(r*=-1,i=nn);let a=d.some(en);f=[];for(let o=e;i(o,t);o+=r){let e;if(c)e=String.fromCharCode(o),e===`\\`&&(e=``);else if(e=String(o),a){let t=n-e.length;if(t>0){let n=Array(t+1).join(`0`);e=o<0?`-`+n+e.slice(1):n+e}}f.push(e)}}else{f=[];for(let e=0;e<d.length;e++)f.push.apply(f,rn(d[e],t,!1))}for(let e=0;e<f.length;e++)for(let i=0;i<o.length&&r.length<t;i++){let t=a+f[e]+o[i];(!n||l||t)&&r.push(t)}}return r}const an=e=>{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},on={"[:alnum:]":[`\\p{L}\\p{Nl}\\p{Nd}`,!0],"[:alpha:]":[`\\p{L}\\p{Nl}`,!0],"[:ascii:]":[`\\x00-\\x7f`,!1],"[:blank:]":[`\\p{Zs}\\t`,!0],"[:cntrl:]":[`\\p{Cc}`,!0],"[:digit:]":[`\\p{Nd}`,!0],"[:graph:]":[`\\p{Z}\\p{C}`,!0,!0],"[:lower:]":[`\\p{Ll}`,!0],"[:print:]":[`\\p{C}`,!0],"[:punct:]":[`\\p{P}`,!0],"[:space:]":[`\\p{Z}\\t\\r\\n\\v\\f`,!0],"[:upper:]":[`\\p{Lu}`,!0],"[:word:]":[`\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}`,!0],"[:xdigit:]":[`A-Fa-f0-9`,!1]},sn=e=>e.replace(/[[\]\\-]/g,`\\$&`),cn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),ln=e=>e.join(``),un=(e,t)=>{let n=t;if(e.charAt(n)!==`[`)throw Error(`not in a brace expression`);let r=[],i=[],a=n+1,o=!1,s=!1,c=!1,l=!1,u=n,d=``;WHILE:for(;a<e.length;){let t=e.charAt(a);if((t===`!`||t===`^`)&&a===n+1){l=!0,a++;continue}if(t===`]`&&o&&!c){u=a+1;break}if(o=!0,t===`\\`&&!c){c=!0,a++;continue}if(t===`[`&&!c){for(let[t,[o,c,l]]of Object.entries(on))if(e.startsWith(t,a)){if(d)return[`$.`,!1,e.length-n,!0];a+=t.length,l?i.push(o):r.push(o),s||=c;continue WHILE}}if(c=!1,d){t>d?r.push(sn(d)+`-`+sn(t)):t===d&&r.push(sn(t)),d=``,a++;continue}if(e.startsWith(`-]`,a+1)){r.push(sn(t+`-`)),a+=2;continue}if(e.startsWith(`-`,a+1)){d=t,a+=2;continue}r.push(sn(t)),a++}if(u<a)return[``,!1,0,!1];if(!r.length&&!i.length)return[`$.`,!1,e.length-n,!0];if(i.length===0&&r.length===1&&/^\\?.$/.test(r[0])&&!l)return[cn(r[0].length===2?r[0].slice(-1):r[0]),!1,u-n,!1];let f=`[`+(l?`^`:``)+ln(r)+`]`,p=`[`+(l?``:`^`)+ln(i)+`]`;return[r.length&&i.length?`(`+f+`|`+p+`)`:r.length?f:p,s,u-n,!0]},dn=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!0}={})=>n?t?e.replace(/\[([^\/\\])\]/g,`$1`):e.replace(/((?!\\).|^)\[([^\/\\])\]/g,`$1$2`).replace(/\\([^\/])/g,`$1`):t?e.replace(/\[([^\/\\{}])\]/g,`$1`):e.replace(/((?!\\).|^)\[([^\/\\{}])\]/g,`$1$2`).replace(/\\([^\/{}])/g,`$1`);var fn;const pn=new Set([`!`,`?`,`+`,`*`,`@`]),mn=e=>pn.has(e),hn=e=>mn(e.type),gn=new Map([[`!`,[`@`]],[`?`,[`?`,`@`]],[`@`,[`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`]]]),_n=new Map([[`!`,[`?`]],[`@`,[`?`]],[`+`,[`?`,`*`]]]),vn=new Map([[`!`,[`?`,`@`]],[`?`,[`?`,`@`]],[`@`,[`?`,`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`,`?`,`*`]]]),yn=new Map([[`!`,new Map([[`!`,`@`]])],[`?`,new Map([[`*`,`*`],[`+`,`*`]])],[`@`,new Map([[`!`,`!`],[`?`,`?`],[`@`,`@`],[`*`,`*`],[`+`,`+`]])],[`+`,new Map([[`?`,`*`],[`*`,`*`]])]]),bn=`(?!\\.)`,xn=new Set([`[`,`.`]),Sn=new Set([`..`,`.`]),Cn=new Set(`().*{}+?[]^$\\!`),wn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),Tn=`[^/]`,En=Tn+`*?`,Dn=Tn+`+?`;let On=0;var kn=class{type;#e;#t;#n=!1;#r=[];#i;#a;#o;#s=!1;#c;#l;#u=!1;id=++On;get depth(){return(this.#i?.depth??-1)+1}[Symbol.for(`nodejs.util.inspect.custom`)](){return{"@@type":`AST`,id:this.id,type:this.type,root:this.#e.id,parent:this.#i?.id,depth:this.depth,partsLength:this.#r.length,parts:this.#r}}constructor(e,t,n={}){this.type=e,e&&(this.#t=!0),this.#i=t,this.#e=this.#i?this.#i.#e:this,this.#c=this.#e===this?n:this.#e.#c,this.#o=this.#e===this?[]:this.#e.#o,e===`!`&&!this.#e.#s&&this.#o.push(this),this.#a=this.#i?this.#i.#r.length:0}get hasMagic(){if(this.#t!==void 0)return this.#t;for(let e of this.#r)if(typeof e!=`string`&&(e.type||e.hasMagic))return this.#t=!0;return this.#t}toString(){return this.#l===void 0?this.type?this.#l=this.type+`(`+this.#r.map(e=>String(e)).join(`|`)+`)`:this.#l=this.#r.map(e=>String(e)).join(``):this.#l}#d(){if(this!==this.#e)throw Error(`should only call on root`);if(this.#s)return this;this.toString(),this.#s=!0;let e;for(;e=this.#o.pop();){if(e.type!==`!`)continue;let t=e,n=t.#i;for(;n;){for(let r=t.#a+1;!n.type&&r<n.#r.length;r++)for(let t of e.#r){if(typeof t==`string`)throw Error(`string part in extglob AST??`);t.copyIn(n.#r[r])}t=n,n=t.#i}}return this}push(...e){for(let t of e)if(t!==``){if(typeof t!=`string`&&!(t instanceof fn&&t.#i===this))throw Error(`invalid part: `+t);this.#r.push(t)}}toJSON(){let e=this.type===null?this.#r.slice().map(e=>typeof e==`string`?e:e.toJSON()):[this.type,...this.#r.map(e=>e.toJSON())];return this.isStart()&&!this.type&&e.unshift([]),this.isEnd()&&(this===this.#e||this.#e.#s&&this.#i?.type===`!`)&&e.push({}),e}isStart(){if(this.#e===this)return!0;if(!this.#i?.isStart())return!1;if(this.#a===0)return!0;let e=this.#i;for(let t=0;t<this.#a;t++){let n=e.#r[t];if(!(n instanceof fn&&n.type===`!`))return!1}return!0}isEnd(){if(this.#e===this||this.#i?.type===`!`)return!0;if(!this.#i?.isEnd())return!1;if(!this.type)return this.#i?.isEnd();let e=this.#i?this.#i.#r.length:0;return this.#a===e-1}copyIn(e){typeof e==`string`?this.push(e):this.push(e.clone(this))}clone(e){let t=new fn(this.type,e);for(let e of this.#r)t.copyIn(e);return t}static#f(e,t,n,r,i){let a=r.maxExtglobRecursion??2,o=!1,s=!1,c=-1,l=!1;if(t.type===null){let u=n,d=``;for(;u<e.length;){let n=e.charAt(u++);if(o||n===`\\`){o=!o,d+=n;continue}if(s){u===c+1?(n===`^`||n===`!`)&&(l=!0):n===`]`&&!(u===c+2&&l)&&(s=!1),d+=n;continue}else if(n===`[`){s=!0,c=u,l=!1,d+=n;continue}if(!r.noext&&mn(n)&&e.charAt(u)===`(`&&i<=a){t.push(d),d=``;let a=new fn(n,t);u=fn.#f(e,a,u,r,i+1),t.push(a);continue}d+=n}return t.push(d),u}let u=n+1,d=new fn(null,t),f=[],p=``;for(;u<e.length;){let n=e.charAt(u++);if(o||n===`\\`){o=!o,p+=n;continue}if(s){u===c+1?(n===`^`||n===`!`)&&(l=!0):n===`]`&&!(u===c+2&&l)&&(s=!1),p+=n;continue}else if(n===`[`){s=!0,c=u,l=!1,p+=n;continue}if(!r.noext&&mn(n)&&e.charAt(u)===`(`&&(i<=a||t&&t.#h(n))){let a=t&&t.#h(n)?0:1;d.push(p),p=``;let o=new fn(n,d);d.push(o),u=fn.#f(e,o,u,r,i+a);continue}if(n===`|`){d.push(p),p=``,f.push(d),d=new fn(null,t);continue}if(n===`)`)return p===``&&t.#r.length===0&&(t.#u=!0),d.push(p),p=``,t.push(...f,d),u;p+=n}return t.type=null,t.#t=void 0,t.#r=[e.substring(n-1)],u}#p(e){return this.#m(e,_n)}#m(e,t=gn){if(!e||typeof e!=`object`||e.type!==null||e.#r.length!==1||this.type===null)return!1;let n=e.#r[0];return!n||typeof n!=`object`||n.type===null?!1:this.#h(n.type,t)}#h(e,t=vn){return!!t.get(this.type)?.includes(e)}#g(e,t){let n=e.#r[0],r=new fn(null,n,this.options);r.#r.push(``),n.push(r),this.#_(e,t)}#_(e,t){let n=e.#r[0];this.#r.splice(t,1,...n.#r);for(let e of n.#r)typeof e==`object`&&(e.#i=this);this.#l=void 0}#v(e){return!!yn.get(this.type)?.has(e)}#y(e){if(!e||typeof e!=`object`||e.type!==null||e.#r.length!==1||this.type===null||this.#r.length!==1)return!1;let t=e.#r[0];return!t||typeof t!=`object`||t.type===null?!1:this.#v(t.type)}#b(e){let t=yn.get(this.type),n=e.#r[0],r=t?.get(n.type);if(!r)return!1;this.#r=n.#r;for(let e of this.#r)typeof e==`object`&&(e.#i=this);this.type=r,this.#l=void 0,this.#u=!1}static fromGlob(e,t={}){let n=new fn(null,void 0,t);return fn.#f(e,n,0,t,0),n}toMMPattern(){if(this!==this.#e)return this.#e.toMMPattern();let e=this.toString(),[t,n,r,i]=this.toRegExpSource();if(!(r||this.#t||this.#c.nocase&&!this.#c.nocaseMagicOnly&&e.toUpperCase()!==e.toLowerCase()))return n;let a=(this.#c.nocase?`i`:``)+(i?`u`:``);return Object.assign(RegExp(`^${t}$`,a),{_src:t,_glob:e})}get options(){return this.#c}toRegExpSource(e){let t=e??!!this.#c.dot;if(this.#e===this&&(this.#x(),this.#d()),!hn(this)){let n=this.isStart()&&this.isEnd()&&!this.#r.some(e=>typeof e!=`string`),r=this.#r.map(t=>{let[r,i,a,o]=typeof t==`string`?fn.#C(t,this.#t,n):t.toRegExpSource(e);return this.#t=this.#t||a,this.#n=this.#n||o,r}).join(``),i=``;if(this.isStart()&&typeof this.#r[0]==`string`&&!(this.#r.length===1&&Sn.has(this.#r[0]))){let n=xn,a=t&&n.has(r.charAt(0))||r.startsWith(`\\.`)&&n.has(r.charAt(2))||r.startsWith(`\\.\\.`)&&n.has(r.charAt(4)),o=!t&&!e&&n.has(r.charAt(0));i=a?`(?!(?:^|/)\\.\\.?(?:$|/))`:o?bn:``}let a=``;return this.isEnd()&&this.#e.#s&&this.#i?.type===`!`&&(a=`(?:$|\\/)`),[i+r+a,dn(r),this.#t=!!this.#t,this.#n]}let n=this.type===`*`||this.type===`+`,r=this.type===`!`?`(?:(?!(?:`:`(?:`,i=this.#S(t);if(this.isStart()&&this.isEnd()&&!i&&this.type!==`!`){let e=this.toString(),t=this;return t.#r=[e],t.type=null,t.#t=void 0,[e,dn(this.toString()),!1,!1]}let a=!n||e||t?``:this.#S(!0);a===i&&(a=``),a&&(i=`(?:${i})(?:${a})*?`);let o=``;if(this.type===`!`&&this.#u)o=(this.isStart()&&!t?bn:``)+Dn;else{let n=this.type===`!`?`))`+(this.isStart()&&!t&&!e?bn:``)+En+`)`:this.type===`@`?`)`:this.type===`?`?`)?`:this.type===`+`&&a?`)`:this.type===`*`&&a?`)?`:`)${this.type}`;o=r+i+n}return[o,dn(i),this.#t=!!this.#t,this.#n]}#x(){if(hn(this)){let e=0,t=!1;do{t=!0;for(let e=0;e<this.#r.length;e++){let n=this.#r[e];typeof n==`object`&&(n.#x(),this.#m(n)?(t=!1,this.#_(n,e)):this.#p(n)?(t=!1,this.#g(n,e)):this.#y(n)&&(t=!1,this.#b(n)))}}while(!t&&++e<10)}else for(let e of this.#r)typeof e==`object`&&e.#x();this.#l=void 0}#S(e){return this.#r.map(t=>{if(typeof t==`string`)throw Error(`string type in extglob ast??`);let[n,r,i,a]=t.toRegExpSource(e);return this.#n=this.#n||a,n}).filter(e=>!(this.isStart()&&this.isEnd())||!!e).join(`|`)}static#C(e,t,n=!1){let r=!1,i=``,a=!1,o=!1;for(let s=0;s<e.length;s++){let c=e.charAt(s);if(r){r=!1,i+=(Cn.has(c)?`\\`:``)+c;continue}if(c===`*`){if(o)continue;o=!0,i+=n&&/^[*]+$/.test(e)?Dn:En,t=!0;continue}else o=!1;if(c===`\\`){s===e.length-1?i+=`\\\\`:r=!0;continue}if(c===`[`){let[n,r,o,c]=un(e,s);if(o){i+=n,a||=r,s+=o-1,t||=c;continue}}if(c===`?`){i+=Tn,t=!0;continue}i+=wn(c)}return[i,dn(e),!!t,a]}};fn=kn;const An=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!1}={})=>n?t?e.replace(/[?*()[\]{}]/g,`[$&]`):e.replace(/[?*()[\]\\{}]/g,`\\$&`):t?e.replace(/[?*()[\]]/g,`[$&]`):e.replace(/[?*()[\]\\]/g,`\\$&`),jn=(e,t,n={})=>(an(t),!n.nocomment&&t.charAt(0)===`#`?!1:new ar(t,n).match(e)),Mn=/^\*+([^+@!?\*\[\(]*)$/,Nn=e=>t=>!t.startsWith(`.`)&&t.endsWith(e),Pn=e=>t=>t.endsWith(e),Fn=e=>(e=e.toLowerCase(),t=>!t.startsWith(`.`)&&t.toLowerCase().endsWith(e)),In=e=>(e=e.toLowerCase(),t=>t.toLowerCase().endsWith(e)),Ln=/^\*+\.\*+$/,Rn=e=>!e.startsWith(`.`)&&e.includes(`.`),zn=e=>e!==`.`&&e!==`..`&&e.includes(`.`),Bn=/^\.\*+$/,Vn=e=>e!==`.`&&e!==`..`&&e.startsWith(`.`),Hn=/^\*+$/,Un=e=>e.length!==0&&!e.startsWith(`.`),Wn=e=>e.length!==0&&e!==`.`&&e!==`..`,Gn=/^\?+([^+@!?\*\[\(]*)?$/,Kn=([e,t=``])=>{let n=Xn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},qn=([e,t=``])=>{let n=Zn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Jn=([e,t=``])=>{let n=Zn([e]);return t?e=>n(e)&&e.endsWith(t):n},Yn=([e,t=``])=>{let n=Xn([e]);return t?e=>n(e)&&e.endsWith(t):n},Xn=([e])=>{let t=e.length;return e=>e.length===t&&!e.startsWith(`.`)},Zn=([e])=>{let t=e.length;return e=>e.length===t&&e!==`.`&&e!==`..`},Qn=typeof process==`object`&&process?{}.__MINIMATCH_TESTING_PLATFORM__||process.platform:`posix`,$n={win32:{sep:`\\`},posix:{sep:`/`}};jn.sep=Qn===`win32`?$n.win32.sep:$n.posix.sep;const er=Symbol(`globstar **`);jn.GLOBSTAR=er,jn.filter=(e,t={})=>n=>jn(n,e,t);const tr=(e,t={})=>Object.assign({},e,t);jn.defaults=e=>{if(!e||typeof e!=`object`||!Object.keys(e).length)return jn;let t=jn;return Object.assign((n,r,i={})=>t(n,r,tr(e,i)),{Minimatch:class extends t.Minimatch{constructor(t,n={}){super(t,tr(e,n))}static defaults(n){return t.defaults(tr(e,n)).Minimatch}},AST:class extends t.AST{constructor(t,n,r={}){super(t,n,tr(e,r))}static fromGlob(n,r={}){return t.AST.fromGlob(n,tr(e,r))}},unescape:(n,r={})=>t.unescape(n,tr(e,r)),escape:(n,r={})=>t.escape(n,tr(e,r)),filter:(n,r={})=>t.filter(n,tr(e,r)),defaults:n=>t.defaults(tr(e,n)),makeRe:(n,r={})=>t.makeRe(n,tr(e,r)),braceExpand:(n,r={})=>t.braceExpand(n,tr(e,r)),match:(n,r,i={})=>t.match(n,r,tr(e,i)),sep:t.sep,GLOBSTAR:er})};const nr=(e,t={})=>(an(e),t.nobrace||!/\{(?:(?!\{).)*\}/.test(e)?[e]:Qt(e,{max:t.braceExpandMax}));jn.braceExpand=nr,jn.makeRe=(e,t={})=>new ar(e,t).makeRe(),jn.match=(e,t,n={})=>{let r=new ar(t,n);return e=e.filter(e=>r.match(e)),r.options.nonull&&!e.length&&e.push(t),e};const rr=/[?*]|[+@!]\(.*?\)|\[|\]/,ir=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`);var ar=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;maxGlobstarRecursion;regexp;constructor(e,t={}){an(e),t||={},this.options=t,this.maxGlobstarRecursion=t.maxGlobstarRecursion??200,this.pattern=e,this.platform=t.platform||Qn,this.isWindows=this.platform===`win32`,this.windowsPathsNoEscape=!!t.windowsPathsNoEscape||t.allowWindowsEscape===!1,this.windowsPathsNoEscape&&(this.pattern=this.pattern.replace(/\\/g,`/`)),this.preserveMultipleSlashes=!!t.preserveMultipleSlashes,this.regexp=null,this.negate=!1,this.nonegate=!!t.nonegate,this.comment=!1,this.empty=!1,this.partial=!!t.partial,this.nocase=!!this.options.nocase,this.windowsNoMagicRoot=t.windowsNoMagicRoot===void 0?!!(this.isWindows&&this.nocase):t.windowsNoMagicRoot,this.globSet=[],this.globParts=[],this.set=[],this.make()}hasMagic(){if(this.options.magicalBraces&&this.set.length>1)return!0;for(let e of this.set)for(let t of e)if(typeof t!=`string`)return!0;return!1}debug(...e){}make(){let e=this.pattern,t=this.options;if(!t.nocomment&&e.charAt(0)===`#`){this.comment=!0;return}if(!e){this.empty=!0;return}this.parseNegate(),this.globSet=[...new Set(this.braceExpand())],t.debug&&(this.debug=(...e)=>console.error(...e)),this.debug(this.pattern,this.globSet);let n=this.globSet.map(e=>this.slashSplit(e));this.globParts=this.preprocess(n),this.debug(this.pattern,this.globParts);let r=this.globParts.map((e,t,n)=>{if(this.isWindows&&this.windowsNoMagicRoot){let t=e[0]===``&&e[1]===``&&(e[2]===`?`||!rr.test(e[2]))&&!rr.test(e[3]),n=/^[a-z]:/i.test(e[0]);if(t)return[...e.slice(0,4),...e.slice(4).map(e=>this.parse(e))];if(n)return[e[0],...e.slice(1).map(e=>this.parse(e))]}return e.map(e=>this.parse(e))});if(this.debug(this.pattern,r),this.set=r.filter(e=>e.indexOf(!1)===-1),this.isWindows)for(let e=0;e<this.set.length;e++){let t=this.set[e];t[0]===``&&t[1]===``&&this.globParts[e][2]===`?`&&typeof t[3]==`string`&&/^[a-z]:$/i.test(t[3])&&(t[2]=`?`)}this.debug(this.pattern,this.set)}preprocess(e){if(this.options.noglobstar)for(let t=0;t<e.length;t++)for(let n=0;n<e[t].length;n++)e[t][n]===`**`&&(e[t][n]=`*`);let{optimizationLevel:t=1}=this.options;return t>=2?(e=this.firstPhasePreProcess(e),e=this.secondPhasePreProcess(e)):e=t>=1?this.levelOneOptimize(e):this.adjascentGlobstarOptimize(e),e}adjascentGlobstarOptimize(e){return e.map(e=>{let t=-1;for(;(t=e.indexOf(`**`,t+1))!==-1;){let n=t;for(;e[n+1]===`**`;)n++;n!==t&&e.splice(t,n-t)}return e})}levelOneOptimize(e){return e.map(e=>(e=e.reduce((e,t)=>{let n=e[e.length-1];return t===`**`&&n===`**`?e:t===`..`&&n&&n!==`..`&&n!==`.`&&n!==`**`?(e.pop(),e):(e.push(t),e)},[]),e.length===0?[``]:e))}levelTwoFileOptimize(e){Array.isArray(e)||(e=this.slashSplit(e));let t=!1;do{if(t=!1,!this.preserveMultipleSlashes){for(let n=1;n<e.length-1;n++){let r=e[n];n===1&&r===``&&e[0]===``||(r===`.`||r===``)&&(t=!0,e.splice(n,1),n--)}e[0]===`.`&&e.length===2&&(e[1]===`.`||e[1]===``)&&(t=!0,e.pop())}let n=0;for(;(n=e.indexOf(`..`,n+1))!==-1;){let r=e[n-1];r&&r!==`.`&&r!==`..`&&r!==`**`&&(t=!0,e.splice(n-1,2),n-=2)}}while(t);return e.length===0?[``]:e}firstPhasePreProcess(e){let t=!1;do{t=!1;for(let n of e){let r=-1;for(;(r=n.indexOf(`**`,r+1))!==-1;){let i=r;for(;n[i+1]===`**`;)i++;i>r&&n.splice(r+1,i-r);let a=n[r+1],o=n[r+2],s=n[r+3];if(a!==`..`||!o||o===`.`||o===`..`||!s||s===`.`||s===`..`)continue;t=!0,n.splice(r,1);let c=n.slice(0);c[r]=`**`,e.push(c),r--}if(!this.preserveMultipleSlashes){for(let e=1;e<n.length-1;e++){let r=n[e];e===1&&r===``&&n[0]===``||(r===`.`||r===``)&&(t=!0,n.splice(e,1),e--)}n[0]===`.`&&n.length===2&&(n[1]===`.`||n[1]===``)&&(t=!0,n.pop())}let i=0;for(;(i=n.indexOf(`..`,i+1))!==-1;){let e=n[i-1];if(e&&e!==`.`&&e!==`..`&&e!==`**`){t=!0;let e=i===1&&n[i+1]===`**`?[`.`]:[];n.splice(i-1,2,...e),n.length===0&&n.push(``),i-=2}}}}while(t);return e}secondPhasePreProcess(e){for(let t=0;t<e.length-1;t++)for(let n=t+1;n<e.length;n++){let r=this.partsMatch(e[t],e[n],!this.preserveMultipleSlashes);if(r){e[t]=[],e[n]=r;break}}return e.filter(e=>e.length)}partsMatch(e,t,n=!1){let r=0,i=0,a=[],o=``;for(;r<e.length&&i<t.length;)if(e[r]===t[i])a.push(o===`b`?t[i]:e[r]),r++,i++;else if(n&&e[r]===`**`&&t[i]===e[r+1])a.push(e[r]),r++;else if(n&&t[i]===`**`&&e[r]===t[i+1])a.push(t[i]),i++;else if(e[r]===`*`&&t[i]&&(this.options.dot||!t[i].startsWith(`.`))&&t[i]!==`**`){if(o===`b`)return!1;o=`a`,a.push(e[r]),r++,i++}else if(t[i]===`*`&&e[r]&&(this.options.dot||!e[r].startsWith(`.`))&&e[r]!==`**`){if(o===`a`)return!1;o=`b`,a.push(t[i]),r++,i++}else return!1;return e.length===t.length&&a}parseNegate(){if(this.nonegate)return;let e=this.pattern,t=!1,n=0;for(let r=0;r<e.length&&e.charAt(r)===`!`;r++)t=!t,n++;n&&(this.pattern=e.slice(n)),this.negate=t}matchOne(e,t,n=!1){let r=0,i=0;if(this.isWindows){let n=typeof e[0]==`string`&&/^[a-z]:$/i.test(e[0]),a=!n&&e[0]===``&&e[1]===``&&e[2]===`?`&&/^[a-z]:$/i.test(e[3]),o=typeof t[0]==`string`&&/^[a-z]:$/i.test(t[0]),s=!o&&t[0]===``&&t[1]===``&&t[2]===`?`&&typeof t[3]==`string`&&/^[a-z]:$/i.test(t[3]),c=a?3:n?0:void 0,l=s?3:o?0:void 0;if(typeof c==`number`&&typeof l==`number`){let[n,a]=[e[c],t[l]];n.toLowerCase()===a.toLowerCase()&&(t[l]=n,i=l,r=c)}}let{optimizationLevel:a=1}=this.options;return a>=2&&(e=this.levelTwoFileOptimize(e)),t.includes(er)?this.#e(e,t,n,r,i):this.#n(e,t,n,r,i)}#e(e,t,n,r,i){let a=t.indexOf(er,i),o=t.lastIndexOf(er),[s,c,l]=n?[t.slice(i,a),t.slice(a+1),[]]:[t.slice(i,a),t.slice(a+1,o),t.slice(o+1)];if(s.length){let t=e.slice(r,r+s.length);if(!this.#n(t,s,n,0,0))return!1;r+=s.length,i+=s.length}let u=0;if(l.length){if(l.length+r>e.length)return!1;let t=e.length-l.length;if(this.#n(e,l,n,t,0))u=l.length;else{if(e[e.length-1]!==``||r+l.length===e.length||(t--,!this.#n(e,l,n,t,0)))return!1;u=l.length+1}}if(!c.length){let t=!!u;for(let n=r;n<e.length-u;n++){let r=String(e[n]);if(t=!0,r===`.`||r===`..`||!this.options.dot&&r.startsWith(`.`))return!1}return n||t}let d=[[[],0]],f=d[0],p=0,m=[0];for(let e of c)e===er?(m.push(p),f=[[],0],d.push(f)):(f[0].push(e),p++);let h=d.length-1,g=e.length-u;for(let e of d)e[1]=g-(m[h--]+e[0].length);return!!this.#t(e,d,r,0,n,0,!!u)}#t(e,t,n,r,i,a,o){let s=t[r];if(!s){for(let t=n;t<e.length;t++){o=!0;let n=e[t];if(n===`.`||n===`..`||!this.options.dot&&n.startsWith(`.`))return!1}return o}let[c,l]=s;for(;n<=l;){if(this.#n(e.slice(0,n+c.length),c,i,n,0)&&a<this.maxGlobstarRecursion){let s=this.#t(e,t,n+c.length,r+1,i,a+1,o);if(s!==!1)return s}let s=e[n];if(s===`.`||s===`..`||!this.options.dot&&s.startsWith(`.`))return!1;n++}return i||null}#n(e,t,n,r,i){let a,o,s,c;for(a=r,o=i,c=e.length,s=t.length;a<c&&o<s;a++,o++){this.debug(`matchOne loop`);let n=t[o],r=e[a];if(this.debug(t,n,r),n===!1||n===er)return!1;let i;if(typeof n==`string`?(i=r===n,this.debug(`string match`,n,r,i)):(i=n.test(r),this.debug(`pattern match`,n,r,i)),!i)return!1}if(a===c&&o===s)return!0;if(a===c)return n;if(o===s)return a===c-1&&e[a]===``;throw Error(`wtf?`)}braceExpand(){return nr(this.pattern,this.options)}parse(e){an(e);let t=this.options;if(e===`**`)return er;if(e===``)return``;let n,r=null;(n=e.match(Hn))?r=t.dot?Wn:Un:(n=e.match(Mn))?r=(t.nocase?t.dot?In:Fn:t.dot?Pn:Nn)(n[1]):(n=e.match(Gn))?r=(t.nocase?t.dot?qn:Kn:t.dot?Jn:Yn)(n):(n=e.match(Ln))?r=t.dot?zn:Rn:(n=e.match(Bn))&&(r=Vn);let i=kn.fromGlob(e,this.options).toMMPattern();return r&&typeof i==`object`&&Reflect.defineProperty(i,`test`,{value:r}),i}makeRe(){if(this.regexp||this.regexp===!1)return this.regexp;let e=this.set;if(!e.length)return this.regexp=!1,this.regexp;let t=this.options,n=t.noglobstar?`[^/]*?`:t.dot?`(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?`:`(?:(?!(?:\\/|^)\\.).)*?`,r=new Set(t.nocase?[`i`]:[]),i=e.map(e=>{let t=e.map(e=>{if(e instanceof RegExp)for(let t of e.flags.split(``))r.add(t);return typeof e==`string`?ir(e):e===er?er:e._src});t.forEach((e,r)=>{let i=t[r+1],a=t[r-1];e!==er||a===er||(a===void 0?i!==void 0&&i!==er?t[r+1]=`(?:\\/|`+n+`\\/)?`+i:t[r]=n:i===void 0?t[r-1]=a+`(?:\\/|\\/`+n+`)?`:i!==er&&(t[r-1]=a+`(?:\\/|\\/`+n+`\\/)`+i,t[r+1]=er))});let i=t.filter(e=>e!==er);if(this.partial&&i.length>=1){let e=[];for(let t=1;t<=i.length;t++)e.push(i.slice(0,t).join(`/`));return`(?:`+e.join(`|`)+`)`}return i.join(`/`)}).join(`|`),[a,o]=e.length>1?[`(?:`,`)`]:[``,``];i=`^`+a+i+o+`$`,this.partial&&(i=`^(?:\\/|`+a+i.slice(1,-1)+o+`)$`),this.negate&&(i=`^(?!`+i+`).+$`);try{this.regexp=new RegExp(i,[...r].join(``))}catch{this.regexp=!1}return this.regexp}slashSplit(e){return this.preserveMultipleSlashes?e.split(`/`):this.isWindows&&/^\/\/[^\/]+/.test(e)?[``,...e.split(/\/+/)]:e.split(/\/+/)}match(e,t=this.partial){if(this.debug(`match`,e,this.pattern),this.comment)return!1;if(this.empty)return e===``;if(e===`/`&&t)return!0;let n=this.options;this.isWindows&&(e=e.split(`\\`).join(`/`));let r=this.slashSplit(e);this.debug(this.pattern,`split`,r);let i=this.set;this.debug(this.pattern,`set`,i);let a=r[r.length-1];if(!a)for(let e=r.length-2;!a&&e>=0;e--)a=r[e];for(let e=0;e<i.length;e++){let o=i[e],s=r;if(n.matchBase&&o.length===1&&(s=[a]),this.matchOne(s,o,t))return n.flipNegate?!0:!this.negate}return n.flipNegate?!1:this.negate}static defaults(e){return jn.defaults(e).Minimatch}};jn.AST=kn,jn.Minimatch=ar,jn.escape=An,jn.unescape=dn;const or={};function sr(){throw Error(`gunzipSync is not available in the browser`)}function cr(){throw Error(`gzipSync is not available in the browser`)}var lr=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r){setTimeout(function(){r(e)},0);return}else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,h=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let h=c&&c.oldPos+1<o;if(!u&&!h){d[r]=void 0;continue}if(s=!h||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);h()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=h();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}};new class extends lr{};function ur(e,t){let n;for(n=0;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function dr(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function fr(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function pr(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function mr(e,t){return fr(e,t,``)}function hr(e,t){return pr(e,t,``)}function gr(e,t){return t.slice(0,_r(e,t))}function _r(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function vr(e){let t;for(t=e.length-1;t>=0&&e[t].match(/\s/);t--);return e.substring(t+1)}function yr(e){let t=e.match(/^\s*/);return t?t[0]:``}const br=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,xr=RegExp(`[${br}]+|\\s+|[^${br}]`,`ug`);new class extends lr{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=[];for(let t of Array.from(r.segment(e))){let e=t.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}}else n=e.match(xr)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&Sr(n,i,r,e),n=e,r=null,i=null)}),(r||i)&&Sr(n,i,r,null),e}};function Sr(e,t,n,r){if(t&&n){let i=yr(t.value),a=vr(t.value),o=yr(n.value),s=vr(n.value);if(e){let r=ur(i,o);e.value=pr(e.value,o,r),t.value=mr(t.value,r),n.value=mr(n.value,r)}if(r){let e=dr(a,s);r.value=fr(r.value,s,e),t.value=hr(t.value,e),n.value=hr(n.value,e)}}else if(n){if(e){let e=yr(n.value);n.value=n.value.substring(e.length)}if(r){let e=yr(r.value);r.value=r.value.substring(e.length)}}else if(e&&r){let n=yr(r.value),i=yr(t.value),a=vr(t.value),o=ur(n,i);t.value=mr(t.value,o);let s=dr(mr(n,o),a);t.value=hr(t.value,s),r.value=fr(r.value,n,s),e.value=pr(e.value,n,n.slice(0,n.length-s.length))}else if(r){let e=yr(r.value),n=gr(vr(t.value),e);t.value=hr(t.value,n)}else if(e){let n=gr(vr(e.value),yr(t.value));t.value=mr(t.value,n)}}new class extends lr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${br}]+|[^\\S\\n\\r]+|[^${br}]`,`ug`);return e.match(t)||[]}};const Cr=new class extends lr{constructor(){super(...arguments),this.tokenize=Tr}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
|
|
879
|
+
}`,returnByValue:!0},this.sessionId)).result?.value;if(!n||n.width===0||n.height===0)throw Error(`Element with backend node ${e} has no dimensions`);return{x:n.x+n.width/2,y:n.y+n.height/2}}async ensureLocalConnected(){this.localClient.state===`disconnected`&&await this.localClient.connect({url:ct()})}async ensureConnected(){this.client.state===`disconnected`&&(this.remoteTargetInfo&&this.trayTargetProvider?.removeRemoteTransport&&(this.trayTargetProvider.removeRemoteTransport(this.remoteTargetInfo.runtimeId,this.remoteTargetInfo.localTargetId),this.setClient(this.localClient),this.remoteTargetInfo=null),this.sessionId=null,this.attachedTargetId=null,this.client.state===`disconnected`&&await this.connect())}ensureAttached(){if(!this.sessionId)throw Error(`Not attached to a page. Call attachToPage(targetId) first.`)}addDialogListener(e){e.on(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}removeDialogListener(e){e.off(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}setClient(e){this.client!==e&&(this.removeDialogListener(this.client),this.client=e,this.addDialogListener(this.client))}async boundingBox(e){await this.client.send(`DOM.enable`,{},this.sessionId);let t=(await this.client.send(`DOM.getDocument`,{depth:0},this.sessionId)).root.nodeId,n;try{n=(await this.client.send(`DOM.querySelector`,{nodeId:t,selector:e},this.sessionId)).nodeId}catch{return null}if(!n)return null;let r=(await this.client.send(`DOM.getBoxModel`,{nodeId:n},this.sessionId)).model;if(!r)return null;let i=r.content;return{x:i[0],y:i[1],width:r.width,height:r.height}}};function ut(e){let t={role:at(e.role,`unknown`),name:at(e.name)},n=at(e.value);n!==``&&(t.value=n);let r=at(e.description);return r!==``&&(t.description=r),Array.isArray(e.children)&&e.children.length>0&&(t.children=e.children.map(e=>ut(e)).filter(e=>e.role!==`unknown`)),t}function dt(e){return e.headers.get(`x-proxy-error`)===`1`}async function ft(e){let t=`Proxy error ${e.status}`,n;try{n=await e.text()}catch{return t}return pt(n,t)}function pt(e,t){let n;try{n=JSON.parse(e)}catch{return t}if(!n||typeof n!=`object`)return t;let r=n.error;if(typeof r==`string`&&r.length>0)return r;if(r&&typeof r==`object`){let e=r.message;if(typeof e==`string`&&e.length>0)return e;try{return JSON.stringify(r)}catch{return t}}return t}i(`tray-leader`);let mt={state:`inactive`,session:null,error:null};function ht(){return{...mt,session:mt.session?{...mt.session}:null}}const gt=new Set;function _t(e){return gt.add(e),()=>{gt.delete(e)}}const vt=new Set([`send_message`,`list_scoops`,`list_tasks`]),yt=`sessions`;function bt(){return new Promise((e,t)=>{let n=indexedDB.open(`browser-coding-agent`,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(yt)||e.createObjectStore(yt,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}var xt=class{db=null;async init(){this.db=await bt()}ensureDb(){if(!this.db)throw Error(`SessionStore not initialized. Call init() first.`);return this.db}async save(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readwrite`);i.objectStore(yt).put(e),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})}async load(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readonly`).objectStore(yt).get(e);i.onsuccess=()=>n(i.result??null),i.onerror=()=>r(i.error)})}async list(){let e=this.ensureDb();return new Promise((t,n)=>{let r=e.transaction(yt,`readonly`).objectStore(yt).getAll();r.onsuccess=()=>{t(r.result.sort((e,t)=>t.updatedAt-e.updatedAt).map(e=>e.id))},r.onerror=()=>n(r.error)})}async delete(e){let t=this.ensureDb();return new Promise((n,r)=>{let i=t.transaction(yt,`readwrite`);i.objectStore(yt).delete(e),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})}async saveMessages(e,t){let n=await this.load(e),r=n?{...n,messages:t,updatedAt:Date.now()}:{id:e,messages:t,createdAt:Date.now(),updatedAt:Date.now()};await this.save(r)}};const St=i(`panel-transport`);function Ct(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function wt(){return{onMessage:e=>{let t=(t,n,r)=>(Ct(t)&&e(t),!1);return chrome.runtime.onMessage.addListener(t),()=>chrome.runtime.onMessage.removeListener(t)},send:e=>{chrome.runtime.sendMessage({source:`offscreen`,payload:e}).catch(e=>{let t=e instanceof Error?e.message:String(e);/receiving end does not exist/i.test(t)||St.error(`Offscreen → panel transport send failed`,{error:t})})}}}var Tt=class{orchestrator=null;browserAPI=null;messageBuffers=new Map;currentMessageId=new Map;scoopStatuses=new Map;sessionStore=null;followerSync=null;_transport;transportUnsubscribe=null;constructor(e){this._transport=e??null}get transport(){return this._transport||=wt(),this._transport}async bind(e,t){this.orchestrator=e,this.browserAPI=t??null,this.transportUnsubscribe?.(),this.transportUnsubscribe=this.setupMessageListener();let n=new xt;await n.init(),this.sessionStore=n}static createCallbacks(e){return{onResponse:(t,n,r)=>{let i=e.getOrCreateAssistantMsg(t);r?i.content+=n:(i.content=n,i.isStreaming=!1),e.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:n})},onResponseDone:t=>{let n=e.currentMessageId.get(t);if(n){let r=e.getBuffer(t).find(e=>e.id===n);r&&(r.isStreaming=!1),e.currentMessageId.delete(t)}e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`})},onSendMessage:(t,n)=>{let r=e.getBuffer(t),i=`msg-${Et()}`;r.push({id:i,role:`assistant`,content:n,timestamp:Date.now()}),e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:n}),e.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`})},onStatusChange:(t,n)=>{e.scoopStatuses.set(t,n),n===`ready`&&e.currentMessageId.delete(t),e.emit({type:`scoop-status`,scoopJid:t,status:n}),e.emitScoopList()},onCompactionStateChange:(t,n)=>{e.emit({type:`compaction-state`,scoopJid:t,state:n})},onError:(t,n)=>{e.emit({type:`error`,scoopJid:t,error:n})},onToolStart:(t,n,r)=>{if(vt.has(n))return;let i=e.getOrCreateAssistantMsg(t);i.toolCalls||=[],i.toolCalls.push({id:Et(),name:n,input:r}),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:n,toolInput:r})},onToolEnd:(t,n,r,i)=>{if(vt.has(n))return;let a=e.currentMessageId.get(t);if(a){let o=e.getBuffer(t).find(e=>e.id===a);if(o?.toolCalls){let e=[...o.toolCalls].reverse().find(e=>e.name===n&&e.result===void 0);e&&(e.result=r,e.isError=i)}}e.persistScoop(t),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_end`,toolName:n,toolResult:r,isError:i})},onToolUI:(t,n,r,i)=>{e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_ui`,toolName:n,requestId:r,html:i})},onToolUIDone:(t,n)=>{e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_ui_done`,requestId:n})},onIncomingMessage:(t,n)=>{let r={id:n.id,role:`user`,content:n.channel===`delegation`?`**[Instructions from sliccy]**\n\n${n.content}`:n.content,attachments:n.attachments,timestamp:new Date(n.timestamp).getTime(),source:n.channel===`delegation`?`delegation`:void 0,channel:n.channel};e.getBuffer(t).push(r),e.persistScoop(t),e.emit({type:`incoming-message`,scoopJid:t,message:{id:n.id,content:n.content,attachments:n.attachments,channel:n.channel,senderName:n.senderName,fromAssistant:n.fromAssistant,timestamp:n.timestamp}})}}}toScoopSnapshot(e){let t=e.config&&(e.config.modelId!==void 0||e.config.thinkingLevel!==void 0)?{...e.config.modelId===void 0?{}:{modelId:e.config.modelId},...e.config.thinkingLevel===void 0?{}:{thinkingLevel:e.config.thinkingLevel}}:void 0;return{jid:e.jid,name:e.name,folder:e.folder,isCone:e.isCone,assistantLabel:e.assistantLabel,status:this.scoopStatuses.get(e.jid)??`ready`,...t?{config:t}:{}}}buildStateSnapshot(){let e=this.orchestrator?.getScoops().map(e=>this.toScoopSnapshot(e))??[];return{type:`state-snapshot`,scoops:e,activeScoopJid:e.find(e=>e.isCone)?.jid??null,trayRuntimeStatus:this.buildTrayRuntimeStatus()}}emitTrayRuntimeStatus(){let e=this.buildTrayRuntimeStatus(),t={type:`tray-runtime-status`,leader:e.leader,follower:e.follower};this.emit(t)}buildTrayRuntimeStatus(){let e=ht(),t=O();return{leader:{state:e.state,session:e.session,error:e.error??null,reconnectAttempts:e.reconnectAttempts??0},follower:{state:t.state,joinUrl:t.joinUrl,trayId:t.trayId,error:t.error,lastError:t.lastError,reconnectAttempts:t.reconnectAttempts,attachAttempts:t.attachAttempts,lastAttachCode:t.lastAttachCode,connectingSince:t.connectingSince,lastPingTime:t.lastPingTime}}}setFollowerSync(e){this.followerSync=e}applyFollowerSnapshot(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoops().find(e=>e.isCone);if(!t)return;let n=e.map(e=>({id:e.id,role:e.role,content:e.content,attachments:e.attachments,timestamp:e.timestamp,source:e.source,channel:e.channel,toolCalls:e.toolCalls?.map(e=>({id:e.id,name:e.name,input:e.input,result:e.result,isError:e.isError})),isStreaming:e.isStreaming}));if(this.messageBuffers.set(t.jid,n),this.currentMessageId.delete(t.jid),this.sessionStore){let n=t.isCone?`session-cone`:`session-${t.folder}`;this.sessionStore.saveMessages(n,e).catch(e=>{console.warn(`[offscreen-bridge] applyFollowerSnapshot persist failed:`,e)})}this.emit({type:`scoop-messages-replaced`,scoopJid:t.jid,messages:n})}getConeJid(){return this.orchestrator?.getScoops().find(e=>e.isCone)?.jid??null}emitFollowerAgentEvent(e){let t=this.getConeJid();if(t)switch(e.type){case`content_delta`:this.emit({type:`agent-event`,scoopJid:t,eventType:`text_delta`,text:e.text});break;case`content_done`:this.emit({type:`agent-event`,scoopJid:t,eventType:`response_done`});break;case`tool_use_start`:this.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:e.toolName,toolInput:e.toolInput});break;case`tool_result`:this.emit({type:`agent-event`,scoopJid:t,eventType:`tool_end`,toolName:e.toolName,toolResult:e.result,isError:e.isError});break;case`turn_end`:this.emit({type:`agent-event`,scoopJid:t,eventType:`turn_end`});break;case`error`:this.emit({type:`error`,scoopJid:t,error:e.error});break}}emitFollowerIncomingMessage(e,t){let n=this.getConeJid();n&&this.emit({type:`incoming-message`,scoopJid:n,message:{id:e,content:t,channel:`web`,senderName:`User`,fromAssistant:!1,timestamp:new Date().toISOString()}})}emitFollowerStatus(e){let t=this.getConeJid();if(!t)return;let n=e===`processing`?`processing`:`ready`;this.scoopStatuses.set(t,n),this.emit({type:`scoop-status`,scoopJid:t,status:n})}async handleRequestScoopMessages(e){if(!this.orchestrator)return;let t=this.orchestrator.getScoops().find(t=>t.jid===e);if(!t)return;let n=this.messageBuffers.get(e);if(n&&n.length>0){this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:n});return}let r=this.orchestrator.getScoopContext(e);if(r){let{agentMessagesToChatMessages:n}=await import(`./agent-message-to-chat-BVeCeF6Q.js`),i=r.getAgentMessages();if(i.length>0){let r=n(i,{source:t.isCone?`cone`:t.name??t.folder}).map(e=>({id:e.id,role:e.role,content:e.content,attachments:e.attachments,timestamp:e.timestamp,source:e.source,channel:e.channel,toolCalls:e.toolCalls?.map(e=>({id:e.id,name:e.name,input:e.input,result:e.result,isError:e.isError})),isStreaming:!1}));this.messageBuffers.set(e,r),this.currentMessageId.delete(e),this.persistScoop(e),this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:r});return}}if(this.sessionStore){let n=t.isCone?`session-cone`:`session-${t.folder}`;try{let t=(await this.sessionStore.load(n))?.messages??[];t.length>0&&(this.messageBuffers.set(e,t),this.currentMessageId.delete(e),this.emit({type:`scoop-messages-replaced`,scoopJid:e,messages:t}))}catch(e){console.warn(`[offscreen-bridge] sessionStore load failed:`,n,e)}}}persistScoop(e){if(!this.sessionStore||!this.orchestrator)return;let t=this.orchestrator.getScoops().find(t=>t.jid===e);if(!t)return;let n=t.isCone?`session-cone`:`session-${t.folder}`,r=this.messageBuffers.get(e);!r||r.length===0||this.sessionStore.saveMessages(n,r).catch(e=>{console.warn(`[offscreen-bridge] persistScoop failed:`,n,e)})}getBuffer(e){let t=this.messageBuffers.get(e);return t||(t=[],this.messageBuffers.set(e,t)),t}getOrCreateAssistantMsg(e){let t=this.getBuffer(e),n=this.currentMessageId.get(e);if(n){let e=t.find(e=>e.id===n);if(e)return e}n=`scoop-${e}-${Et()}`,this.currentMessageId.set(e,n);let r=(this.orchestrator?.getScoops()??[]).find(t=>t.jid===e),i=r?.isCone?`cone`:r?.name??`unknown`,a={id:n,role:`assistant`,content:``,timestamp:Date.now(),toolCalls:[],isStreaming:!0,source:i};return t.push(a),a}setupMessageListener(){return this.transport.onMessage(e=>{if(e.source===`panel`){if(e.payload?.type===`sprinkle-op-response`){import(`./sprinkle-proxy-CgcbIA81.js`).then(({handleSprinkleOpResponse:t})=>{t(e.payload)});return}this.handlePanelMessage(e.payload).catch(t=>{console.error(`[offscreen-bridge] handlePanelMessage error:`,t);let n=e.payload.scoopJid;n&&this.emit({type:`error`,scoopJid:n,error:t instanceof Error?t.message:String(t)})})}})}async handlePanelMessage(e){if(this.orchestrator)switch(e.type){case`user-message`:{if(this.followerSync){this.getBuffer(e.scoopJid).push({id:e.messageId,role:`user`,content:e.text,attachments:e.attachments,timestamp:Date.now()}),this.persistScoop(e.scoopJid),this.followerSync.sendMessage(e.text,e.messageId,e.attachments);break}let t={id:e.messageId,chatJid:e.scoopJid,senderId:`user`,senderName:`User`,content:e.text,attachments:e.attachments,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`web`};this.getBuffer(e.scoopJid).push({id:e.messageId,role:`user`,content:e.text,attachments:e.attachments,timestamp:Date.now()}),this.persistScoop(e.scoopJid),await this.orchestrator.handleMessage(t),this.orchestrator.createScoopTab(e.scoopJid);break}case`cone-create`:{let t={jid:`cone_${Date.now()}`,name:e.name,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()};await this.orchestrator.registerScoop(t),this.emit({type:`scoop-created`,scoop:this.toScoopSnapshot(t)});break}case`scoop-feed`:await this.orchestrator.delegateToScoop(e.scoopJid,e.prompt,`sliccy`);break;case`scoop-drop`:{let t=this.orchestrator.getScoops().find(t=>t.jid===e.scoopJid);if(await this.orchestrator.unregisterScoop(e.scoopJid),this.messageBuffers.delete(e.scoopJid),this.currentMessageId.delete(e.scoopJid),this.scoopStatuses.delete(e.scoopJid),t&&this.sessionStore){let e=t.isCone?`session-cone`:`session-${t.folder}`;this.sessionStore.delete(e).catch(t=>{console.warn(`[offscreen-bridge] Failed to delete session on scoop drop:`,e,t)})}this.emitScoopList();break}case`abort`:this.orchestrator.stopScoop(e.scoopJid),this.orchestrator.clearQueuedMessages(e.scoopJid).catch(e=>{console.warn(`[offscreen-bridge] Failed to clear queued messages on abort:`,e)});break;case`set-model`:this.orchestrator.updateModel();break;case`request-state`:this.emit(this.buildStateSnapshot());break;case`request-scoop-messages`:await this.handleRequestScoopMessages(e.scoopJid);break;case`clear-chat`:{let t=this.orchestrator.getScoops().find(e=>e.isCone)?.jid;t&&await this.orchestrator.clearScoopMessages(t),this.sessionStore&&await this.sessionStore.delete(`session-cone`),t&&(this.messageBuffers.delete(t),this.currentMessageId.delete(t)),this.emit({type:`clear-chat-ack`,requestId:e.requestId});break}case`clear-filesystem`:try{await this.orchestrator.resetFilesystem()}catch(e){console.error(`[offscreen-bridge] clear-filesystem failed:`,e)}break;case`refresh-model`:this.orchestrator.updateModel();break;case`set-thinking-level`:{let t=e;try{await this.orchestrator.setScoopThinkingLevel(t.scoopJid,t.level)}catch(e){console.error(`[offscreen-bridge] set-thinking-level failed:`,e)}break}case`sprinkle-lick`:{let t=this.orchestrator.getScoops(),n=e,r=n.targetScoop?t.find(e=>e.name===n.targetScoop||e.folder===n.targetScoop||e.folder===`${n.targetScoop}-scoop`):void 0;if(r||=t.find(e=>e.isCone),r){let e=`sprinkle-${n.sprinkleName}-${Date.now()}`,t=`[Sprinkle Event: ${n.sprinkleName}]\n\`\`\`json\n${JSON.stringify(n.body,null,2)}\n\`\`\``,i={id:e,chatJid:r.jid,senderId:`sprinkle`,senderName:`sprinkle:${n.sprinkleName}`,content:t,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`sprinkle`};this.getBuffer(r.jid).push({id:e,role:`user`,content:t,timestamp:Date.now(),source:`lick`,channel:`sprinkle`}),this.persistScoop(r.jid),await this.orchestrator.handleMessage(i)}break}case`lick-webhook-event`:this.orchestrator.handleWebhookEvent(e.webhookId,e.headers,e.body);break;case`reload-skills`:this.orchestrator.reloadAllSkills().catch(e=>{console.warn(`[offscreen-bridge] Skill reload failed:`,e)});break;case`panel-cdp-command`:{let{id:t,method:n,params:r,sessionId:i}=e;if(!this.browserAPI){console.warn(`[offscreen-bridge] Panel CDP command received but BrowserAPI is null`),this.emit({type:`panel-cdp-response`,id:t,error:`BrowserAPI not available`});break}try{let e=await this.browserAPI.getTransport().send(n,r,i);this.emit({type:`panel-cdp-response`,id:t,result:e})}catch(e){this.emit({type:`panel-cdp-response`,id:t,error:e instanceof Error?e.message:String(e)})}break}case`tool-ui-action`:{let{requestId:t,action:n,data:r}=e;try{await pe.handleAction(t,{action:n,data:r})}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`[offscreen-bridge] Tool UI action failed`,{requestId:t,action:n,error:r}),pe.cancel(t,`Action failed: ${r}`)}break}case`local-storage-set`:try{globalThis.localStorage?.setItem(e.key,e.value)}catch(e){console.warn(`[offscreen-bridge] local-storage-set failed:`,e)}break;case`local-storage-remove`:try{globalThis.localStorage?.removeItem(e.key)}catch(e){console.warn(`[offscreen-bridge] local-storage-remove failed:`,e)}break;case`local-storage-clear`:try{globalThis.localStorage?.clear()}catch(e){console.warn(`[offscreen-bridge] local-storage-clear failed:`,e)}break}}emitScoopList(){let e=this.orchestrator?.getScoops().map(e=>this.toScoopSnapshot(e))??[];this.emit({type:`scoop-list`,scoops:e})}emit(e){this.transport.send(e)}};function Et(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}const Dt=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`];function Ot(e){return typeof e==`string`&&Dt.includes(e)}var kt=r((e=>{(function(){var t={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function n(e){return i(o(e),arguments)}function r(e,t){return n.apply(null,[e].concat(t||[]))}function i(e,r){var i=1,a=e.length,o,s=``,c,l,u,d,f,p,m,h;for(c=0;c<a;c++)if(typeof e[c]==`string`)s+=e[c];else if(typeof e[c]==`object`){if(u=e[c],u.keys)for(o=r[i],l=0;l<u.keys.length;l++){if(o==null)throw Error(n(`[sprintf] Cannot access property "%s" of undefined value "%s"`,u.keys[l],u.keys[l-1]));o=o[u.keys[l]]}else o=u.param_no?r[u.param_no]:r[i++];if(t.not_type.test(u.type)&&t.not_primitive.test(u.type)&&o instanceof Function&&(o=o()),t.numeric_arg.test(u.type)&&typeof o!=`number`&&isNaN(o))throw TypeError(n(`[sprintf] expecting number but found %T`,o));switch(t.number.test(u.type)&&(m=o>=0),u.type){case`b`:o=parseInt(o,10).toString(2);break;case`c`:o=String.fromCharCode(parseInt(o,10));break;case`d`:case`i`:o=parseInt(o,10);break;case`j`:o=JSON.stringify(o,null,u.width?parseInt(u.width):0);break;case`e`:o=u.precision?parseFloat(o).toExponential(u.precision):parseFloat(o).toExponential();break;case`f`:o=u.precision?parseFloat(o).toFixed(u.precision):parseFloat(o);break;case`g`:o=u.precision?String(Number(o.toPrecision(u.precision))):parseFloat(o);break;case`o`:o=(parseInt(o,10)>>>0).toString(8);break;case`s`:o=String(o),o=u.precision?o.substring(0,u.precision):o;break;case`t`:o=String(!!o),o=u.precision?o.substring(0,u.precision):o;break;case`T`:o=Object.prototype.toString.call(o).slice(8,-1).toLowerCase(),o=u.precision?o.substring(0,u.precision):o;break;case`u`:o=parseInt(o,10)>>>0;break;case`v`:o=o.valueOf(),o=u.precision?o.substring(0,u.precision):o;break;case`x`:o=(parseInt(o,10)>>>0).toString(16);break;case`X`:o=(parseInt(o,10)>>>0).toString(16).toUpperCase();break}t.json.test(u.type)?s+=o:(t.number.test(u.type)&&(!m||u.sign)?(h=m?`+`:`-`,o=o.toString().replace(t.sign,``)):h=``,f=u.pad_char?u.pad_char===`0`?`0`:u.pad_char.charAt(1):` `,p=u.width-(h+o).length,d=u.width&&p>0?f.repeat(p):``,s+=u.align?h+o+d:f===`0`?h+d+o:d+h+o)}return s}var a=Object.create(null);function o(e){if(a[e])return a[e];for(var n=e,r,i=[],o=0;n;){if((r=t.text.exec(n))!==null)i.push(r[0]);else if((r=t.modulo.exec(n))!==null)i.push(`%`);else if((r=t.placeholder.exec(n))!==null){if(r[2]){o|=1;var s=[],c=r[2],l=[];if((l=t.key.exec(c))!==null)for(s.push(l[1]);(c=c.substring(l[0].length))!==``;)if((l=t.key_access.exec(c))!==null)s.push(l[1]);else if((l=t.index_access.exec(c))!==null)s.push(l[1]);else throw SyntaxError(`[sprintf] failed to parse named argument key`);else throw SyntaxError(`[sprintf] failed to parse named argument key`);r[2]=s}else o|=2;if(o===3)throw Error(`[sprintf] mixing positional and named placeholders is not (yet) supported`);i.push({placeholder:r[0],param_no:r[1],keys:r[2],sign:r[3],pad_char:r[4],align:r[5],width:r[6],precision:r[7],type:r[8]})}else throw SyntaxError(`[sprintf] unexpected placeholder`);n=n.substring(r[0].length)}return a[e]=i}e!==void 0&&(e.sprintf=n,e.vsprintf=r),typeof window<`u`&&(window.sprintf=n,window.vsprintf=r,typeof define==`function`&&define.amd&&define(function(){return{sprintf:n,vsprintf:r}}))})()}))();const At=(e,t,n)=>{let r=e instanceof RegExp?jt(e,n):e,i=t instanceof RegExp?jt(t,n):t,a=r!==null&&i!=null&&Mt(r,i,n);return a&&{start:a[0],end:a[1],pre:n.slice(0,a[0]),body:n.slice(a[0]+r.length,a[1]),post:n.slice(a[1]+i.length)}},jt=(e,t)=>{let n=t.match(e);return n?n[0]:null},Mt=(e,t,n)=>{let r,i,a,o,s,c=n.indexOf(e),l=n.indexOf(t,c+1),u=c;if(c>=0&&l>0){if(e===t)return[c,l];for(r=[],a=n.length;u>=0&&!s;){if(u===c)r.push(u),c=n.indexOf(e,u+1);else if(r.length===1){let e=r.pop();e!==void 0&&(s=[e,l])}else i=r.pop(),i!==void 0&&i<a&&(a=i,o=l),l=n.indexOf(t,u+1);u=c<l&&c>=0?c:l}r.length&&o!==void 0&&(s=[a,o])}return s},Nt=`\0SLASH`+Math.random()+`\0`,Pt=`\0OPEN`+Math.random()+`\0`,Ft=`\0CLOSE`+Math.random()+`\0`,It=`\0COMMA`+Math.random()+`\0`,Lt=`\0PERIOD`+Math.random()+`\0`,Rt=new RegExp(Nt,`g`),zt=new RegExp(Pt,`g`),Bt=new RegExp(Ft,`g`),Vt=new RegExp(It,`g`),Ht=new RegExp(Lt,`g`),Ut=/\\\\/g,Wt=/\\{/g,Gt=/\\}/g,Kt=/\\,/g,qt=/\\\./g;function Jt(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function Yt(e){return e.replace(Ut,Nt).replace(Wt,Pt).replace(Gt,Ft).replace(Kt,It).replace(qt,Lt)}function Xt(e){return e.replace(Rt,`\\`).replace(zt,`{`).replace(Bt,`}`).replace(Vt,`,`).replace(Ht,`.`)}function Zt(e){if(!e)return[``];let t=[],n=At(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=Zt(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function Qt(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),rn(Yt(e),n,!0).map(Xt)}function $t(e){return`{`+e+`}`}function en(e){return/^-?0\d/.test(e)}function tn(e,t){return e<=t}function nn(e,t){return e>=t}function rn(e,t,n){let r=[],i=At(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?rn(i.post,t,!1):[``];if(/\$$/.test(i.pre))for(let e=0;e<o.length&&e<t;e++){let t=a+`{`+i.body+`}`+o[e];r.push(t)}else{let s=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(i.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(i.body),l=s||c,u=i.body.indexOf(`,`)>=0;if(!l&&!u)return i.post.match(/,(?!,).*\}/)?(e=i.pre+`{`+i.body+Ft+i.post,rn(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=Zt(i.body),d.length===1&&d[0]!==void 0&&(d=rn(d[0],t,!1).map($t),d.length===1))return o.map(e=>i.pre+d[0]+e);let f;if(l&&d[0]!==void 0&&d[1]!==void 0){let e=Jt(d[0]),t=Jt(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.abs(Jt(d[2])):1,i=tn;t<e&&(r*=-1,i=nn);let a=d.some(en);f=[];for(let o=e;i(o,t);o+=r){let e;if(c)e=String.fromCharCode(o),e===`\\`&&(e=``);else if(e=String(o),a){let t=n-e.length;if(t>0){let n=Array(t+1).join(`0`);e=o<0?`-`+n+e.slice(1):n+e}}f.push(e)}}else{f=[];for(let e=0;e<d.length;e++)f.push.apply(f,rn(d[e],t,!1))}for(let e=0;e<f.length;e++)for(let i=0;i<o.length&&r.length<t;i++){let t=a+f[e]+o[i];(!n||l||t)&&r.push(t)}}return r}const an=e=>{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},on={"[:alnum:]":[`\\p{L}\\p{Nl}\\p{Nd}`,!0],"[:alpha:]":[`\\p{L}\\p{Nl}`,!0],"[:ascii:]":[`\\x00-\\x7f`,!1],"[:blank:]":[`\\p{Zs}\\t`,!0],"[:cntrl:]":[`\\p{Cc}`,!0],"[:digit:]":[`\\p{Nd}`,!0],"[:graph:]":[`\\p{Z}\\p{C}`,!0,!0],"[:lower:]":[`\\p{Ll}`,!0],"[:print:]":[`\\p{C}`,!0],"[:punct:]":[`\\p{P}`,!0],"[:space:]":[`\\p{Z}\\t\\r\\n\\v\\f`,!0],"[:upper:]":[`\\p{Lu}`,!0],"[:word:]":[`\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}`,!0],"[:xdigit:]":[`A-Fa-f0-9`,!1]},sn=e=>e.replace(/[[\]\\-]/g,`\\$&`),cn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),ln=e=>e.join(``),un=(e,t)=>{let n=t;if(e.charAt(n)!==`[`)throw Error(`not in a brace expression`);let r=[],i=[],a=n+1,o=!1,s=!1,c=!1,l=!1,u=n,d=``;WHILE:for(;a<e.length;){let t=e.charAt(a);if((t===`!`||t===`^`)&&a===n+1){l=!0,a++;continue}if(t===`]`&&o&&!c){u=a+1;break}if(o=!0,t===`\\`&&!c){c=!0,a++;continue}if(t===`[`&&!c){for(let[t,[o,c,l]]of Object.entries(on))if(e.startsWith(t,a)){if(d)return[`$.`,!1,e.length-n,!0];a+=t.length,l?i.push(o):r.push(o),s||=c;continue WHILE}}if(c=!1,d){t>d?r.push(sn(d)+`-`+sn(t)):t===d&&r.push(sn(t)),d=``,a++;continue}if(e.startsWith(`-]`,a+1)){r.push(sn(t+`-`)),a+=2;continue}if(e.startsWith(`-`,a+1)){d=t,a+=2;continue}r.push(sn(t)),a++}if(u<a)return[``,!1,0,!1];if(!r.length&&!i.length)return[`$.`,!1,e.length-n,!0];if(i.length===0&&r.length===1&&/^\\?.$/.test(r[0])&&!l)return[cn(r[0].length===2?r[0].slice(-1):r[0]),!1,u-n,!1];let f=`[`+(l?`^`:``)+ln(r)+`]`,p=`[`+(l?``:`^`)+ln(i)+`]`;return[r.length&&i.length?`(`+f+`|`+p+`)`:r.length?f:p,s,u-n,!0]},dn=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!0}={})=>n?t?e.replace(/\[([^\/\\])\]/g,`$1`):e.replace(/((?!\\).|^)\[([^\/\\])\]/g,`$1$2`).replace(/\\([^\/])/g,`$1`):t?e.replace(/\[([^\/\\{}])\]/g,`$1`):e.replace(/((?!\\).|^)\[([^\/\\{}])\]/g,`$1$2`).replace(/\\([^\/{}])/g,`$1`);var fn;const pn=new Set([`!`,`?`,`+`,`*`,`@`]),mn=e=>pn.has(e),hn=e=>mn(e.type),gn=new Map([[`!`,[`@`]],[`?`,[`?`,`@`]],[`@`,[`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`]]]),_n=new Map([[`!`,[`?`]],[`@`,[`?`]],[`+`,[`?`,`*`]]]),vn=new Map([[`!`,[`?`,`@`]],[`?`,[`?`,`@`]],[`@`,[`?`,`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`,`?`,`*`]]]),yn=new Map([[`!`,new Map([[`!`,`@`]])],[`?`,new Map([[`*`,`*`],[`+`,`*`]])],[`@`,new Map([[`!`,`!`],[`?`,`?`],[`@`,`@`],[`*`,`*`],[`+`,`+`]])],[`+`,new Map([[`?`,`*`],[`*`,`*`]])]]),bn=`(?!\\.)`,xn=new Set([`[`,`.`]),Sn=new Set([`..`,`.`]),Cn=new Set(`().*{}+?[]^$\\!`),wn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),Tn=`[^/]`,En=Tn+`*?`,Dn=Tn+`+?`;let On=0;var kn=class{type;#e;#t;#n=!1;#r=[];#i;#a;#o;#s=!1;#c;#l;#u=!1;id=++On;get depth(){return(this.#i?.depth??-1)+1}[Symbol.for(`nodejs.util.inspect.custom`)](){return{"@@type":`AST`,id:this.id,type:this.type,root:this.#e.id,parent:this.#i?.id,depth:this.depth,partsLength:this.#r.length,parts:this.#r}}constructor(e,t,n={}){this.type=e,e&&(this.#t=!0),this.#i=t,this.#e=this.#i?this.#i.#e:this,this.#c=this.#e===this?n:this.#e.#c,this.#o=this.#e===this?[]:this.#e.#o,e===`!`&&!this.#e.#s&&this.#o.push(this),this.#a=this.#i?this.#i.#r.length:0}get hasMagic(){if(this.#t!==void 0)return this.#t;for(let e of this.#r)if(typeof e!=`string`&&(e.type||e.hasMagic))return this.#t=!0;return this.#t}toString(){return this.#l===void 0?this.type?this.#l=this.type+`(`+this.#r.map(e=>String(e)).join(`|`)+`)`:this.#l=this.#r.map(e=>String(e)).join(``):this.#l}#d(){if(this!==this.#e)throw Error(`should only call on root`);if(this.#s)return this;this.toString(),this.#s=!0;let e;for(;e=this.#o.pop();){if(e.type!==`!`)continue;let t=e,n=t.#i;for(;n;){for(let r=t.#a+1;!n.type&&r<n.#r.length;r++)for(let t of e.#r){if(typeof t==`string`)throw Error(`string part in extglob AST??`);t.copyIn(n.#r[r])}t=n,n=t.#i}}return this}push(...e){for(let t of e)if(t!==``){if(typeof t!=`string`&&!(t instanceof fn&&t.#i===this))throw Error(`invalid part: `+t);this.#r.push(t)}}toJSON(){let e=this.type===null?this.#r.slice().map(e=>typeof e==`string`?e:e.toJSON()):[this.type,...this.#r.map(e=>e.toJSON())];return this.isStart()&&!this.type&&e.unshift([]),this.isEnd()&&(this===this.#e||this.#e.#s&&this.#i?.type===`!`)&&e.push({}),e}isStart(){if(this.#e===this)return!0;if(!this.#i?.isStart())return!1;if(this.#a===0)return!0;let e=this.#i;for(let t=0;t<this.#a;t++){let n=e.#r[t];if(!(n instanceof fn&&n.type===`!`))return!1}return!0}isEnd(){if(this.#e===this||this.#i?.type===`!`)return!0;if(!this.#i?.isEnd())return!1;if(!this.type)return this.#i?.isEnd();let e=this.#i?this.#i.#r.length:0;return this.#a===e-1}copyIn(e){typeof e==`string`?this.push(e):this.push(e.clone(this))}clone(e){let t=new fn(this.type,e);for(let e of this.#r)t.copyIn(e);return t}static#f(e,t,n,r,i){let a=r.maxExtglobRecursion??2,o=!1,s=!1,c=-1,l=!1;if(t.type===null){let u=n,d=``;for(;u<e.length;){let n=e.charAt(u++);if(o||n===`\\`){o=!o,d+=n;continue}if(s){u===c+1?(n===`^`||n===`!`)&&(l=!0):n===`]`&&!(u===c+2&&l)&&(s=!1),d+=n;continue}else if(n===`[`){s=!0,c=u,l=!1,d+=n;continue}if(!r.noext&&mn(n)&&e.charAt(u)===`(`&&i<=a){t.push(d),d=``;let a=new fn(n,t);u=fn.#f(e,a,u,r,i+1),t.push(a);continue}d+=n}return t.push(d),u}let u=n+1,d=new fn(null,t),f=[],p=``;for(;u<e.length;){let n=e.charAt(u++);if(o||n===`\\`){o=!o,p+=n;continue}if(s){u===c+1?(n===`^`||n===`!`)&&(l=!0):n===`]`&&!(u===c+2&&l)&&(s=!1),p+=n;continue}else if(n===`[`){s=!0,c=u,l=!1,p+=n;continue}if(!r.noext&&mn(n)&&e.charAt(u)===`(`&&(i<=a||t&&t.#h(n))){let a=t&&t.#h(n)?0:1;d.push(p),p=``;let o=new fn(n,d);d.push(o),u=fn.#f(e,o,u,r,i+a);continue}if(n===`|`){d.push(p),p=``,f.push(d),d=new fn(null,t);continue}if(n===`)`)return p===``&&t.#r.length===0&&(t.#u=!0),d.push(p),p=``,t.push(...f,d),u;p+=n}return t.type=null,t.#t=void 0,t.#r=[e.substring(n-1)],u}#p(e){return this.#m(e,_n)}#m(e,t=gn){if(!e||typeof e!=`object`||e.type!==null||e.#r.length!==1||this.type===null)return!1;let n=e.#r[0];return!n||typeof n!=`object`||n.type===null?!1:this.#h(n.type,t)}#h(e,t=vn){return!!t.get(this.type)?.includes(e)}#g(e,t){let n=e.#r[0],r=new fn(null,n,this.options);r.#r.push(``),n.push(r),this.#_(e,t)}#_(e,t){let n=e.#r[0];this.#r.splice(t,1,...n.#r);for(let e of n.#r)typeof e==`object`&&(e.#i=this);this.#l=void 0}#v(e){return!!yn.get(this.type)?.has(e)}#y(e){if(!e||typeof e!=`object`||e.type!==null||e.#r.length!==1||this.type===null||this.#r.length!==1)return!1;let t=e.#r[0];return!t||typeof t!=`object`||t.type===null?!1:this.#v(t.type)}#b(e){let t=yn.get(this.type),n=e.#r[0],r=t?.get(n.type);if(!r)return!1;this.#r=n.#r;for(let e of this.#r)typeof e==`object`&&(e.#i=this);this.type=r,this.#l=void 0,this.#u=!1}static fromGlob(e,t={}){let n=new fn(null,void 0,t);return fn.#f(e,n,0,t,0),n}toMMPattern(){if(this!==this.#e)return this.#e.toMMPattern();let e=this.toString(),[t,n,r,i]=this.toRegExpSource();if(!(r||this.#t||this.#c.nocase&&!this.#c.nocaseMagicOnly&&e.toUpperCase()!==e.toLowerCase()))return n;let a=(this.#c.nocase?`i`:``)+(i?`u`:``);return Object.assign(RegExp(`^${t}$`,a),{_src:t,_glob:e})}get options(){return this.#c}toRegExpSource(e){let t=e??!!this.#c.dot;if(this.#e===this&&(this.#x(),this.#d()),!hn(this)){let n=this.isStart()&&this.isEnd()&&!this.#r.some(e=>typeof e!=`string`),r=this.#r.map(t=>{let[r,i,a,o]=typeof t==`string`?fn.#C(t,this.#t,n):t.toRegExpSource(e);return this.#t=this.#t||a,this.#n=this.#n||o,r}).join(``),i=``;if(this.isStart()&&typeof this.#r[0]==`string`&&!(this.#r.length===1&&Sn.has(this.#r[0]))){let n=xn,a=t&&n.has(r.charAt(0))||r.startsWith(`\\.`)&&n.has(r.charAt(2))||r.startsWith(`\\.\\.`)&&n.has(r.charAt(4)),o=!t&&!e&&n.has(r.charAt(0));i=a?`(?!(?:^|/)\\.\\.?(?:$|/))`:o?bn:``}let a=``;return this.isEnd()&&this.#e.#s&&this.#i?.type===`!`&&(a=`(?:$|\\/)`),[i+r+a,dn(r),this.#t=!!this.#t,this.#n]}let n=this.type===`*`||this.type===`+`,r=this.type===`!`?`(?:(?!(?:`:`(?:`,i=this.#S(t);if(this.isStart()&&this.isEnd()&&!i&&this.type!==`!`){let e=this.toString(),t=this;return t.#r=[e],t.type=null,t.#t=void 0,[e,dn(this.toString()),!1,!1]}let a=!n||e||t?``:this.#S(!0);a===i&&(a=``),a&&(i=`(?:${i})(?:${a})*?`);let o=``;if(this.type===`!`&&this.#u)o=(this.isStart()&&!t?bn:``)+Dn;else{let n=this.type===`!`?`))`+(this.isStart()&&!t&&!e?bn:``)+En+`)`:this.type===`@`?`)`:this.type===`?`?`)?`:this.type===`+`&&a?`)`:this.type===`*`&&a?`)?`:`)${this.type}`;o=r+i+n}return[o,dn(i),this.#t=!!this.#t,this.#n]}#x(){if(hn(this)){let e=0,t=!1;do{t=!0;for(let e=0;e<this.#r.length;e++){let n=this.#r[e];typeof n==`object`&&(n.#x(),this.#m(n)?(t=!1,this.#_(n,e)):this.#p(n)?(t=!1,this.#g(n,e)):this.#y(n)&&(t=!1,this.#b(n)))}}while(!t&&++e<10)}else for(let e of this.#r)typeof e==`object`&&e.#x();this.#l=void 0}#S(e){return this.#r.map(t=>{if(typeof t==`string`)throw Error(`string type in extglob ast??`);let[n,r,i,a]=t.toRegExpSource(e);return this.#n=this.#n||a,n}).filter(e=>!(this.isStart()&&this.isEnd())||!!e).join(`|`)}static#C(e,t,n=!1){let r=!1,i=``,a=!1,o=!1;for(let s=0;s<e.length;s++){let c=e.charAt(s);if(r){r=!1,i+=(Cn.has(c)?`\\`:``)+c;continue}if(c===`*`){if(o)continue;o=!0,i+=n&&/^[*]+$/.test(e)?Dn:En,t=!0;continue}else o=!1;if(c===`\\`){s===e.length-1?i+=`\\\\`:r=!0;continue}if(c===`[`){let[n,r,o,c]=un(e,s);if(o){i+=n,a||=r,s+=o-1,t||=c;continue}}if(c===`?`){i+=Tn,t=!0;continue}i+=wn(c)}return[i,dn(e),!!t,a]}};fn=kn;const An=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!1}={})=>n?t?e.replace(/[?*()[\]{}]/g,`[$&]`):e.replace(/[?*()[\]\\{}]/g,`\\$&`):t?e.replace(/[?*()[\]]/g,`[$&]`):e.replace(/[?*()[\]\\]/g,`\\$&`),jn=(e,t,n={})=>(an(t),!n.nocomment&&t.charAt(0)===`#`?!1:new ar(t,n).match(e)),Mn=/^\*+([^+@!?\*\[\(]*)$/,Nn=e=>t=>!t.startsWith(`.`)&&t.endsWith(e),Pn=e=>t=>t.endsWith(e),Fn=e=>(e=e.toLowerCase(),t=>!t.startsWith(`.`)&&t.toLowerCase().endsWith(e)),In=e=>(e=e.toLowerCase(),t=>t.toLowerCase().endsWith(e)),Ln=/^\*+\.\*+$/,Rn=e=>!e.startsWith(`.`)&&e.includes(`.`),zn=e=>e!==`.`&&e!==`..`&&e.includes(`.`),Bn=/^\.\*+$/,Vn=e=>e!==`.`&&e!==`..`&&e.startsWith(`.`),Hn=/^\*+$/,Un=e=>e.length!==0&&!e.startsWith(`.`),Wn=e=>e.length!==0&&e!==`.`&&e!==`..`,Gn=/^\?+([^+@!?\*\[\(]*)?$/,Kn=([e,t=``])=>{let n=Xn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},qn=([e,t=``])=>{let n=Zn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Jn=([e,t=``])=>{let n=Zn([e]);return t?e=>n(e)&&e.endsWith(t):n},Yn=([e,t=``])=>{let n=Xn([e]);return t?e=>n(e)&&e.endsWith(t):n},Xn=([e])=>{let t=e.length;return e=>e.length===t&&!e.startsWith(`.`)},Zn=([e])=>{let t=e.length;return e=>e.length===t&&e!==`.`&&e!==`..`},Qn=typeof process==`object`&&process?{}.__MINIMATCH_TESTING_PLATFORM__||process.platform:`posix`,$n={win32:{sep:`\\`},posix:{sep:`/`}};jn.sep=Qn===`win32`?$n.win32.sep:$n.posix.sep;const er=Symbol(`globstar **`);jn.GLOBSTAR=er,jn.filter=(e,t={})=>n=>jn(n,e,t);const tr=(e,t={})=>Object.assign({},e,t);jn.defaults=e=>{if(!e||typeof e!=`object`||!Object.keys(e).length)return jn;let t=jn;return Object.assign((n,r,i={})=>t(n,r,tr(e,i)),{Minimatch:class extends t.Minimatch{constructor(t,n={}){super(t,tr(e,n))}static defaults(n){return t.defaults(tr(e,n)).Minimatch}},AST:class extends t.AST{constructor(t,n,r={}){super(t,n,tr(e,r))}static fromGlob(n,r={}){return t.AST.fromGlob(n,tr(e,r))}},unescape:(n,r={})=>t.unescape(n,tr(e,r)),escape:(n,r={})=>t.escape(n,tr(e,r)),filter:(n,r={})=>t.filter(n,tr(e,r)),defaults:n=>t.defaults(tr(e,n)),makeRe:(n,r={})=>t.makeRe(n,tr(e,r)),braceExpand:(n,r={})=>t.braceExpand(n,tr(e,r)),match:(n,r,i={})=>t.match(n,r,tr(e,i)),sep:t.sep,GLOBSTAR:er})};const nr=(e,t={})=>(an(e),t.nobrace||!/\{(?:(?!\{).)*\}/.test(e)?[e]:Qt(e,{max:t.braceExpandMax}));jn.braceExpand=nr,jn.makeRe=(e,t={})=>new ar(e,t).makeRe(),jn.match=(e,t,n={})=>{let r=new ar(t,n);return e=e.filter(e=>r.match(e)),r.options.nonull&&!e.length&&e.push(t),e};const rr=/[?*]|[+@!]\(.*?\)|\[|\]/,ir=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`);var ar=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;maxGlobstarRecursion;regexp;constructor(e,t={}){an(e),t||={},this.options=t,this.maxGlobstarRecursion=t.maxGlobstarRecursion??200,this.pattern=e,this.platform=t.platform||Qn,this.isWindows=this.platform===`win32`,this.windowsPathsNoEscape=!!t.windowsPathsNoEscape||t.allowWindowsEscape===!1,this.windowsPathsNoEscape&&(this.pattern=this.pattern.replace(/\\/g,`/`)),this.preserveMultipleSlashes=!!t.preserveMultipleSlashes,this.regexp=null,this.negate=!1,this.nonegate=!!t.nonegate,this.comment=!1,this.empty=!1,this.partial=!!t.partial,this.nocase=!!this.options.nocase,this.windowsNoMagicRoot=t.windowsNoMagicRoot===void 0?!!(this.isWindows&&this.nocase):t.windowsNoMagicRoot,this.globSet=[],this.globParts=[],this.set=[],this.make()}hasMagic(){if(this.options.magicalBraces&&this.set.length>1)return!0;for(let e of this.set)for(let t of e)if(typeof t!=`string`)return!0;return!1}debug(...e){}make(){let e=this.pattern,t=this.options;if(!t.nocomment&&e.charAt(0)===`#`){this.comment=!0;return}if(!e){this.empty=!0;return}this.parseNegate(),this.globSet=[...new Set(this.braceExpand())],t.debug&&(this.debug=(...e)=>console.error(...e)),this.debug(this.pattern,this.globSet);let n=this.globSet.map(e=>this.slashSplit(e));this.globParts=this.preprocess(n),this.debug(this.pattern,this.globParts);let r=this.globParts.map((e,t,n)=>{if(this.isWindows&&this.windowsNoMagicRoot){let t=e[0]===``&&e[1]===``&&(e[2]===`?`||!rr.test(e[2]))&&!rr.test(e[3]),n=/^[a-z]:/i.test(e[0]);if(t)return[...e.slice(0,4),...e.slice(4).map(e=>this.parse(e))];if(n)return[e[0],...e.slice(1).map(e=>this.parse(e))]}return e.map(e=>this.parse(e))});if(this.debug(this.pattern,r),this.set=r.filter(e=>e.indexOf(!1)===-1),this.isWindows)for(let e=0;e<this.set.length;e++){let t=this.set[e];t[0]===``&&t[1]===``&&this.globParts[e][2]===`?`&&typeof t[3]==`string`&&/^[a-z]:$/i.test(t[3])&&(t[2]=`?`)}this.debug(this.pattern,this.set)}preprocess(e){if(this.options.noglobstar)for(let t=0;t<e.length;t++)for(let n=0;n<e[t].length;n++)e[t][n]===`**`&&(e[t][n]=`*`);let{optimizationLevel:t=1}=this.options;return t>=2?(e=this.firstPhasePreProcess(e),e=this.secondPhasePreProcess(e)):e=t>=1?this.levelOneOptimize(e):this.adjascentGlobstarOptimize(e),e}adjascentGlobstarOptimize(e){return e.map(e=>{let t=-1;for(;(t=e.indexOf(`**`,t+1))!==-1;){let n=t;for(;e[n+1]===`**`;)n++;n!==t&&e.splice(t,n-t)}return e})}levelOneOptimize(e){return e.map(e=>(e=e.reduce((e,t)=>{let n=e[e.length-1];return t===`**`&&n===`**`?e:t===`..`&&n&&n!==`..`&&n!==`.`&&n!==`**`?(e.pop(),e):(e.push(t),e)},[]),e.length===0?[``]:e))}levelTwoFileOptimize(e){Array.isArray(e)||(e=this.slashSplit(e));let t=!1;do{if(t=!1,!this.preserveMultipleSlashes){for(let n=1;n<e.length-1;n++){let r=e[n];n===1&&r===``&&e[0]===``||(r===`.`||r===``)&&(t=!0,e.splice(n,1),n--)}e[0]===`.`&&e.length===2&&(e[1]===`.`||e[1]===``)&&(t=!0,e.pop())}let n=0;for(;(n=e.indexOf(`..`,n+1))!==-1;){let r=e[n-1];r&&r!==`.`&&r!==`..`&&r!==`**`&&(t=!0,e.splice(n-1,2),n-=2)}}while(t);return e.length===0?[``]:e}firstPhasePreProcess(e){let t=!1;do{t=!1;for(let n of e){let r=-1;for(;(r=n.indexOf(`**`,r+1))!==-1;){let i=r;for(;n[i+1]===`**`;)i++;i>r&&n.splice(r+1,i-r);let a=n[r+1],o=n[r+2],s=n[r+3];if(a!==`..`||!o||o===`.`||o===`..`||!s||s===`.`||s===`..`)continue;t=!0,n.splice(r,1);let c=n.slice(0);c[r]=`**`,e.push(c),r--}if(!this.preserveMultipleSlashes){for(let e=1;e<n.length-1;e++){let r=n[e];e===1&&r===``&&n[0]===``||(r===`.`||r===``)&&(t=!0,n.splice(e,1),e--)}n[0]===`.`&&n.length===2&&(n[1]===`.`||n[1]===``)&&(t=!0,n.pop())}let i=0;for(;(i=n.indexOf(`..`,i+1))!==-1;){let e=n[i-1];if(e&&e!==`.`&&e!==`..`&&e!==`**`){t=!0;let e=i===1&&n[i+1]===`**`?[`.`]:[];n.splice(i-1,2,...e),n.length===0&&n.push(``),i-=2}}}}while(t);return e}secondPhasePreProcess(e){for(let t=0;t<e.length-1;t++)for(let n=t+1;n<e.length;n++){let r=this.partsMatch(e[t],e[n],!this.preserveMultipleSlashes);if(r){e[t]=[],e[n]=r;break}}return e.filter(e=>e.length)}partsMatch(e,t,n=!1){let r=0,i=0,a=[],o=``;for(;r<e.length&&i<t.length;)if(e[r]===t[i])a.push(o===`b`?t[i]:e[r]),r++,i++;else if(n&&e[r]===`**`&&t[i]===e[r+1])a.push(e[r]),r++;else if(n&&t[i]===`**`&&e[r]===t[i+1])a.push(t[i]),i++;else if(e[r]===`*`&&t[i]&&(this.options.dot||!t[i].startsWith(`.`))&&t[i]!==`**`){if(o===`b`)return!1;o=`a`,a.push(e[r]),r++,i++}else if(t[i]===`*`&&e[r]&&(this.options.dot||!e[r].startsWith(`.`))&&e[r]!==`**`){if(o===`a`)return!1;o=`b`,a.push(t[i]),r++,i++}else return!1;return e.length===t.length&&a}parseNegate(){if(this.nonegate)return;let e=this.pattern,t=!1,n=0;for(let r=0;r<e.length&&e.charAt(r)===`!`;r++)t=!t,n++;n&&(this.pattern=e.slice(n)),this.negate=t}matchOne(e,t,n=!1){let r=0,i=0;if(this.isWindows){let n=typeof e[0]==`string`&&/^[a-z]:$/i.test(e[0]),a=!n&&e[0]===``&&e[1]===``&&e[2]===`?`&&/^[a-z]:$/i.test(e[3]),o=typeof t[0]==`string`&&/^[a-z]:$/i.test(t[0]),s=!o&&t[0]===``&&t[1]===``&&t[2]===`?`&&typeof t[3]==`string`&&/^[a-z]:$/i.test(t[3]),c=a?3:n?0:void 0,l=s?3:o?0:void 0;if(typeof c==`number`&&typeof l==`number`){let[n,a]=[e[c],t[l]];n.toLowerCase()===a.toLowerCase()&&(t[l]=n,i=l,r=c)}}let{optimizationLevel:a=1}=this.options;return a>=2&&(e=this.levelTwoFileOptimize(e)),t.includes(er)?this.#e(e,t,n,r,i):this.#n(e,t,n,r,i)}#e(e,t,n,r,i){let a=t.indexOf(er,i),o=t.lastIndexOf(er),[s,c,l]=n?[t.slice(i,a),t.slice(a+1),[]]:[t.slice(i,a),t.slice(a+1,o),t.slice(o+1)];if(s.length){let t=e.slice(r,r+s.length);if(!this.#n(t,s,n,0,0))return!1;r+=s.length,i+=s.length}let u=0;if(l.length){if(l.length+r>e.length)return!1;let t=e.length-l.length;if(this.#n(e,l,n,t,0))u=l.length;else{if(e[e.length-1]!==``||r+l.length===e.length||(t--,!this.#n(e,l,n,t,0)))return!1;u=l.length+1}}if(!c.length){let t=!!u;for(let n=r;n<e.length-u;n++){let r=String(e[n]);if(t=!0,r===`.`||r===`..`||!this.options.dot&&r.startsWith(`.`))return!1}return n||t}let d=[[[],0]],f=d[0],p=0,m=[0];for(let e of c)e===er?(m.push(p),f=[[],0],d.push(f)):(f[0].push(e),p++);let h=d.length-1,g=e.length-u;for(let e of d)e[1]=g-(m[h--]+e[0].length);return!!this.#t(e,d,r,0,n,0,!!u)}#t(e,t,n,r,i,a,o){let s=t[r];if(!s){for(let t=n;t<e.length;t++){o=!0;let n=e[t];if(n===`.`||n===`..`||!this.options.dot&&n.startsWith(`.`))return!1}return o}let[c,l]=s;for(;n<=l;){if(this.#n(e.slice(0,n+c.length),c,i,n,0)&&a<this.maxGlobstarRecursion){let s=this.#t(e,t,n+c.length,r+1,i,a+1,o);if(s!==!1)return s}let s=e[n];if(s===`.`||s===`..`||!this.options.dot&&s.startsWith(`.`))return!1;n++}return i||null}#n(e,t,n,r,i){let a,o,s,c;for(a=r,o=i,c=e.length,s=t.length;a<c&&o<s;a++,o++){this.debug(`matchOne loop`);let n=t[o],r=e[a];if(this.debug(t,n,r),n===!1||n===er)return!1;let i;if(typeof n==`string`?(i=r===n,this.debug(`string match`,n,r,i)):(i=n.test(r),this.debug(`pattern match`,n,r,i)),!i)return!1}if(a===c&&o===s)return!0;if(a===c)return n;if(o===s)return a===c-1&&e[a]===``;throw Error(`wtf?`)}braceExpand(){return nr(this.pattern,this.options)}parse(e){an(e);let t=this.options;if(e===`**`)return er;if(e===``)return``;let n,r=null;(n=e.match(Hn))?r=t.dot?Wn:Un:(n=e.match(Mn))?r=(t.nocase?t.dot?In:Fn:t.dot?Pn:Nn)(n[1]):(n=e.match(Gn))?r=(t.nocase?t.dot?qn:Kn:t.dot?Jn:Yn)(n):(n=e.match(Ln))?r=t.dot?zn:Rn:(n=e.match(Bn))&&(r=Vn);let i=kn.fromGlob(e,this.options).toMMPattern();return r&&typeof i==`object`&&Reflect.defineProperty(i,`test`,{value:r}),i}makeRe(){if(this.regexp||this.regexp===!1)return this.regexp;let e=this.set;if(!e.length)return this.regexp=!1,this.regexp;let t=this.options,n=t.noglobstar?`[^/]*?`:t.dot?`(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?`:`(?:(?!(?:\\/|^)\\.).)*?`,r=new Set(t.nocase?[`i`]:[]),i=e.map(e=>{let t=e.map(e=>{if(e instanceof RegExp)for(let t of e.flags.split(``))r.add(t);return typeof e==`string`?ir(e):e===er?er:e._src});t.forEach((e,r)=>{let i=t[r+1],a=t[r-1];e!==er||a===er||(a===void 0?i!==void 0&&i!==er?t[r+1]=`(?:\\/|`+n+`\\/)?`+i:t[r]=n:i===void 0?t[r-1]=a+`(?:\\/|\\/`+n+`)?`:i!==er&&(t[r-1]=a+`(?:\\/|\\/`+n+`\\/)`+i,t[r+1]=er))});let i=t.filter(e=>e!==er);if(this.partial&&i.length>=1){let e=[];for(let t=1;t<=i.length;t++)e.push(i.slice(0,t).join(`/`));return`(?:`+e.join(`|`)+`)`}return i.join(`/`)}).join(`|`),[a,o]=e.length>1?[`(?:`,`)`]:[``,``];i=`^`+a+i+o+`$`,this.partial&&(i=`^(?:\\/|`+a+i.slice(1,-1)+o+`)$`),this.negate&&(i=`^(?!`+i+`).+$`);try{this.regexp=new RegExp(i,[...r].join(``))}catch{this.regexp=!1}return this.regexp}slashSplit(e){return this.preserveMultipleSlashes?e.split(`/`):this.isWindows&&/^\/\/[^\/]+/.test(e)?[``,...e.split(/\/+/)]:e.split(/\/+/)}match(e,t=this.partial){if(this.debug(`match`,e,this.pattern),this.comment)return!1;if(this.empty)return e===``;if(e===`/`&&t)return!0;let n=this.options;this.isWindows&&(e=e.split(`\\`).join(`/`));let r=this.slashSplit(e);this.debug(this.pattern,`split`,r);let i=this.set;this.debug(this.pattern,`set`,i);let a=r[r.length-1];if(!a)for(let e=r.length-2;!a&&e>=0;e--)a=r[e];for(let e=0;e<i.length;e++){let o=i[e],s=r;if(n.matchBase&&o.length===1&&(s=[a]),this.matchOne(s,o,t))return n.flipNegate?!0:!this.negate}return n.flipNegate?!1:this.negate}static defaults(e){return jn.defaults(e).Minimatch}};jn.AST=kn,jn.Minimatch=ar,jn.escape=An,jn.unescape=dn;const or={};function sr(){throw Error(`gunzipSync is not available in the browser`)}function cr(){throw Error(`gzipSync is not available in the browser`)}var lr=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r){setTimeout(function(){r(e)},0);return}else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,h=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let h=c&&c.oldPos+1<o;if(!u&&!h){d[r]=void 0;continue}if(s=!h||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);h()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=h();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}};new class extends lr{};function ur(e,t){let n;for(n=0;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function dr(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function fr(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function pr(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function mr(e,t){return fr(e,t,``)}function hr(e,t){return pr(e,t,``)}function gr(e,t){return t.slice(0,_r(e,t))}function _r(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function vr(e){let t;for(t=e.length-1;t>=0&&e[t].match(/\s/);t--);return e.substring(t+1)}function yr(e){let t=e.match(/^\s*/);return t?t[0]:``}const br=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,xr=RegExp(`[${br}]+|\\s+|[^${br}]`,`ug`);new class extends lr{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=[];for(let t of Array.from(r.segment(e))){let e=t.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}}else n=e.match(xr)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&Sr(n,i,r,e),n=e,r=null,i=null)}),(r||i)&&Sr(n,i,r,null),e}};function Sr(e,t,n,r){if(t&&n){let i=yr(t.value),a=vr(t.value),o=yr(n.value),s=vr(n.value);if(e){let r=ur(i,o);e.value=pr(e.value,o,r),t.value=mr(t.value,r),n.value=mr(n.value,r)}if(r){let e=dr(a,s);r.value=fr(r.value,s,e),t.value=hr(t.value,e),n.value=hr(n.value,e)}}else if(n){if(e){let e=yr(n.value);n.value=n.value.substring(e.length)}if(r){let e=yr(r.value);r.value=r.value.substring(e.length)}}else if(e&&r){let n=yr(r.value),i=yr(t.value),a=vr(t.value),o=ur(n,i);t.value=mr(t.value,o);let s=dr(mr(n,o),a);t.value=hr(t.value,s),r.value=fr(r.value,n,s),e.value=pr(e.value,n,n.slice(0,n.length-s.length))}else if(r){let e=yr(r.value),n=gr(vr(t.value),e);t.value=hr(t.value,n)}else if(e){let n=gr(vr(e.value),yr(t.value));t.value=mr(t.value,n)}}new class extends lr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${br}]+|[^\\S\\n\\r]+|[^${br}]`,`ug`);return e.match(t)||[]}};const Cr=new class extends lr{constructor(){super(...arguments),this.tokenize=Tr}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
|
|
880
880
|
`))&&(e=e.trim()),(!n.newlineIsToken||!t.includes(`
|
|
881
881
|
`))&&(t=t.trim())):n.ignoreNewlineAtEof&&!n.newlineIsToken&&(e.endsWith(`
|
|
882
882
|
`)&&(e=e.slice(0,-1)),t.endsWith(`
|
|
@@ -2637,7 +2637,117 @@ Available commands:
|
|
|
2637
2637
|
`,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 VU({fs:this.lfs,dir:e,filepath:i}),await ZG({fs:this.lfs,dir:e,filepath:r}),{stdout:``,stderr:``,exitCode:0}}async revParse(e,t){if(t.includes(`--show-toplevel`))try{return{stdout:`${await bG({fs:this.lfs,filepath:e})}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`fatal: not a git repository
|
|
2638
2638
|
`,exitCode:128}}if(t.includes(`--is-inside-work-tree`))try{return await bG({fs:this.lfs,filepath:e}),{stdout:`true
|
|
2639
2639
|
`,stderr:``,exitCode:0}}catch{return{stdout:`false
|
|
2640
|
-
`,stderr:``,exitCode:0}}let n=t.find(e=>!e.startsWith(`-`))??`HEAD`;try{return{stdout:`${await eK({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}};i(`cdp:debugger`);var VK=class{_state=`disconnected`;nextCommandId=1;listeners=new Map;pendingCommands=new Map;unsubscribe=null;opts;label;constructor(e){this.opts=e,this.label=e.label??`CDP transport`}get state(){return this._state}async connect(e){if(this._state!==`disconnected`)throw Error(`Cannot connect: state is ${this._state}`);this.unsubscribe=this.opts.subscribeIncoming(e=>this.handleIncoming(e)),this._state=`connected`}disconnect(){this.unsubscribe?.(),this.unsubscribe=null;for(let[,e]of this.pendingCommands)clearTimeout(e.timer),e.reject(Error(`${this.label} disconnected`));this.pendingCommands.clear(),this.listeners.clear(),this._state=`disconnected`}async send(e,t,n,r=3e4){if(this._state!==`connected`)throw Error(`${this.label} is not connected`);let i=this.nextCommandId++,a=this.opts.buildCommandEnvelope(i,e,t,n);return new Promise((t,n)=>{let o=!1,s=setTimeout(()=>{o||(o=!0,this.pendingCommands.delete(i),n(Error(`CDP command timed out after ${r}ms: ${e}`)))},r);this.pendingCommands.set(i,{resolve:e=>{o||(o=!0,t(e))},reject:e=>{o||(o=!0,n(e))},timer:s}),this.opts.sendEnvelope(a).catch(e=>{o||(o=!0,this.pendingCommands.delete(i),clearTimeout(s),n(Error(`Failed to send CDP command: ${e instanceof Error?e.message:String(e)}`)))})})}on(e,t){let n=this.listeners.get(e),r=!n;n||(n=new Set,this.listeners.set(e,n)),n.add(t),r&&this.opts.onSubscribeEvent?.(e)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&(this.listeners.delete(e),this.opts.onUnsubscribeEvent?.(e)))}once(e,t=3e4){return new Promise((n,r)=>{let i=setTimeout(()=>{this.off(e,a),r(Error(`Timed out waiting for event: ${e}`))},t),a=t=>{clearTimeout(i),this.off(e,a),n(t)};this.on(e,a)})}handleIncoming(e){let t=this.opts.parseResponse(e);if(t){this.handleResponse(t);return}let n=this.opts.parseEvent(e);n&&this.handleEvent(n)}handleResponse(e){let t=this.pendingCommands.get(e.id);if(!t){this.opts.onUnknownResponseId?.(e.id);return}this.pendingCommands.delete(e.id),clearTimeout(t.timer),e.error?t.reject(Error(e.error)):t.resolve(e.result??{})}handleEvent(e){let t=this.listeners.get(e.method);if(t)for(let n of t)try{n(e.params??{})}catch(t){this.opts.onListenerError?.(e.method,t)}}};const HK=i(`har-recorder`);var UK=class{recordings=new Map;client;fs;eventCleanup=new Map;constructor(e,t){this.client=e,this.fs=t}async startRecording(e,t,n){let r=`rec-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await this.client.send(`Network.enable`,{},t),await this.client.send(`Page.enable`,{},t);let i=(await this.client.send(`Runtime.evaluate`,{expression:`location.href`,returnByValue:!0},t)).result?.value??`about:blank`,a={id:r,targetId:e,sessionId:t,filterCode:n,pendingRequests:new Map,entries:[],startTime:Date.now(),currentUrl:i,snapshotCount:0};return this.recordings.set(r,a),this.setupEventListeners(a),await this.ensureDir(`/recordings/${r}`),HK.debug(`Started recording`,{recordingId:r,targetId:e,currentUrl:i}),r}setupEventListeners(e){let{sessionId:t,id:n}=e,r=n=>{n.sessionId===t&&this.handleRequestWillBeSent(e,n)},i=n=>{n.sessionId===t&&this.handleResponseReceived(e,n)},a=n=>{n.sessionId===t&&this.handleLoadingFinished(e,n)},o=n=>{n.sessionId===t&&this.handleLoadingFailed(e,n)},s=r=>{if(r.sessionId!==t)return;let i=r.frame;if(!i?.parentId&&i?.url){let t=[...e.entries],r=e.currentUrl;e.currentUrl=i.url,e.entries=[],e.pendingRequests.clear(),this.saveSnapshotWithEntries(e,`navigation`,t,r).catch(e=>{HK.error(`Failed to save navigation snapshot`,{recordingId:n,error:e instanceof Error?e.message:String(e)})})}};this.client.on(`Network.requestWillBeSent`,r),this.client.on(`Network.responseReceived`,i),this.client.on(`Network.loadingFinished`,a),this.client.on(`Network.loadingFailed`,o),this.client.on(`Page.frameNavigated`,s),this.eventCleanup.set(n,()=>{this.client.off(`Network.requestWillBeSent`,r),this.client.off(`Network.responseReceived`,i),this.client.off(`Network.loadingFinished`,a),this.client.off(`Network.loadingFailed`,o),this.client.off(`Page.frameNavigated`,s)})}handleRequestWillBeSent(e,t){let n=t.requestId,r=t.request,i=t.timestamp;e.pendingRequests.set(n,{requestId:n,startTime:i*1e3,request:{method:r.method,url:r.url,headers:r.headers,postData:r.postData}})}handleResponseReceived(e,t){let n=t.requestId,r=t.response,i=e.pendingRequests.get(n);i&&(i.response={status:r.status,statusText:r.statusText,headers:r.headers,mimeType:r.mimeType},i.timing=r.timing)}async handleLoadingFinished(e,t){let n=t.requestId,r=t.timestamp,i=e.pendingRequests.get(n);if(!i)return;i.endTime=r*1e3;try{let t=await this.client.send(`Network.getResponseBody`,{requestId:n},e.sessionId);i.responseBody=t.body,i.responseBodyBase64=t.base64Encoded}catch{}let a=this.buildHarEntry(i);a&&e.entries.push(a),e.pendingRequests.delete(n)}handleLoadingFailed(e,t){let n=t.requestId;e.pendingRequests.delete(n)}buildHarEntry(e){if(!e.response)return null;let{request:t,response:n,timing:r,startTime:i,endTime:a,responseBody:o,responseBodyBase64:s}=e,c=a?a-i:0,l=[];try{let e=new URL(t.url);l=Array.from(e.searchParams.entries()).map(([e,t])=>({name:e,value:t}))}catch{}let u=r?(()=>{let e=(e,t)=>{if(e==null||t==null||e<0||t<0)return-1;let n=t-e;return n>=0?n:-1},t=r.dnsStart>=0?r.dnsStart:r.connectStart>=0?r.connectStart:0;return{blocked:t>0?t:-1,dns:e(r.dnsStart,r.dnsEnd),connect:e(r.connectStart,r.connectEnd),ssl:e(r.sslStart,r.sslEnd),send:e(r.sendStart,r.sendEnd),wait:e(r.sendEnd,r.receiveHeadersStart),receive:e(r.receiveHeadersStart,r.receiveHeadersEnd)}})():{blocked:-1,dns:-1,connect:-1,ssl:-1,send:0,wait:c,receive:0},d={size:o?.length??0,mimeType:n.mimeType??`application/octet-stream`};o&&(d.text=o,s&&(d.encoding=`base64`));let f;return t.postData&&(f={mimeType:t.headers[`content-type`]??t.headers[`Content-Type`]??`text/plain`,text:t.postData}),{startedDateTime:new Date(i).toISOString(),time:c,request:{method:t.method,url:t.url,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(t.headers).map(([e,t])=>({name:e,value:t})),queryString:l,postData:f,headersSize:-1,bodySize:t.postData?.length??0},response:{status:n.status,statusText:n.statusText,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(n.headers).map(([e,t])=>({name:e,value:t})),content:d,redirectURL:n.headers.location??n.headers.Location??``,headersSize:-1,bodySize:d.size},cache:{},timings:u}}async saveSnapshot(e,t){return this.saveSnapshotWithEntries(e,t,e.entries,e.currentUrl)}async applyFilter(e,t){if(typeof chrome<`u`&&chrome?.runtime?.id)try{let n=document.querySelector(`iframe[data-js-tool]`);n||(n=document.createElement(`iframe`),n.style.display=`none`,n.dataset.jsTool=`true`,n.src=chrome.runtime.getURL(`sandbox.html`),document.body.appendChild(n),await Promise.race([new Promise(e=>{n.addEventListener(`load`,()=>e(),{once:!0})}),new Promise((e,t)=>{setTimeout(()=>t(Error(`Sandbox iframe failed to load`)),5e3)})]));let r=`har-filter-${Date.now()}-${Math.random().toString(36).slice(2)}`;return await new Promise((i,a)=>{let o=setTimeout(()=>{window.removeEventListener(`message`,s),a(Error(`HAR filter sandbox timeout`))},1e4),s=e=>{e.data?.type===`har_filter_result`&&e.data.id===r&&(window.removeEventListener(`message`,s),clearTimeout(o),e.data.error?a(Error(e.data.error)):i(e.data.entries))};window.addEventListener(`message`,s),n.contentWindow.postMessage({type:`har_filter`,id:r,entries:e,filterCode:t},`*`)})}catch(t){return HK.error(`HAR filter sandbox error, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}else try{let n=Function(`entry`,`return (${t})(entry);`),r=[];for(let t of e)try{let e=n(t);if(e===!1)continue;typeof e==`object`&&e?r.push(e):r.push(t)}catch(e){HK.error(`Filter function error on entry, keeping it`,{error:e instanceof Error?e.message:String(e)}),r.push(t)}return r}catch(t){return HK.error(`Failed to compile filter, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}}async saveSnapshotWithEntries(e,t,n,r){if(n.length===0)return HK.debug(`No entries to save`,{recordingId:e.id,trigger:t}),null;let i=e.filterCode?await this.applyFilter(n,e.filterCode):n;if(i.length===0)return HK.debug(`All entries filtered out`,{recordingId:e.id,trigger:t}),null;e.snapshotCount++;let a=new Date().toISOString().replace(/[:.]/g,`-`),o=this.urlToSlug(r),s=`${e.snapshotCount.toString().padStart(3,`0`)}-${a}-${t}-${o}.har`,c=`/recordings/${e.id}/${s}`,l={log:{version:`1.2`,creator:{name:`SLICC HAR Recorder`,version:`1.0.0`},entries:i}};return await this.fs.writeFile(c,JSON.stringify(l,null,2)),HK.debug(`Saved HAR snapshot`,{recordingId:e.id,path:c,entryCount:i.length}),c}urlToSlug(e){try{let t=new URL(e);return`${t.hostname}${t.pathname}`.replace(/[^a-zA-Z0-9]/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,50)||`page`}catch{return`page`}}async stopRecording(e){let t=this.recordings.get(e);if(!t)throw Error(`Recording not found: ${e}`);await this.saveSnapshot(t,`close`);let n=this.eventCleanup.get(e);n&&(n(),this.eventCleanup.delete(e));try{await this.client.send(`Network.disable`,{},t.sessionId)}catch{}this.recordings.delete(e);let r=`/recordings/${e}`;return HK.debug(`Stopped recording`,{recordingId:e,snapshotCount:t.snapshotCount}),r}getRecording(e){return this.recordings.get(e)}getRecordingByTarget(e){for(let[t,n]of this.recordings)if(n.targetId===e)return t}async ensureDir(e){await this.fs.mkdir(e,{recursive:!0})}};function WK(e,t){if(e==null)return[];let n;if(Array.isArray(e))n=e.join(`, `).replace(/\n/g,`, `);else if(typeof e==`string`)n=e.replace(/\n/g,`, `);else return[];if(n.length===0)return[];let r=[],i=n.length,a=0;for(;a<i&&(a=GK(n,a),!(a>=i));){if(n[a]!==`<`){a=qK(n,a);continue}let e=n.indexOf(`>`,a+1);if(e===-1)break;let o=n.slice(a+1,e);a=e+1;let s=[];for(;a<i&&(a=GK(n,a),!(a>=i));){if(n[a]===`,`){a++;break}if(n[a]!==`;`){a=qK(n,a);break}a++,a=GK(n,a);let e=a;for(;a<i&&YK(n.charCodeAt(a));)a++;if(a<i&&n[a]===`*`&&a++,e===a){a=qK(n,a);break}let t=n.slice(e,a).toLowerCase();a=GK(n,a);let r=``;if(a<i&&n[a]===`=`)if(a++,a=GK(n,a),a<i&&n[a]===`"`){let e=JK(n,a);r=e.value,a=e.end}else{let e=a;for(;a<i&&n[a]!==`;`&&n[a]!==`,`&&!KK(n[a]);)a++;r=n.slice(e,a)}s.push([t,r])}let c=XK(o,s,t);c&&r.push(c)}return r}function GK(e,t){for(;t<e.length&&(e[t]===` `||e[t]===` `);)t++;return t}function KK(e){return e===` `||e===` `}function qK(e,t){let n=!1;for(;t<e.length;){let r=e[t];if(n){if(r===`\\`&&t+1<e.length){t+=2;continue}r===`"`&&(n=!1)}else if(r===`"`)n=!0;else if(r===`,`)return t+1;t++}return t}function JK(e,t){t++;let n=``;for(;t<e.length;){let r=e[t];if(r===`\\`)t++,t<e.length&&(n+=e[t],t++);else if(r===`"`)return{value:n,end:t+1};else n+=r,t++}return{value:n,end:t}}function YK(e){if(e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122)return!0;switch(e){case 33:case 35:case 36:case 37:case 38:case 39:case 42:case 43:case 45:case 46:case 94:case 95:case 96:case 124:case 126:return!0}return!1}function XK(e,t,n){let r={},i={};for(let[e,n]of t){if(e.endsWith(`*`)){let t=QK(n);t!=null&&(i[e.slice(0,-1)]=t);continue}e===`rel`&&`rel`in r||(r[e]=n)}for(let[e,t]of Object.entries(i))r[e]=t;let a=ZK(e,n),o=r.anchor==null?void 0:ZK(r.anchor,n),s={href:a,rel:(r.rel??``).split(/[ \t]+/).filter(e=>e.length>0),params:r};return o!=null&&(s.anchor=o),r.type!=null&&(s.type=r.type),r.title!=null&&(s.title=r.title),r.hreflang!=null&&(s.hreflang=r.hreflang),s}function ZK(e,t){if(!t)return e;try{return new URL(e,t).toString()}catch{return e}}function QK(e){let t=e.indexOf(`'`);if(t===-1)return null;let n=e.indexOf(`'`,t+1);if(n===-1||e.slice(0,t).toLowerCase()!==`utf-8`)return null;try{return decodeURIComponent(e.slice(n+1))}catch{return null}}function $K(e){if(!e)return[];let t=[];for(let[n,r]of Object.entries(e))n.toLowerCase()===`link`&&typeof r==`string`&&r.length>0&&t.push(r);return t}function eq(e){let t=e.replace(/\/+$/,``),n=t.toLowerCase();return n.endsWith(`/skill.md`)?t.slice(0,-9):n===`skill.md`?``:t}const tq=/^[A-Za-z0-9._/-]+$/,nq=/^[A-Za-z0-9._/-]+$/;function rq(e){return!(e.length===0||e.length>250||!tq.test(e)||e.startsWith(`-`)||e.startsWith(`/`)||e.endsWith(`/`)||e.includes(`..`)||e.endsWith(`.lock`))}function iq(e){return!(e.length===0||e.length>1024||!nq.test(e)||e.startsWith(`-`)||e.startsWith(`/`)||e.includes(`..`))}function aq(e){for(let t of e){if(t.rel.includes(`https://www.sliccy.ai/rel/handoff`)){let e={verb:`handoff`,target:t.href};return t.title!=null&&t.title.length>0&&(e.instruction=t.title),e}if(t.rel.includes(`https://www.sliccy.ai/rel/upskill`)){let e={verb:`upskill`,target:t.href};t.title!=null&&t.title.length>0&&(e.instruction=t.title);let n=t.params.branch;typeof n==`string`&&rq(n)&&(e.branch=n);let r=t.params.path;if(typeof r==`string`&&r.length>0){let t=eq(r);t.length>0&&iq(t)&&(e.path=t)}return e}}return null}function oq(e,t){let n=$K(e);if(n.length===0)return{match:null,links:[]};let r=WK(n,t);return{match:aq(r),links:r}}const sq=i(`navigation-watcher`);function cq(e,t){return oq(e,t)}var lq=class{transport;onEvent;sessions=new Map;started=!1;onAttachedToTarget=e=>{this.handleAttachedToTarget(e)};onDetachedFromTarget=e=>{let t=e.sessionId;t&&this.sessions.delete(t)};onTargetInfoChanged=e=>{let t=e.targetInfo;if(t?.targetId)for(let e of this.sessions.values())e.targetId===t.targetId&&(typeof t.title==`string`&&(e.title=t.title),typeof t.url==`string`&&(e.url=t.url))};onTargetCreated=e=>{this.handleTargetCreated(e)};onFrameNavigated=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n)return;let r=e.frame;r?.id&&(r.parentId||(n.rootFrameId=r.id,typeof r.url==`string`&&(n.url=r.url)))};onResponseReceived=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n||e.type!==`Document`)return;let r=e.frameId;if(!r||r!==n.rootFrameId)return;let i=e.response;if(!i)return;let a=typeof i.url==`string`&&i.url.length>0?i.url:n.url;if(!a)return;let{match:o,links:s}=cq(i.headers,a);if(!o)return;let c={url:a,verb:o.verb,target:o.target,links:s,targetId:n.targetId};o.instruction!=null&&(c.instruction=o.instruction),o.branch!=null&&(c.branch=o.branch),o.path!=null&&(c.path=o.path),n.title!=null&&(c.title=n.title),this.onEvent(c)};constructor(e,t){this.transport=e,this.onEvent=t}async start(){if(!this.started){this.transport.on(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.on(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.on(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.on(`Target.targetCreated`,this.onTargetCreated),this.transport.on(`Page.frameNavigated`,this.onFrameNavigated),this.transport.on(`Network.responseReceived`,this.onResponseReceived);try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!0})}catch(e){sq.error(`Failed to enable target discovery`,{error:e instanceof Error?e.message:String(e)}),this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Target.targetCreated`,this.onTargetCreated),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived);return}this.started=!0;try{let e=(await this.transport.send(`Target.getTargets`)).targetInfos??[];for(let t of e){if(t.type!==`page`)continue;let e=t.attached===!0,n=t.targetId;if(!(e||typeof n!=`string`))try{await this.transport.send(`Target.attachToTarget`,{targetId:n,flatten:!0})}catch(e){sq.debug(`Failed to attach to preexisting target`,{targetId:n,error:e instanceof Error?e.message:String(e)})}}}catch(e){sq.debug(`Failed to enumerate preexisting targets`,{error:e instanceof Error?e.message:String(e)})}}}async stop(){if(this.started){this.started=!1,this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Target.targetCreated`,this.onTargetCreated),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived),this.sessions.clear();try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!1})}catch(e){sq.debug(`Failed to disable target discovery on stop`,{error:e instanceof Error?e.message:String(e)})}}}async handleTargetCreated(e){let t=e.targetInfo;if(!(!t||t.type!==`page`||typeof t.targetId!=`string`)&&!t.attached){if(t.openerId){sq.debug(`Skipping popup target to avoid debugger pause`,{targetId:t.targetId,openerId:t.openerId});return}try{await this.transport.send(`Target.attachToTarget`,{targetId:t.targetId,flatten:!0})}catch(e){sq.debug(`Failed to attach to discovered target`,{targetId:t.targetId,error:e instanceof Error?e.message:String(e)})}}}async handleAttachedToTarget(e){let t=e.sessionId,n=e.targetInfo;if(!(!t||!n||n.type!==`page`||typeof n.targetId!=`string`)){this.sessions.set(t,{targetId:n.targetId,rootFrameId:null,title:n.title,url:n.url});try{await this.transport.send(`Page.enable`,{},t),await this.transport.send(`Network.enable`,{},t);let e=(await this.transport.send(`Page.getFrameTree`,{},t)).frameTree?.frame;if(e?.id&&typeof e.id==`string`){let n=this.sessions.get(t);n&&(n.rootFrameId=e.id)}}catch(e){sq.debug(`Failed to enable Page/Network on attached target`,{sessionId:t,error:e instanceof Error?e.message:String(e)})}}}};i(`tray-sync`);const uq=[`api-catalog`,`service-desc`,`service-meta`,`status`,`https://llmstxt.org/rel/llms-txt`];async function dq(e,t={}){let n=t.fetchImpl??fetch,r=t.timeoutMs??3e3,i={links:e,failures:[]},a=[],o=new Set;for(let s of e)for(let e of s.rel)uq.includes(e)&&(o.has(e)||(o.add(e),a.push(fq(n,s.href,r,t.signal).then(t=>pq(i,e,t)).catch(t=>{i.failures.push({rel:e,href:s.href,error:t instanceof Error?t.message:String(t)})}))));return await Promise.all(a),i}async function fq(e,t,n,r){let i=new AbortController,a=setTimeout(()=>i.abort(Error(`timeout`)),n),o=()=>i.abort(Error(`aborted`));r&&r.addEventListener(`abort`,o,{once:!0});try{let n=await e(t,{signal:i.signal});if(!n.ok)throw Error(`HTTP ${n.status}`);return{contentType:n.headers.get(`content-type`)??``,body:await n.text()}}finally{clearTimeout(a),r&&r.removeEventListener(`abort`,o)}}function pq(e,t,n){if(t===`https://llmstxt.org/rel/llms-txt`){e.llmsTxt=n.body;return}let r=n.contentType.includes(`json`)||n.contentType.includes(`linkset`),i=n.body;if(r)try{i=JSON.parse(n.body)}catch{i=n.body}switch(t){case`api-catalog`:e.catalog=i;break;case`service-desc`:e.serviceDesc=i;break;case`service-meta`:e.serviceMeta=i;break;case`status`:e.status=i;break}}const Q=i(`playwright-teleport`);function mq(e){let t=e.match(/^(f[0-9]+)(e[0-9]+)$/);return t?{framePrefix:t[1],isIframe:!0}:{framePrefix:``,isIframe:!1}}function hq(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}const gq=[`playwright-cli`,`playwright`,`puppeteer`],_q=new WeakMap,vq=new Set([`click`,`dblclick`,`fill`,`type`,`press`,`goto`,`navigate`,`select`,`check`,`uncheck`,`drag`,`dialog-accept`,`dialog-dismiss`]);function yq(e){return e.toISOString().replace(/:/g,`-`)}function bq(e,t){let n=_q.get(e);n||(n=new WeakMap,_q.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 xq(e){return e instanceof ve||typeof e==`object`&&e&&`code`in e?e.code===`EEXIST`:e instanceof Error&&e.message.includes(`EEXIST`)}const Sq=`function(text) {
|
|
2640
|
+
`,stderr:``,exitCode:0}}let n=t.find(e=>!e.startsWith(`-`))??`HEAD`;try{return{stdout:`${await eK({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}};i(`cdp:debugger`);var VK=class{_state=`disconnected`;nextCommandId=1;listeners=new Map;pendingCommands=new Map;unsubscribe=null;opts;label;constructor(e){this.opts=e,this.label=e.label??`CDP transport`}get state(){return this._state}async connect(e){if(this._state!==`disconnected`)throw Error(`Cannot connect: state is ${this._state}`);this.unsubscribe=this.opts.subscribeIncoming(e=>this.handleIncoming(e)),this._state=`connected`}disconnect(){this.unsubscribe?.(),this.unsubscribe=null;for(let[,e]of this.pendingCommands)clearTimeout(e.timer),e.reject(Error(`${this.label} disconnected`));this.pendingCommands.clear(),this.listeners.clear(),this._state=`disconnected`}async send(e,t,n,r=3e4){if(this._state!==`connected`)throw Error(`${this.label} is not connected`);let i=this.nextCommandId++,a=this.opts.buildCommandEnvelope(i,e,t,n);return new Promise((t,n)=>{let o=!1,s=setTimeout(()=>{o||(o=!0,this.pendingCommands.delete(i),n(Error(`CDP command timed out after ${r}ms: ${e}`)))},r);this.pendingCommands.set(i,{resolve:e=>{o||(o=!0,t(e))},reject:e=>{o||(o=!0,n(e))},timer:s}),this.opts.sendEnvelope(a).catch(e=>{o||(o=!0,this.pendingCommands.delete(i),clearTimeout(s),n(Error(`Failed to send CDP command: ${e instanceof Error?e.message:String(e)}`)))})})}on(e,t){let n=this.listeners.get(e),r=!n;n||(n=new Set,this.listeners.set(e,n)),n.add(t),r&&this.opts.onSubscribeEvent?.(e)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&(this.listeners.delete(e),this.opts.onUnsubscribeEvent?.(e)))}once(e,t=3e4){return new Promise((n,r)=>{let i=setTimeout(()=>{this.off(e,a),r(Error(`Timed out waiting for event: ${e}`))},t),a=t=>{clearTimeout(i),this.off(e,a),n(t)};this.on(e,a)})}handleIncoming(e){let t=this.opts.parseResponse(e);if(t){this.handleResponse(t);return}let n=this.opts.parseEvent(e);n&&this.handleEvent(n)}handleResponse(e){let t=this.pendingCommands.get(e.id);if(!t){this.opts.onUnknownResponseId?.(e.id);return}this.pendingCommands.delete(e.id),clearTimeout(t.timer),e.error?t.reject(Error(e.error)):t.resolve(e.result??{})}handleEvent(e){let t=this.listeners.get(e.method);if(t)for(let n of t)try{n(e.params??{})}catch(t){this.opts.onListenerError?.(e.method,t)}}};const HK=i(`har-recorder`);var UK=class{recordings=new Map;client;fs;eventCleanup=new Map;constructor(e,t){this.client=e,this.fs=t}async startRecording(e,t,n){let r=`rec-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await this.client.send(`Network.enable`,{},t),await this.client.send(`Page.enable`,{},t);let i=(await this.client.send(`Runtime.evaluate`,{expression:`location.href`,returnByValue:!0},t)).result?.value??`about:blank`,a={id:r,targetId:e,sessionId:t,filterCode:n,pendingRequests:new Map,entries:[],startTime:Date.now(),currentUrl:i,snapshotCount:0};return this.recordings.set(r,a),this.setupEventListeners(a),await this.ensureDir(`/recordings/${r}`),HK.debug(`Started recording`,{recordingId:r,targetId:e,currentUrl:i}),r}setupEventListeners(e){let{sessionId:t,id:n}=e,r=n=>{n.sessionId===t&&this.handleRequestWillBeSent(e,n)},i=n=>{n.sessionId===t&&this.handleResponseReceived(e,n)},a=n=>{n.sessionId===t&&this.handleLoadingFinished(e,n)},o=n=>{n.sessionId===t&&this.handleLoadingFailed(e,n)},s=r=>{if(r.sessionId!==t)return;let i=r.frame;if(!i?.parentId&&i?.url){let t=[...e.entries],r=e.currentUrl;e.currentUrl=i.url,e.entries=[],e.pendingRequests.clear(),this.saveSnapshotWithEntries(e,`navigation`,t,r).catch(e=>{HK.error(`Failed to save navigation snapshot`,{recordingId:n,error:e instanceof Error?e.message:String(e)})})}};this.client.on(`Network.requestWillBeSent`,r),this.client.on(`Network.responseReceived`,i),this.client.on(`Network.loadingFinished`,a),this.client.on(`Network.loadingFailed`,o),this.client.on(`Page.frameNavigated`,s),this.eventCleanup.set(n,()=>{this.client.off(`Network.requestWillBeSent`,r),this.client.off(`Network.responseReceived`,i),this.client.off(`Network.loadingFinished`,a),this.client.off(`Network.loadingFailed`,o),this.client.off(`Page.frameNavigated`,s)})}handleRequestWillBeSent(e,t){let n=t.requestId,r=t.request,i=t.timestamp;e.pendingRequests.set(n,{requestId:n,startTime:i*1e3,request:{method:r.method,url:r.url,headers:r.headers,postData:r.postData}})}handleResponseReceived(e,t){let n=t.requestId,r=t.response,i=e.pendingRequests.get(n);i&&(i.response={status:r.status,statusText:r.statusText,headers:r.headers,mimeType:r.mimeType},i.timing=r.timing)}async handleLoadingFinished(e,t){let n=t.requestId,r=t.timestamp,i=e.pendingRequests.get(n);if(!i)return;i.endTime=r*1e3;try{let t=await this.client.send(`Network.getResponseBody`,{requestId:n},e.sessionId);i.responseBody=t.body,i.responseBodyBase64=t.base64Encoded}catch{}let a=this.buildHarEntry(i);a&&e.entries.push(a),e.pendingRequests.delete(n)}handleLoadingFailed(e,t){let n=t.requestId;e.pendingRequests.delete(n)}buildHarEntry(e){if(!e.response)return null;let{request:t,response:n,timing:r,startTime:i,endTime:a,responseBody:o,responseBodyBase64:s}=e,c=a?a-i:0,l=[];try{let e=new URL(t.url);l=Array.from(e.searchParams.entries()).map(([e,t])=>({name:e,value:t}))}catch{}let u=r?(()=>{let e=(e,t)=>{if(e==null||t==null||e<0||t<0)return-1;let n=t-e;return n>=0?n:-1},t=r.dnsStart>=0?r.dnsStart:r.connectStart>=0?r.connectStart:0;return{blocked:t>0?t:-1,dns:e(r.dnsStart,r.dnsEnd),connect:e(r.connectStart,r.connectEnd),ssl:e(r.sslStart,r.sslEnd),send:e(r.sendStart,r.sendEnd),wait:e(r.sendEnd,r.receiveHeadersStart),receive:e(r.receiveHeadersStart,r.receiveHeadersEnd)}})():{blocked:-1,dns:-1,connect:-1,ssl:-1,send:0,wait:c,receive:0},d={size:o?.length??0,mimeType:n.mimeType??`application/octet-stream`};o&&(d.text=o,s&&(d.encoding=`base64`));let f;return t.postData&&(f={mimeType:t.headers[`content-type`]??t.headers[`Content-Type`]??`text/plain`,text:t.postData}),{startedDateTime:new Date(i).toISOString(),time:c,request:{method:t.method,url:t.url,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(t.headers).map(([e,t])=>({name:e,value:t})),queryString:l,postData:f,headersSize:-1,bodySize:t.postData?.length??0},response:{status:n.status,statusText:n.statusText,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(n.headers).map(([e,t])=>({name:e,value:t})),content:d,redirectURL:n.headers.location??n.headers.Location??``,headersSize:-1,bodySize:d.size},cache:{},timings:u}}async saveSnapshot(e,t){return this.saveSnapshotWithEntries(e,t,e.entries,e.currentUrl)}async applyFilter(e,t){if(typeof chrome<`u`&&chrome?.runtime?.id)try{let n=document.querySelector(`iframe[data-js-tool]`);n||(n=document.createElement(`iframe`),n.style.display=`none`,n.dataset.jsTool=`true`,n.src=chrome.runtime.getURL(`sandbox.html`),document.body.appendChild(n),await Promise.race([new Promise(e=>{n.addEventListener(`load`,()=>e(),{once:!0})}),new Promise((e,t)=>{setTimeout(()=>t(Error(`Sandbox iframe failed to load`)),5e3)})]));let r=`har-filter-${Date.now()}-${Math.random().toString(36).slice(2)}`;return await new Promise((i,a)=>{let o=setTimeout(()=>{window.removeEventListener(`message`,s),a(Error(`HAR filter sandbox timeout`))},1e4),s=e=>{e.data?.type===`har_filter_result`&&e.data.id===r&&(window.removeEventListener(`message`,s),clearTimeout(o),e.data.error?a(Error(e.data.error)):i(e.data.entries))};window.addEventListener(`message`,s),n.contentWindow.postMessage({type:`har_filter`,id:r,entries:e,filterCode:t},`*`)})}catch(t){return HK.error(`HAR filter sandbox error, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}else try{let n=Function(`entry`,`return (${t})(entry);`),r=[];for(let t of e)try{let e=n(t);if(e===!1)continue;typeof e==`object`&&e?r.push(e):r.push(t)}catch(e){HK.error(`Filter function error on entry, keeping it`,{error:e instanceof Error?e.message:String(e)}),r.push(t)}return r}catch(t){return HK.error(`Failed to compile filter, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}}async saveSnapshotWithEntries(e,t,n,r){if(n.length===0)return HK.debug(`No entries to save`,{recordingId:e.id,trigger:t}),null;let i=e.filterCode?await this.applyFilter(n,e.filterCode):n;if(i.length===0)return HK.debug(`All entries filtered out`,{recordingId:e.id,trigger:t}),null;e.snapshotCount++;let a=new Date().toISOString().replace(/[:.]/g,`-`),o=this.urlToSlug(r),s=`${e.snapshotCount.toString().padStart(3,`0`)}-${a}-${t}-${o}.har`,c=`/recordings/${e.id}/${s}`,l={log:{version:`1.2`,creator:{name:`SLICC HAR Recorder`,version:`1.0.0`},entries:i}};return await this.fs.writeFile(c,JSON.stringify(l,null,2)),HK.debug(`Saved HAR snapshot`,{recordingId:e.id,path:c,entryCount:i.length}),c}urlToSlug(e){try{let t=new URL(e);return`${t.hostname}${t.pathname}`.replace(/[^a-zA-Z0-9]/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,50)||`page`}catch{return`page`}}async stopRecording(e){let t=this.recordings.get(e);if(!t)throw Error(`Recording not found: ${e}`);await this.saveSnapshot(t,`close`);let n=this.eventCleanup.get(e);n&&(n(),this.eventCleanup.delete(e));try{await this.client.send(`Network.disable`,{},t.sessionId)}catch{}this.recordings.delete(e);let r=`/recordings/${e}`;return HK.debug(`Stopped recording`,{recordingId:e,snapshotCount:t.snapshotCount}),r}getRecording(e){return this.recordings.get(e)}getRecordingByTarget(e){for(let[t,n]of this.recordings)if(n.targetId===e)return t}async ensureDir(e){await this.fs.mkdir(e,{recursive:!0})}};function WK(e,t){if(e==null)return[];let n;if(Array.isArray(e))n=e.join(`, `).replace(/\n/g,`, `);else if(typeof e==`string`)n=e.replace(/\n/g,`, `);else return[];if(n.length===0)return[];let r=[],i=n.length,a=0;for(;a<i&&(a=GK(n,a),!(a>=i));){if(n[a]!==`<`){a=qK(n,a);continue}let e=n.indexOf(`>`,a+1);if(e===-1)break;let o=n.slice(a+1,e);a=e+1;let s=[];for(;a<i&&(a=GK(n,a),!(a>=i));){if(n[a]===`,`){a++;break}if(n[a]!==`;`){a=qK(n,a);break}a++,a=GK(n,a);let e=a;for(;a<i&&YK(n.charCodeAt(a));)a++;if(a<i&&n[a]===`*`&&a++,e===a){a=qK(n,a);break}let t=n.slice(e,a).toLowerCase();a=GK(n,a);let r=``;if(a<i&&n[a]===`=`)if(a++,a=GK(n,a),a<i&&n[a]===`"`){let e=JK(n,a);r=e.value,a=e.end}else{let e=a;for(;a<i&&n[a]!==`;`&&n[a]!==`,`&&!KK(n[a]);)a++;r=n.slice(e,a)}s.push([t,r])}let c=XK(o,s,t);c&&r.push(c)}return r}function GK(e,t){for(;t<e.length&&(e[t]===` `||e[t]===` `);)t++;return t}function KK(e){return e===` `||e===` `}function qK(e,t){let n=!1;for(;t<e.length;){let r=e[t];if(n){if(r===`\\`&&t+1<e.length){t+=2;continue}r===`"`&&(n=!1)}else if(r===`"`)n=!0;else if(r===`,`)return t+1;t++}return t}function JK(e,t){t++;let n=``;for(;t<e.length;){let r=e[t];if(r===`\\`)t++,t<e.length&&(n+=e[t],t++);else if(r===`"`)return{value:n,end:t+1};else n+=r,t++}return{value:n,end:t}}function YK(e){if(e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122)return!0;switch(e){case 33:case 35:case 36:case 37:case 38:case 39:case 42:case 43:case 45:case 46:case 94:case 95:case 96:case 124:case 126:return!0}return!1}function XK(e,t,n){let r={},i={};for(let[e,n]of t){if(e.endsWith(`*`)){let t=QK(n);t!=null&&(i[e.slice(0,-1)]=t);continue}e===`rel`&&`rel`in r||(r[e]=n)}for(let[e,t]of Object.entries(i))r[e]=t;let a=ZK(e,n),o=r.anchor==null?void 0:ZK(r.anchor,n),s={href:a,rel:(r.rel??``).split(/[ \t]+/).filter(e=>e.length>0),params:r};return o!=null&&(s.anchor=o),r.type!=null&&(s.type=r.type),r.title!=null&&(s.title=r.title),r.hreflang!=null&&(s.hreflang=r.hreflang),s}function ZK(e,t){if(!t)return e;try{return new URL(e,t).toString()}catch{return e}}function QK(e){let t=e.indexOf(`'`);if(t===-1)return null;let n=e.indexOf(`'`,t+1);if(n===-1||e.slice(0,t).toLowerCase()!==`utf-8`)return null;try{return decodeURIComponent(e.slice(n+1))}catch{return null}}function $K(e){if(!e)return[];let t=[];for(let[n,r]of Object.entries(e))n.toLowerCase()===`link`&&typeof r==`string`&&r.length>0&&t.push(r);return t}function eq(e){let t=e.replace(/\/+$/,``),n=t.toLowerCase();return n.endsWith(`/skill.md`)?t.slice(0,-9):n===`skill.md`?``:t}const tq=/^[A-Za-z0-9._/-]+$/,nq=/^[A-Za-z0-9._/-]+$/;function rq(e){return!(e.length===0||e.length>250||!tq.test(e)||e.startsWith(`-`)||e.startsWith(`/`)||e.endsWith(`/`)||e.includes(`..`)||e.endsWith(`.lock`))}function iq(e){return!(e.length===0||e.length>1024||!nq.test(e)||e.startsWith(`-`)||e.startsWith(`/`)||e.includes(`..`))}function aq(e){for(let t of e){if(t.rel.includes(`https://www.sliccy.ai/rel/handoff`)){let e={verb:`handoff`,target:t.href};return t.title!=null&&t.title.length>0&&(e.instruction=t.title),e}if(t.rel.includes(`https://www.sliccy.ai/rel/upskill`)){let e={verb:`upskill`,target:t.href};t.title!=null&&t.title.length>0&&(e.instruction=t.title);let n=t.params.branch;typeof n==`string`&&rq(n)&&(e.branch=n);let r=t.params.path;if(typeof r==`string`&&r.length>0){let t=eq(r);t.length>0&&iq(t)&&(e.path=t)}return e}}return null}function oq(e,t){let n=$K(e);if(n.length===0)return{match:null,links:[]};let r=WK(n,t);return{match:aq(r),links:r}}const sq=i(`navigation-watcher`);function cq(e,t){return oq(e,t)}var lq=class{transport;onEvent;sessions=new Map;started=!1;onAttachedToTarget=e=>{this.handleAttachedToTarget(e)};onDetachedFromTarget=e=>{let t=e.sessionId;t&&this.sessions.delete(t)};onTargetInfoChanged=e=>{let t=e.targetInfo;if(t?.targetId)for(let e of this.sessions.values())e.targetId===t.targetId&&(typeof t.title==`string`&&(e.title=t.title),typeof t.url==`string`&&(e.url=t.url))};onTargetCreated=e=>{this.handleTargetCreated(e)};onFrameNavigated=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n)return;let r=e.frame;r?.id&&(r.parentId||(n.rootFrameId=r.id,typeof r.url==`string`&&(n.url=r.url)))};onResponseReceived=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n||e.type!==`Document`)return;let r=e.frameId;if(!r||r!==n.rootFrameId)return;let i=e.response;if(!i)return;let a=typeof i.url==`string`&&i.url.length>0?i.url:n.url;if(!a)return;let{match:o,links:s}=cq(i.headers,a);if(!o)return;let c={url:a,verb:o.verb,target:o.target,links:s,targetId:n.targetId};o.instruction!=null&&(c.instruction=o.instruction),o.branch!=null&&(c.branch=o.branch),o.path!=null&&(c.path=o.path),n.title!=null&&(c.title=n.title),this.onEvent(c)};constructor(e,t){this.transport=e,this.onEvent=t}async start(){if(!this.started){this.transport.on(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.on(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.on(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.on(`Target.targetCreated`,this.onTargetCreated),this.transport.on(`Page.frameNavigated`,this.onFrameNavigated),this.transport.on(`Network.responseReceived`,this.onResponseReceived);try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!0})}catch(e){sq.error(`Failed to enable target discovery`,{error:e instanceof Error?e.message:String(e)}),this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Target.targetCreated`,this.onTargetCreated),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived);return}this.started=!0;try{let e=(await this.transport.send(`Target.getTargets`)).targetInfos??[];for(let t of e){if(t.type!==`page`)continue;let e=t.attached===!0,n=t.targetId;if(!(e||typeof n!=`string`))try{await this.transport.send(`Target.attachToTarget`,{targetId:n,flatten:!0})}catch(e){sq.debug(`Failed to attach to preexisting target`,{targetId:n,error:e instanceof Error?e.message:String(e)})}}}catch(e){sq.debug(`Failed to enumerate preexisting targets`,{error:e instanceof Error?e.message:String(e)})}}}async stop(){if(this.started){this.started=!1,this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Target.targetCreated`,this.onTargetCreated),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived),this.sessions.clear();try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!1})}catch(e){sq.debug(`Failed to disable target discovery on stop`,{error:e instanceof Error?e.message:String(e)})}}}async handleTargetCreated(e){let t=e.targetInfo;if(!(!t||t.type!==`page`||typeof t.targetId!=`string`)&&!t.attached){if(t.openerId){sq.debug(`Skipping popup target to avoid debugger pause`,{targetId:t.targetId,openerId:t.openerId});return}try{await this.transport.send(`Target.attachToTarget`,{targetId:t.targetId,flatten:!0})}catch(e){sq.debug(`Failed to attach to discovered target`,{targetId:t.targetId,error:e instanceof Error?e.message:String(e)})}}}async handleAttachedToTarget(e){let t=e.sessionId,n=e.targetInfo;if(!(!t||!n||n.type!==`page`||typeof n.targetId!=`string`)){this.sessions.set(t,{targetId:n.targetId,rootFrameId:null,title:n.title,url:n.url});try{await this.transport.send(`Page.enable`,{},t),await this.transport.send(`Network.enable`,{},t);let e=(await this.transport.send(`Page.getFrameTree`,{},t)).frameTree?.frame;if(e?.id&&typeof e.id==`string`){let n=this.sessions.get(t);n&&(n.rootFrameId=e.id)}}catch(e){sq.debug(`Failed to enable Page/Network on attached target`,{sessionId:t,error:e instanceof Error?e.message:String(e)})}}}};i(`tray-sync`);const uq=[`api-catalog`,`service-desc`,`service-meta`,`status`,`https://llmstxt.org/rel/llms-txt`];async function dq(e,t={}){let n=t.fetchImpl??fetch,r=t.timeoutMs??3e3,i={links:e,failures:[]},a=[],o=new Set;for(let s of e)for(let e of s.rel)uq.includes(e)&&(o.has(e)||(o.add(e),a.push(fq(n,s.href,r,t.signal).then(t=>pq(i,e,t)).catch(t=>{i.failures.push({rel:e,href:s.href,error:t instanceof Error?t.message:String(t)})}))));return await Promise.all(a),i}async function fq(e,t,n,r){let i=new AbortController,a=setTimeout(()=>i.abort(Error(`timeout`)),n),o=()=>i.abort(Error(`aborted`));r&&r.addEventListener(`abort`,o,{once:!0});try{let n=await e(t,{signal:i.signal});if(!n.ok)throw Error(`HTTP ${n.status}`);return{contentType:n.headers.get(`content-type`)??``,body:await n.text()}}finally{clearTimeout(a),r&&r.removeEventListener(`abort`,o)}}function pq(e,t,n){if(t===`https://llmstxt.org/rel/llms-txt`){e.llmsTxt=n.body;return}let r=n.contentType.includes(`json`)||n.contentType.includes(`linkset`),i=n.body;if(r)try{i=JSON.parse(n.body)}catch{i=n.body}switch(t){case`api-catalog`:e.catalog=i;break;case`service-desc`:e.serviceDesc=i;break;case`service-meta`:e.serviceMeta=i;break;case`status`:e.status=i;break}}var mq=Uint8Array,hq=Uint16Array,gq=Int32Array,_q=new mq([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),vq=new mq([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),yq=new mq([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),bq=function(e,t){for(var n=new hq(31),r=0;r<31;++r)n[r]=t+=1<<e[r-1];for(var i=new gq(n[30]),r=1;r<30;++r)for(var a=n[r];a<n[r+1];++a)i[a]=a-n[r]<<5|r;return{b:n,r:i}},xq=bq(_q,2),Sq=xq.b,Cq=xq.r;Sq[28]=258,Cq[258]=28;for(var wq=bq(vq,0),Tq=wq.b,Eq=wq.r,Dq=new hq(32768),Oq=0;Oq<32768;++Oq){var kq=(Oq&43690)>>1|(Oq&21845)<<1;kq=(kq&52428)>>2|(kq&13107)<<2,kq=(kq&61680)>>4|(kq&3855)<<4,Dq[Oq]=((kq&65280)>>8|(kq&255)<<8)>>1}for(var Aq=(function(e,t,n){for(var r=e.length,i=0,a=new hq(t);i<r;++i)e[i]&&++a[e[i]-1];var o=new hq(t);for(i=1;i<t;++i)o[i]=o[i-1]+a[i-1]<<1;var s;if(n){s=new hq(1<<t);var c=15-t;for(i=0;i<r;++i)if(e[i])for(var l=i<<4|e[i],u=t-e[i],d=o[e[i]-1]++<<u,f=d|(1<<u)-1;d<=f;++d)s[Dq[d]>>c]=l}else for(s=new hq(r),i=0;i<r;++i)e[i]&&(s[i]=Dq[o[e[i]-1]++]>>15-e[i]);return s}),jq=new mq(288),Oq=0;Oq<144;++Oq)jq[Oq]=8;for(var Oq=144;Oq<256;++Oq)jq[Oq]=9;for(var Oq=256;Oq<280;++Oq)jq[Oq]=7;for(var Oq=280;Oq<288;++Oq)jq[Oq]=8;for(var Mq=new mq(32),Oq=0;Oq<32;++Oq)Mq[Oq]=5;var Nq=Aq(jq,9,0),Pq=Aq(jq,9,1),Fq=Aq(Mq,5,0),Iq=Aq(Mq,5,1),Lq=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},Rq=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},zq=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},Bq=function(e){return(e+7)/8|0},Vq=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new mq(e.subarray(t,n))},Hq=[`unexpected EOF`,`invalid block type`,`invalid length/literal`,`invalid distance`,`stream finished`,`no stream handler`,,`no callback`,`invalid UTF-8 data`,`extra field too long`,`date not in range 1980-2099`,`filename too long`,`stream finishing`,`invalid zip data`],Uq=function(e,t,n){var r=Error(t||Hq[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,Uq),!n)throw r;return r},Wq=function(e,t,n,r){var i=e.length,a=r?r.length:0;if(!i||t.f&&!t.l)return n||new mq(0);var o=!n,s=o||t.i!=2,c=t.i;o&&(n=new mq(i*3));var l=function(e){var t=n.length;if(e>t){var r=new mq(Math.max(t*2,e));r.set(n),n=r}},u=t.f||0,d=t.p||0,f=t.b||0,p=t.l,m=t.d,h=t.m,g=t.n,_=i*8;do{if(!p){u=Rq(e,d,1);var v=Rq(e,d+1,3);if(d+=3,!v){var y=Bq(d)+4,b=e[y-4]|e[y-3]<<8,x=y+b;if(x>i){c&&Uq(0);break}s&&l(f+b),n.set(e.subarray(y,x),f),t.b=f+=b,t.p=d=x*8,t.f=u;continue}else if(v==1)p=Pq,m=Iq,h=9,g=5;else if(v==2){var S=Rq(e,d,31)+257,C=Rq(e,d+10,15)+4,w=S+Rq(e,d+5,31)+1;d+=14;for(var T=new mq(w),E=new mq(19),D=0;D<C;++D)E[yq[D]]=Rq(e,d+D*3,7);d+=C*3;for(var O=Lq(E),ee=(1<<O)-1,te=Aq(E,O,1),D=0;D<w;){var ne=te[Rq(e,d,ee)];d+=ne&15;var y=ne>>4;if(y<16)T[D++]=y;else{var k=0,re=0;for(y==16?(re=3+Rq(e,d,3),d+=2,k=T[D-1]):y==17?(re=3+Rq(e,d,7),d+=3):y==18&&(re=11+Rq(e,d,127),d+=7);re--;)T[D++]=k}}var ie=T.subarray(0,S),ae=T.subarray(S);h=Lq(ie),g=Lq(ae),p=Aq(ie,h,1),m=Aq(ae,g,1)}else Uq(1);if(d>_){c&&Uq(0);break}}s&&l(f+131072);for(var oe=(1<<h)-1,se=(1<<g)-1,ce=d;;ce=d){var k=p[zq(e,d)&oe],le=k>>4;if(d+=k&15,d>_){c&&Uq(0);break}if(k||Uq(2),le<256)n[f++]=le;else if(le==256){ce=d,p=null;break}else{var ue=le-254;if(le>264){var D=le-257,de=_q[D];ue=Rq(e,d,(1<<de)-1)+Sq[D],d+=de}var fe=m[zq(e,d)&se],A=fe>>4;fe||Uq(3),d+=fe&15;var ae=Tq[A];if(A>3){var de=vq[A];ae+=zq(e,d)&(1<<de)-1,d+=de}if(d>_){c&&Uq(0);break}s&&l(f+131072);var pe=f+ue;if(f<ae){var me=a-ae,he=Math.min(ae,pe);for(me+f<0&&Uq(3);f<he;++f)n[f]=r[me+f]}for(;f<pe;++f)n[f]=n[f-ae]}}t.l=p,t.p=ce,t.b=f,t.f=u,p&&(u=1,t.m=h,t.d=m,t.n=g)}while(!u);return f!=n.length&&o?Vq(n,0,f):n.subarray(0,f)},Gq=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8},Kq=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8,e[r+2]|=n>>16},qq=function(e,t){for(var n=[],r=0;r<e.length;++r)e[r]&&n.push({s:r,f:e[r]});var i=n.length,a=n.slice();if(!i)return{t:eJ,l:0};if(i==1){var o=new mq(n[0].s+1);return o[n[0].s]=1,{t:o,l:1}}n.sort(function(e,t){return e.f-t.f}),n.push({s:-1,f:25001});var s=n[0],c=n[1],l=0,u=1,d=2;for(n[0]={s:-1,f:s.f+c.f,l:s,r:c};u!=i-1;)s=n[n[l].f<n[d].f?l++:d++],c=n[l!=u&&n[l].f<n[d].f?l++:d++],n[u++]={s:-1,f:s.f+c.f,l:s,r:c};for(var f=a[0].s,r=1;r<i;++r)a[r].s>f&&(f=a[r].s);var p=new hq(f+1),m=Jq(n[u-1],p,0);if(m>t){var r=0,h=0,g=m-t,_=1<<g;for(a.sort(function(e,t){return p[t.s]-p[e.s]||e.f-t.f});r<i;++r){var v=a[r].s;if(p[v]>t)h+=_-(1<<m-p[v]),p[v]=t;else break}for(h>>=g;h>0;){var y=a[r].s;p[y]<t?h-=1<<t-p[y]++-1:++r}for(;r>=0&&h;--r){var b=a[r].s;p[b]==t&&(--p[b],++h)}m=t}return{t:new mq(p),l:m}},Jq=function(e,t,n){return e.s==-1?Math.max(Jq(e.l,t,n+1),Jq(e.r,t,n+1)):t[e.s]=n},Yq=function(e){for(var t=e.length;t&&!e[--t];);for(var n=new hq(++t),r=0,i=e[0],a=1,o=function(e){n[r++]=e},s=1;s<=t;++s)if(e[s]==i&&s!=t)++a;else{if(!i&&a>2){for(;a>138;a-=138)o(32754);a>2&&(o(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(o(i),--a;a>6;a-=6)o(8304);a>2&&(o(a-3<<5|8208),a=0)}for(;a--;)o(i);a=1,i=e[s]}return{c:n.subarray(0,r),n:t}},Xq=function(e,t){for(var n=0,r=0;r<t.length;++r)n+=e[r]*t[r];return n},Zq=function(e,t,n){var r=n.length,i=Bq(t+2);e[i]=r&255,e[i+1]=r>>8,e[i+2]=e[i]^255,e[i+3]=e[i+1]^255;for(var a=0;a<r;++a)e[i+a+4]=n[a];return(i+4+r)*8},Qq=function(e,t,n,r,i,a,o,s,c,l,u){Gq(t,u++,n),++i[256];for(var d=qq(i,15),f=d.t,p=d.l,m=qq(a,15),h=m.t,g=m.l,_=Yq(f),v=_.c,y=_.n,b=Yq(h),x=b.c,S=b.n,C=new hq(19),w=0;w<v.length;++w)++C[v[w]&31];for(var w=0;w<x.length;++w)++C[x[w]&31];for(var T=qq(C,7),E=T.t,D=T.l,O=19;O>4&&!E[yq[O-1]];--O);var ee=l+5<<3,te=Xq(i,jq)+Xq(a,Mq)+o,ne=Xq(i,f)+Xq(a,h)+o+14+3*O+Xq(C,E)+2*C[16]+3*C[17]+7*C[18];if(c>=0&&ee<=te&&ee<=ne)return Zq(t,u,e.subarray(c,c+l));var k,re,ie,ae;if(Gq(t,u,1+(ne<te)),u+=2,ne<te){k=Aq(f,p,0),re=f,ie=Aq(h,g,0),ae=h;var oe=Aq(E,D,0);Gq(t,u,y-257),Gq(t,u+5,S-1),Gq(t,u+10,O-4),u+=14;for(var w=0;w<O;++w)Gq(t,u+3*w,E[yq[w]]);u+=3*O;for(var se=[v,x],ce=0;ce<2;++ce)for(var le=se[ce],w=0;w<le.length;++w){var ue=le[w]&31;Gq(t,u,oe[ue]),u+=E[ue],ue>15&&(Gq(t,u,le[w]>>5&127),u+=le[w]>>12)}}else k=Nq,re=jq,ie=Fq,ae=Mq;for(var w=0;w<s;++w){var de=r[w];if(de>255){var ue=de>>18&31;Kq(t,u,k[ue+257]),u+=re[ue+257],ue>7&&(Gq(t,u,de>>23&31),u+=_q[ue]);var fe=de&31;Kq(t,u,ie[fe]),u+=ae[fe],fe>3&&(Kq(t,u,de>>5&8191),u+=vq[fe])}else Kq(t,u,k[de]),u+=re[de]}return Kq(t,u,k[256]),u+re[256]},$q=new gq([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),eJ=new mq(0),tJ=function(e,t,n,r,i,a){var o=a.z||e.length,s=new mq(r+o+5*(1+Math.ceil(o/7e3))+i),c=s.subarray(r,s.length-i),l=a.l,u=(a.r||0)&7;if(t){u&&(c[0]=a.r>>3);for(var d=$q[t-1],f=d>>13,p=d&8191,m=(1<<n)-1,h=a.p||new hq(32768),g=a.h||new hq(m+1),_=Math.ceil(n/3),v=2*_,y=function(t){return(e[t]^e[t+1]<<_^e[t+2]<<v)&m},b=new gq(25e3),x=new hq(288),S=new hq(32),C=0,w=0,T=a.i||0,E=0,D=a.w||0,O=0;T+2<o;++T){var ee=y(T),te=T&32767,ne=g[ee];if(h[te]=ne,g[ee]=te,D<=T){var k=o-T;if((C>7e3||E>24576)&&(k>423||!l)){u=Qq(e,c,0,b,x,S,w,E,O,T-O,u),E=C=w=0,O=T;for(var re=0;re<286;++re)x[re]=0;for(var re=0;re<30;++re)S[re]=0}var ie=2,ae=0,oe=p,se=te-ne&32767;if(k>2&&ee==y(T-se))for(var ce=Math.min(f,k)-1,le=Math.min(32767,T),ue=Math.min(258,k);se<=le&&--oe&&te!=ne;){if(e[T+ie]==e[T+ie-se]){for(var de=0;de<ue&&e[T+de]==e[T+de-se];++de);if(de>ie){if(ie=de,ae=se,de>ce)break;for(var fe=Math.min(se,de-2),A=0,re=0;re<fe;++re){var pe=T-se+re&32767,me=pe-h[pe]&32767;me>A&&(A=me,ne=pe)}}}te=ne,ne=h[te],se+=te-ne&32767}if(ae){b[E++]=268435456|Cq[ie]<<18|Eq[ae];var he=Cq[ie]&31,ge=Eq[ae]&31;w+=_q[he]+vq[ge],++x[257+he],++S[ge],D=T+ie,++C}else b[E++]=e[T],++x[e[T]]}}for(T=Math.max(T,D);T<o;++T)b[E++]=e[T],++x[e[T]];u=Qq(e,c,l,b,x,S,w,E,O,T-O,u),l||(a.r=u&7|c[u/8|0]<<3,u-=7,a.h=g,a.p=h,a.i=T,a.w=D)}else{for(var T=a.w||0;T<o+l;T+=65535){var _e=T+65535;_e>=o&&(c[u/8|0]=l,_e=o),u=Zq(c,u+1,e.subarray(T,_e))}a.i=o}return Vq(s,0,r+Bq(u)+i)},nJ=(function(){for(var e=new Int32Array(256),t=0;t<256;++t){for(var n=t,r=9;--r;)n=(n&1&&-306674912)^n>>>1;e[t]=n}return e})(),rJ=function(){var e=-1;return{p:function(t){for(var n=e,r=0;r<t.length;++r)n=nJ[n&255^t[r]]^n>>>8;e=n},d:function(){return~e}}},iJ=function(e,t,n,r,i){if(!i&&(i={l:1},t.dictionary)){var a=t.dictionary.subarray(-32768),o=new mq(a.length+e.length);o.set(a),o.set(e,a.length),e=o,i.w=a.length}return tJ(e,t.level==null?6:t.level,t.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(e.length)))*1.5):20:12+t.mem,n,r,i)},aJ=function(e,t){var n={};for(var r in e)n[r]=e[r];for(var r in t)n[r]=t[r];return n},oJ=function(e,t){return e[t]|e[t+1]<<8},sJ=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},cJ=function(e,t){return sJ(e,t)+sJ(e,t+4)*4294967296},lJ=function(e,t,n){for(;n;++t)e[t]=n,n>>>=8};function uJ(e,t){return iJ(e,t||{},0,0)}function dJ(e,t){return Wq(e,{i:2},t&&t.out,t&&t.dictionary)}var fJ=function(e,t,n,r){for(var i in e){var a=e[i],o=t+i,s=r;Array.isArray(a)&&(s=aJ(r,a[1]),a=a[0]),a instanceof mq?n[o]=[a,s]:(n[o+=`/`]=[new mq(0),s],fJ(a,o,n,r))}},pJ=typeof TextEncoder<`u`&&new TextEncoder,mJ=typeof TextDecoder<`u`&&new TextDecoder;try{mJ.decode(eJ,{stream:!0})}catch{}var hJ=function(e){for(var t=``,n=0;;){var r=e[n++],i=(r>127)+(r>223)+(r>239);if(n+i>e.length)return{s:t,r:Vq(e,n-1)};i?i==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):i&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function gJ(e,t){if(t){for(var n=new mq(e.length),r=0;r<e.length;++r)n[r]=e.charCodeAt(r);return n}if(pJ)return pJ.encode(e);for(var i=e.length,a=new mq(e.length+(e.length>>1)),o=0,s=function(e){a[o++]=e},r=0;r<i;++r){if(o+5>a.length){var c=new mq(o+8+(i-r<<1));c.set(a),a=c}var l=e.charCodeAt(r);l<128||t?s(l):l<2048?(s(192|l>>6),s(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|e.charCodeAt(++r)&1023,s(240|l>>18),s(128|l>>12&63),s(128|l>>6&63),s(128|l&63)):(s(224|l>>12),s(128|l>>6&63),s(128|l&63))}return Vq(a,0,o)}function _J(e,t){if(t){for(var n=``,r=0;r<e.length;r+=16384)n+=String.fromCharCode.apply(null,e.subarray(r,r+16384));return n}else if(mJ)return mJ.decode(e);else{var i=hJ(e),a=i.s,n=i.r;return n.length&&Uq(8),a}}var vJ=function(e,t){return t+30+oJ(e,t+26)+oJ(e,t+28)},yJ=function(e,t,n){var r=oJ(e,t+28),i=_J(e.subarray(t+46,t+46+r),!(oJ(e,t+8)&2048)),a=t+46+r,o=sJ(e,t+20),s=n&&o==4294967295?bJ(e,a):[o,sJ(e,t+24),sJ(e,t+42)],c=s[0],l=s[1],u=s[2];return[oJ(e,t+10),c,l,i,a+oJ(e,t+30)+oJ(e,t+32),u]},bJ=function(e,t){for(;oJ(e,t)!=1;t+=4+oJ(e,t+2));return[cJ(e,t+12),cJ(e,t+4),cJ(e,t+20)]},xJ=function(e){var t=0;if(e)for(var n in e){var r=e[n].length;r>65535&&Uq(9),t+=r+4}return t},SJ=function(e,t,n,r,i,a,o,s){var c=r.length,l=n.extra,u=s&&s.length,d=xJ(l);lJ(e,t,o==null?67324752:33639248),t+=4,o!=null&&(e[t++]=20,e[t++]=n.os),e[t]=20,t+=2,e[t++]=n.flag<<1|(a<0&&8),e[t++]=i&&8,e[t++]=n.compression&255,e[t++]=n.compression>>8;var f=new Date(n.mtime==null?Date.now():n.mtime),p=f.getFullYear()-1980;if((p<0||p>119)&&Uq(10),lJ(e,t,p<<25|f.getMonth()+1<<21|f.getDate()<<16|f.getHours()<<11|f.getMinutes()<<5|f.getSeconds()>>1),t+=4,a!=-1&&(lJ(e,t,n.crc),lJ(e,t+4,a<0?-a-2:a),lJ(e,t+8,n.size)),lJ(e,t+12,c),lJ(e,t+14,d),t+=16,o!=null&&(lJ(e,t,u),lJ(e,t+6,n.attrs),lJ(e,t+10,o),t+=14),e.set(r,t),t+=c,d)for(var m in l){var h=l[m],g=h.length;lJ(e,t,+m),lJ(e,t+2,g),e.set(h,t+4),t+=4+g}return u&&(e.set(s,t),t+=u),t},CJ=function(e,t,n,r,i){lJ(e,t,101010256),lJ(e,t+8,n),lJ(e,t+10,n),lJ(e,t+12,r),lJ(e,t+16,i)};function wJ(e,t){t||={};var n={},r=[];fJ(e,``,n,t);var i=0,a=0;for(var o in n){var s=n[o],c=s[0],l=s[1],u=l.level==0?0:8,d=gJ(o),f=d.length,p=l.comment,m=p&&gJ(p),h=m&&m.length,g=xJ(l.extra);f>65535&&Uq(11);var _=u?uJ(c,l):c,v=_.length,y=rJ();y.p(c),r.push(aJ(l,{size:c.length,crc:y.d(),c:_,f:d,m,u:f!=o.length||m&&p.length!=h,o:i,compression:u})),i+=30+f+g+v,a+=76+2*(f+g)+(h||0)+v}for(var b=new mq(a+22),x=i,S=a-i,C=0;C<r.length;++C){var d=r[C];SJ(b,d.o,d,d.f,d.u,d.c.length);var w=30+d.f.length+xJ(d.extra);b.set(d.c,d.o+w),SJ(b,i,d,d.f,d.u,d.c.length,d.o,d.m),i+=16+w+(d.m?d.m.length:0)}return CJ(b,i,r.length,S,x),b}function TJ(e,t){for(var n={},r=e.length-22;sJ(e,r)!=101010256;--r)(!r||e.length-r>65558)&&Uq(13);var i=oJ(e,r+8);if(!i)return{};var a=sJ(e,r+16),o=a==4294967295||i==65535;if(o){var s=sJ(e,r-12);o=sJ(e,s)==101075792,o&&(i=sJ(e,s+32),a=sJ(e,s+48))}for(var c=t&&t.filter,l=0;l<i;++l){var u=yJ(e,a,o),d=u[0],f=u[1],p=u[2],m=u[3],h=u[4],g=u[5],_=vJ(e,g);a=h,(!c||c({name:m,size:f,originalSize:p,compression:d}))&&(d?d==8?n[m]=dJ(e.subarray(_,_+f),{out:new mq(p)}):Uq(14,`unknown compression type `+d):n[m]=Vq(e,_,_+f))}return n}const EJ=`https://api.tessl.io`,DJ=`https://browse.sh/api/skills`,OJ=`/workspace/skills`,kJ=`application/vnd.github.v3+json`,AJ=`https://www.sliccy.com/skills/catalog.json`;function jJ(e){if(!(!e||!e.trim()))return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function MJ(e){if(!e)return!1;let t=e.trim().toLowerCase();return t===`true`||t===`1`||t===`yes`}function NJ(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,installAll:MJ(e.installAll)},affinity:{apps:jJ(e.apps),tasks:jJ(e.tasks),role:jJ(e.role),purpose:jJ(e.purpose)},priority:n}})}const PJ={apps:3,tasks:2,role:1,purpose:1};function FJ(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*PJ.apps,r.push(`apps(${i.join(`, `)})`));let a=(e.affinity.tasks??[]).filter(e=>t.tasks.includes(e));return a.length&&(n+=a.length*PJ.tasks,r.push(`tasks(${a.join(`, `)})`)),(e.affinity.role??[]).includes(t.role)&&(n+=PJ.role,r.push(`role(${t.role})`)),(e.affinity.purpose??[]).includes(t.purpose)&&(n+=PJ.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 IJ(e){let t=`upskill ${e.repo}`;return e.path&&(t+=` --path ${e.path}`),e.installAll?t+=` --all`:e.skill&&(t+=` --skill ${e.skill}`),t}async function LJ(e){let t=new Set;try{let n=await e.readDir(OJ);for(let e of n)e.type===`directory`&&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}let RJ;function zJ(){return RJ||=he.create({dbName:`slicc-fs-global`}),RJ}async function BJ(){try{return(await(await zJ()).readTextFile(`/workspace/.git/github-token`)).trim()||void 0}catch{return}}function VJ(e,t=kJ){let n={Accept:t,"User-Agent":`slicc-upskill`};return e&&(n.Authorization=`Bearer ${e}`),n}async function HJ(e){let t=await BJ();return{hasToken:!!t,request:(n,r=kJ)=>e(n,{headers:VJ(t,r)})}}function UJ(e,t){if(!e)return;let n=t.toLowerCase();for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}function WJ(e){let t=mK(e);if(!t)return;try{let e=JSON.parse(t);if(typeof e.message==`string`&&e.message.trim())return e.message.trim()}catch{}let n=t.trim();if(n)return n.slice(0,200)}function GJ(e,t,n){let r=WJ(e.body),i=r?` GitHub said: ${r}`:``,a=UJ(e.headers,`retry-after`),o=UJ(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 KJ(){return`Discovery roots: /workspace/skills plus accessible **/.agents/skills/* and **/.claude/skills/* anywhere in the VFS.
|
|
2641
|
+
`}function qJ(e){switch(e){case`native`:return`native`;case`agents`:return`.agents`;case`claude`:return`.claude`}}function JJ(e,t){let n=`${t}:\n\n`;n+=` NAME SOURCE DESCRIPTION
|
|
2642
|
+
`,n+=` ─────────────────────────────────────────────────────────────
|
|
2643
|
+
`;for(let t of e){let e=t.description||``;n+=` ${t.name.padEnd(20)} ${qJ(t.source).padEnd(9)} ${e}\n`}return n+=`\n${KJ()}`,n}function YJ(e){let t=`Skill: ${e.name}\n`;if(t+=`Description: ${e.description||`(none)`}\n`,t+=`Source: ${qJ(e.source)}\n`,t+=`Source root: ${e.sourceRoot}\n`,e.skillFilePath&&(t+=`Instructions: ${e.skillFilePath}\n`),e.shadowedPaths?.length){t+=`Shadowed paths:
|
|
2644
|
+
`;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function XJ(){return{stdout:`usage: upskill <command> [options]
|
|
2645
|
+
|
|
2646
|
+
Install skills from GitHub repositories, the Tessl registry, or browse.sh.
|
|
2647
|
+
|
|
2648
|
+
Commands:
|
|
2649
|
+
search <query> Search registries for skills
|
|
2650
|
+
list List discoverable local skills
|
|
2651
|
+
tabs [--json] Suggest skills for open browser tabs
|
|
2652
|
+
info <name> Show details about a discoverable local skill
|
|
2653
|
+
read <name> Read the SKILL.md instructions
|
|
2654
|
+
<owner/repo> Install skill(s) from GitHub repository
|
|
2655
|
+
tessl:<name> Install skill from Tessl registry
|
|
2656
|
+
browse:<hostname>/<task> Install site-specific skill from browse.sh
|
|
2657
|
+
|
|
2658
|
+
${KJ()}
|
|
2659
|
+
GitHub Installation:
|
|
2660
|
+
upskill owner/repo List available skills in repo
|
|
2661
|
+
upskill owner/repo --skill name Install specific skill
|
|
2662
|
+
upskill owner/repo --all Install all skills from repo
|
|
2663
|
+
upskill owner/repo --path subdir Restrict to subfolder
|
|
2664
|
+
upskill owner/repo@branch Install from a specific branch
|
|
2665
|
+
upskill owner/repo --branch name Same, using flag syntax
|
|
2666
|
+
|
|
2667
|
+
Recommendations:
|
|
2668
|
+
upskill recommendations Show skills matching your profile
|
|
2669
|
+
upskill recommendations --install Install all recommended skills
|
|
2670
|
+
|
|
2671
|
+
Registry Search:
|
|
2672
|
+
upskill search "pdf conversion" Search registries
|
|
2673
|
+
upskill tessl:postgres-pro Install from Tessl (via GitHub)
|
|
2674
|
+
upskill browse:weather.gov/get-forecast-1uezib
|
|
2675
|
+
Install from browse.sh by slug
|
|
2676
|
+
upskill https://browse.sh/skills/weather.gov/get-forecast-1uezib
|
|
2677
|
+
Same, using the URL form
|
|
2678
|
+
|
|
2679
|
+
Options:
|
|
2680
|
+
--skill <name> Install specific skill (repeatable)
|
|
2681
|
+
--all Install all skills from source
|
|
2682
|
+
--path <subfolder> Only discover skills under this subfolder
|
|
2683
|
+
--branch, -b <name> Install from a specific branch (default: main)
|
|
2684
|
+
--list List available skills without installing
|
|
2685
|
+
--force Overwrite existing skills
|
|
2686
|
+
-h, --help Show help
|
|
2687
|
+
|
|
2688
|
+
GitHub rate limits:
|
|
2689
|
+
On shared VPNs or corporate IPs, anonymous GitHub access may be rate-limited.
|
|
2690
|
+
Configure a token to avoid shared-IP limits: git config github.token <PAT>
|
|
2691
|
+
|
|
2692
|
+
Examples:
|
|
2693
|
+
upskill search "browser automation"
|
|
2694
|
+
upskill anthropics/skills --list
|
|
2695
|
+
upskill anthropics/skills --skill pdf --skill xlsx
|
|
2696
|
+
upskill adobe/skills --path skills/aem --all
|
|
2697
|
+
upskill aemcoder/skills@fix/stateless-tab-targeting --all
|
|
2698
|
+
upskill tessl:postgres-pro
|
|
2699
|
+
upskill browse:weather.gov/get-forecast-1uezib
|
|
2700
|
+
`,stderr:``,exitCode:0}}function ZJ(e){let t=e.match(/github\.com\/([^\/?#]+)\/([^\/?#]+)/);return t?{owner:t[1],repo:t[2].replace(/\.git$/,``)}:null}async function QJ(e,t){let n=await t(`${EJ}/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=hK(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=ZJ(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())}let $J,eY;async function tY(e){if($J)return $J;if(eY)return eY;eY=(async()=>{let t=await e(DJ,{headers:{Accept:`application/json`}});if(t.status!==200)throw Error(`browse.sh returned HTTP ${t.status}`);let n=hK(t.body),r=Array.isArray(n)?n:n.skills??[];return $J=r,r})();try{return await eY}catch(e){throw eY=void 0,e}}async function nY(e,t){let n=await tY(t),r=e.trim().toLowerCase();return r?n.filter(e=>[e.title??``,e.name??``,e.description??``,e.hostname??``,...e.tags??[]].join(` `).toLowerCase().includes(r)).map(e=>({name:e.slug,displayName:e.title||e.name||e.task||e.slug,summary:e.description||``,source:`browseSh`,qualityScore:null,installHint:`upskill browse:${e.hostname}/${e.task}`,sourceRepo:e.hostname})):[]}const rY=/^[A-Za-z0-9._-]+$/;function iY(e){return!e||e===`.`||e===`..`?!1:rY.test(e)}function aY(e){let t;if(e.startsWith(`browse:`))t=e.slice(7);else{let n=e.match(/^https:\/\/browse\.sh\/skills\/([^/?#]+)\/([^/?#]+?)\/?$/);n&&(t=`${n[1]}/${n[2]}`)}if(!t)return null;let n=t.indexOf(`/`);if(n<0)return null;let r=t.slice(0,n),i=t.slice(n+1);if(!r||!i||i.includes(`/`)||!iY(r)||!iY(i))return null;let a=TY(r);return iY(a)?{hostname:a,task:i}:null}function oY(e,t){let n=e.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(n)for(let e of n[1].split(/\r?\n/)){let n=e.match(/^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/);if(!n||n[1]!==t)continue;let r=n[2].trim();return(r.startsWith(`"`)&&r.endsWith(`"`)||r.startsWith(`'`)&&r.endsWith(`'`))&&(r=r.slice(1,-1)),r||void 0}}function sY(e,t){let n=e.updated?` · updated ${e.updated}`:``;return[`> [!NOTE] **Imported from browse.sh** — original slug: \`${t}\``,`>`,"> **SLICC adaptation:** use `playwright-cli` — you are running inside the user's real browser session, so the bot-detection workarounds the upstream skill assumes are usually unnecessary.",`>`,`> Source: <https://browse.sh/skills/${t}>${n}`].join(`
|
|
2701
|
+
`)}function cY(e,t){let n=e.match(/^(---\r?\n[\s\S]*?\r?\n---)(\r?\n|$)/);return n?`${n[1]}${n[2]||`
|
|
2702
|
+
`}\n${t}\n\n${e.slice(n[0].length)}`:`${t}\n\n${e}`}async function lY(e,t,n,r,i=!1){let a=`${e}/${t}`,o=`${DJ}/${e}/${t}`,s;try{let e=await r(o,{headers:{Accept:`application/json`}});if(e.status===404)return{stdout:``,stderr:`upskill: browse.sh skill "${a}" not found\n`,exitCode:1};if(e.status!==200)return{stdout:``,stderr:`upskill: browse.sh returned HTTP ${e.status} for "${a}"\n`,exitCode:1};s=hK(e.body)}catch(e){return{stdout:``,stderr:`upskill: failed to fetch browse.sh skill "${a}": ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let c;if(s.skillMdUrl)try{let e=await r(s.skillMdUrl,{headers:{Accept:`text/plain`}});e.status===200&&(c=mK(e.body))}catch{}if(!c&&s.skillMd&&(c=s.skillMd),!c)return{stdout:``,stderr:`upskill: browse.sh skill "${a}" has no SKILL.md content\n`,exitCode:1};let l=oY(c,`name`),u=t.replace(/-[A-Za-z0-9]{4,8}$/,``),d=l||u||t;if(!iY(d)||d.length>64)return{stdout:``,stderr:`upskill: refusing to install browse.sh skill with unsafe name "${d}"\n`,exitCode:1};if(!iY(e))return{stdout:``,stderr:`upskill: refusing to install browse.sh skill with unsafe hostname "${e}"\n`,exitCode:1};let f=`browse-${e}-${d}`,p=`${OJ}/${f}`;try{if(await n.stat(p),!i)return{stdout:``,stderr:`upskill: skill "${f}" already exists (use --force to overwrite)\n`,exitCode:1};await n.rm(p,{recursive:!0})}catch{}let m=sY(s,a),h=cY(c,m);return await n.mkdir(p,{recursive:!0}),await n.writeFile(`${p}/SKILL.md`,h),await vY(),{stdout:`Installed skill "${f}" from browse.sh (${a})\n`,stderr:``,exitCode:0}}const uY=[{label:`Tessl`,fetch:QJ},{label:`browse.sh`,fetch:nY}];function dY(e){let t=[],n=e.reduce((e,t)=>Math.max(e,t.length),0);for(let r=0;r<n;r++)for(let n of e)r<n.length&&t.push(n[r]);return t}async function fY(e,t,n=1){let r=await Promise.allSettled(uY.map(n=>n.fetch(e,t))),i=r.map(e=>e.status===`fulfilled`?e.value:[]),a=r.every(e=>e.status===`rejected`),o=dY(i);if(o.length===0){let t=a?`upskill: registries failed to respond
|
|
2703
|
+
`:``;return{stdout:`No skills found for "${e}"\n\nTry a different search term or browse the registries at https://tessl.io/registry or https://browse.sh\n`,stderr:t,exitCode:+!!t}}let s=o.length,c=Math.ceil(s/10),l=Math.max(1,Math.min(n,c)),u=(l-1)*10,d=o.slice(u,u+10),f=`Search results for "${e}" (page ${l}/${c}, ${s} total):\n\n`;for(let e of d){let t=e.qualityScore==null?` `:String(e.qualityScore).padStart(3),n=`[${e.source}]`,r=e.sourceRepo?` ${e.sourceRepo}`:``;f+=` ${e.name.padEnd(30)} ${t} ${n.padEnd(10)}${r}\n`,e.summary&&(f+=` ${e.summary}\n`),f+=`
|
|
2704
|
+
`}return l<c&&(f+=`Showing ${u+1}-${u+d.length} of ${s}. `,f+=`Next page: upskill search ${e} --page ${l+1}\n\n`),f+=`To install:
|
|
2705
|
+
`,f+=` From Tessl: upskill <owner/repo> --skill <name>
|
|
2706
|
+
`,f+=` From browse.sh: upskill browse:<hostname>/<task>
|
|
2707
|
+
`,{stdout:f,stderr:``,exitCode:0}}async function pY(e,t){let n=await t(`${EJ}/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=hK(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=ZJ(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 mY(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`?mY(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=ZR(i);o||=gK(a.body);try{return{status:`ok`,files:TJ(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function hY(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 gY(e,t,n,r,i,a){if(i){let n=await mY(e,t,i,a);if(n.status===`ok`){let e=hY(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(GJ(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=hK(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 _Y(e,t,n,r,i,a,o=!1,s,c){try{let l=`${OJ}/${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 mY(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=hY(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 SY(),await bY(),{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: ${GJ(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=hK(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(GJ(n,`${e}/${t}/${o.path}`,a.hasToken));let s=ZR(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(GJ(l,`${e}/${t}/${o.path}`,a.hasToken));let u=hK(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 vY(),{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}}}async function vY(){await SY(),await bY()}async function yY(e,t,n,r,i=!1){let a=`${OJ}/${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 bY(){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 xY(e){let t=e.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+?)(?:\/(.+?))?)?\/?$/);if(t)return{owner:t[1],repo:t[2],branch:t[3],path:t[4]};let n=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return n?{owner:n[1],repo:n[2],branch:n[3]}:null}async function SY(){try{let e=globalThis.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}function CY(e){return{purpose:e.purpose??``,role:e.role??``,tasks:Array.isArray(e.tasks)?e.tasks:[],apps:Array.isArray(e.apps)?e.apps:[],name:e.name??``}}async function wY(e,t,n){let r=Date.now(),i=(e,t=[])=>({installedNames:[],errors:t,skipped:e,log:``,elapsedSeconds:(Date.now()-r)/1e3}),a=null;if(n)a=CY(n);else try{let t=await e.readDir(`/home`);for(let n of t)try{let t=await e.readTextFile(`/home/${n.name}/.welcome.json`);a=CY(JSON.parse(t));break}catch{}}catch{}if(!a)return i(`no-profile`);let o,s;try{let[n,r]=await Promise.all([(async()=>{let e=await t(AJ,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return NJ(hK(e.body).data)})(),LJ(e)]);o=n,s=r}catch(e){return i(`catalog-fetch`,[`upskill: failed to fetch skill catalog from ${AJ}: ${e instanceof Error?e.message:String(e)}`])}let c=FJ(o,a).filter(e=>!s.has(e.entry.name));if(c.length===0)return i(`all-installed`);let l=new Map;for(let e of c){let t=e.entry.source.repo,n=l.get(t);n?n.push(e):l.set(t,[e])}let u=c.length,d=0,f=``,p=[],m=[],h=await Promise.allSettled(Array.from(l.entries()).map(async([n,i])=>{let[a,o]=n.split(`/`),c=await mY(a,o,t);if(c.status===`not_found`||c.status===`error`){let e=c.status===`not_found`?`upskill: repository ${n} not found`:`upskill: failed to fetch ${n}: ${c.message}`,t=[];for(let e of i){d++;let i=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${e.entry.name}" from ${n}: repo fetch failed${i}\n`,t.push({ok:!1,name:e.entry.name,error:`repo fetch failed for ${n}`})}return{errors:[e],results:t}}let l=hY(c.files),p=[],m=new Map;for(let e of Object.keys(l))if(e.endsWith(`/SKILL.md`)){let t=e.replace(/\/SKILL\.md$/,``),n=t.split(`/`).pop()||t;m.set(n,t)}for(let t of i){let i=t.entry.source;if(i.installAll&&i.path){let a=i.path.replace(/^\/|\/$/g,``),o=[];for(let[e,t]of m)(t===a||t.startsWith(a+`/`))&&o.push({name:e,path:t});d++;let c=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;if(o.length===0){let e=`no skills found under "${i.path}" in ${n}`;p.push({ok:!1,name:t.entry.name,error:e}),f+=`[${d}/${u}] Failed "${t.entry.name}" bundle from ${n}: ${e}${c}\n`;continue}let h=Date.now(),g=0,_=0;for(let t of o){if(s.has(t.name))continue;let n=await yY(t.path,t.name,l,e,!1);n.ok?(p.push({ok:!0,name:t.name}),g++):(p.push({ok:!1,name:t.name,error:n.error}),_++)}let v=((Date.now()-h)/1e3).toFixed(1);g===0&&_===0?f+=`[${d}/${u}] Skipped "${t.entry.name}" bundle from ${n}: all sub-skills already installed${c}\n`:_===0?f+=`[${d}/${u}] Installed "${t.entry.name}" bundle (${g} skill(s)) from ${n} (${v}s)${c}\n`:f+=`[${d}/${u}] Installed "${t.entry.name}" bundle (${g}/${g+_} skill(s)) from ${n} (${v}s)${c}\n`;continue}let a,o;if(i.skill){let e=m.get(i.skill);if(e)a=e,o=i.skill;else if(i.path)a=i.path.replace(/^\/|\/$/g,``),o=i.skill;else{let e=`skill "${i.skill}" not found in ${n}`;p.push({ok:!1,name:t.entry.name,error:e}),d++;let a=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${t.entry.name}" from ${n}: ${e}${a}\n`;continue}}else if(i.path)a=i.path.replace(/^\/|\/$/g,``),o=t.entry.name;else{let e=m.get(t.entry.name);if(e)a=e,o=t.entry.name;else{let e=`skill "${t.entry.name}" not found in ${n} and no explicit path provided`;p.push({ok:!1,name:t.entry.name,error:e}),d++;let i=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${t.entry.name}" from ${n}: ${e}${i}\n`;continue}}let c=Date.now(),h=await yY(a,o,l,e,!1);d++;let g=((Date.now()-c)/1e3).toFixed(1),_=(Date.now()-r)/d,v=Math.round((u-d)*_/1e3),y=d<u?` (~${v}s remaining)`:``;h.ok?(p.push({ok:!0,name:o}),f+=`[${d}/${u}] Installed "${o}" from ${n} (${g}s)${y}\n`):(p.push({ok:!1,name:o,error:h.error}),f+=`[${d}/${u}] Failed "${o}" from ${n}: ${h.error}${y}\n`)}return{errors:[],results:p}}));for(let e of h){if(e.status===`rejected`){p.push(`upskill: unexpected error: ${e.reason}`);continue}for(let t of e.value.errors)p.push(t);for(let t of e.value.results)t.ok?m.push(t.name):t.error&&p.push(`upskill: ${t.error}`)}m.length>0&&await vY();let g=(Date.now()-r)/1e3;return m.length>0&&(f+=`\nInstalled ${m.length} recommended skill(s) in ${g.toFixed(1)}s\n`),{installedNames:m,errors:p,skipped:null,log:f,elapsedSeconds:g}}function TY(e){let t=e.toLowerCase();return t.startsWith(`www.`)?t.slice(4):t}function EY(e,t,n){let r=`upskill ${e}`;return t&&(r+=` --branch ${t}`),n&&(r+=` --path ${n}`),r}async function DY(e,t){let n=[],r;try{r=await t(e,{method:`GET`})}catch(t){return n.push({rel:`https://www.sliccy.ai/rel/upskill`,href:e,error:t instanceof Error?t.message:String(t)}),{links:[],failures:n}}let i=[];for(let[e,t]of Object.entries(r.headers||{}))e.toLowerCase()===`link`&&typeof t==`string`&&t.length>0&&i.push(t);if(i.length===0)return{links:[],failures:n};let a=WK(i,e),o=[];for(let e of a){if(!e.rel.includes(`https://www.sliccy.ai/rel/upskill`))continue;let t=aq([e]);!t||t.verb!==`upskill`||o.push({target:t.target,branch:t.branch,path:t.path,instruction:t.instruction,installHint:EY(t.target,t.branch,t.path)})}return{links:o,failures:n}}async function OY(e,t,n,r){if(!n)return{stdout:``,stderr:`upskill: browser APIs unavailable in this environment
|
|
2708
|
+
`,exitCode:1};let i;try{i=await n.listPages()}catch{try{i=await n.listAllTargets()}catch(e){return{stdout:``,stderr:`upskill: failed to list browser tabs: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}if(i.length===0)return r?{stdout:JSON.stringify({tabs:[]},null,2)+`
|
|
2709
|
+
`,stderr:``,exitCode:0}:{stdout:`No open browser tabs.
|
|
2710
|
+
`,stderr:``,exitCode:0};let a=[],o=``;try{a=await tY(t)}catch(e){o=`upskill: warning: browse.sh catalog unavailable: ${e instanceof Error?e.message:String(e)}\n`}let s=await LJ(e),c=[];for(let e of i){let n=``;try{n=new URL(e.url).hostname}catch{}let r=n?TY(n):``,i=[],o=[];if(n&&/^https?:/i.test(e.url)){let n=await DY(e.url,t);i=n.links,o=n.failures}let l=[];if(r&&a.length>0)for(let e of a){if(!e.hostname||TY(e.hostname)!==r)continue;let t=e.name||e.task.replace(/-[A-Za-z0-9]{4,8}$/,``)||e.task,n=`browse-${e.hostname}-${t}`;l.push({slug:e.slug,hostname:e.hostname,task:e.task,title:e.title||e.name||e.task,description:e.description,installed:s.has(n),installHint:`upskill browse:${e.hostname}/${e.task}`})}c.push({targetId:e.targetId,title:e.title,url:e.url,hostname:r,active:e.active,origin:i,catalog:l,failures:o})}if(r)return{stdout:JSON.stringify({tabs:c},null,2)+`
|
|
2711
|
+
`,stderr:o,exitCode:0};let l=``;for(let e of c){let t=e.active?` [active]`:``;if(l+=`${e.title||`(untitled)`}${t}\n`,l+=` ${e.url}\n`,e.origin.length>0){l+=` Origin-advertised:
|
|
2712
|
+
`;for(let t of e.origin)l+=` ${t.installHint}`,t.instruction&&(l+=` # ${t.instruction}`),l+=`
|
|
2713
|
+
`}if(e.catalog.length>0){l+=` Browse.sh catalog:
|
|
2714
|
+
`;for(let t of e.catalog){let e=t.installed?`✓`:` `;l+=` ${e} ${t.title.padEnd(40)} ${t.installHint}\n`}}if(e.origin.length===0&&e.catalog.length===0&&!e.failures.length&&(l+=` No skill suggestions for this tab.
|
|
2715
|
+
`),e.failures.length>0)for(let t of e.failures)l+=` (discovery failed: ${t.error})\n`;l+=`
|
|
2716
|
+
`}return{stdout:l,stderr:o,exitCode:0}}async function kY(e,t,n){if(n){let n=await wY(e,t);return n.skipped===`no-profile`?{stdout:``,stderr:`upskill: no user profile found. Complete the welcome onboarding first, or create /home/<name>/.welcome.json manually.
|
|
2717
|
+
`,exitCode:1}:n.skipped===`catalog-fetch`?{stdout:``,stderr:n.errors.map(e=>`${e}\n`).join(``),exitCode:1}:n.skipped===`all-installed`?{stdout:`No new skill recommendations — all matching skills are already installed.
|
|
2718
|
+
`,stderr:``,exitCode:0}:{stdout:n.log,stderr:n.errors.map(e=>`${e}\n`).join(``),exitCode:+(n.errors.length>0)}}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.
|
|
2719
|
+
`,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(AJ,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return NJ(hK(e.body).data)})(),LJ(e)]);i=n,a=r}catch(e){return{stdout:``,stderr:`upskill: failed to fetch skill catalog from ${AJ}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=FJ(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.
|
|
2720
|
+
`,stderr:``,exitCode:0};let s=`Recommended skills for you:
|
|
2721
|
+
|
|
2722
|
+
`,c=0;for(let e of o){c++;let t=IJ(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
|
|
2723
|
+
`,{stdout:s,stderr:``,exitCode:0}}function AY(e,t,n){return FM(`upskill`,async(r,i)=>{if(r.length===0||r.includes(`--help`)||r.includes(`-h`))return XJ();if(r[0]===`tabs`)return OY(e,t,n,r.includes(`--json`));let a=[],o,s=!1,c=!1,l=!1,u=``,d,f=``,p=1,m=0;for(;m<r.length;){let n=r[m];if(n===`search`){let e=r.slice(m+1),t=e.indexOf(`--page`);t>=0&&(p=parseInt(e[t+1],10)||1,e.splice(t,2)),f=e.join(` `);break}else if(n===`recommendations`)return kY(e,t,r.includes(`--install`));else if(n===`list`){let t=await(await Promise.resolve().then(()=>B4)).discoverSkills(e);return t.length===0?{stdout:`No discoverable local skills found.\n\n${KJ()}`,stderr:``,exitCode:0}:{stdout:JJ(t,`Discoverable local skills`),stderr:``,exitCode:0}}else if(n===`info`||n===`read`){let t=r[m+1];if(!t)return{stdout:``,stderr:`upskill: ${n} requires a skill name\n`,exitCode:1};let i=await Promise.resolve().then(()=>B4);if(n===`info`){let n=await i.getSkillInfo(e,t);return n?{stdout:YJ(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+`
|
|
2724
|
+
`,stderr:``,exitCode:0}}}else if(n===`--skill`)a.push(r[++m]);else if(n===`--path`||n===`-p`){let e=r[++m];if(typeof e!=`string`||!iq(e))return{stdout:``,stderr:`upskill: --path must be a repo-relative sub-path of [A-Za-z0-9._/-]+ with no "..", leading "-"/"/", or shell metacharacters
|
|
2725
|
+
`,exitCode:1};o=e}else if(n===`--list`)s=!0;else if(n===`--all`)c=!0;else if(n===`--force`)l=!0;else if(n===`--branch`||n===`-b`){let e=r[m+1];if(!e||e.startsWith(`-`))return{stdout:``,stderr:`upskill: --branch requires a value
|
|
2726
|
+
`,exitCode:1};if(!rq(e))return{stdout:``,stderr:`upskill: --branch must be a git ref of [A-Za-z0-9._/-]+ with no "..", leading "-"/"/", trailing "/" or ".lock", or shell metacharacters
|
|
2727
|
+
`,exitCode:1};d=r[++m]}else n.startsWith(`-`)||(u=n);m++}if(f)return fY(f,t,p);if(!u)return XJ();if(u.startsWith(`tessl:`)){let n=u.slice(6);if(!n)return{stdout:``,stderr:`upskill: tessl: requires a skill name
|
|
2728
|
+
`,exitCode:1};let r=await pY(n,t);if(`error`in r)return{stdout:``,stderr:`upskill: ${r.error}\n`,exitCode:1};let i=await HJ(t);return _Y(r.owner,r.repo,r.skillPath,r.skillName,e,i,l,t)}let h=aY(u);if(h)return lY(h.hostname,h.task,e,t,l);let g=xY(u);if(g){let{owner:n,repo:r}=g,i=d??g.branch,f=o??g.path,p=await HJ(t),m=await gY(n,r,p,f,t,i);if(m.error)return{stdout:``,stderr:`upskill: failed to list skills: ${m.error}\n`,exitCode:1};if(m.skills.length===0)return{stdout:`No skills found in ${n}/${r}${f?`/`+f:``}\n`,stderr:``,exitCode:0};if(s){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of m.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${m.skills.length} skill(s)\n`,e+=`\nTo install: upskill ${u} --skill <name>\n`,e+=`To install all: upskill ${u} --all\n`,{stdout:e,stderr:``,exitCode:0}}let h=m.skills;if(a.length>0){h=m.skills.filter(e=>a.includes(e.name));for(let e of a)if(!m.skills.find(t=>t.name===e))return{stdout:``,stderr:`upskill: skill "${e}" not found in ${n}/${r}\n`,exitCode:1}}else if(!c){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of m.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${m.skills.length} skill(s)\n`,e+=`\nTo install specific skills: upskill ${u} --skill <name>\n`,e+=`To install all: upskill ${u} --all\n`,{stdout:e,stderr:``,exitCode:0}}let _=``,v=``,y=0,b=h.length,x=Date.now();if(b>1){let a=await mY(n,r,t,i);if(a.status===`not_found`)return{stdout:``,stderr:`upskill: ${i?`branch "${i}" in ${n}/${r}`:`repository ${n}/${r}`} not found\n`,exitCode:1};if(a.status===`error`)return{stdout:``,stderr:`upskill: failed to fetch ${n}/${r}: ${a.message}\n`,exitCode:1};let o=hY(a.files);for(let t=0;t<h.length;t++){let i=h[t],a=await yY(i.path,i.name,o,e,l),s=t+1,c=((Date.now()-x)/1e3).toFixed(1),u=(Date.now()-x)/s,d=Math.round((b-s)*u/1e3),f=s<b?` (~${d}s remaining)`:``;a.ok?(_+=`[${s}/${b}] Installed "${i.name}" from ${n}/${r} (${c}s)${f}\n`,y++):(_+=`[${s}/${b}] Failed "${i.name}": ${a.error}${f}\n`,v+=`upskill: ${a.error}\n`)}}else for(let a of h){let o=await _Y(n,r,a.path,a.name,e,p,l,t,i);o.exitCode===0?(_+=o.stdout,y++):v+=o.stderr}let S=((Date.now()-x)/1e3).toFixed(1);return y>0&&(_+=`\nInstalled ${y} skill(s)${b>1?` in ${S}s`:``}\n`,await vY()),{stdout:_,stderr:v,exitCode:+!!v}}return{stdout:``,stderr:`upskill: unrecognized source "${u}"\n\nExpected: owner/repo, tessl:<name>, or browse:<hostname>/<task>\n`,exitCode:1}})}function jY(e){return FM(`skill`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return{stdout:`usage: skill <command> [options]
|
|
2729
|
+
|
|
2730
|
+
Commands:
|
|
2731
|
+
list List discoverable skills
|
|
2732
|
+
info <name> Show details about a skill
|
|
2733
|
+
read <name> Read the SKILL.md instructions
|
|
2734
|
+
|
|
2735
|
+
${KJ()}
|
|
2736
|
+
For installing skills from registries or GitHub, use 'upskill':
|
|
2737
|
+
upskill search "query" Search registries (Tessl + browse.sh)
|
|
2738
|
+
upskill owner/repo --list List skills in GitHub repo
|
|
2739
|
+
upskill owner/repo --all Install from GitHub
|
|
2740
|
+
upskill tessl:<name> Install from Tessl registry
|
|
2741
|
+
upskill browse:<host>/<task> Install from browse.sh catalog
|
|
2742
|
+
|
|
2743
|
+
Examples:
|
|
2744
|
+
skill list
|
|
2745
|
+
skill info bluebubbles
|
|
2746
|
+
skill read bluebubbles
|
|
2747
|
+
`,stderr:``,exitCode:0};let r=t[0],i=await Promise.resolve().then(()=>B4);try{switch(r){case`list`:{let t=await i.discoverSkills(e);return t.length===0?{stdout:`No discoverable skills found.\n\n${KJ()}Install skills with: upskill owner/repo --all\n`,stderr:``,exitCode:0}:{stdout:JJ(t,`Discoverable skills`),stderr:``,exitCode:0}}case`info`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: info requires a skill name
|
|
2748
|
+
`,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:YJ(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
|
|
2749
|
+
`,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+`
|
|
2750
|
+
`,stderr:``,exitCode:0}}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}}})}const Q=i(`playwright-teleport`);function MY(e){let t=e.match(/^(f[0-9]+)(e[0-9]+)$/);return t?{framePrefix:t[1],isIframe:!0}:{framePrefix:``,isIframe:!1}}function NY(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}const PY=[`playwright-cli`,`playwright`,`puppeteer`],FY=new WeakMap,IY=new Set([`click`,`dblclick`,`fill`,`type`,`press`,`goto`,`navigate`,`select`,`check`,`uncheck`,`drag`,`dialog-accept`,`dialog-dismiss`]);function LY(e){return e.toISOString().replace(/:/g,`-`)}function RY(e,t){let n=FY.get(e);n||(n=new WeakMap,FY.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 zY(e){return e instanceof ve||typeof e==`object`&&e&&`code`in e?e.code===`EEXIST`:e instanceof Error&&e.message.includes(`EEXIST`)}const BY=`function(text) {
|
|
2641
2751
|
const el = this;
|
|
2642
2752
|
const tag = el.tagName;
|
|
2643
2753
|
const proto = tag === 'TEXTAREA' ? window.HTMLTextAreaElement.prototype : window.HTMLInputElement.prototype;
|
|
@@ -2649,11 +2759,11 @@ Available commands:
|
|
|
2649
2759
|
}
|
|
2650
2760
|
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
2651
2761
|
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
2652
|
-
}`,
|
|
2762
|
+
}`,VY=`function() {
|
|
2653
2763
|
const el = this;
|
|
2654
2764
|
if (el.isContentEditable) return el.textContent || '';
|
|
2655
2765
|
return el.value ?? '';
|
|
2656
|
-
}`,
|
|
2766
|
+
}`,HY=`function() {
|
|
2657
2767
|
const el = this;
|
|
2658
2768
|
if (!(el instanceof HTMLElement)) return false;
|
|
2659
2769
|
el.focus();
|
|
@@ -2677,15 +2787,15 @@ Available commands:
|
|
|
2677
2787
|
return true;
|
|
2678
2788
|
}
|
|
2679
2789
|
return false;
|
|
2680
|
-
}`;async function
|
|
2790
|
+
}`;async function UY(e){let t=await e.evaluate(`JSON.stringify({ href: location.href, hostname: location.hostname, pathname: location.pathname })`);return JSON.parse(t)}async function WY(e,t){if(!t.sessionDirsCreated){for(let t of[`/.playwright`,`/.playwright/snapshots`,`/.playwright/screenshots`])try{await e.mkdir(t,{recursive:!0})}catch(e){if(!zY(e))throw e}t.sessionDirsCreated=!0}}async function GY(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=YY(await e.getAccessibilityTree(),new Map,new Map,{value:0}).join(`
|
|
2681
2791
|
`),o=[`Page URL: ${r}`,`Page Title: ${i}`,``,a].join(`
|
|
2682
|
-
`),s=`/.playwright/snapshots/page-${
|
|
2792
|
+
`),s=`/.playwright/snapshots/page-${LY(new Date)}.yml`;return await t.writeFile(s,o),s})}catch{return null}}async function KY(e,t,n){await WY(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(`
|
|
2683
2793
|
`)+`
|
|
2684
|
-
`,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
|
|
2794
|
+
`,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 qY(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`)}function JY(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}function YY(e,t,n,r,i=``,a=``){let o=[],s=at(e.role,`unknown`).toLowerCase(),c=at(e.name),l=at(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=JY(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+=` "${qY(c)}"`),d&&(f+=` [ref=${d}]`),l&&(f+=`: "${qY(l)}"`),o.push(f),e.children)for(let s of e.children)o.push(...YY(s,t,n,r,i+` `,a));return o}async function XY(e,t){if(t.appTabId)return;let n=await e.listPages(),r=await ZY(),i=n.find(e=>e.url.startsWith(r)&&!e.url.includes(`/preview/`));i&&(t.appTabId=i.targetId)}async function ZY(){if(typeof window<`u`)return window.location.origin;let e=P();if(e)try{let t=await e.call(`page-info`,void 0,{timeoutMs:2e3});if(t.origin)return t.origin}catch{}return`http://localhost:5710`}function QY(e,t){return t===e.appTabId}function $Y(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 eX(e,t){return!QY(e,t.targetId)&&!$Y(t)}async function tX(e,t){return await XY(e,t),(typeof e.listAllTargets==`function`?await e.listAllTargets():await e.listPages()).filter(e=>eX(t,e))}async function nX(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=YY(s,c,l,{value:0}).join(`
|
|
2685
2795
|
`);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(`
|
|
2686
|
-
`),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=
|
|
2796
|
+
`),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=YY(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(`
|
|
2687
2797
|
`)}}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(`
|
|
2688
|
-
`)}}function
|
|
2798
|
+
`)}}function rX(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(`, `)}const iX={origin:``,localStorage:{},sessionStorage:{}};function aX(e){return Object.keys(e.localStorage).length+Object.keys(e.sessionStorage).length}function oX(e){if(!e)return null;try{return new URL(e).origin}catch{return null}}function sX(e){try{return new URL(`/favicon.ico`,e).toString()}catch{return e}}function cX(e,t,n){let r=oX(t);if(t&&r===e)return t;let i=oX(n);return n&&i===e?n:e||(t??n)}async function lX(e,t){let n=await e.evaluate(`(() => {
|
|
2689
2799
|
const collect = (storage) => {
|
|
2690
2800
|
const items = {};
|
|
2691
2801
|
for (let i = 0; i < storage.length; i++) {
|
|
@@ -2699,7 +2809,7 @@ Available commands:
|
|
|
2699
2809
|
localStorage: collect(window.localStorage),
|
|
2700
2810
|
sessionStorage: collect(window.sessionStorage),
|
|
2701
2811
|
});
|
|
2702
|
-
})()`);if(typeof n!=`string`||n.length===0)return Q.warn(`Teleport storage capture returned non-string result`,{label:t,type:typeof n}),
|
|
2812
|
+
})()`);if(typeof n!=`string`||n.length===0)return Q.warn(`Teleport storage capture returned non-string result`,{label:t,type:typeof n}),iX;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)}),iX}}function uX(e){return`(() => {
|
|
2703
2813
|
const snapshot = ${JSON.stringify(e)};
|
|
2704
2814
|
if (!snapshot.origin || window.location.origin !== snapshot.origin) return;
|
|
2705
2815
|
const markerKey = '__slicc_teleport_storage_applied__:' + snapshot.origin;
|
|
@@ -2715,7 +2825,7 @@ Available commands:
|
|
|
2715
2825
|
apply(window.localStorage, snapshot.localStorage || {});
|
|
2716
2826
|
apply(window.sessionStorage, snapshot.sessionStorage || {});
|
|
2717
2827
|
try { window.sessionStorage.setItem(markerKey, '1'); } catch {}
|
|
2718
|
-
})();`}function
|
|
2828
|
+
})();`}function dX(e){return`(() => {
|
|
2719
2829
|
const snapshot = ${JSON.stringify(e)};
|
|
2720
2830
|
if (!snapshot.origin || globalThis.location.origin !== snapshot.origin) {
|
|
2721
2831
|
throw new Error('Teleport storage origin mismatch');
|
|
@@ -2733,11 +2843,11 @@ Available commands:
|
|
|
2733
2843
|
localStorageCount: Object.keys(snapshot.localStorage || {}).length,
|
|
2734
2844
|
sessionStorageCount: Object.keys(snapshot.sessionStorage || {}).length,
|
|
2735
2845
|
});
|
|
2736
|
-
})();`}async function
|
|
2846
|
+
})();`}async function fX(e,t,n){let r=aX(t);if(r===0)return;let i=await e.evaluate(dX(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 pX(e,t,n,r){let i=aX(t);if(i===0)return null;let a=await e.sendCDP(`Page.addScriptToEvaluateOnNewDocument`,{source:uX(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 mX(e){let t=await e.evaluate(`(() => JSON.stringify({
|
|
2737
2847
|
url: window.location.href,
|
|
2738
2848
|
title: document.title || '',
|
|
2739
2849
|
bodySnippet: document.body?.innerText?.replace(/s+/g, ' ').trim().slice(0, 500) || '(empty)',
|
|
2740
|
-
}))()`);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 Zq(e){return/callback|authorize\/resume|error/i.test(e)}async function Qq(e,t,n){try{let r=await Xq(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 $q(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 eJ(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 Qq(e,t,`timeout`)}catch(e){Q.warn(`Could not attach to follower for timeout diagnostics`,{error:String(e)})}await $q(t,`timeout`)}if(tJ(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 tJ(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 nJ(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}),rJ(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 rJ(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=Bq;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 Gq(e,`leader`),Q.info(`Captured leader storage for follower`,{totalEntries:Vq(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)throw Error(`No follower selection available — not connected to a tray`);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 Yq(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`)&&eJ(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}),Zq(i)&&await Qq(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}),iJ(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 $q(n,`trigger-error`),n.phase=`done`,tJ(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}async function iJ(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?zq(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=Bq;try{o=await Gq(e,`follower`),Q.info(`Captured follower storage for leader`,{totalEntries:Vq(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=Vq(o);await Qq(e,n,`capture`),await $q(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=Wq(l,n.originalLeaderUrl,t),d=Hq(n.originalLeaderUrl),f=!!l&&d!==l,p=f?Uq(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 Jq(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 Yq(e,o,c,`leader`);try{u&&await e.navigate(u)}finally{await n?.()}}}else{let r=await Yq(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`,tJ(n);let m=i.length>0?` (${zq(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 $q(n,`capture-error`),n.phase=`done`,tJ(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}function aJ(e){return`Usage: ${e} <command> [args...]
|
|
2850
|
+
}))()`);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 hX(e){return/callback|authorize\/resume|error/i.test(e)}async function gX(e,t,n){try{let r=await mX(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 _X(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 vX(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 gX(e,t,`timeout`)}catch(e){Q.warn(`Could not attach to follower for timeout diagnostics`,{error:String(e)})}await _X(t,`timeout`)}if(yX(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 yX(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 bX(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}),xX(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 xX(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=iX;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 lX(e,`leader`),Q.info(`Captured leader storage for follower`,{totalEntries:aX(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)throw Error(`No follower selection available — not connected to a tray`);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 pX(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`)&&vX(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}),hX(i)&&await gX(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}),SX(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 _X(n,`trigger-error`),n.phase=`done`,yX(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}async function SX(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?rX(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=iX;try{o=await lX(e,`follower`),Q.info(`Captured follower storage for leader`,{totalEntries:aX(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=aX(o);await gX(e,n,`capture`),await _X(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=cX(l,n.originalLeaderUrl,t),d=oX(n.originalLeaderUrl),f=!!l&&d!==l,p=f?sX(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 fX(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 pX(e,o,c,`leader`);try{u&&await e.navigate(u)}finally{await n?.()}}}else{let r=await pX(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`,yX(n);let m=i.length>0?` (${rX(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 _X(n,`capture-error`),n.phase=`done`,yX(n),n.rejectBlock?.(e instanceof Error?e:Error(String(e)))}}}function CX(e){return`Usage: ${e} <command> [args...]
|
|
2741
2851
|
|
|
2742
2852
|
Commands:
|
|
2743
2853
|
open [url|/vfs/path] [--foreground|--fg] [--runtime=<id>] [--discover]
|
|
@@ -2820,21 +2930,21 @@ Commands:
|
|
|
2820
2930
|
sessionstorage-clear Clear all sessionStorage
|
|
2821
2931
|
help Show this help message
|
|
2822
2932
|
|
|
2823
|
-
Aliases: ${
|
|
2824
|
-
`}}function
|
|
2825
|
-
`,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),c,l;try{({positional:c,flags:l}=
|
|
2826
|
-
`,exitCode:1};break}if(l.off===`true`){let e=
|
|
2827
|
-
`,stderr:``,exitCode:0};break}let e=
|
|
2933
|
+
Aliases: ${PY.filter(t=>t!==e).join(`, `)}`}const wX=new Set([`tab`,`filename`,`max-width`,`runtime`,`timeout`,`filter`,`output`,`start`,`return`,`teleport-start`,`teleport-return`,`teleport-runtime`,`domain`,`path`,`expires`,`method`]);function TX(e){let t=[],n={};for(let r=0;r<e.length;r++){let i=e[r];if(i.startsWith(`--`)&&i.includes(`=`)){let e=i.indexOf(`=`);n[i.slice(2,e)]=i.slice(e+1)}else if(i.startsWith(`--`)){let t=i.slice(2);if(wX.has(t))if(r+1<e.length&&!e[r+1].startsWith(`--`))n[t]=e[++r];else throw Error(`--${t} requires a value`);else n[t]=`true`}else t.push(i)}return{positional:t,flags:n}}function EX(e){let t=e.tab;return t?{targetId:t}:{error:`Error: --tab <targetId> is required. Run 'playwright-cli tab-list' to get tab IDs.
|
|
2934
|
+
`}}function DX(e){return async(t,n)=>{let r=await e(typeof t==`string`?t:t instanceof URL?t.toString():t.url,{method:n?.method??`GET`});return new Response(r.body,{status:r.status,statusText:r.statusText,headers:r.headers})}}async function OX(e){let t=new Set;try{let n=await e.readDir(`/workspace/skills`);for(let e of n)e.type===`directory`&&e.name.startsWith(`browse-`)&&t.add(e.name)}catch{}return t}async function kX(e,t,n){let r=``;try{r=new URL(e).hostname}catch{return{}}let i=r?TY(r):``;if(!i)return{};let a;try{a=await tY(n)}catch(e){return{warning:`playwright-cli: warning: browse.sh catalog unavailable: ${e instanceof Error?e.message:String(e)}`}}let o=await OX(t),s=[];for(let e of a){if(!e.hostname||TY(e.hostname)!==i)continue;let t=e.name||e.task.replace(/-[A-Za-z0-9]{4,8}$/,``)||e.task,n=`browse-${e.hostname}-${t}`;s.push({slug:e.slug,name:e.name,title:e.title||e.name||e.task,recommendedMethod:e.recommendedMethod,installed:o.has(n),installHint:`upskill browse:${e.hostname}/${e.task}`})}return{skills:s}}async function AX(e,t={}){let n=t.fetchImpl??DK(),r;try{r=await n(e,{method:t.method??`GET`})}catch(t){return{url:e,links:[],handoff:null,error:t instanceof Error?t.message:String(t)}}let i=[];for(let[e,t]of Object.entries(r.headers))e.toLowerCase()===`link`&&typeof t==`string`&&t.length>0&&i.push(t);let a=WK(i,e),o=aq(a),s={url:e,status:r.status,links:a,handoff:o};if(t.discover&&a.length>0){let e=await dq(a,{fetchImpl:DX(n)});s.discovery={catalog:e.catalog,serviceDesc:e.serviceDesc,serviceMeta:e.serviceMeta,status:e.status,llmsTxt:e.llmsTxt,failures:e.failures}}else t.discover&&(s.discovery={failures:[]});if(t.discover&&t.fs){let r=await kX(e,t.fs,n);r.warning?s.browseShWarning=r.warning:r.skills&&r.skills.length>0&&(s.discovery={...s.discovery??{failures:[]},browseShSkills:r.skills})}return s}function jX(e,t,n){let r=CX(e),i=t?RY(t,n):null;return FM(e,async a=>{if(a.length===0||a[0]===`help`||a[0]===`--help`||a[0]===`-h`)return{stdout:r+`
|
|
2935
|
+
`,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),c,l;try{({positional:c,flags:l}=TX(s))}catch(t){return{stdout:``,stderr:`${e} ${o}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}let u;try{switch(o){case`teleport`:{if(l.list===`true`){Q.info(`Listing available follower runtimes`),u={stdout:``,stderr:`teleport: not connected to a tray
|
|
2936
|
+
`,exitCode:1};break}if(l.off===`true`){let e=EX(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&&(yX(t),i.teleportWatchers.delete(e.targetId)),u={stdout:`Teleport watcher disarmed
|
|
2937
|
+
`,stderr:``,exitCode:0};break}let e=EX(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>
|
|
2828
2938
|
`,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
|
|
2829
|
-
`,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}),
|
|
2830
|
-
`,stderr
|
|
2831
|
-
`,exitCode:1};break}let e=c[0],t=await
|
|
2832
|
-
`,stderr
|
|
2833
|
-
`,exitCode:1};break}let e=
|
|
2834
|
-
`,stderr
|
|
2835
|
-
`,stderr:``,exitCode:0};break}case`frames`:{let e=
|
|
2939
|
+
`,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}),yX(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}),bX(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`,r=l.runtime;await XY(t,i);let a;a=r?await t.createRemotePage(r,e):await t.createPage(e);let o=l[`teleport-start`],s=l[`teleport-return`];if(o&&s){Q.info(`Arming teleport via open/tab-new flags`),Q.debug(`Arming teleport via open/tab-new flags details`,{targetId:a,startPattern:o,returnPattern:s});let n,r;try{n=new RegExp(o)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${o}\n`,exitCode:1};break}try{r=new RegExp(s)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${s}\n`,exitCode:1};break}let c=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(a);d&&(yX(d),i.teleportWatchers.delete(a)),bX(t,i,n,r,c*1e3,l[`teleport-runtime`],e,a)}if(l.discover===`true`){let{browseShWarning:t,...r}=await AX(e,{discover:!0,fs:n}),i={action:`open`,targetId:a,source:`auxiliary-fetch`,...r};u={stdout:JSON.stringify(i,null,2)+`
|
|
2940
|
+
`,stderr:t?`${t}\n`:``,exitCode:0};break}u={stdout:`Opened ${e} in new tab [targetId: ${a}]\n`,stderr:``,exitCode:0};break}case`fetch`:{if(c.length===0){u={stdout:``,stderr:`fetch requires a URL
|
|
2941
|
+
`,exitCode:1};break}let e=c[0],{browseShWarning:t,...r}=await AX(e,{discover:l.discover===`true`,method:l.method??`GET`,fs:n});u={stdout:JSON.stringify(r,null,2)+`
|
|
2942
|
+
`,stderr:t?`${t}\n`:``,exitCode:+!!r.error};break}case`goto`:case`navigate`:{if(c.length===0){u={stdout:``,stderr:`goto requires a URL
|
|
2943
|
+
`,exitCode:1};break}let e=EX(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 r=l[`teleport-start`],a=l[`teleport-return`];if(r&&a){Q.info(`Arming teleport via goto/navigate flags`),Q.debug(`Arming teleport via goto/navigate flags details`,{targetId:e.targetId,startPattern:r,returnPattern:a});let n,o;try{n=new RegExp(r)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-start: ${r}\n`,exitCode:1};break}try{o=new RegExp(a)}catch{u={stdout:``,stderr:`Invalid regex for --teleport-return: ${a}\n`,exitCode:1};break}let s=l.timeout?parseInt(l.timeout,10):300,d=i.teleportWatchers.get(e.targetId);d&&(yX(d),i.teleportWatchers.delete(e.targetId)),bX(t,i,n,o,s*1e3,l[`teleport-runtime`],c[0],e.targetId)}if(l.discover===`true`){let{browseShWarning:t,...r}=await AX(c[0],{discover:!0,fs:n}),i={action:`navigate`,targetId:e.targetId,source:`auxiliary-fetch`,...r};u={stdout:JSON.stringify(i,null,2)+`
|
|
2944
|
+
`,stderr:t?`${t}\n`:``,exitCode:0};break}u={stdout:`Navigated to ${c[0]}\n`,stderr:``,exitCode:0};break}case`snapshot`:{let e=EX(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 nX(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+`
|
|
2945
|
+
`,stderr:``,exitCode:0};break}case`frames`:{let e=EX(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(`
|
|
2836
2946
|
`)}`)+`
|
|
2837
|
-
`,stderr:``,exitCode:0};break}case`screenshot`:{let e=
|
|
2947
|
+
`,stderr:``,exitCode:0};break}case`screenshot`:{let e=EX(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() {
|
|
2838
2948
|
this.scrollIntoView({ block: 'center' });
|
|
2839
2949
|
const r = this.getBoundingClientRect();
|
|
2840
2950
|
return { x: r.x + window.scrollX, y: r.y + window.scrollY, width: r.width, height: r.height };
|
|
@@ -2844,17 +2954,17 @@ Aliases: ${gq.filter(t=>t!==e).join(`, `)}`}const oJ=new Set([`tab`,`filename`,`
|
|
|
2844
2954
|
el.scrollIntoView({ block: 'center' });
|
|
2845
2955
|
const r = el.getBoundingClientRect();
|
|
2846
2956
|
return JSON.stringify({ x: r.x + window.scrollX, y: r.y + window.scrollY, width: r.width, height: r.height });
|
|
2847
|
-
})()`);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=
|
|
2957
|
+
})()`);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=NY(o);await n.writeFile(s,u);try{await WY(n,i);let e=`/.playwright/screenshots/screenshot-${LY(new Date)}.png`;await n.writeFile(e,u)}catch{}return`Screenshot saved to ${s} (${Math.round(u.length/1024)} KB)`})+`
|
|
2848
2958
|
`,stderr:``,exitCode:0};break}case`click`:{if(c.length===0){u={stdout:``,stderr:`click requires a ref (e.g. e5)
|
|
2849
|
-
`,exitCode:1};break}let e=
|
|
2959
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2850
2960
|
var el = document.querySelector(${JSON.stringify(s)});
|
|
2851
2961
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2852
2962
|
el.scrollIntoView({ block: 'center' });
|
|
2853
2963
|
el.click();
|
|
2854
2964
|
})()`),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}`})+`
|
|
2855
2965
|
`,stderr:``,exitCode:0};break}case`type`:{if(c.length===0){u={stdout:``,stderr:`type requires text
|
|
2856
|
-
`,exitCode:1};break}let e=
|
|
2857
|
-
`,exitCode:1};break}let e=
|
|
2966
|
+
`,exitCode:1};break}let e=EX(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>
|
|
2967
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2858
2968
|
var el = document.querySelector(${JSON.stringify(c)});
|
|
2859
2969
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2860
2970
|
el.scrollIntoView({ block: 'center' });
|
|
@@ -2863,55 +2973,55 @@ Aliases: ${gq.filter(t=>t!==e).join(`, `)}`}const oJ=new Set([`tab`,`filename`,`
|
|
|
2863
2973
|
el.value = ${JSON.stringify(r)};
|
|
2864
2974
|
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
2865
2975
|
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
2866
|
-
})()`),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:
|
|
2976
|
+
})()`),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:HY,returnByValue:!0},o),await t.type(r),s?.objectId&&((await a.send(`Runtime.callFunctionOn`,{objectId:s.objectId,functionDeclaration:VY,returnByValue:!0},o)).result?.value??``)!==r&&await a.send(`Runtime.callFunctionOn`,{objectId:s.objectId,functionDeclaration:BY,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() {
|
|
2867
2977
|
const el = document.querySelector(${JSON.stringify(l)});
|
|
2868
2978
|
if (el) {
|
|
2869
|
-
return (${
|
|
2979
|
+
return (${HY}).call(el);
|
|
2870
2980
|
}
|
|
2871
2981
|
return false;
|
|
2872
2982
|
})()`),await t.type(r),await t.evaluate(`(function() {
|
|
2873
2983
|
const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
|
|
2874
2984
|
if (!el) return '';
|
|
2875
|
-
return (${
|
|
2985
|
+
return (${VY}).call(el);
|
|
2876
2986
|
})()`)!==r&&await t.evaluate(`(function() {
|
|
2877
2987
|
const el = document.querySelector(${JSON.stringify(l.split(`,`)[0].trim())});
|
|
2878
2988
|
if (!el) return;
|
|
2879
|
-
(${
|
|
2989
|
+
(${BY}).call(el, ${JSON.stringify(r)});
|
|
2880
2990
|
})()`),i.snapshots.delete(e.targetId),`Filled ${n} with: ${r}`})+`
|
|
2881
2991
|
`,stderr:``,exitCode:0};break}case`eval`:{if(c.length===0){u={stdout:``,stderr:`eval requires an expression
|
|
2882
|
-
`,exitCode:1};break}let e=
|
|
2992
|
+
`,exitCode:1};break}let e=EX(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`)+`
|
|
2883
2993
|
`,stderr:``,exitCode:0};break}case`eval-file`:{if(c.length===0){u={stdout:``,stderr:`eval-file requires a file path
|
|
2884
|
-
`,exitCode:1};break}let e=
|
|
2994
|
+
`,exitCode:1};break}let e=EX(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`)+`
|
|
2885
2995
|
`,stderr:``,exitCode:0};break}case`press`:{if(c.length===0){u={stdout:``,stderr:`press requires a key name
|
|
2886
|
-
`,exitCode:1};break}let e=
|
|
2887
|
-
`,stderr:``,exitCode:0};break}case`go-forward`:{let e=
|
|
2888
|
-
`,stderr:``,exitCode:0};break}case`reload`:{let e=
|
|
2889
|
-
`,stderr:``,exitCode:0};break}case`tab-list`:{let e=await
|
|
2996
|
+
`,exitCode:1};break}let e=EX(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=EX(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
|
|
2997
|
+
`,stderr:``,exitCode:0};break}case`go-forward`:{let e=EX(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
|
|
2998
|
+
`,stderr:``,exitCode:0};break}case`reload`:{let e=EX(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
|
|
2999
|
+
`,stderr:``,exitCode:0};break}case`tab-list`:{let e=await tX(t,i);if(e.length===0){u={stdout:`No tabs open
|
|
2890
3000
|
`,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(`
|
|
2891
3001
|
`)+`
|
|
2892
|
-
`,stderr:``,exitCode:0};break}case`tab-close`:case`close`:{let e=
|
|
2893
|
-
`,exitCode:1};break}let e=
|
|
3002
|
+
`,stderr:``,exitCode:0};break}case`tab-close`:case`close`:{let e=EX(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)
|
|
3003
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2894
3004
|
var el = document.querySelector(${JSON.stringify(o)});
|
|
2895
3005
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2896
3006
|
el.scrollIntoView({ block: 'center' });
|
|
2897
3007
|
el.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }));
|
|
2898
3008
|
})()`),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}`})+`
|
|
2899
3009
|
`,stderr:``,exitCode:0};break}case`hover`:{if(c.length===0){u={stdout:``,stderr:`hover requires a ref (e.g. e5)
|
|
2900
|
-
`,exitCode:1};break}let e=
|
|
3010
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2901
3011
|
var el = document.querySelector(${JSON.stringify(i)});
|
|
2902
3012
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2903
3013
|
el.scrollIntoView({ block: 'center' });
|
|
2904
3014
|
el.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
|
|
2905
3015
|
})()`),`Hovered ${n} (in iframe)`}let s=r.refToBackendNodeId.get(n);if(!s)throw Error(`Unknown ref "${n}"`);return await t.hoverByBackendNodeId(s),`Hovered ${n}`})+`
|
|
2906
3016
|
`,stderr:``,exitCode:0};break}case`select`:{if(c.length<2){u={stdout:``,stderr:`select requires <ref> <value>
|
|
2907
|
-
`,exitCode:1};break}let e=
|
|
3017
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2908
3018
|
var el = document.querySelector(${JSON.stringify(c)});
|
|
2909
3019
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2910
3020
|
el.value = ${JSON.stringify(r)};
|
|
2911
3021
|
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
2912
3022
|
})()`),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}`})+`
|
|
2913
3023
|
`,stderr:``,exitCode:0};break}case`check`:{if(c.length===0){u={stdout:``,stderr:`check requires a ref (e.g. e5)
|
|
2914
|
-
`,exitCode:1};break}let e=
|
|
3024
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2915
3025
|
var el = document.querySelector(${JSON.stringify(s)});
|
|
2916
3026
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2917
3027
|
if (!el.checked) {
|
|
@@ -2921,7 +3031,7 @@ Aliases: ${gq.filter(t=>t!==e).join(`, `)}`}const oJ=new Set([`tab`,`filename`,`
|
|
|
2921
3031
|
}
|
|
2922
3032
|
})()`),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}`})+`
|
|
2923
3033
|
`,stderr:``,exitCode:0};break}case`uncheck`:{if(c.length===0){u={stdout:``,stderr:`uncheck requires a ref (e.g. e5)
|
|
2924
|
-
`,exitCode:1};break}let e=
|
|
3034
|
+
`,exitCode:1};break}let e=EX(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}=MY(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() {
|
|
2925
3035
|
var el = document.querySelector(${JSON.stringify(s)});
|
|
2926
3036
|
if (!el) throw new Error('Element not found in iframe for ref ${n}');
|
|
2927
3037
|
if (el.checked) {
|
|
@@ -2931,37 +3041,37 @@ Aliases: ${gq.filter(t=>t!==e).join(`, `)}`}const oJ=new Set([`tab`,`filename`,`
|
|
|
2931
3041
|
}
|
|
2932
3042
|
})()`),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}`})+`
|
|
2933
3043
|
`,stderr:``,exitCode:0};break}case`drag`:{if(c.length<2){u={stdout:``,stderr:`drag requires <startRef> <endRef>
|
|
2934
|
-
`,exitCode:1};break}let e=
|
|
3044
|
+
`,exitCode:1};break}let e=EX(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}`})+`
|
|
2935
3045
|
`,stderr:``,exitCode:0};break}case`resize`:{if(c.length<2){u={stdout:``,stderr:`resize requires <width> <height>
|
|
2936
|
-
`,exitCode:1};break}let e=
|
|
2937
|
-
`,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=
|
|
2938
|
-
`,stderr:``,exitCode:0};break}case`cookie-list`:{let e=
|
|
3046
|
+
`,exitCode:1};break}let e=EX(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
|
|
3047
|
+
`,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=EX(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=EX(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
|
|
3048
|
+
`,stderr:``,exitCode:0};break}case`cookie-list`:{let e=EX(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(`
|
|
2939
3049
|
`)})+`
|
|
2940
3050
|
`,stderr:``,exitCode:0};break}case`cookie-get`:{if(c.length===0){u={stdout:``,stderr:`cookie-get requires a cookie name
|
|
2941
|
-
`,exitCode:1};break}let e=
|
|
3051
|
+
`,exitCode:1};break}let e=EX(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(`
|
|
2942
3052
|
`)})+`
|
|
2943
3053
|
`,stderr:``,exitCode:0};break}case`cookie-set`:{if(c.length<2){u={stdout:``,stderr:`cookie-set requires <name> <value>
|
|
2944
|
-
`,exitCode:1};break}let e=
|
|
2945
|
-
`,exitCode:1};break}let e=
|
|
2946
|
-
`,stderr:``,exitCode:0};break}case`localstorage-list`:{let e=
|
|
3054
|
+
`,exitCode:1};break}let e=EX(l);if(`error`in e){u={stdout:``,stderr:e.error,exitCode:1};break}await t.withTab(e.targetId,async()=>{let e=await UY(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
|
|
3055
|
+
`,exitCode:1};break}let e=EX(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 UY(t)).href),await t.sendCDP(`Network.deleteCookies`,e)}),u={stdout:`Cookie "${c[0]}" deleted\n`,stderr:``,exitCode:0};break}case`cookie-clear`:{let e=EX(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
|
|
3056
|
+
`,stderr:``,exitCode:0};break}case`localstorage-list`:{let e=EX(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(`
|
|
2947
3057
|
`)})+`
|
|
2948
3058
|
`,stderr:``,exitCode:0};break}case`localstorage-get`:{if(c.length===0){u={stdout:``,stderr:`localstorage-get requires a key
|
|
2949
|
-
`,exitCode:1};break}let e=
|
|
3059
|
+
`,exitCode:1};break}let e=EX(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})+`
|
|
2950
3060
|
`,stderr:``,exitCode:0};break}case`localstorage-set`:{if(c.length<2){u={stdout:``,stderr:`localstorage-set requires <key> <value>
|
|
2951
|
-
`,exitCode:1};break}let e=
|
|
2952
|
-
`,exitCode:1};break}let e=
|
|
2953
|
-
`,stderr:``,exitCode:0};break}case`sessionstorage-list`:{let e=
|
|
3061
|
+
`,exitCode:1};break}let e=EX(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
|
|
3062
|
+
`,exitCode:1};break}let e=EX(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=EX(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
|
|
3063
|
+
`,stderr:``,exitCode:0};break}case`sessionstorage-list`:{let e=EX(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(`
|
|
2954
3064
|
`)})+`
|
|
2955
3065
|
`,stderr:``,exitCode:0};break}case`sessionstorage-get`:{if(c.length===0){u={stdout:``,stderr:`sessionstorage-get requires a key
|
|
2956
|
-
`,exitCode:1};break}let e=
|
|
3066
|
+
`,exitCode:1};break}let e=EX(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})+`
|
|
2957
3067
|
`,stderr:``,exitCode:0};break}case`sessionstorage-set`:{if(c.length<2){u={stdout:``,stderr:`sessionstorage-set requires <key> <value>
|
|
2958
|
-
`,exitCode:1};break}let e=
|
|
2959
|
-
`,exitCode:1};break}let e=
|
|
2960
|
-
`,stderr:``,exitCode:0};break}case`record`:{let e=c[0]||`about:blank`,r=l.filter;await
|
|
2961
|
-
`,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;
|
|
2962
|
-
`);let i=[];for(let[e,t]of
|
|
3068
|
+
`,exitCode:1};break}let e=EX(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
|
|
3069
|
+
`,exitCode:1};break}let e=EX(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=EX(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
|
|
3070
|
+
`,stderr:``,exitCode:0};break}case`record`:{let e=c[0]||`about:blank`,r=l.filter;await XY(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 UK(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
|
|
3071
|
+
`,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;IY.has(o)&&u.exitCode===0&&d&&(f=await GY(t,n,i,d));try{await KY(n,i,{command:o,args:s,result:u,snapshotPath:f,targetId:d})}catch{}return u})}const MX=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`,`ffmpeg`]],[`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`,`secret`,`nuke`,`models`,`local-llm`,`cost`]],[`Data processing`,[`xargs`,`jq`,`base64`,`date`]],[`Network`,[`curl`,`wget`,`websocat`,`html-to-markdown`]],[`Version control`,[`git`]],[`Languages`,[`node`,`python`,`python3`,`sqlite3`]],[`Skills`,[`skill`,`upskill`]],[`Browser & UI`,[`serve`,`open`,`imgcat`,...PY,`webhook`]],[`Filesystem`,[`mount`,`fswatch`]],[`Scoops & agents`,[`agent`]],[`Process`,[`ps`,`kill`]]]);function NX(e,t=[]){let n=[],r=new Set(e);n.push(`Available commands:
|
|
3072
|
+
`);let i=[];for(let[e,t]of MX){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(`
|
|
2963
3073
|
`)+`
|
|
2964
|
-
`}function
|
|
3074
|
+
`}function PX(e={}){return FM(`commands`,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return{stdout:`commands - display available commands
|
|
2965
3075
|
|
|
2966
3076
|
Usage: commands [command]
|
|
2967
3077
|
|
|
@@ -2972,7 +3082,7 @@ If a command name is provided, shows help for that command.
|
|
|
2972
3082
|
Otherwise, lists all available commands.
|
|
2973
3083
|
|
|
2974
3084
|
Note: This is an enhanced version of 'help' that shows all custom commands.
|
|
2975
|
-
`,stderr:``,exitCode:0};if(t.length>0&&n.exec){let e=t[0];return n.exec(`${e} --help`,{cwd:n.cwd})}return{stdout:
|
|
3085
|
+
`,stderr:``,exitCode:0};if(t.length>0&&n.exec){let e=t[0];return n.exec(`${e} --help`,{cwd:n.cwd})}return{stdout:NX(n.getRegisteredCommands?.()??[],await e.getJshCommands?.()??[]),stderr:``,exitCode:0}})}function FX(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 IX(){return{stdout:`usage: convert [input] [operations...] [output]
|
|
2976
3086
|
|
|
2977
3087
|
Operations:
|
|
2978
3088
|
-resize WxH resize to width x height
|
|
@@ -2987,7 +3097,7 @@ Examples:
|
|
|
2987
3097
|
convert photo.png -resize 50% smaller.png
|
|
2988
3098
|
convert image.jpg -rotate 90 -quality 85 rotated.jpg
|
|
2989
3099
|
convert input.png -crop 100x100+50+50 cropped.png
|
|
2990
|
-
`,stderr:``,exitCode:0}}function
|
|
3100
|
+
`,stderr:``,exitCode:0}}function LX(e=`convert`){return FM(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return IX();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 We(),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=FX(s);e.write(t,e=>{a=new Uint8Array(e)})}),!a||a.byteLength===0)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}}})}function RX(){let e=ht();if(e.state!==`inactive`)return e;try{let e=globalThis.localStorage?.getItem(`slicc.leaderTrayStatus`);if(e){let t=JSON.parse(e);if(t?.state&&t.state!==`inactive`)return t}}catch{}return e}function zX(){try{let e=globalThis.localStorage?.getItem(`slicc.leaderTrayFollowers`);if(e)return JSON.parse(e)}catch{}return[]}function BX(){let e=P();if(e)return async()=>await e.call(`tray-reset`,void 0)}function VX(){return{stdout:`host - display or manage the current tray host status
|
|
2991
3101
|
|
|
2992
3102
|
Usage: host [reset]
|
|
2993
3103
|
|
|
@@ -2995,24 +3105,24 @@ Shows the current tray state (leader or follower) and, when available, the join
|
|
|
2995
3105
|
|
|
2996
3106
|
Subcommands:
|
|
2997
3107
|
reset Disconnect all followers and create a fresh tray session with a new join URL
|
|
2998
|
-
`,stderr:``,exitCode:0}}function
|
|
2999
|
-
`)}\n`}function
|
|
3000
|
-
`)}\n`}function
|
|
3001
|
-
`,exitCode:1};let a=n();return a.state===`inactive`?{stdout:
|
|
3108
|
+
`,stderr:``,exitCode:0}}function HX(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 UX(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 ${HX(n)}`)}n.push(` - ${t.join(` `)}`)}}return`${n.join(`
|
|
3109
|
+
`)}\n`}function WX(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: ${HX(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(`
|
|
3110
|
+
`)}\n`}function GX(e={}){let t=e.getStatus??RX,n=e.getFollowerStatus??O,r=e.getFollowers??zX;return FM(`host`,async i=>{if(i.includes(`--help`)||i.includes(`-h`))return VX();if(i[0]===`reset`)return KX(n,t,e.resetTray??void 0??BX());if(i.length>0)return{stdout:``,stderr:`host: unsupported arguments
|
|
3111
|
+
`,exitCode:1};let a=n();return a.state===`inactive`?{stdout:UX(t(),r()),stderr:``,exitCode:0}:{stdout:WX(a),stderr:``,exitCode:0}})}async function KX(e,t,n){if(e().state!==`inactive`)return{stdout:``,stderr:`host reset: only the leader can reset the tray session
|
|
3002
3112
|
`,exitCode:1};let r=t();if(r.state!==`leader`&&r.state!==`error`)return{stdout:``,stderr:`host reset: no active tray session to reset
|
|
3003
3113
|
`,exitCode:1};if(!n)return{stdout:``,stderr:`host reset: tray reset is not available in this environment
|
|
3004
3114
|
`,exitCode:1};try{return{stdout:`Tray session reset. All followers disconnected.
|
|
3005
|
-
`+
|
|
3115
|
+
`+UX(await n(),[]),stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`host reset: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}function qX(){return{stdout:`imgcat - preview image and video files in the preview tab
|
|
3006
3116
|
|
|
3007
3117
|
Usage: imgcat <path> [path...]
|
|
3008
3118
|
|
|
3009
3119
|
Options:
|
|
3010
3120
|
-h, --help Show this help message
|
|
3011
|
-
`,stderr:``,exitCode:0}}function
|
|
3121
|
+
`,stderr:``,exitCode:0}}function JX(e={}){return FM(`imgcat`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return qX();if(typeof window>`u`||typeof document>`u`)return{stdout:``,stderr:`imgcat: browser APIs are unavailable in this environment
|
|
3012
3122
|
`,exitCode:1};if(!e.onMediaPreview)return{stdout:``,stderr:`imgcat: terminal preview is unavailable
|
|
3013
|
-
`,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=ke(t);if(!Oe(i))return{stdout:``,stderr:`imgcat: unsupported media type: ${e}\n`,exitCode:1};let a=await n.fs.readFileBuffer(t),o=new Uint8Array(a.byteLength);o.set(a),r.push({path:t,mimeType:i,bytes:o})}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
|
|
3123
|
+
`,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=ke(t);if(!Oe(i))return{stdout:``,stderr:`imgcat: unsupported media type: ${e}\n`,exitCode:1};let a=await n.fs.readFileBuffer(t),o=new Uint8Array(a.byteLength);o.set(a),r.push({path:t,mimeType:i,bytes:o})}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 YX=n({Gate:()=>XX,ProcessManager:()=>eZ}),XX=class{paused=!1;resumePromise=null;resumeResolve=null;released=!1;pause(){this.released||this.paused||(this.paused=!0,this.resumePromise=new Promise(e=>{this.resumeResolve=e}))}resume(){if(!this.paused)return;this.paused=!1;let e=this.resumeResolve;this.resumePromise=null,this.resumeResolve=null,e?.()}wait(){return!this.paused||this.released?Promise.resolve():this.resumePromise}release(){if(this.released)return;this.released=!0,this.paused=!1;let e=this.resumeResolve;this.resumePromise=null,this.resumeResolve=null,e?.()}isPaused(){return this.paused}};const ZX=1024,QX=4294967295,$X={SIGINT:130,SIGTERM:143,SIGKILL:137,SIGSTOP:147,SIGCONT:146};var eZ=class{processes=new Map;nextPid=ZX;listeners={spawn:new Set,exit:new Set};signalListeners=new Set;spawn(e){let t=this.allocatePid(),n=e.adoptAbort??new AbortController,r={pid:t,ppid:e.ppid??1,kind:e.kind,argv:e.argv.slice(),cwd:e.cwd??`/`,env:{...e.env??{}},owner:{...e.owner},abort:n,gate:new XX,startedAt:Date.now(),status:`running`,exitCode:null,terminatedBy:null,finishedAt:null};return this.processes.set(t,r),this.fire(`spawn`,r),r}exit(e,t){let n=this.processes.get(e);n&&(n.status===`exited`||n.status===`killed`||(n.finishedAt=Date.now(),t===null?n.terminatedBy?(n.exitCode=$X[n.terminatedBy],n.status=`killed`):(n.exitCode=0,n.status=`exited`):(n.exitCode=t,n.status=n.terminatedBy?`killed`:`exited`),n.gate.release(),this.fire(`exit`,n)))}signal(e,t){let n=this.processes.get(e);return!n||n.status===`exited`||n.status===`killed`?!1:t===`SIGSTOP`?(n.gate.pause(),this.fireSignal(n,t),!0):t===`SIGCONT`?(n.gate.resume(),this.fireSignal(n,t),!0):(t===`SIGKILL`?n.terminatedBy=`SIGKILL`:n.terminatedBy===null&&(n.terminatedBy=t),n.abort.signal.aborted||n.abort.abort(),n.gate.release(),this.fireSignal(n,t),!0)}list(){return Array.from(this.processes.values())}get(e){return this.processes.get(e)??null}wait(e){let t=this.processes.get(e);return t?t.status===`exited`||t.status===`killed`?Promise.resolve(t):new Promise(t=>{let n=r=>{r.pid===e&&(this.listeners.exit.delete(n),t(r))};this.listeners.exit.add(n)}):Promise.reject(Error(`pm: no such process: ${e}`))}on(e,t){return this.listeners[e].add(t),()=>{this.listeners[e].delete(t)}}onSignal(e){return this.signalListeners.add(e),()=>{this.signalListeners.delete(e)}}allocatePid(){let e=this.nextPid,t=this.processes.size+1,n=e,r=0;for(;r<=t;){if(!this.processes.has(n))return this.nextPid=n+1>QX?ZX:n+1,n;if(n=n+1>QX?ZX:n+1,r++,n===e)throw Error(`pm: pid space exhausted`)}throw Error(`pm: pid allocation gave up after ${r} probes (table size=${this.processes.size}); the process table is likely corrupt`)}fire(e,t){let n=Array.from(this.listeners[e]);for(let e of n)try{e(t)}catch(e){console.warn(`[pm] listener error`,e)}}fireSignal(e,t){let n=Array.from(this.signalListeners);for(let r of n)try{r(e,t)}catch(e){console.warn(`[pm] signal listener error`,e)}}};function tZ(e){return async function(t,n){let r=t instanceof Request?t:null,i=nZ(t),a=(n?.method??r?.method??`GET`).toUpperCase(),o=iZ(r?.headers,n?.headers),s,c;if(n&&`body`in n&&n.body!==void 0)s=oZ(n.body,a),c=n.body;else if(r&&a!==`GET`&&a!==`HEAD`){let e=await r.arrayBuffer();s=e.byteLength===0?void 0:new TextDecoder(`utf-8`).decode(new Uint8Array(e)),c=void 0}else s=void 0,c=void 0;c instanceof URLSearchParams&&o&&!aZ(o,`content-type`)&&(o[`Content-Type`]=`application/x-www-form-urlencoded;charset=UTF-8`);let l=await e(i,{method:a,headers:o,body:s}),u=new Headers;for(let[e,t]of Object.entries(l.headers))try{u.set(e,t)}catch{}let d=l.status===204||l.status===205||l.status===304||!l.body||l.body.byteLength===0?null:l.body,f=new Response(d,{status:l.status,statusText:l.statusText,headers:u});try{Object.defineProperty(f,`url`,{value:l.url||i,writable:!1,configurable:!0,enumerable:!1})}catch{}return f}}function nZ(e){return typeof e==`string`?e:e instanceof URL?e.toString():e.url}function rZ(e){if(e){if(e instanceof Headers){let t={};return e.forEach((e,n)=>{t[n]=e}),t}if(Array.isArray(e)){let t={};for(let[n,r]of e)t[n]=r;return t}return{...e}}}function iZ(e,t){let n={};e&&e.forEach((e,t)=>{n[t]=e});let r=rZ(t);if(r)for(let[e,t]of Object.entries(r))n[e]=t;return n}function aZ(e,t){let n=t.toLowerCase();for(let t of Object.keys(e))if(t.toLowerCase()===n)return!0;return!1}function oZ(e,t){if(e!=null&&!(t===`GET`||t===`HEAD`)){if(typeof e==`string`)return e;if(e instanceof URLSearchParams)return e.toString();if(e instanceof Uint8Array)return new TextDecoder(`utf-8`).decode(e);if(e instanceof ArrayBuffer)return new TextDecoder(`utf-8`).decode(new Uint8Array(e));if(ArrayBuffer.isView(e)){let t=e;return new TextDecoder(`utf-8`).decode(new Uint8Array(t.buffer,t.byteOffset,t.byteLength))}throw typeof Blob<`u`&&e instanceof Blob?Error(`node fetch shim: Blob request bodies are not supported (use a string, Uint8Array, or URLSearchParams)`):typeof FormData<`u`&&e instanceof FormData?Error(`node fetch shim: FormData request bodies are not supported (post raw application/x-www-form-urlencoded with URLSearchParams instead)`):typeof ReadableStream<`u`&&e instanceof ReadableStream?Error(`node fetch shim: ReadableStream request bodies are not supported (collect into a Uint8Array or string before calling fetch)`):Error(`node fetch shim: unsupported request body type (${Object.prototype.toString.call(e)}); use a string, Uint8Array, ArrayBuffer, or URLSearchParams`)}}function sZ(e,t){let n=n=>{if(n.data?.type!==`realm-rpc-req`)return;let r=n.data;cZ(e,r,t)};e.addEventListener(`message`,n),e.start?.();let r=!1;return{dispose:()=>{r||(r=!0,e.removeEventListener(`message`,n))}}}async function cZ(e,t,n){try{let r=await lZ(t,n),i={type:`realm-rpc-res`,id:t.id,result:r},a=mZ(r);e.postMessage(i,a)}catch(n){let r=n instanceof Error?n.message:String(n),i={type:`realm-rpc-res`,id:t.id,error:r};e.postMessage(i)}}async function lZ(e,t){switch(e.channel){case`vfs`:return uZ(e.op,e.args,t);case`exec`:return fZ(e.op,e.args,t);case`fetch`:return pZ(e.op,e.args,t);default:throw Error(`realm-host: unknown channel '${e.channel}'`)}}async function uZ(e,t,n){let r=typeof t[0]==`string`?t[0]:null,i=r===null?null:n.fs.resolvePath(n.cwd,r);switch(e){case`readFile`:return n.fs.readFile(i);case`readFileBinary`:return n.fs.readFileBuffer(i);case`writeFile`:return await n.fs.writeFile(i,t[1]),!0;case`writeFileBinary`:return await n.fs.writeFile(i,t[1]),!0;case`readDir`:return n.fs.readdir(i);case`exists`:return n.fs.exists(i);case`stat`:{let e=await n.fs.stat(i);return{isDirectory:e.isDirectory,isFile:e.isFile,size:e.size}}case`mkdir`:return await n.fs.mkdir(i,{recursive:!0}),!0;case`rm`:return await n.fs.rm(i,{recursive:!0}),!0;case`resolvePath`:return n.fs.resolvePath(n.cwd,t[0]);case`walkTree`:{let e=t[1]??{},r=typeof e.maxFileBytes==`number`?e.maxFileBytes:1/0,a=[];return await dZ(n,i,r,a),a}case`writeBatch`:{let e=t[0]??{},r=[],i=[];for(let t of e.mkdirs??[]){let e=n.fs.resolvePath(n.cwd,t);try{await n.fs.mkdir(e,{recursive:!0})}catch(e){let n=e instanceof Error?e.message:String(e);/EEXIST/i.test(n)||r.push({path:t,error:n})}}for(let t of e.files??[]){let e=n.fs.resolvePath(n.cwd,t.path);try{await n.fs.writeFile(e,t.content)}catch(e){i.push({path:t.path,error:e instanceof Error?e.message:String(e)})}}return{ok:!0,failedMkdirs:r,failedFiles:i}}default:throw Error(`realm-host: unknown vfs op '${e}'`)}}async function dZ(e,t,n,r){let i;try{i=await e.fs.readdir(t)}catch{return}for(let a of i){let i=t===`/`?`/${a}`:`${t}/${a}`,o;try{o=await e.fs.stat(i)}catch{continue}if(o.isDirectory)r.push({path:i,isDir:!0}),await dZ(e,i,n,r);else if(o.isFile){if(o.size<=n)try{let t=await e.fs.readFileBuffer(i);r.push({path:i,isDir:!1,size:o.size,content:t});continue}catch{}r.push({path:i,isDir:!1,size:o.size})}}}async function fZ(e,t,n){if(e!==`run`)throw Error(`realm-host: unknown exec op '${e}'`);if(!n.exec)throw Error(`exec is not available in this runtime`);let r=t[0],i=await n.exec(r,{cwd:n.cwd});return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}}async function pZ(e,t,n){if(e!==`request`)throw Error(`realm-host: unknown fetch op '${e}'`);let[r,i]=t,a=await(n.fetch?tZ(n.fetch):globalThis.fetch.bind(globalThis))(r,i),o={};a.headers.forEach((e,t)=>{o[t]=e});let s=new Uint8Array(await a.arrayBuffer());return{status:a.status,statusText:a.statusText,headers:o,body:s,url:a.url}}function mZ(e){return e instanceof Uint8Array?[e.buffer]:e&&typeof e==`object`&&`body`in e&&e.body instanceof Uint8Array?[e.body.buffer]:[]}async function hZ(e){let t=e.procKind??`jsh`,n=e.pm.spawn({kind:t,argv:e.argv,cwd:e.cwd,env:e.env,owner:e.owner,ppid:e.ppid}),r;try{r=await e.realmFactory({kind:e.kind,ctx:e.ctx})}catch(t){let r=t instanceof Error?t.message:String(t);return e.pm.exit(n.pid,1),{stdout:``,stderr:`realm-runner: ${r}\n`,exitCode:1}}let i=sZ(r.controlPort,e.ctx);return new Promise(t=>{let a=!1,o=null,s=null,c=null,l=()=>{s&&r.controlPort.removeEventListener(`message`,s),c&&r.removeEventListener&&r.removeEventListener(`error`,c),o?.(),i.dispose()},u=(i,o)=>{if(!a){a=!0,l();try{r.terminate()}catch{}e.pm.exit(n.pid,o),t(i)}};s=e=>{let t=e.data;if(t?.type===`realm-done`){let t=e.data;u({stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode},t.exitCode)}else if(t?.type===`realm-error`){let t=e.data;u({stdout:``,stderr:t.message+`
|
|
3014
3124
|
`,exitCode:1},1)}},c=e=>{u({stdout:``,stderr:(e.message??`realm error`)+`
|
|
3015
|
-
`,exitCode:1},1)},o=e.pm.onSignal((e,t)=>{e.pid===n.pid&&t===`SIGKILL`&&u({stdout:``,stderr:``,exitCode:137},137)}),r.controlPort.addEventListener(`message`,s),r.addEventListener&&r.addEventListener(`error`,c);let d={type:`realm-init`,kind:e.kind,code:e.code,argv:e.realmArgv??e.argv,env:e.env,cwd:e.cwd,filename:e.filename,stdin:e.stdin,pyodideIndexURL:e.pyodideIndexURL,pyodideSyncDirs:e.pyodideSyncDirs};r.controlPort.postMessage(d)})}async function
|
|
3125
|
+
`,exitCode:1},1)},o=e.pm.onSignal((e,t)=>{e.pid===n.pid&&t===`SIGKILL`&&u({stdout:``,stderr:``,exitCode:137},137)}),r.controlPort.addEventListener(`message`,s),r.addEventListener&&r.addEventListener(`error`,c);let d={type:`realm-init`,kind:e.kind,code:e.code,argv:e.realmArgv??e.argv,env:e.env,cwd:e.cwd,filename:e.filename,stdin:e.stdin,pyodideIndexURL:e.pyodideIndexURL,pyodideSyncDirs:e.pyodideSyncDirs};r.controlPort.postMessage(d)})}async function gZ(e,t,n={}){if(typeof document>`u`)throw Error(`createIframeRealm: document is not available in this runtime`);let r=n.sandboxUrl??_Z();if(!r)throw Error(`createIframeRealm: sandbox URL not available (extension API missing)`);let i=n.container??document.body,a=n.messageChannelCtor??globalThis.MessageChannel;if(typeof a!=`function`)throw Error(`createIframeRealm: MessageChannel is not available`);let o=new a,s=document.createElement(`iframe`);s.style.display=`none`,s.dataset.realm=`js`,s.src=r,i.appendChild(s),n.onIframeCreated?.(s),await new Promise((e,t)=>{let n=!1,r=r=>{n||(n=!0,window.removeEventListener(`message`,i),r?t(r):e())},i=e=>{e.source===s.contentWindow&&e.data?.type===`realm-iframe-ready`&&(s.contentWindow.postMessage({type:`realm-port-init`},`*`,[o.port2]),r())};window.addEventListener(`message`,i),s.addEventListener(`error`,()=>r(Error(`realm-iframe: iframe failed to load`)),{once:!0})});let c=!1;return{controlPort:o.port1,terminate(){if(!c){c=!0;try{s.remove()}catch{}try{o.port1.close()}catch{}}}}}function _Z(){let e=globalThis.chrome;return e?.runtime?.getURL?e.runtime.getURL(`sandbox.html`):null}var vZ=class{port;nextId=1;pending=new Map;handler;disposed=!1;constructor(e){this.port=e,this.handler=e=>{if(e.data?.type!==`realm-rpc-res`)return;let t=e.data,n=this.pending.get(t.id);n&&(this.pending.delete(t.id),typeof t.error==`string`?n.reject(Error(t.error)):n.resolve(t.result))},e.addEventListener(`message`,this.handler),e.start?.()}call(e,t,n=[]){if(this.disposed)return Promise.reject(Error(`realm-rpc: client disposed`));let r=this.nextId++,i={type:`realm-rpc-req`,id:r,channel:e,op:t,args:n};return new Promise((e,t)=>{this.pending.set(r,{resolve:e,reject:t}),this.port.postMessage(i)})}dispose(){if(this.disposed)return;this.disposed=!0,this.port.removeEventListener(`message`,this.handler);let e=Error(`realm-rpc: client disposed`);for(let t of this.pending.values())t.reject(e);this.pending.clear()}};const yZ=new Set([`bcrypt`,`better-sqlite3`,`canvas`,`cpu-features`,`fsevents`,`leveldown`,`libxmljs`,`libxmljs2`,`node-gyp-build`,`node-sass`,`puppeteer`,`robotjs`,`sass-embedded`,`sharp`,`snappy`,`sqlite3`,`tree-sitter`,`usb`]),bZ={sharp:` Use the built-in 'convert' shell command for image work.`,canvas:` Use the built-in 'convert' / OffscreenCanvas for image work.`,"better-sqlite3":` Use the built-in 'sqlite3' shell command (sql.js WASM).`,sqlite3:` Use the built-in 'sqlite3' shell command (sql.js WASM).`,bcrypt:` Use crypto.subtle.digest() with PBKDF2 / Argon2 in pure JS.`,puppeteer:` Use the built-in browser-automation shell commands.`};function xZ(e,t){let n=bZ[t]??``;return Error(`require('${e}'): '${t}' is a Node native module (C++ bindings) — it cannot run in the browser sandbox.${n}`)}function SZ(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>{i(Error(`Timed out after ${t/1e3}s loading ${n}`))},t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}const CZ=new Set([`http`,`https`,`net`,`tls`,`dgram`,`dns`,`cluster`,`worker_threads`,`child_process`,`crypto`,`os`,`stream`,`zlib`,`vm`,`v8`,`perf_hooks`,`readline`,`repl`,`tty`,`inspector`]),wZ=new Set([`fs`,`process`,`buffer`]);var TZ=class extends Error{code;constructor(e){super(`Process exited with code ${e}`),this.code=e,this.name=`NodeExitError`}};function EZ(e){let t=/\brequire\s*\(\s*(['"`])([^'"`\s]+)\1\s*\)/g,n=new Set,r;for(;(r=t.exec(e))!==null;)n.add(r[2]);return[...n]}function DZ(e){if(typeof e==`string`)return e;if(e==null)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}async function OZ(e,t,n=AZ){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(DZ).join(` `)}\n`),info:(...e)=>a(`${e.map(DZ).join(` `)}\n`),warn:(...e)=>o(`${e.map(DZ).join(` `)}\n`),error:(...e)=>o(`${e.map(DZ).join(` `)}\n`)},c=e.stdin??``,l=!1,u={isTTY:!1,read(){return l?null:(l=!0,c)},toString(){return c},[Symbol.asyncIterator](){return{async next(){return l?{value:void 0,done:!0}:(l=!0,{value:c,done:!1})}}}},d={argv:e.argv,env:e.env,cwd:()=>e.cwd,exit:e=>{throw new TZ(Number.isFinite(e)?Number(e):0)},stdin:u,stdout:{write:a},stderr:{write:o}},f=new vZ(t),p={readFile:e=>f.call(`vfs`,`readFile`,[e]),readFileBinary:e=>f.call(`vfs`,`readFileBinary`,[e]),writeFile:(e,t)=>f.call(`vfs`,`writeFile`,[e,t]),writeFileBinary:(e,t)=>f.call(`vfs`,`writeFileBinary`,[e,t]),readDir:e=>f.call(`vfs`,`readDir`,[e]),exists:e=>f.call(`vfs`,`exists`,[e]),stat:e=>f.call(`vfs`,`stat`,[e]),mkdir:e=>f.call(`vfs`,`mkdir`,[e]),rm:e=>f.call(`vfs`,`rm`,[e]),fetchToFile:async(e,t)=>{let n=await h(e);if(!n.ok)throw Error(`fetch ${n.status} ${n.statusText}`);let r=new Uint8Array(await n.arrayBuffer());return await f.call(`vfs`,`writeFileBinary`,[t,r]),r.byteLength}},m=e=>f.call(`exec`,`run`,[e]);async function h(e,t){let n=e instanceof Request?e.url:e instanceof URL?e.toString():String(e),r=await f.call(`fetch`,`request`,[n,kZ(t,e)]),i=r.body.byteLength===0?null:r.body.buffer.slice(r.body.byteOffset,r.body.byteOffset+r.body.byteLength),a=new Response(i,{status:r.status,statusText:r.statusText,headers:r.headers});return Object.defineProperty(a,`url`,{value:r.url||n}),a}let g=EZ(e.code).map(e=>e.startsWith(`node:`)?e.slice(5):e).filter(e=>!wZ.has(e)&&!CZ.has(e)),_=g.filter(e=>yZ.has(e)),v=g.filter(e=>!yZ.has(e));for(let e of _)o(`Warning: ${xZ(e,e).message}\n`);let y=Object.create(null);if(v.length>0){let e=await Promise.allSettled(v.map(async e=>{let t=await SZ(n(e),15e3,`require('${e}')`);y[e]=t&&`default`in t?t.default:t}));for(let t=0;t<e.length;t++){let n=e[t];if(n.status===`rejected`){let e=n.reason instanceof Error?n.reason.message:String(n.reason);o(`Warning: failed to pre-load require('${v[t]}'): ${e}\n`)}}}let b=e=>{let t=e.startsWith(`node:`)?e.slice(5):e;if(t===`fs`)return p;if(t===`process`)return d;if(t===`buffer`)return{Buffer:globalThis.Buffer};if(t===`path`){if(`path`in y)return y.path;if(e in y)return y[e];throw Error(`require('${e}'): path module not pre-loaded. Add require('path') as a static import.`)}if(yZ.has(t))throw xZ(e,t);if(CZ.has(t))throw Error(`require('${e}'): Node built-in '${t}' is not available in the browser environment.${{http:` Use fetch() instead.`,https:` Use fetch() instead.`,child_process:` Use exec() which is available as a shell bridge.`,crypto:` Use globalThis.crypto (Web Crypto API) instead.`}[t]||``}`);if(e in y)return y[e];if(t in y)return y[t];throw Error(`require('${e}'): module not pre-loaded. Use a string literal so it can be pre-fetched, or use \`await import('https://esm.sh/${e}')\` directly.`)},x={exports:{},filename:e.filename},S=0;try{let t=Object.getPrototypeOf(async function(){}).constructor;await new t(`fs`,`process`,`console`,`require`,`module`,`exports`,`exec`,`fetch`,`"use strict";\n${e.code}`)(p,d,s,b,x,x.exports,m,h)}catch(e){e instanceof TZ?S=e.code:(o(`${e instanceof Error?e.stack??e.message:String(e)}\n`),S=1)}f.dispose();let C={type:`realm-done`,stdout:r.join(``),stderr:i.join(``),exitCode:S};t.postMessage(C)}function kZ(e,t){if(!e&&!(t instanceof Request))return;let n=t instanceof Request?t:null,r=(e?.method??n?.method??`GET`).toUpperCase(),i={};if(e?.headers)if(e.headers instanceof Headers)e.headers.forEach((e,t)=>{i[t]=e});else if(Array.isArray(e.headers))for(let[t,n]of e.headers)i[t]=n;else Object.assign(i,e.headers);else n&&n.headers.forEach((e,t)=>{i[t]=e});let a;return e?.body!==void 0&&e?.body!==null&&e?.body!==``&&(a=typeof e.body==`string`?e.body:String(e.body)),{method:r,headers:i,body:a}}async function AZ(e){return await import(`https://esm.sh/`+e)}const jZ=`https://cdn.jsdelivr.net/pyodide/v${Fe(`pyodide`,`0.29.4`)}/full/`;async function MZ(e,t,n=()=>import(`./pyodide-DOGWuEal.js`)){let r=[],i=[],a=new vZ(t),o;try{o=await(await n()).loadPyodide({indexURL:e.pyodideIndexURL,fullStdLib:!1})}catch(e){a.dispose();let n={type:`realm-error`,message:`loadPyodide: ${e instanceof Error?e.message:String(e)}`};t.postMessage(n);return}let s=e.pyodideSyncDirs??[e.cwd,`/tmp`],c=e=>{i.push(`Warning: ${e}\n`)},l={files:new Map,dirs:new Set};try{l=await PZ(a,o,s,c)}catch(e){c(`VFS→Pyodide sync failed: ${e instanceof Error?e.message:String(e)}`)}try{o.FS.chdir(e.cwd)}catch{}o.setStdout({batched:e=>r.push(e+`
|
|
3016
3126
|
`)}),o.setStderr({batched:e=>i.push(e+`
|
|
3017
3127
|
`)});let u=!1;o.setStdin({stdin:()=>u||!e.stdin?null:(u=!0,e.stdin)}),o.globals.set(`__slicc_code`,e.code),o.globals.set(`__slicc_filename`,e.filename),o.globals.set(`__slicc_argv`,e.argv);let d;try{await o.runPythonAsync(`
|
|
3018
3128
|
import sys
|
|
@@ -3034,24 +3144,24 @@ except SystemExit as exc:
|
|
|
3034
3144
|
except BaseException:
|
|
3035
3145
|
traceback.print_exc()
|
|
3036
3146
|
__slicc_exit_code = 1
|
|
3037
|
-
`);let e=o.globals.get(`__slicc_exit_code`);d=typeof e==`number`?e:Number(e??1)}catch(e){let t=e instanceof Error?e.message:String(e);i.push(`${t}\n`),d=1}try{o.runPython(`del __slicc_code, __slicc_filename, __slicc_argv, __slicc_exit_code`)}catch{}try{await
|
|
3038
|
-
`,stderr:``,exitCode:0}}function
|
|
3147
|
+
`);let e=o.globals.get(`__slicc_exit_code`);d=typeof e==`number`?e:Number(e??1)}catch(e){let t=e instanceof Error?e.message:String(e);i.push(`${t}\n`),d=1}try{o.runPython(`del __slicc_code, __slicc_filename, __slicc_argv, __slicc_exit_code`)}catch{}try{await FZ(a,o,s,l,c)}catch(e){c(`Pyodide→VFS sync failed: ${e instanceof Error?e.message:String(e)}`)}a.dispose();let f={type:`realm-done`,stdout:r.join(``),stderr:i.join(``),exitCode:d};t.postMessage(f)}const NZ=10*1024*1024;async function PZ(e,t,n,r=()=>{}){let i=t.FS,a={files:new Map,dirs:new Set};function o(e){try{i.stat(e)}catch{i.mkdirTree(e)}a.dirs.add(e)}function s(e){let t;try{t=i.stat(e)}catch{return}if(i.isDir(t.mode)){a.dirs.add(e);let t;try{t=i.readdir(e).filter(e=>e!==`.`&&e!==`..`)}catch{return}for(let n of t)s(e===`/`?`/${n}`:`${e}/${n}`)}else i.isFile(t.mode)&&a.files.set(e,t.size)}for(let t of n){o(t),s(t);let n;try{n=await e.call(`vfs`,`walkTree`,[t,{maxFileBytes:NZ}])}catch(e){r(`VFS→Pyodide sync skipped '${t}': ${e instanceof Error?e.message:String(e)}`);continue}for(let e of n)try{if(e.isDir){o(e.path);continue}if(e.content===void 0){e.size<=NZ&&r(`VFS→Pyodide skipped '${e.path}': unreadable from VFS`);continue}let t=e.path.lastIndexOf(`/`);t>0&&o(e.path.slice(0,t)),i.writeFile(e.path,e.content),a.files.set(e.path,e.size)}catch(t){let n=t instanceof Error?t.message:String(t);r(`VFS→Pyodide entry '${e.path}' failed: ${n}`)}}return a}async function FZ(e,t,n,r,i=()=>{}){let a=t.FS,o=new Set,s=[];function c(e){let t;try{t=a.readdir(e).filter(e=>e!==`.`&&e!==`..`)}catch{return}for(let n of t){let t=e===`/`?`/${n}`:`${e}/${n}`,l;try{l=a.stat(t)}catch{continue}if(a.isDir(l.mode))r.dirs.has(t)||o.add(t),c(t);else if(a.isFile(l.mode)){let e=r.files.get(t);if(e===void 0||e!==l.size)try{let e=a.readFile(t);s.push({path:t,content:new Uint8Array(e)})}catch(e){i(`Pyodide→VFS read '${t}' failed: ${e instanceof Error?e.message:String(e)}`)}}}}for(let e of n)c(e);if(o.size===0&&s.length===0)return;let l;try{l=await e.call(`vfs`,`writeBatch`,[{mkdirs:[...o],files:s}])}catch(e){i(`Pyodide→VFS writeBatch RPC failed: ${e instanceof Error?e.message:String(e)}`);return}for(let e of l.failedFiles)i(`Pyodide→VFS write '${e.path}' failed: ${e.error}`);for(let e of l.failedMkdirs)i(`Pyodide→VFS mkdir '${e.path}' failed: ${e.error}`)}function IZ(){let e=new Set,t=new Set;return{realmSide:{postMessage:e=>{queueMicrotask(()=>{for(let n of[...t])n({data:e})})},addEventListener:(t,n)=>{e.add(n)},removeEventListener:(t,n)=>{e.delete(n)}},hostSide:{postMessage:t=>{queueMicrotask(()=>{for(let n of[...e])n({data:t})})},addEventListener:(e,n)=>{t.add(n)},removeEventListener:(e,n)=>{t.delete(n)}}}}function LZ(){return async({kind:e})=>{if(e!==`js`)throw Error(`createInProcessJsRealmFactory: only kind:js is supported`);let{realmSide:t,hostSide:n}=IZ(),r=e=>{if(e.data?.type!==`realm-init`)return;t.removeEventListener(`message`,r);let n=e.data;n.kind===`js`&&OZ(n,t,e=>Promise.reject(Error(`in-process realm: require('${e}') is not pre-loaded`))).catch(e=>{let n={type:`realm-error`,message:e instanceof Error?e.message:String(e)};t.postMessage(n)})};return t.addEventListener(`message`,r),{controlPort:n,terminate(){t.removeEventListener(`message`,r)}}}}function RZ(){return async({kind:e})=>{if(e!==`py`)throw Error(`createInProcessPyRealmFactory: only kind:py is supported`);let{realmSide:t,hostSide:n}=IZ(),r=e=>{if(e.data?.type!==`realm-init`)return;t.removeEventListener(`message`,r);let n=e.data;n.kind===`py`&&MZ(n,t).catch(e=>{let n={type:`realm-error`,message:e instanceof Error?e.message:String(e)};t.postMessage(n)})};return t.addEventListener(`message`,r),{controlPort:n,terminate(){t.removeEventListener(`message`,r)}}}}const zZ=LZ(),BZ=RZ();function VZ(){return async({kind:e,ctx:t})=>e===`py`?typeof Worker<`u`?UZ():BZ({kind:e,ctx:t}):Ge()&&typeof document<`u`?gZ(e,t):typeof Worker<`u`?HZ():zZ({kind:e,ctx:t})}function HZ(){if(typeof Worker>`u`)throw Error(`realm-factory: Worker is not available in this runtime`);return WZ(new Worker(new URL(`/assets/js-realm-worker-B3OvP1qG.js`,``+import.meta.url),{type:`module`}))}function UZ(){if(typeof Worker>`u`)throw Error(`realm-factory: Worker is not available in this runtime`);return WZ(new Worker(new URL(`/assets/py-realm-worker-vbqFsiux.js`,``+import.meta.url),{type:`module`}))}function WZ(e){let t={postMessage:(t,n)=>n?e.postMessage(t,n):e.postMessage(t),addEventListener:(t,n)=>e.addEventListener(t,n),removeEventListener:(t,n)=>e.removeEventListener(t,n)},n=!1;return{controlPort:t,addEventListener:(t,n,r)=>e.addEventListener(t,n,r),removeEventListener:(t,n)=>e.removeEventListener(t,n),terminate(){if(!n){n=!0;try{e.terminate()}catch{}}}}}function GZ(){if(Ge()){let e=globalThis.chrome;if(e?.runtime?.getURL)return e.runtime.getURL(`pyodide/`)}return Pe()?decodeURIComponent(Ie(`pyodide/pyodide.mjs`,`../../../../../node_modules/pyodide/`).pathname):jZ}async function KZ(e,t,n,r,i={}){return await n.fs.exists(e)?qZ(await n.fs.readFile(e),[`node`,e,...t],n,r,{...i,filename:e}):{stdout:``,stderr:`jsh: cannot find script '${e}'\n`,exitCode:127}}async function qZ(e,t,n,r,i={}){let a=i.realmFactory??JZ(),o=r?.processManager??ZZ()??XZ(),s=r?.owner??{kind:`system`},c=i.filename??t[1]??`<eval>`;return await hZ({pm:o,realmFactory:a,owner:s,kind:`js`,code:e,argv:t,env:Object.fromEntries(n.env.entries()),cwd:n.cwd,filename:c,stdin:n.stdin,ctx:n,ppid:r?.getParentPid?.()})}function JZ(){return typeof Worker<`u`||typeof document<`u`?VZ():LZ()}let YZ=null;function XZ(){return YZ||=new eZ,YZ}function ZZ(){let e=globalThis.__slicc_pm;return e&&typeof e==`object`&&typeof e.spawn==`function`&&typeof e.onSignal==`function`?e:null}function QZ(){return{stdout:`usage: node -e <code> [args...]
|
|
3148
|
+
`,stderr:``,exitCode:0}}function $Z(){return{stdout:`${He}\n`,stderr:``,exitCode:0}}function eQ(){return FM(`node`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return QZ();if(e.includes(`--version`)||e.includes(`-v`))return $Z();let n=``,r=`<stdin>`,i=[`node`],a=t;if(e.length>0&&(e[0]===`-e`||e[0]===`--eval`)){if(!e[1])return{stdout:``,stderr:`node: option requires an argument -- eval
|
|
3039
3149
|
`,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`],a={...t,stdin:``};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"
|
|
3040
|
-
`,exitCode:9};return
|
|
3150
|
+
`,exitCode:9};return qZ(n,i,a,void 0,{filename:r})})}const tQ=[`--download`,`-d`,`--view`,`-v`];function nQ(){return{stdout:`usage: open [--download|-d] [--view|-v] <url|path> [url|path...]
|
|
3041
3151
|
|
|
3042
3152
|
VFS paths are served in a new browser tab via the preview service worker.
|
|
3043
3153
|
URLs (http/https/etc.) are opened directly in a new tab.
|
|
3044
3154
|
For app directories with a default entry file, prefer serve <dir>.
|
|
3045
3155
|
--download, -d Force download instead of opening in a tab.
|
|
3046
3156
|
--view, -v Return image inline so the agent can see it.
|
|
3047
|
-
`,stderr:``,exitCode:0}}function
|
|
3157
|
+
`,stderr:``,exitCode:0}}function rQ(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 iQ(){return FM(`open`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return nQ();let n=e.includes(`--download`)||e.includes(`-d`),r=e.includes(`--view`)||e.includes(`-v`),i=e.filter(e=>!tQ.includes(e));if(i.length===0)return nQ();let a=globalThis.__slicc_sprinkleManager,o=typeof window<`u`&&typeof document<`u`,s=o?null:P(),c=o||!!s,l=async e=>{if(o){window.open(e,`_blank`,`noopener,noreferrer`);return}try{await s.call(`window-open`,{url:e,target:`_blank`,features:`noopener,noreferrer`})}catch(e){throw Error(`open: ${e instanceof Error?e.message:String(e)}`)}},u=[];for(let e of i){if(!Ne(e)&&e.endsWith(`.shtml`)&&t.fs){let n=t.fs.resolvePath(t.cwd,e);if(a){let e=(n.split(`/`).pop()??``).replace(/\.shtml$/,``);try{await a.open(e),u.push(`opened sprinkle ${e} from ${n}`)}catch(e){return{stdout:``,stderr:`open: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}else if(c){let e=Ke(n);try{await l(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}u.push(`opened ${n} → ${e}`)}else return{stdout:``,stderr:`open: sprinkle manager not initialized
|
|
3048
3158
|
`,exitCode:1};continue}if(!r&&!c)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
|
|
3049
3159
|
`,exitCode:1};if(Ne(e)){if(!c)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
|
|
3050
|
-
`,exitCode:1};try{await l(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}u.push(`opened ${e}`);continue}let i=t.fs.resolvePath(t.cwd,e);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 a=je(i),o=
|
|
3160
|
+
`,exitCode:1};try{await l(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}u.push(`opened ${e}`);continue}let i=t.fs.resolvePath(t.cwd,e);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 a=je(i),o=rQ(new Uint8Array(r));u.push(`${i} (${Math.round(r.byteLength/1024)} KB)\n<img:data:${a};base64,${o}>`)}else if(n){if(!o)return{stdout:``,stderr:`open: --download requires the in-panel terminal (DOM-only)
|
|
3051
3161
|
`,exitCode:1};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 a=new Uint8Array(r.byteLength);a.set(r);let s=new Blob([a.buffer],{type:je(i)}),c=URL.createObjectURL(s),l=document.createElement(`a`);l.href=c,l.download=Le(i)||`download`,l.style.display=`none`,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(c),0),u.push(`downloaded ${i}`)}else{if(!c)return{stdout:``,stderr:`open: browser APIs are unavailable in this environment
|
|
3052
3162
|
`,exitCode:1};let e=Ke(i);try{await l(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}u.push(`opened ${i} → ${e}`)}}return{stdout:u.join(`
|
|
3053
3163
|
`)+`
|
|
3054
|
-
`,stderr:``,exitCode:0}})}let
|
|
3164
|
+
`,stderr:``,exitCode:0}})}let aQ=null,oQ=null;async function sQ(){return aQ||=import(`./es-DuN0Jsb9.js`),aQ}async function cQ(){return oQ||=import(`./dist-Dv2Nk_Uq.js`),oQ}function lQ(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 uQ(e){let{range:t,rotation:n}=lQ(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 dQ(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 fQ(){return{stdout:`usage: pdftk <input.pdf> <operation> [args...]
|
|
3055
3165
|
|
|
3056
3166
|
Operations:
|
|
3057
3167
|
dump_data Print metadata (page count, title, author, etc.)
|
|
@@ -3075,12 +3185,12 @@ Page ranges:
|
|
|
3075
3185
|
1-endright Pages 1 to end, rotated 90° clockwise
|
|
3076
3186
|
3left Page 3 rotated 270° (counterclockwise)
|
|
3077
3187
|
1-5down Pages 1-5 rotated 180°
|
|
3078
|
-
`,stderr:``,exitCode:0}}function
|
|
3188
|
+
`,stderr:``,exitCode:0}}function pQ(e=`pdftk`){return FM(e,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return fQ();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 sQ(),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(`
|
|
3079
3189
|
`)+`
|
|
3080
|
-
`,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
|
|
3081
|
-
`,stderr:``,exitCode:0}}if(a===`cat`){let a=await
|
|
3082
|
-
`,stderr:``,exitCode:0}}function
|
|
3083
|
-
`,stderr:``,exitCode:0}}function
|
|
3190
|
+
`,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 cQ(),i=await n.fs.readFileBuffer(r[0].path);return{stdout:(await t.extractText(i)).text+`
|
|
3191
|
+
`,stderr:``,exitCode:0}}if(a===`cat`){let a=await sQ(),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=uQ(t),c=dQ(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 sQ(),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=uQ(t);if(!n.rotation)return{stdout:``,stderr:`${e}: rotation suffix required (right/left/down) for range '${t}'\n`,exitCode:1};let r=dQ(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}}})}function mQ(){return{stdout:`usage: python3 [-c code | script.py] [args...]
|
|
3192
|
+
`,stderr:``,exitCode:0}}function hQ(){return{stdout:`Python 3.12 (Pyodide)
|
|
3193
|
+
`,stderr:``,exitCode:0}}function gQ(e,t={}){return FM(e,async(n,r)=>{if(n.includes(`--help`)||n.includes(`-h`))return mQ();if(n.includes(`--version`)||n.includes(`-V`))return hQ();let i=``,a=`<stdin>`,o,s;if(n[0]===`-c`){if(!n[1])return{stdout:``,stderr:`${e}: option requires an argument -- 'c'\n`,exitCode:2};i=n[1],a=`-c`,s=[`-c`,...n.slice(2)],o=[e,`-c`,i,...n.slice(2)]}else if(n.length>0&&!n[0].startsWith(`-`)){let t=n[0],c=r.fs.resolvePath(r.cwd,t);if(!await r.fs.exists(c))return{stdout:``,stderr:`${e}: can't open file '${t}': [Errno 2] No such file or directory\n`,exitCode:2};i=await r.fs.readFile(c),a=t,s=[t,...n.slice(1)],o=[e,t,...n.slice(1)]}else if(r.stdin.trim().length>0)i=r.stdin,a=`<stdin>`,s=[`<stdin>`],o=[e];else if(n.length>0)return{stdout:``,stderr:`${e}: unsupported option '${n[0]}'\n`,exitCode:2};else return{stdout:``,stderr:`${e}: no input provided (use -c CODE, script path, or stdin)\n`,exitCode:2};let c=[r.cwd,`/tmp`];if(a!==`<stdin>`&&a!==`-c`){let e=a.includes(`/`)?a.slice(0,a.lastIndexOf(`/`)):r.cwd;c.includes(e)||c.push(e)}let l=t?_Q():null,u={kind:`system`},d=t.realmFactory??VZ(),f=t.pyodideIndexURL??GZ();return l?hZ({pm:l,realmFactory:d,owner:u,kind:`py`,code:i,argv:o,realmArgv:s,env:Object.fromEntries(r.env.entries()),cwd:r.cwd,filename:a,ctx:r,stdin:r.stdin,pyodideIndexURL:f,pyodideSyncDirs:c,procKind:`py`}):yQ({realmFactory:d,owner:u,code:i,argv:o,realmArgv:s,env:Object.fromEntries(r.env.entries()),cwd:r.cwd,filename:a,ctx:r,stdin:r.stdin,pyodideIndexURL:f,pyodideSyncDirs:c})})}function _Q(){let e=globalThis.__slicc_pm;return e&&typeof e==`object`&&typeof e.spawn==`function`&&typeof e.onSignal==`function`?e:null}let vQ=null;async function yQ(e){if(!vQ){let{ProcessManager:e}=await Promise.resolve().then(()=>YX);vQ=new e}return hZ({pm:vQ,realmFactory:e.realmFactory,owner:e.owner,kind:`py`,code:e.code,argv:e.argv,realmArgv:e.realmArgv,env:e.env,cwd:e.cwd,filename:e.filename,ctx:e.ctx,stdin:e.stdin,pyodideIndexURL:e.pyodideIndexURL,pyodideSyncDirs:e.pyodideSyncDirs,procKind:`py`})}var bQ;(function(e){e.LOAD=`LOAD`,e.EXEC=`EXEC`,e.FFPROBE=`FFPROBE`,e.WRITE_FILE=`WRITE_FILE`,e.READ_FILE=`READ_FILE`,e.DELETE_FILE=`DELETE_FILE`,e.RENAME=`RENAME`,e.CREATE_DIR=`CREATE_DIR`,e.LIST_DIR=`LIST_DIR`,e.DELETE_DIR=`DELETE_DIR`,e.ERROR=`ERROR`,e.DOWNLOAD=`DOWNLOAD`,e.PROGRESS=`PROGRESS`,e.LOG=`LOG`,e.MOUNT=`MOUNT`,e.UNMOUNT=`UNMOUNT`})(bQ||={});const xQ=(()=>{let e=0;return()=>e++})(),SQ=Error("ffmpeg is not loaded, call `await ffmpeg.load()` first"),CQ=Error(`called FFmpeg.terminate()`);var wQ=class{#e=null;#t={};#n={};#r=[];#i=[];loaded=!1;#a=()=>{this.#e&&(this.#e.onmessage=({data:{id:e,type:t,data:n}})=>{switch(t){case bQ.LOAD:this.loaded=!0,this.#t[e](n);break;case bQ.MOUNT:case bQ.UNMOUNT:case bQ.EXEC:case bQ.FFPROBE:case bQ.WRITE_FILE:case bQ.READ_FILE:case bQ.DELETE_FILE:case bQ.RENAME:case bQ.CREATE_DIR:case bQ.LIST_DIR:case bQ.DELETE_DIR:this.#t[e](n);break;case bQ.LOG:this.#r.forEach(e=>e(n));break;case bQ.PROGRESS:this.#i.forEach(e=>e(n));break;case bQ.ERROR:this.#n[e](n);break}delete this.#t[e],delete this.#n[e]})};#o=({type:e,data:t},n=[],r)=>this.#e?new Promise((i,a)=>{let o=xQ();this.#e&&this.#e.postMessage({id:o,type:e,data:t},n),this.#t[o]=i,this.#n[o]=a,r?.addEventListener(`abort`,()=>{a(new DOMException(`Message # ${o} was aborted`,`AbortError`))},{once:!0})}):Promise.reject(SQ);on(e,t){e===`log`?this.#r.push(t):e===`progress`&&this.#i.push(t)}off(e,t){e===`log`?this.#r=this.#r.filter(e=>e!==t):e===`progress`&&(this.#i=this.#i.filter(e=>e!==t))}load=({classWorkerURL:e,...t}={},{signal:n}={})=>(this.#e||(this.#e=e?new Worker(new URL(e,import.meta.url),{type:`module`}):new Worker(new URL(`/assets/worker-B1VFCur7.js`,``+import.meta.url),{type:`module`}),this.#a()),this.#o({type:bQ.LOAD,data:t},void 0,n));exec=(e,t=-1,{signal:n}={})=>this.#o({type:bQ.EXEC,data:{args:e,timeout:t}},void 0,n);ffprobe=(e,t=-1,{signal:n}={})=>this.#o({type:bQ.FFPROBE,data:{args:e,timeout:t}},void 0,n);terminate=()=>{let e=Object.keys(this.#n);for(let t of e)this.#n[t](CQ),delete this.#n[t],delete this.#t[t];this.#e&&(this.#e.terminate(),this.#e=null,this.loaded=!1)};writeFile=(e,t,{signal:n}={})=>{let r=[];return t instanceof Uint8Array&&r.push(t.buffer),this.#o({type:bQ.WRITE_FILE,data:{path:e,data:t}},r,n)};mount=(e,t,n)=>this.#o({type:bQ.MOUNT,data:{fsType:e,options:t,mountPoint:n}},[]);unmount=e=>this.#o({type:bQ.UNMOUNT,data:{mountPoint:e}},[]);readFile=(e,t=`binary`,{signal:n}={})=>this.#o({type:bQ.READ_FILE,data:{path:e,encoding:t}},void 0,n);deleteFile=(e,{signal:t}={})=>this.#o({type:bQ.DELETE_FILE,data:{path:e}},void 0,t);rename=(e,t,{signal:n}={})=>this.#o({type:bQ.RENAME,data:{oldPath:e,newPath:t}},void 0,n);createDir=(e,{signal:t}={})=>this.#o({type:bQ.CREATE_DIR,data:{path:e}},void 0,t);listDir=(e,{signal:t}={})=>this.#o({type:bQ.LIST_DIR,data:{path:e}},void 0,t);deleteDir=(e,{signal:t}={})=>this.#o({type:bQ.DELETE_DIR,data:{path:e}},void 0,t)},TQ;(function(e){e.MEMFS=`MEMFS`,e.NODEFS=`NODEFS`,e.NODERAWFS=`NODERAWFS`,e.IDBFS=`IDBFS`,e.WORKERFS=`WORKERFS`,e.PROXYFS=`PROXYFS`})(TQ||={});var EQ=`/// <reference no-default-lib="true" />
|
|
3084
3194
|
/// <reference lib="esnext" />
|
|
3085
3195
|
/// <reference lib="webworker" />
|
|
3086
3196
|
import { CORE_URL, FFMessageType } from "./const.js";
|
|
@@ -3241,7 +3351,7 @@ self.onmessage = async ({ data: { id, type, data: _data }, }) => {
|
|
|
3241
3351
|
}
|
|
3242
3352
|
self.postMessage({ id, type, data }, trans);
|
|
3243
3353
|
};
|
|
3244
|
-
`;const
|
|
3354
|
+
`;const DQ=`0.12.10`,OQ=`https://unpkg.com/@ffmpeg/core@${DQ}/dist/esm/`,kQ=`slicc-ffmpeg-${DQ}`;let AQ=null;async function jQ(e={}){return AQ||=MQ(e.onProgress).catch(e=>{throw AQ=null,e}),AQ}async function MQ(e){let t=e??(()=>{}),n=new wQ,r=await NQ(t);return t(`initializing ffmpeg-core...`),await n.load({coreURL:r.coreURL,wasmURL:r.wasmURL,...r.classWorkerURL?{classWorkerURL:r.classWorkerURL}:{}}),t(`ffmpeg ready`),n}async function NQ(e){let t=`${OQ}ffmpeg-core.js`,n=`${OQ}ffmpeg-core.wasm`;if(!Ge())return await Promise.all([PQ(t,e),PQ(n,e)]),{coreURL:t,wasmURL:n};e(`downloading ffmpeg-core (cached after first run)...`);let[r,i]=await Promise.all([FQ(t,`application/javascript`,e),FQ(n,`application/wasm`,e)]);return{coreURL:IQ(r,`application/javascript`),wasmURL:IQ(i,`application/wasm`),classWorkerURL:LQ(EQ,`application/javascript`)}}async function PQ(e,t){if(!(typeof caches>`u`))try{let n=await caches.open(kQ);if(await n.match(e))return;t(`fetching ${RQ(e)}...`);let r=await fetch(e);if(!r.ok)throw Error(`ffmpeg-core fetch ${e} failed: HTTP ${r.status}`);await n.put(e,r.clone())}catch(e){t(`cache preload failed (${e instanceof Error?e.message:String(e)})`)}}async function FQ(e,t,n){if(typeof caches<`u`)try{let t=await(await caches.open(kQ)).match(e);if(t)return new Uint8Array(await t.arrayBuffer())}catch{}n(`fetching ${RQ(e)}...`);let r=await fetch(e);if(!r.ok)throw Error(`ffmpeg asset fetch ${e} failed: HTTP ${r.status}`);let i=new Uint8Array(await r.arrayBuffer());if(typeof caches<`u`)try{let n=await caches.open(kQ),r=new Response(i,{headers:{"content-type":t}});await n.put(e,r)}catch{}return i}function IQ(e,t){let n=new ArrayBuffer(e.byteLength);return new Uint8Array(n).set(e),URL.createObjectURL(new Blob([n],{type:t}))}function LQ(e,t){return URL.createObjectURL(new Blob([e],{type:t}))}function RQ(e){return e.replace(/^https?:\/\//,``).slice(0,64)}async function zQ(e){if(!navigator.mediaDevices?.getUserMedia)throw Error(`getUserMedia is not supported in this browser`);let t=e.mode===`photo`||e.captureVideo!==!1,n=!!e.captureAudio&&e.mode===`video`;if(!t&&!n)throw Error(`camera capture: at least one of video or audio must be requested`);let r=await VQ({wantVideo:t,videoDeviceId:t?await BQ(e.deviceId,`videoinput`):void 0,audioDeviceId:n?await BQ(e.audioDeviceId,`audioinput`):void 0,wantAudio:n,width:e.width,height:e.height,frameRate:e.frameRate,exact:!!e.exactSize});try{let n=null,i=0,a=0;if(t){n=document.createElement(`video`),n.srcObject=r,n.muted=!0,n.playsInline=!0;let e=n;await new Promise((t,n)=>{e.onloadedmetadata=()=>e.play().then(()=>t()).catch(n),e.onerror=()=>n(Error(`Failed to load camera stream`))}),await new Promise(e=>requestAnimationFrame(()=>e())),await new Promise(e=>requestAnimationFrame(()=>e())),i=e.videoWidth,a=e.videoHeight}if(e.mode===`photo`){if(!n)throw Error(`photo capture requires a video track`);let t=e.warmupMs??1500;t>0&&await new Promise(e=>setTimeout(e,t));let r=document.createElement(`canvas`);r.width=i,r.height=a;let o=r.getContext(`2d`);if(!o)throw Error(`Failed to get canvas context`);o.drawImage(n,0,0,i,a);let s=await new Promise((t,n)=>{r.toBlob(e=>e?t(e):n(Error(`Failed to encode photo`)),e.mimeType,e.quality)});return{bytes:await s.arrayBuffer(),mimeType:s.type||e.mimeType,width:i,height:a}}let o=Math.max(100,Math.min(e.durationMs??5e3,6e4)),s=typeof MediaRecorder<`u`&&MediaRecorder.isTypeSupported(e.mimeType)?e.mimeType:`video/webm`,c=new MediaRecorder(r,{mimeType:s}),l=[];c.ondataavailable=e=>{e.data&&e.data.size>0&&l.push(e.data)};let u=new Promise(e=>{c.onstop=()=>e()});c.start(),await new Promise(e=>setTimeout(e,o)),c.stop(),await u;let d=new Blob(l,{type:s});return{bytes:await d.arrayBuffer(),mimeType:d.type||s,width:i,height:a,durationMs:o}}finally{r.getTracks().forEach(e=>e.stop())}}async function BQ(e,t){if(e===void 0||e===``)return;if(!/^\d+$/.test(e))return e;if(!navigator.mediaDevices?.enumerateDevices)return;let n=parseInt(e,10);return(await navigator.mediaDevices.enumerateDevices()).filter(e=>e.kind===t)[n]?.deviceId}async function VQ(e){let t=t=>{if(!e.wantVideo)return!1;let n={};return e.videoDeviceId&&(n.deviceId={exact:e.videoDeviceId}),e.width&&(n.width=t===`exact`?{exact:e.width}:{ideal:e.width}),e.height&&(n.height=t===`exact`?{exact:e.height}:{ideal:e.height}),e.frameRate&&(n.frameRate=t===`exact`?{exact:e.frameRate}:{ideal:e.frameRate}),Object.keys(n).length>0?n:!0},n=()=>e.wantAudio?e.audioDeviceId?{deviceId:{exact:e.audioDeviceId}}:!0:!1;try{return await navigator.mediaDevices.getUserMedia({video:t(e.exact?`exact`:`ideal`),audio:n()})}catch(r){let i=r?.name;if(!e.exact||i!==`OverconstrainedError`&&i!==`NotReadableError`)throw r;return console.warn(`panel-rpc:capture-camera: exact ${e.width??`?`}x${e.height??`?`}@${e.frameRate??`?`} unmet, falling back to ideal`),await navigator.mediaDevices.getUserMedia({video:t(`ideal`),audio:n()})}}function HQ(){return{stdout:`ffmpeg - WASM build, downloaded on demand
|
|
3245
3355
|
|
|
3246
3356
|
Usage:
|
|
3247
3357
|
ffmpeg [global-opts] -i input [input-opts] ... output [output-opts]
|
|
@@ -3278,14 +3388,14 @@ Notes:
|
|
|
3278
3388
|
- The browser will prompt for camera/mic permission on first capture.
|
|
3279
3389
|
- Numeric -i values index into the per-kind enumerateDevices() list,
|
|
3280
3390
|
matching ffmpeg's native avfoundation device numbering on macOS.
|
|
3281
|
-
`,stderr:``,exitCode:0}}function
|
|
3282
|
-
`,stderr:``,exitCode:0}}function
|
|
3283
|
-
`,exitCode:1}:
|
|
3284
|
-
`,exitCode:1}})}async function
|
|
3285
|
-
`)}\n`,exitCode:0}}async function
|
|
3391
|
+
`,stderr:``,exitCode:0}}function UQ(){return{stdout:`ffmpeg (wasm via @ffmpeg/ffmpeg)
|
|
3392
|
+
`,stderr:``,exitCode:0}}function WQ(e){if(!e.includes(`:`))return{video:e};let t=e.indexOf(`:`),n=e.slice(0,t),r=e.slice(t+1);return{...n?{video:n}:{},...r?{audio:r}:{}}}function GQ(e){let t=[],n=[],r=null,i=!1,a,o=!1,s=0,c=[],l,u,d,f=e=>new Set(`-f.-i.-c.-c:v.-c:a.-vf.-af.-filter:v.-filter:a.-filter_complex.-r.-b:v.-b:a.-s.-t.-ss.-to.-pix_fmt.-vcodec.-acodec.-ar.-ac.-frames:v.-frames:a.-q:v.-q:a.-crf.-preset.-tune.-movflags.-map.-metadata.-loglevel.-threads.-video_size.-framerate.-pixel_format.-update.-list_devices.-warmup`.split(`.`)).has(e),p=t=>{let n=e[s+1];if(typeof n!=`string`)throw Error(`ffmpeg: ${t} requires a value`);return n};for(;s<e.length;){let m=e[s];if(m===`-i`){let e=p(`-i`);t.push({path:e,format:l,videoSize:u,frameRate:d,raw:[...c,`-i`,e]}),l=void 0,u=void 0,d=void 0,c=[],s+=2;continue}if(m===`-f`){let e=p(`-f`);l=e,c.push(m,e),s+=2;continue}if(m===`-video_size`){let e=p(`-video_size`),t=/^(\d+)x(\d+)$/.exec(e);t&&(u={width:parseInt(t[1],10),height:parseInt(t[2],10)}),c.push(m,e),s+=2;continue}if(m===`-framerate`){let e=p(`-framerate`),t=parseFloat(e);Number.isNaN(t)||(d=t),c.push(m,e),s+=2;continue}if(m===`-list_devices`){let e=p(`-list_devices`);/^(true|1|yes)$/i.test(e)&&(i=!0),c.push(m,e),s+=2;continue}if(m===`-warmup`){let e=p(`-warmup`),t=parseInt(e,10);!Number.isNaN(t)&&t>=0&&(a=t),s+=2;continue}if(m===`-exact_size`){o=!0,s+=1;continue}if(m.startsWith(`-`)){if(f(m)){let e=p(m);c.push(m,e),s+=2;continue}c.push(m),s+=1;continue}r=m,n=c,c=[],s+=1}return{inputs:t,outputOpts:n,outputPath:r,listDevices:i,...a===void 0?{}:{warmupMs:a},exactSize:o}}function KQ(e){return e.inputs.some(e=>e.format===`avfoundation`)}function qQ(e){let t=e.inputs.find(e=>e.format===`avfoundation`);if(!t)throw Error(`ffmpeg: no avfoundation input found`);if(!e.outputPath)throw Error(`ffmpeg: output path is required`);let n=e.outputOpts.indexOf(`-frames:v`),r=n>=0&&e.outputOpts[n+1]===`1`,i=e.outputOpts.indexOf(`-update`),a=i>=0&&e.outputOpts[i+1]===`1`,o=e.outputOpts.indexOf(`-t`),s=o>=0?parseFloat(e.outputOpts[o+1]):NaN,c=WQ(t.path),l=YQ(e.outputPath),u=/^image\//.test(l),d=!c.video&&!!c.audio;if(!d&&(r||a||u)){let n=u&&/^image\/(jpeg|png|webp)$/.test(l)?l:`image/jpeg`;return{outputPath:e.outputPath,captureMime:n,needsTranscode:JQ(e.outputOpts,`photo`)||n!==l,request:{mode:`photo`,deviceId:c.video,width:t.videoSize?.width,height:t.videoSize?.height,frameRate:t.frameRate,exactSize:e.exactSize,mimeType:n,quality:.92,...e.warmupMs===void 0?{}:{warmupMs:e.warmupMs}}}}let f=d||!!c.audio,p=`video/webm`;return{outputPath:e.outputPath,captureMime:p,needsTranscode:JQ(e.outputOpts,`video`)||p!==l,request:{mode:`video`,deviceId:c.video,captureVideo:!d,...f?{captureAudio:!0}:{},...c.audio?{audioDeviceId:c.audio}:{},width:t.videoSize?.width,height:t.videoSize?.height,frameRate:t.frameRate,exactSize:e.exactSize,mimeType:p,durationMs:Number.isFinite(s)?s*1e3:void 0}}}function JQ(e,t){let n=t===`photo`?new Set([`-vf`,`-filter:v`,`-filter_complex`,`-pix_fmt`,`-q:v`,`-vcodec`,`-c:v`]):new Set([`-c`,`-c:v`,`-c:a`,`-vcodec`,`-acodec`,`-vf`,`-af`,`-filter:v`,`-filter:a`,`-filter_complex`,`-pix_fmt`,`-pixel_format`,`-crf`,`-preset`,`-tune`,`-b:v`,`-b:a`,`-ar`,`-ac`,`-q:v`,`-q:a`,`-movflags`,`-r`]);return e.some(e=>n.has(e))}function YQ(e){let t=e.toLowerCase();return t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)?`image/jpeg`:t.endsWith(`.png`)?`image/png`:t.endsWith(`.webp`)?`image/webp`:t.endsWith(`.gif`)?`image/gif`:t.endsWith(`.webm`)?`video/webm`:t.endsWith(`.mp4`)?`video/mp4`:t.endsWith(`.mov`)?`video/quicktime`:t.endsWith(`.mkv`)?`video/x-matroska`:t.endsWith(`.m4a`)?`audio/mp4`:t.endsWith(`.mp3`)?`audio/mpeg`:t.endsWith(`.wav`)?`audio/wav`:t.endsWith(`.ogg`)?`audio/ogg`:`application/octet-stream`}function XQ(e){return e===`image/jpeg`?`jpg`:e===`image/png`?`png`:e===`image/webp`?`webp`:e===`video/webm`?`webm`:e===`video/mp4`?`mp4`:e===`audio/webm`?`webm`:`bin`}function ZQ(e,t){let n=e.path.lastIndexOf(`/`),r=n>=0?e.path.slice(n+1):e.path;return r?`__in${t}_${r}`:`__in${t}.bin`}function QQ(){return FM(`ffmpeg`,async(e,t)=>{if(e.length===0||e.includes(`--help`))return HQ();if(e.includes(`-version`)||e.includes(`--version`))return UQ();let n;try{n=GQ(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return n.listDevices&&KQ(n)?$Q():n.outputPath?n.inputs.length===0?{stdout:``,stderr:`ffmpeg: at least one input file must be specified
|
|
3393
|
+
`,exitCode:1}:KQ(n)?t$(n,t):r$(n,t):{stdout:``,stderr:`ffmpeg: at least one output file must be specified
|
|
3394
|
+
`,exitCode:1}})}async function $Q(){let e;try{e=await e$()}catch(e){return{stdout:``,stderr:`ffmpeg: failed to enumerate devices: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let t=[];return t.push(`[AVFoundation indev @ 0x0] AVFoundation video devices:`),e.videoinputs.length===0?t.push(`[AVFoundation indev @ 0x0] (none)`):e.videoinputs.forEach((e,n)=>{t.push(`[AVFoundation indev @ 0x0] [${n}] ${e.label||`Camera ${n}`}`)}),t.push(`[AVFoundation indev @ 0x0] AVFoundation audio devices:`),e.audioinputs.length===0?t.push(`[AVFoundation indev @ 0x0] (none)`):e.audioinputs.forEach((e,n)=>{t.push(`[AVFoundation indev @ 0x0] [${n}] ${e.label||`Microphone ${n}`}`)}),{stdout:``,stderr:`${t.join(`
|
|
3395
|
+
`)}\n`,exitCode:0}}async function e$(){if(N()&&typeof navigator<`u`&&navigator.mediaDevices?.enumerateDevices){let e=await navigator.mediaDevices.enumerateDevices(),t=e=>({deviceId:e.deviceId,label:e.label||``,...e.groupId?{groupId:e.groupId}:{}});return{videoinputs:e.filter(e=>e.kind===`videoinput`).map(t),audioinputs:e.filter(e=>e.kind===`audioinput`).map(t)}}let e=P();if(!e)throw Error(`device enumeration requires a browser context`);return e.call(`enumerate-media-devices`,void 0,{timeoutMs:1e4})}async function t$(e,t){let n;try{n=qQ(e)}catch(e){return{stdout:``,stderr:`${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let r;try{if(N()&&typeof navigator<`u`&&navigator.mediaDevices)r=await zQ(n.request);else{let e=P();if(!e)return{stdout:``,stderr:`ffmpeg: camera capture requires a browser context — not available in this runtime
|
|
3286
3396
|
`,exitCode:1};let t=await e.call(`capture-camera`,n.request,{timeoutMs:5*6e4});r={bytes:t.bytes,mimeType:t.mimeType,width:t.width,height:t.height,durationMs:t.durationMs}}}catch(e){let t=e instanceof Error?e.message:String(e);return/NotAllowedError|Permission denied/i.test(t)?{stdout:``,stderr:`ffmpeg: camera permission denied
|
|
3287
3397
|
`,exitCode:1}:/NotFoundError/i.test(t)?{stdout:``,stderr:`ffmpeg: no camera device found
|
|
3288
|
-
`,exitCode:1}:{stdout:``,stderr:`ffmpeg: ${t}\n`,exitCode:1}}let i=Math.round(r.bytes.byteLength/1024),a=`${r.width}x${r.height}`,o=n.request.mode===`video`&&r.durationMs?`${a}, ${Math.round(r.durationMs)}ms`:a,s=new Uint8Array(r.bytes),c=``;if(n.needsTranscode)try{let t=await
|
|
3398
|
+
`,exitCode:1}:{stdout:``,stderr:`ffmpeg: ${t}\n`,exitCode:1}}let i=Math.round(r.bytes.byteLength/1024),a=`${r.width}x${r.height}`,o=n.request.mode===`video`&&r.durationMs?`${a}, ${Math.round(r.durationMs)}ms`:a,s=new Uint8Array(r.bytes),c=``;if(n.needsTranscode)try{let t=await n$({bytes:s,captureMime:n.captureMime,outputName:n.outputPath,outputOpts:e.outputOpts,onLog:e=>{c+=`${e}\n`}});s=new Uint8Array(t.byteLength),s.set(t)}catch(e){let t=e instanceof Error?e.message:String(e);return{stdout:``,stderr:`${c}ffmpeg: captured ${o} (${i} KB) but transcode failed: ${t}\n`,exitCode:1}}let l=t.fs.resolvePath(t.cwd,n.outputPath);try{await t.fs.writeFile(l,s)}catch(e){return{stdout:``,stderr:`ffmpeg: failed to write ${n.outputPath}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let u=Math.round(s.byteLength/1024),d=n.needsTranscode?`${i} KB → ${u} KB`:`${i} KB`;return{stdout:``,stderr:`${c}ffmpeg: captured ${o} (${d}) to ${n.outputPath}\n`,exitCode:0}}async function n$(e){let t=`__capture.${XQ(e.captureMime)}`,n=`__out_${e.outputName.split(`/`).pop()||`out.bin`}`;e.onLog(`transcoding captured stream...`);let r=await jQ({onProgress:e.onLog}),i=t=>{e.onLog(t.message)};r.on(`log`,i);try{await r.writeFile(t,e.bytes);let i=[`-i`,t,...e.outputOpts,n],a=await r.exec(i);if(a!==0)throw Error(`ffmpeg-core exited with code ${a}`);let o=await r.readFile(n);if(o instanceof Uint8Array)return o;if(typeof o==`string`)return new TextEncoder().encode(o);throw Error(`ffmpeg-core returned an unknown payload type`)}finally{try{r.off(`log`,i)}catch{}try{await r.deleteFile(t)}catch{}try{await r.deleteFile(n)}catch{}}}async function r$(e,t){let n=[];for(let[r,i]of e.inputs.entries()){let e=t.fs.resolvePath(t.cwd,i.path);if(!await t.fs.exists(e))return{stdout:``,stderr:`ffmpeg: input file not found: ${i.path}\n`,exitCode:1};let a=await t.fs.readFileBuffer(e);n.push({ffmpegName:ZQ(i,r),bytes:a})}let r=e.outputPath,i=`__out_${r.split(`/`).pop()||`out.bin`}`,a=``,o;try{o=await jQ({onProgress:e=>{a+=`${e}\n`}})}catch(e){return{stdout:``,stderr:`${a}ffmpeg: failed to load wasm: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let s=e=>{a+=`${e.message}\n`};o.on(`log`,s);try{for(let e of n)await o.writeFile(e.ffmpegName,e.bytes);let s=[];for(let[t,r]of e.inputs.entries()){let e=n[t].ffmpegName,i=[],a=r.raw;for(let t=0;t<a.length;t++){if(a[t]===`-i`){i.push(`-i`,e),t+=1;continue}i.push(a[t])}s.push(...i)}s.push(...e.outputOpts),s.push(i);let c=await o.exec(s);if(c!==0)return{stdout:``,stderr:a||`ffmpeg: exited with code ${c}\n`,exitCode:c||1};let l=await o.readFile(i),u=l instanceof Uint8Array?l:new TextEncoder().encode(typeof l==`string`?l:``),d=t.fs.resolvePath(t.cwd,r);return await t.fs.writeFile(d,u),{stdout:``,stderr:a,exitCode:0}}catch(e){return{stdout:``,stderr:`${a}ffmpeg: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}finally{try{o.off(`log`,s)}catch{}for(let e of n)try{await o.deleteFile(e.ffmpegName)}catch{}try{await o.deleteFile(i)}catch{}}}function i$(){return{stdout:`usage: serve [--entry <relative-path>] [--project] <directory>
|
|
3289
3399
|
|
|
3290
3400
|
Serve a VFS directory in a new browser tab via the preview service worker.
|
|
3291
3401
|
Defaults to index.html inside the target directory.
|
|
@@ -3294,23 +3404,23 @@ Notes:
|
|
|
3294
3404
|
--project Enable project serve mode. Root-relative paths (/scripts/,
|
|
3295
3405
|
/styles/, etc.) resolve against the served directory.
|
|
3296
3406
|
Use this for frameworks like EDS that expect a local dev server.
|
|
3297
|
-
`,stderr:``,exitCode:0}}function
|
|
3407
|
+
`,stderr:``,exitCode:0}}function a$(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
|
|
3298
3408
|
`};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
|
|
3299
|
-
`};n=a}return{directory:n,entry:t,project:r}}function
|
|
3300
|
-
`,exitCode:1};let a=
|
|
3301
|
-
`,stderr:``,exitCode:0}}function
|
|
3302
|
-
`)}\n`:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function
|
|
3303
|
-
`,stderr:``,exitCode:0}}function
|
|
3409
|
+
`};n=a}return{directory:n,entry:t,project:r}}function o$(e,t){return FM(`serve`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return i$();let i=typeof window<`u`&&typeof window.open==`function`;if(!e&&!i)return{stdout:``,stderr:`serve: browser APIs are unavailable in this environment
|
|
3410
|
+
`,exitCode:1};let a=a$(n);if(a.error)return{stdout:``,stderr:a.error,exitCode:1};if(!a.directory)return i$();if(!Ve(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=Ae(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=Ke(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 s$(){return{stdout:`usage: sqlite3 [database] [sql]
|
|
3411
|
+
`,stderr:``,exitCode:0}}function c$(e=`sqlite3`){return FM(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return s$();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 Re(),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(Me).join(`|`));return{stdout:l.length>0?`${l.join(`
|
|
3412
|
+
`)}\n`:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}})}function l$(){return{stdout:`usage: uname
|
|
3413
|
+
`,stderr:``,exitCode:0}}function u$(){return FM(`uname`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return l$();if(e.length>0)return{stdout:``,stderr:`uname: unsupported arguments
|
|
3304
3414
|
`,exitCode:1};let t=globalThis.navigator?.userAgent;return typeof t!=`string`||t.length===0?{stdout:``,stderr:`uname: navigator.userAgent is unavailable
|
|
3305
|
-
`,exitCode:1}:{stdout:`${t}\n`,stderr:``,exitCode:0}})}function
|
|
3415
|
+
`,exitCode:1}:{stdout:`${t}\n`,stderr:``,exitCode:0}})}function d$(){return{stdout:`usage: man <topic>
|
|
3306
3416
|
|
|
3307
3417
|
Fetches documentation for a given topic from sliccy.com.
|
|
3308
|
-
`,stderr:``,exitCode:0}}function
|
|
3418
|
+
`,stderr:``,exitCode:0}}function f$(e){return e.replace(/<[^>]*>/g,``).replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`).replace(/ /g,` `).trimEnd()}function p$(){let e=DK();return FM(`man`,async t=>{if(t.includes(`--help`)||t.includes(`-h`))return d$();if(t.length===0)return{stdout:``,stderr:`What manual page do you want?
|
|
3309
3419
|
For example, try 'man commands'.
|
|
3310
|
-
`,exitCode:1};let n=t.join(`-`),r=`https://www.sliccy.com/man/${n}.plain.html`;try{let t=await e(r,{method:`GET`});return t.status===404?{stdout:``,stderr:`No manual entry for ${n}\n`,exitCode:1}:t.status<200||t.status>=300?{stdout:``,stderr:`man: failed to fetch manual page for ${n}: ${t.status} ${t.statusText}\n`,exitCode:1}:{stdout:
|
|
3311
|
-
`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`man: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}var JX=Uint8Array,YX=Uint16Array,XX=Int32Array,ZX=new JX([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),QX=new JX([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),$X=new JX([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),eZ=function(e,t){for(var n=new YX(31),r=0;r<31;++r)n[r]=t+=1<<e[r-1];for(var i=new XX(n[30]),r=1;r<30;++r)for(var a=n[r];a<n[r+1];++a)i[a]=a-n[r]<<5|r;return{b:n,r:i}},tZ=eZ(ZX,2),nZ=tZ.b,rZ=tZ.r;nZ[28]=258,rZ[258]=28;for(var iZ=eZ(QX,0),aZ=iZ.b,oZ=iZ.r,sZ=new YX(32768),cZ=0;cZ<32768;++cZ){var lZ=(cZ&43690)>>1|(cZ&21845)<<1;lZ=(lZ&52428)>>2|(lZ&13107)<<2,lZ=(lZ&61680)>>4|(lZ&3855)<<4,sZ[cZ]=((lZ&65280)>>8|(lZ&255)<<8)>>1}for(var uZ=(function(e,t,n){for(var r=e.length,i=0,a=new YX(t);i<r;++i)e[i]&&++a[e[i]-1];var o=new YX(t);for(i=1;i<t;++i)o[i]=o[i-1]+a[i-1]<<1;var s;if(n){s=new YX(1<<t);var c=15-t;for(i=0;i<r;++i)if(e[i])for(var l=i<<4|e[i],u=t-e[i],d=o[e[i]-1]++<<u,f=d|(1<<u)-1;d<=f;++d)s[sZ[d]>>c]=l}else for(s=new YX(r),i=0;i<r;++i)e[i]&&(s[i]=sZ[o[e[i]-1]++]>>15-e[i]);return s}),dZ=new JX(288),cZ=0;cZ<144;++cZ)dZ[cZ]=8;for(var cZ=144;cZ<256;++cZ)dZ[cZ]=9;for(var cZ=256;cZ<280;++cZ)dZ[cZ]=7;for(var cZ=280;cZ<288;++cZ)dZ[cZ]=8;for(var fZ=new JX(32),cZ=0;cZ<32;++cZ)fZ[cZ]=5;var pZ=uZ(dZ,9,0),mZ=uZ(dZ,9,1),hZ=uZ(fZ,5,0),gZ=uZ(fZ,5,1),_Z=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},vZ=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},yZ=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},bZ=function(e){return(e+7)/8|0},xZ=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new JX(e.subarray(t,n))},SZ=[`unexpected EOF`,`invalid block type`,`invalid length/literal`,`invalid distance`,`stream finished`,`no stream handler`,,`no callback`,`invalid UTF-8 data`,`extra field too long`,`date not in range 1980-2099`,`filename too long`,`stream finishing`,`invalid zip data`],CZ=function(e,t,n){var r=Error(t||SZ[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,CZ),!n)throw r;return r},wZ=function(e,t,n,r){var i=e.length,a=r?r.length:0;if(!i||t.f&&!t.l)return n||new JX(0);var o=!n,s=o||t.i!=2,c=t.i;o&&(n=new JX(i*3));var l=function(e){var t=n.length;if(e>t){var r=new JX(Math.max(t*2,e));r.set(n),n=r}},u=t.f||0,d=t.p||0,f=t.b||0,p=t.l,m=t.d,h=t.m,g=t.n,_=i*8;do{if(!p){u=vZ(e,d,1);var v=vZ(e,d+1,3);if(d+=3,!v){var y=bZ(d)+4,b=e[y-4]|e[y-3]<<8,x=y+b;if(x>i){c&&CZ(0);break}s&&l(f+b),n.set(e.subarray(y,x),f),t.b=f+=b,t.p=d=x*8,t.f=u;continue}else if(v==1)p=mZ,m=gZ,h=9,g=5;else if(v==2){var S=vZ(e,d,31)+257,C=vZ(e,d+10,15)+4,w=S+vZ(e,d+5,31)+1;d+=14;for(var T=new JX(w),E=new JX(19),D=0;D<C;++D)E[$X[D]]=vZ(e,d+D*3,7);d+=C*3;for(var O=_Z(E),ee=(1<<O)-1,te=uZ(E,O,1),D=0;D<w;){var ne=te[vZ(e,d,ee)];d+=ne&15;var y=ne>>4;if(y<16)T[D++]=y;else{var k=0,re=0;for(y==16?(re=3+vZ(e,d,3),d+=2,k=T[D-1]):y==17?(re=3+vZ(e,d,7),d+=3):y==18&&(re=11+vZ(e,d,127),d+=7);re--;)T[D++]=k}}var ie=T.subarray(0,S),ae=T.subarray(S);h=_Z(ie),g=_Z(ae),p=uZ(ie,h,1),m=uZ(ae,g,1)}else CZ(1);if(d>_){c&&CZ(0);break}}s&&l(f+131072);for(var oe=(1<<h)-1,se=(1<<g)-1,ce=d;;ce=d){var k=p[yZ(e,d)&oe],le=k>>4;if(d+=k&15,d>_){c&&CZ(0);break}if(k||CZ(2),le<256)n[f++]=le;else if(le==256){ce=d,p=null;break}else{var ue=le-254;if(le>264){var D=le-257,de=ZX[D];ue=vZ(e,d,(1<<de)-1)+nZ[D],d+=de}var fe=m[yZ(e,d)&se],A=fe>>4;fe||CZ(3),d+=fe&15;var ae=aZ[A];if(A>3){var de=QX[A];ae+=yZ(e,d)&(1<<de)-1,d+=de}if(d>_){c&&CZ(0);break}s&&l(f+131072);var pe=f+ue;if(f<ae){var me=a-ae,he=Math.min(ae,pe);for(me+f<0&&CZ(3);f<he;++f)n[f]=r[me+f]}for(;f<pe;++f)n[f]=n[f-ae]}}t.l=p,t.p=ce,t.b=f,t.f=u,p&&(u=1,t.m=h,t.d=m,t.n=g)}while(!u);return f!=n.length&&o?xZ(n,0,f):n.subarray(0,f)},TZ=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8},EZ=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8,e[r+2]|=n>>16},DZ=function(e,t){for(var n=[],r=0;r<e.length;++r)e[r]&&n.push({s:r,f:e[r]});var i=n.length,a=n.slice();if(!i)return{t:PZ,l:0};if(i==1){var o=new JX(n[0].s+1);return o[n[0].s]=1,{t:o,l:1}}n.sort(function(e,t){return e.f-t.f}),n.push({s:-1,f:25001});var s=n[0],c=n[1],l=0,u=1,d=2;for(n[0]={s:-1,f:s.f+c.f,l:s,r:c};u!=i-1;)s=n[n[l].f<n[d].f?l++:d++],c=n[l!=u&&n[l].f<n[d].f?l++:d++],n[u++]={s:-1,f:s.f+c.f,l:s,r:c};for(var f=a[0].s,r=1;r<i;++r)a[r].s>f&&(f=a[r].s);var p=new YX(f+1),m=OZ(n[u-1],p,0);if(m>t){var r=0,h=0,g=m-t,_=1<<g;for(a.sort(function(e,t){return p[t.s]-p[e.s]||e.f-t.f});r<i;++r){var v=a[r].s;if(p[v]>t)h+=_-(1<<m-p[v]),p[v]=t;else break}for(h>>=g;h>0;){var y=a[r].s;p[y]<t?h-=1<<t-p[y]++-1:++r}for(;r>=0&&h;--r){var b=a[r].s;p[b]==t&&(--p[b],++h)}m=t}return{t:new JX(p),l:m}},OZ=function(e,t,n){return e.s==-1?Math.max(OZ(e.l,t,n+1),OZ(e.r,t,n+1)):t[e.s]=n},kZ=function(e){for(var t=e.length;t&&!e[--t];);for(var n=new YX(++t),r=0,i=e[0],a=1,o=function(e){n[r++]=e},s=1;s<=t;++s)if(e[s]==i&&s!=t)++a;else{if(!i&&a>2){for(;a>138;a-=138)o(32754);a>2&&(o(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(o(i),--a;a>6;a-=6)o(8304);a>2&&(o(a-3<<5|8208),a=0)}for(;a--;)o(i);a=1,i=e[s]}return{c:n.subarray(0,r),n:t}},AZ=function(e,t){for(var n=0,r=0;r<t.length;++r)n+=e[r]*t[r];return n},jZ=function(e,t,n){var r=n.length,i=bZ(t+2);e[i]=r&255,e[i+1]=r>>8,e[i+2]=e[i]^255,e[i+3]=e[i+1]^255;for(var a=0;a<r;++a)e[i+a+4]=n[a];return(i+4+r)*8},MZ=function(e,t,n,r,i,a,o,s,c,l,u){TZ(t,u++,n),++i[256];for(var d=DZ(i,15),f=d.t,p=d.l,m=DZ(a,15),h=m.t,g=m.l,_=kZ(f),v=_.c,y=_.n,b=kZ(h),x=b.c,S=b.n,C=new YX(19),w=0;w<v.length;++w)++C[v[w]&31];for(var w=0;w<x.length;++w)++C[x[w]&31];for(var T=DZ(C,7),E=T.t,D=T.l,O=19;O>4&&!E[$X[O-1]];--O);var ee=l+5<<3,te=AZ(i,dZ)+AZ(a,fZ)+o,ne=AZ(i,f)+AZ(a,h)+o+14+3*O+AZ(C,E)+2*C[16]+3*C[17]+7*C[18];if(c>=0&&ee<=te&&ee<=ne)return jZ(t,u,e.subarray(c,c+l));var k,re,ie,ae;if(TZ(t,u,1+(ne<te)),u+=2,ne<te){k=uZ(f,p,0),re=f,ie=uZ(h,g,0),ae=h;var oe=uZ(E,D,0);TZ(t,u,y-257),TZ(t,u+5,S-1),TZ(t,u+10,O-4),u+=14;for(var w=0;w<O;++w)TZ(t,u+3*w,E[$X[w]]);u+=3*O;for(var se=[v,x],ce=0;ce<2;++ce)for(var le=se[ce],w=0;w<le.length;++w){var ue=le[w]&31;TZ(t,u,oe[ue]),u+=E[ue],ue>15&&(TZ(t,u,le[w]>>5&127),u+=le[w]>>12)}}else k=pZ,re=dZ,ie=hZ,ae=fZ;for(var w=0;w<s;++w){var de=r[w];if(de>255){var ue=de>>18&31;EZ(t,u,k[ue+257]),u+=re[ue+257],ue>7&&(TZ(t,u,de>>23&31),u+=ZX[ue]);var fe=de&31;EZ(t,u,ie[fe]),u+=ae[fe],fe>3&&(EZ(t,u,de>>5&8191),u+=QX[fe])}else EZ(t,u,k[de]),u+=re[de]}return EZ(t,u,k[256]),u+re[256]},NZ=new XX([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),PZ=new JX(0),FZ=function(e,t,n,r,i,a){var o=a.z||e.length,s=new JX(r+o+5*(1+Math.ceil(o/7e3))+i),c=s.subarray(r,s.length-i),l=a.l,u=(a.r||0)&7;if(t){u&&(c[0]=a.r>>3);for(var d=NZ[t-1],f=d>>13,p=d&8191,m=(1<<n)-1,h=a.p||new YX(32768),g=a.h||new YX(m+1),_=Math.ceil(n/3),v=2*_,y=function(t){return(e[t]^e[t+1]<<_^e[t+2]<<v)&m},b=new XX(25e3),x=new YX(288),S=new YX(32),C=0,w=0,T=a.i||0,E=0,D=a.w||0,O=0;T+2<o;++T){var ee=y(T),te=T&32767,ne=g[ee];if(h[te]=ne,g[ee]=te,D<=T){var k=o-T;if((C>7e3||E>24576)&&(k>423||!l)){u=MZ(e,c,0,b,x,S,w,E,O,T-O,u),E=C=w=0,O=T;for(var re=0;re<286;++re)x[re]=0;for(var re=0;re<30;++re)S[re]=0}var ie=2,ae=0,oe=p,se=te-ne&32767;if(k>2&&ee==y(T-se))for(var ce=Math.min(f,k)-1,le=Math.min(32767,T),ue=Math.min(258,k);se<=le&&--oe&&te!=ne;){if(e[T+ie]==e[T+ie-se]){for(var de=0;de<ue&&e[T+de]==e[T+de-se];++de);if(de>ie){if(ie=de,ae=se,de>ce)break;for(var fe=Math.min(se,de-2),A=0,re=0;re<fe;++re){var pe=T-se+re&32767,me=pe-h[pe]&32767;me>A&&(A=me,ne=pe)}}}te=ne,ne=h[te],se+=te-ne&32767}if(ae){b[E++]=268435456|rZ[ie]<<18|oZ[ae];var he=rZ[ie]&31,ge=oZ[ae]&31;w+=ZX[he]+QX[ge],++x[257+he],++S[ge],D=T+ie,++C}else b[E++]=e[T],++x[e[T]]}}for(T=Math.max(T,D);T<o;++T)b[E++]=e[T],++x[e[T]];u=MZ(e,c,l,b,x,S,w,E,O,T-O,u),l||(a.r=u&7|c[u/8|0]<<3,u-=7,a.h=g,a.p=h,a.i=T,a.w=D)}else{for(var T=a.w||0;T<o+l;T+=65535){var _e=T+65535;_e>=o&&(c[u/8|0]=l,_e=o),u=jZ(c,u+1,e.subarray(T,_e))}a.i=o}return xZ(s,0,r+bZ(u)+i)},IZ=(function(){for(var e=new Int32Array(256),t=0;t<256;++t){for(var n=t,r=9;--r;)n=(n&1&&-306674912)^n>>>1;e[t]=n}return e})(),LZ=function(){var e=-1;return{p:function(t){for(var n=e,r=0;r<t.length;++r)n=IZ[n&255^t[r]]^n>>>8;e=n},d:function(){return~e}}},RZ=function(e,t,n,r,i){if(!i&&(i={l:1},t.dictionary)){var a=t.dictionary.subarray(-32768),o=new JX(a.length+e.length);o.set(a),o.set(e,a.length),e=o,i.w=a.length}return FZ(e,t.level==null?6:t.level,t.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(e.length)))*1.5):20:12+t.mem,n,r,i)},zZ=function(e,t){var n={};for(var r in e)n[r]=e[r];for(var r in t)n[r]=t[r];return n},BZ=function(e,t){return e[t]|e[t+1]<<8},VZ=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},HZ=function(e,t){return VZ(e,t)+VZ(e,t+4)*4294967296},UZ=function(e,t,n){for(;n;++t)e[t]=n,n>>>=8};function WZ(e,t){return RZ(e,t||{},0,0)}function GZ(e,t){return wZ(e,{i:2},t&&t.out,t&&t.dictionary)}var KZ=function(e,t,n,r){for(var i in e){var a=e[i],o=t+i,s=r;Array.isArray(a)&&(s=zZ(r,a[1]),a=a[0]),a instanceof JX?n[o]=[a,s]:(n[o+=`/`]=[new JX(0),s],KZ(a,o,n,r))}},qZ=typeof TextEncoder<`u`&&new TextEncoder,JZ=typeof TextDecoder<`u`&&new TextDecoder;try{JZ.decode(PZ,{stream:!0})}catch{}var YZ=function(e){for(var t=``,n=0;;){var r=e[n++],i=(r>127)+(r>223)+(r>239);if(n+i>e.length)return{s:t,r:xZ(e,n-1)};i?i==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):i&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function XZ(e,t){if(t){for(var n=new JX(e.length),r=0;r<e.length;++r)n[r]=e.charCodeAt(r);return n}if(qZ)return qZ.encode(e);for(var i=e.length,a=new JX(e.length+(e.length>>1)),o=0,s=function(e){a[o++]=e},r=0;r<i;++r){if(o+5>a.length){var c=new JX(o+8+(i-r<<1));c.set(a),a=c}var l=e.charCodeAt(r);l<128||t?s(l):l<2048?(s(192|l>>6),s(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|e.charCodeAt(++r)&1023,s(240|l>>18),s(128|l>>12&63),s(128|l>>6&63),s(128|l&63)):(s(224|l>>12),s(128|l>>6&63),s(128|l&63))}return xZ(a,0,o)}function ZZ(e,t){if(t){for(var n=``,r=0;r<e.length;r+=16384)n+=String.fromCharCode.apply(null,e.subarray(r,r+16384));return n}else if(JZ)return JZ.decode(e);else{var i=YZ(e),a=i.s,n=i.r;return n.length&&CZ(8),a}}var QZ=function(e,t){return t+30+BZ(e,t+26)+BZ(e,t+28)},$Z=function(e,t,n){var r=BZ(e,t+28),i=ZZ(e.subarray(t+46,t+46+r),!(BZ(e,t+8)&2048)),a=t+46+r,o=VZ(e,t+20),s=n&&o==4294967295?eQ(e,a):[o,VZ(e,t+24),VZ(e,t+42)],c=s[0],l=s[1],u=s[2];return[BZ(e,t+10),c,l,i,a+BZ(e,t+30)+BZ(e,t+32),u]},eQ=function(e,t){for(;BZ(e,t)!=1;t+=4+BZ(e,t+2));return[HZ(e,t+12),HZ(e,t+4),HZ(e,t+20)]},tQ=function(e){var t=0;if(e)for(var n in e){var r=e[n].length;r>65535&&CZ(9),t+=r+4}return t},nQ=function(e,t,n,r,i,a,o,s){var c=r.length,l=n.extra,u=s&&s.length,d=tQ(l);UZ(e,t,o==null?67324752:33639248),t+=4,o!=null&&(e[t++]=20,e[t++]=n.os),e[t]=20,t+=2,e[t++]=n.flag<<1|(a<0&&8),e[t++]=i&&8,e[t++]=n.compression&255,e[t++]=n.compression>>8;var f=new Date(n.mtime==null?Date.now():n.mtime),p=f.getFullYear()-1980;if((p<0||p>119)&&CZ(10),UZ(e,t,p<<25|f.getMonth()+1<<21|f.getDate()<<16|f.getHours()<<11|f.getMinutes()<<5|f.getSeconds()>>1),t+=4,a!=-1&&(UZ(e,t,n.crc),UZ(e,t+4,a<0?-a-2:a),UZ(e,t+8,n.size)),UZ(e,t+12,c),UZ(e,t+14,d),t+=16,o!=null&&(UZ(e,t,u),UZ(e,t+6,n.attrs),UZ(e,t+10,o),t+=14),e.set(r,t),t+=c,d)for(var m in l){var h=l[m],g=h.length;UZ(e,t,+m),UZ(e,t+2,g),e.set(h,t+4),t+=4+g}return u&&(e.set(s,t),t+=u),t},rQ=function(e,t,n,r,i){UZ(e,t,101010256),UZ(e,t+8,n),UZ(e,t+10,n),UZ(e,t+12,r),UZ(e,t+16,i)};function iQ(e,t){t||={};var n={},r=[];KZ(e,``,n,t);var i=0,a=0;for(var o in n){var s=n[o],c=s[0],l=s[1],u=l.level==0?0:8,d=XZ(o),f=d.length,p=l.comment,m=p&&XZ(p),h=m&&m.length,g=tQ(l.extra);f>65535&&CZ(11);var _=u?WZ(c,l):c,v=_.length,y=LZ();y.p(c),r.push(zZ(l,{size:c.length,crc:y.d(),c:_,f:d,m,u:f!=o.length||m&&p.length!=h,o:i,compression:u})),i+=30+f+g+v,a+=76+2*(f+g)+(h||0)+v}for(var b=new JX(a+22),x=i,S=a-i,C=0;C<r.length;++C){var d=r[C];nQ(b,d.o,d,d.f,d.u,d.c.length);var w=30+d.f.length+tQ(d.extra);b.set(d.c,d.o+w),nQ(b,i,d,d.f,d.u,d.c.length,d.o,d.m),i+=16+w+(d.m?d.m.length:0)}return rQ(b,i,r.length,S,x),b}function aQ(e,t){for(var n={},r=e.length-22;VZ(e,r)!=101010256;--r)(!r||e.length-r>65558)&&CZ(13);var i=BZ(e,r+8);if(!i)return{};var a=VZ(e,r+16),o=a==4294967295||i==65535;if(o){var s=VZ(e,r-12);o=VZ(e,s)==101075792,o&&(i=VZ(e,s+32),a=VZ(e,s+48))}for(var c=t&&t.filter,l=0;l<i;++l){var u=$Z(e,a,o),d=u[0],f=u[1],p=u[2],m=u[3],h=u[4],g=u[5],_=QZ(e,g);a=h,(!c||c({name:m,size:f,originalSize:p,compression:d}))&&(d?d==8?n[m]=GZ(e.subarray(_,_+f),{out:new JX(p)}):CZ(14,`unknown compression type `+d):n[m]=xZ(e,_,_+f))}return n}function oQ(){return{stdout:`usage: unzip <archive.zip> [-d <destination>]
|
|
3312
|
-
`,stderr:``,exitCode:0}}function
|
|
3313
|
-
`,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=
|
|
3420
|
+
`,exitCode:1};let n=t.join(`-`),r=`https://www.sliccy.com/man/${n}.plain.html`;try{let t=await e(r,{method:`GET`});return t.status===404?{stdout:``,stderr:`No manual entry for ${n}\n`,exitCode:1}:t.status<200||t.status>=300?{stdout:``,stderr:`man: failed to fetch manual page for ${n}: ${t.status} ${t.statusText}\n`,exitCode:1}:{stdout:f$(new TextDecoder(`utf-8`).decode(t.body))+`
|
|
3421
|
+
`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`man: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function m$(){return{stdout:`usage: unzip <archive.zip> [-d <destination>]
|
|
3422
|
+
`,stderr:``,exitCode:0}}function h$(){return FM(`unzip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return m$();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
|
|
3423
|
+
`,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=TJ(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(!Ue(a,i))return{stdout:``,stderr:`unzip: blocked suspicious path ${e}\n`,exitCode:1};let o=Be(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 g$(){return{stdout:`usage: webhook <command> [options]
|
|
3314
3424
|
|
|
3315
3425
|
Commands:
|
|
3316
3426
|
create --scoop <name> [--name <name>] [--filter <code>] Create a new webhook endpoint
|
|
@@ -3328,12 +3438,12 @@ Examples:
|
|
|
3328
3438
|
webhook create --scoop slack-relay --name slack --filter "(e) => ({ text: e.body.text, user: e.body.user })"
|
|
3329
3439
|
webhook list
|
|
3330
3440
|
webhook delete abc123
|
|
3331
|
-
`,stderr:``,exitCode:0}}async function
|
|
3332
|
-
`,exitCode:1};let{ok:s,data:c}=await
|
|
3441
|
+
`,stderr:``,exitCode:0}}async function _$(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 v$(){return FM(`webhook`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return g$();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)
|
|
3442
|
+
`,exitCode:1};let{ok:s,data:c}=await _$(`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 _$(`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
|
|
3333
3443
|
`,stderr:``,exitCode:0};let r=`Active webhooks:
|
|
3334
3444
|
`;for(let e of n)r+=` ${e.id} ${e.name.padEnd(20)} ${e.url}`,e.scoop&&(r+=` -> ${e.scoop}`),e.filter&&(r+=` [filtered]`),r+=`
|
|
3335
3445
|
`;return{stdout:r,stderr:``,exitCode:0}}case`delete`:{let t=e[1];if(!t)return{stdout:``,stderr:`webhook: delete requires an ID
|
|
3336
|
-
`,exitCode:1};let{ok:n,status:r,data:i}=await
|
|
3446
|
+
`,exitCode:1};let{ok:n,status:r,data:i}=await _$(`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 y$(){return{stdout:`usage: websocat [FLAGS] [OPTIONS] <ws://URL | wss://URL>
|
|
3337
3447
|
|
|
3338
3448
|
Minimal websocat client. Sends stdin lines as WebSocket messages and prints
|
|
3339
3449
|
received messages to stdout. Server mode and advanced specifiers (exec:, tcp:,
|
|
@@ -3375,19 +3485,19 @@ EXAMPLES:
|
|
|
3375
3485
|
echo 'Page.navigate {"url":"https://example.com"}' \\
|
|
3376
3486
|
| websocat -1 --jsonrpc --jsonrpc-omit-jsonrpc \\
|
|
3377
3487
|
ws://127.0.0.1:9222/devtools/page/<id>
|
|
3378
|
-
`,stderr:``,exitCode:0}}const
|
|
3488
|
+
`,stderr:``,exitCode:0}}const b$=new Set([`-s`,`--server-mode`,`--oneshot`,`--socks5`,`--basic-auth`,`--basic-auth-file`,`--header-to-env`,`--server-header`,`--exec`,`--ws-c-uri`,`--restrict-uri`,`--unlink`,`--strict`,`-S`]);function x$(e){let t={text:!0,binary:!1,oneMessage:!1,noClose:!1,exitOnEof:!1,unidirectional:!1,unidirectionalReverse:!1,insecure:!1,quiet:!1,verbose:0,nullTerminated:!1,base64:!1,jsonrpc:!1,jsonrpcOmit:!1,bufferSize:65536,connTimeoutMs:3e4,customHeaders:[],showHelp:!1},n=(n,r)=>{let i=e[n].indexOf(`=`);if(i!==-1&&e[n].startsWith(r))return{value:e[n].slice(i+1),next:n};let a=e[n+1];return a===void 0?(t.error=`websocat: missing value for ${r}\n`,null):{value:a,next:n+1}};for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`-h`||i===`--help`)return t.showHelp=!0,t;if(b$.has(i)||b$.has(i.split(`=`)[0]))return t.error=`websocat: flag '${i}' is not supported in slicc's minimal client\n`,t;if(i===`-t`||i===`--text`){t.text=!0,t.binary=!1;continue}if(i===`-b`||i===`--binary`){t.binary=!0,t.text=!1;continue}if(i===`-1n`||i===`-n1`){t.oneMessage=!0,t.noClose=!0;continue}if(i===`-1`||i===`--one-message`){t.oneMessage=!0;continue}if(i===`-n`||i===`--no-close`){t.noClose=!0;continue}if(i===`-E`||i===`--exit-on-eof`){t.exitOnEof=!0;continue}if(i===`-u`||i===`--unidirectional`){t.unidirectional=!0;continue}if(i===`-U`||i===`--unidirectional-reverse`){t.unidirectionalReverse=!0;continue}if(i===`-k`||i===`--insecure`){t.insecure=!0;continue}if(i===`-q`){t.quiet=!0;continue}if(i===`-v`){t.verbose+=1;continue}if(i===`-vv`){t.verbose+=2;continue}if(i===`-0`||i===`--null-terminated`){t.nullTerminated=!0;continue}if(i===`--base64`){t.base64=!0;continue}if(i===`--jsonrpc`){t.jsonrpc=!0;continue}if(i===`--jsonrpc-omit-jsonrpc`){t.jsonrpcOmit=!0,t.jsonrpc=!0;continue}if(i===`--close-status-code`||i.startsWith(`--close-status-code=`)){let e=n(r,`--close-status-code`);if(!e)return t;let i=Number(e.value);if(!Number.isFinite(i)||i<1e3||i>4999)return t.error=`websocat: --close-status-code expects 1000..4999, got '${e.value}'\n`,t;t.closeStatus=i,r=e.next;continue}if(i===`--close-reason`||i.startsWith(`--close-reason=`)){let e=n(r,`--close-reason`);if(!e)return t;t.closeReason=e.value,r=e.next;continue}if(i===`-B`||i===`--buffer-size`||i.startsWith(`--buffer-size=`)){let e=n(r,i===`-B`?`-B`:`--buffer-size`);if(!e)return t;let a=Number(e.value);if(!Number.isFinite(a)||a<=0)return t.error=`websocat: --buffer-size expects positive integer
|
|
3379
3489
|
`,t;t.bufferSize=a,r=e.next;continue}if(i===`--max-messages`||i.startsWith(`--max-messages=`)){let e=n(r,`--max-messages`);if(!e)return t;let i=Number(e.value);if(!Number.isFinite(i)||i<=0)return t.error=`websocat: --max-messages expects positive integer
|
|
3380
3490
|
`,t;t.maxMessages=i,r=e.next;continue}if(i===`--protocol`||i.startsWith(`--protocol=`)){let e=n(r,`--protocol`);if(!e)return t;t.protocol=e.value,r=e.next;continue}if(i===`--ping-interval`||i.startsWith(`--ping-interval=`)){let e=n(r,`--ping-interval`);if(!e)return t;t.pingInterval=Number(e.value),r=e.next;continue}if(i===`--conn-timeout`||i.startsWith(`--conn-timeout=`)){let e=n(r,`--conn-timeout`);if(!e)return t;let i=Number(e.value);if(!Number.isFinite(i)||i<=0)return t.error=`websocat: --conn-timeout expects positive seconds
|
|
3381
3491
|
`,t;t.connTimeoutMs=Math.round(i*1e3),r=e.next;continue}if(i===`-H`||i===`--header`||i.startsWith(`--header=`)){let e=n(r,i===`-H`?`-H`:`--header`);if(!e)return t;t.customHeaders.push(e.value),r=e.next;continue}if(i.startsWith(`-`))return t.error=`websocat: unknown flag '${i}'\n`,t;if(t.url)return t.error=`websocat: extra positional argument '${i}' — advanced mode is not supported\n`,t;t.url=i}return t.closeReason!==void 0&&t.closeStatus===void 0&&(t.error=`websocat: --close-reason requires --close-status-code (the WebSocket close frame cannot carry a reason without a status code)
|
|
3382
|
-
`),t}function
|
|
3383
|
-
`,r=e.split(n);return r.length>0&&r[r.length-1]===``&&r.pop(),r}function
|
|
3492
|
+
`),t}function S$(e,t){if(!e)return[];let n=t?`\0`:`
|
|
3493
|
+
`,r=e.split(n);return r.length>0&&r[r.length-1]===``&&r.pop(),r}function C$(e,t,n){let r=e.trim();if(!r)return e;let i=r.search(/\s/),a=i===-1?r:r.slice(0,i),o=i===-1?``:r.slice(i+1).trim(),s=[];if(o)try{s=JSON.parse(o)}catch{s=[o]}let c={id:t,method:a,params:s};return n||(c.jsonrpc=`2.0`),JSON.stringify(c)}function w$(e){let t=``;for(let n=0;n<e.length;n+=1)t+=String.fromCharCode(e[n]);return btoa(t)}function T$(e){try{return new TextDecoder(`utf-8`,{fatal:!1}).decode(e)}catch{return w$(e)}}async function E$(e,t,n={}){let r=x$(e);if(r.showHelp)return y$();if(r.error)return{stdout:``,stderr:r.error,exitCode:2};if(!r.url)return{stdout:``,stderr:`websocat: missing ws:// or wss:// URL (use --help for usage)
|
|
3384
3494
|
`,exitCode:2};if(!/^wss?:\/\//i.test(r.url))return{stdout:``,stderr:`websocat: URL must start with ws:// or wss://, got '${r.url}'\n`,exitCode:2};let i=n.WebSocketCtor??(typeof WebSocket<`u`?WebSocket:void 0);if(!i)return{stdout:``,stderr:`websocat: no WebSocket implementation available in this runtime
|
|
3385
3495
|
`,exitCode:1};let a=[],o=e=>{r.quiet||a.push(`websocat: ${e}`)};r.verbose>=1&&(r.customHeaders.length>0&&o(`-H/--header is accepted for parity but browsers do not allow setting WebSocket request headers; only --protocol is honored`),r.pingInterval!==void 0&&o(`--ping-interval has no effect in browsers (no ping API exposed)`),r.insecure&&o(`-k/--insecure has no effect in browsers`));let s=[],c=r.nullTerminated?`\0`:`
|
|
3386
|
-
`,l;try{l=r.protocol?new i(r.url,r.protocol):new i(r.url)}catch(e){return{stdout:``,stderr:`websocat: connect failed: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}l.binaryType=`arraybuffer`;let u=0,d=1e4,f=0,p=!1,m,h,g=new Promise((e,t)=>{m=e,h=t}),_,v=!1,y=new Promise(e=>{_=t=>{v||(v=!0,e(t))}}),b=0,x=!1,S=setTimeout(()=>{x=!0;try{l.close()}catch{}p||h(Error(`connect timeout`))},r.connTimeoutMs);l.onopen=()=>{clearTimeout(S),p=!0,m()};let C=!1;l.onmessage=e=>{if(!C){if(!r.unidirectional){let t,n=!1;typeof e.data==`string`?t=new TextEncoder().encode(e.data):e.data instanceof ArrayBuffer?(t=new Uint8Array(e.data),n=!0):ArrayBuffer.isView(e.data)?(t=new Uint8Array(e.data.buffer,e.data.byteOffset,e.data.byteLength),n=!0):t=new TextEncoder().encode(String(e.data)),t.length>r.bufferSize&&(o(`inbound message of ${t.length} bytes exceeds --buffer-size ${r.bufferSize}; truncating`),t=t.slice(0,r.bufferSize));let i=n&&r.base64?
|
|
3496
|
+
`,l;try{l=r.protocol?new i(r.url,r.protocol):new i(r.url)}catch(e){return{stdout:``,stderr:`websocat: connect failed: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}l.binaryType=`arraybuffer`;let u=0,d=1e4,f=0,p=!1,m,h,g=new Promise((e,t)=>{m=e,h=t}),_,v=!1,y=new Promise(e=>{_=t=>{v||(v=!0,e(t))}}),b=0,x=!1,S=setTimeout(()=>{x=!0;try{l.close()}catch{}p||h(Error(`connect timeout`))},r.connTimeoutMs);l.onopen=()=>{clearTimeout(S),p=!0,m()};let C=!1;l.onmessage=e=>{if(!C){if(!r.unidirectional){let t,n=!1;typeof e.data==`string`?t=new TextEncoder().encode(e.data):e.data instanceof ArrayBuffer?(t=new Uint8Array(e.data),n=!0):ArrayBuffer.isView(e.data)?(t=new Uint8Array(e.data.buffer,e.data.byteOffset,e.data.byteLength),n=!0):t=new TextEncoder().encode(String(e.data)),t.length>r.bufferSize&&(o(`inbound message of ${t.length} bytes exceeds --buffer-size ${r.bufferSize}; truncating`),t=t.slice(0,r.bufferSize));let i=n&&r.base64?w$(t):T$(t);s.length<d?s.push(i):(f===0&&o(`output buffer reached ${d} messages; dropping further inbound messages — use -1, --max-messages, or pipe to a file with a different tool for long-running streams`),f+=1)}if(u+=1,r.maxMessages!==void 0&&u>=r.maxMessages){C=!0,T();return}r.oneMessage&&(C=!0,T())}},l.onerror=()=>{x||(o(`websocket error`),b=1,p||h(Error(`connect failed`)))},l.onclose=e=>{if(clearTimeout(S),x){_(124);return}r.verbose>=1&&o(`closed code=${e.code} reason=${JSON.stringify(e.reason||``)}`),b===0&&e.code!==1e3&&e.code!==1005&&e.code!==1001&&(b=1),p||h(Error(`connect closed (code ${e.code})`)),_(b)};function w(e,t){try{t===void 0?l.close(e):l.close(e,t)}catch{}}function T(){if(r.noClose){_(b);return}w(r.closeStatus??1e3,r.closeReason)}try{await g}catch(e){clearTimeout(S);let t=e instanceof Error?e.message:String(e);return{stdout:s.join(c)+(s.length?c:``),stderr:a.concat([`websocat: ${t}`]).join(`
|
|
3387
3497
|
`)+`
|
|
3388
|
-
`,exitCode:t===`connect timeout`?124:1}}if(r.unidirectionalReverse)!r.noClose&&r.exitOnEof&&!r.oneMessage&&setTimeout(()=>{w(r.closeStatus??1e3,r.closeReason)},0);else{let e=
|
|
3498
|
+
`,exitCode:t===`connect timeout`?124:1}}if(r.unidirectionalReverse)!r.noClose&&r.exitOnEof&&!r.oneMessage&&setTimeout(()=>{w(r.closeStatus??1e3,r.closeReason)},0);else{let e=S$(t.stdin,r.nullTerminated),n=1,i=0,a=r.oneMessage?e.slice(0,1):e;for(let e of a){let t=e;r.jsonrpc&&(t=C$(e,n,r.jsonrpcOmit),n+=1),r.binary?l.send(new TextEncoder().encode(t).buffer):l.send(t),i+=1}!r.oneMessage&&!r.noClose&&(r.exitOnEof||i===0)&&setTimeout(()=>{w(r.closeStatus??1e3,r.closeReason)},0)}let E=await y;return f>0&&o(`dropped ${f} inbound message(s) due to output buffer cap`),{stdout:s.length?s.join(c)+c:``,stderr:a.length?a.join(`
|
|
3389
3499
|
`)+`
|
|
3390
|
-
`:``,exitCode:E}}function
|
|
3500
|
+
`:``,exitCode:E}}function D$(){return FM(`websocat`,async(e,t)=>E$(e,{stdin:t.stdin}))}function O$(){return{stdout:`usage: crontask <command> [options]
|
|
3391
3501
|
|
|
3392
3502
|
Commands:
|
|
3393
3503
|
create [options] Create a new cron task
|
|
@@ -3419,16 +3529,16 @@ Examples:
|
|
|
3419
3529
|
crontask create --name every-5min --scoop poller --cron "*/5 * * * *" --filter "() => ({ time: Date.now() })"
|
|
3420
3530
|
crontask list
|
|
3421
3531
|
crontask delete abc123
|
|
3422
|
-
`,stderr:``,exitCode:0}}const
|
|
3532
|
+
`,stderr:``,exitCode:0}}const k$=typeof chrome<`u`&&!!chrome?.runtime?.id;function A$(){return globalThis.__slicc_lickManager??null}let j$=null;async function M$(){if(j$)return j$;let{createLickManagerProxy:e}=await import(`./lick-manager-proxy-D4WRd8z3.js`);return j$=e(),j$}async function N$(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 P$(){return FM(`crontask`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return O$();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
|
|
3423
3533
|
`,exitCode:1};if(!n)return{stdout:``,stderr:`crontask: --cron is required
|
|
3424
|
-
`,exitCode:1};if(
|
|
3425
|
-
`,exitCode:1};let e=
|
|
3534
|
+
`,exitCode:1};if(k$){if(r)return{stdout:``,stderr:`crontask: --filter is not supported in extension mode (CSP restriction)
|
|
3535
|
+
`,exitCode:1};let e=A$(),a=e?await e.createCronTask(t,n,i):await(await M$()).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 N$(`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(k$){let e=A$(),t=e?e.listCronTasks():await(async()=>{let{listCronTasksAsync:e}=await import(`./lick-manager-proxy-D4WRd8z3.js`);return e()})();if(t.length===0)return{stdout:`No active cron tasks
|
|
3426
3536
|
`,stderr:``,exitCode:0};let n=`Active cron tasks:
|
|
3427
3537
|
`;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+=`
|
|
3428
|
-
`;return{stdout:n,stderr:``,exitCode:0}}let{ok:e,data:t}=await
|
|
3538
|
+
`;return{stdout:n,stderr:``,exitCode:0}}let{ok:e,data:t}=await N$(`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
|
|
3429
3539
|
`,stderr:``,exitCode:0};let r=`Active cron tasks:
|
|
3430
3540
|
`;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+=`
|
|
3431
|
-
`;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(
|
|
3541
|
+
`;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(k$){let e=A$();return(e?await e.deleteCronTask(n):await(await M$()).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 N$(`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}}})}const F$=new Map;let I$=0;function L$(){return FM(`fswatch`,async e=>{let t=e[0];if(!t||t===`--help`)return{stdout:`usage: fswatch <command> [options]
|
|
3432
3542
|
|
|
3433
3543
|
Commands:
|
|
3434
3544
|
create --path <path> --pattern <glob> [--scoop <name>] [--name <name>] Watch for file changes
|
|
@@ -3440,11 +3550,11 @@ Options:
|
|
|
3440
3550
|
--pattern <glob> File pattern to match, e.g. "*.md", "*.bsh" (required)
|
|
3441
3551
|
--scoop <name> Route change events to this scoop as lick events
|
|
3442
3552
|
--name <name> Human-readable name for the watcher
|
|
3443
|
-
`,stderr:``,exitCode:0};if(t===`list`){if(
|
|
3444
|
-
`,stderr:``,exitCode:0};let e=``;for(let[,t]of
|
|
3445
|
-
`,exitCode:1};let n=
|
|
3553
|
+
`,stderr:``,exitCode:0};if(t===`list`){if(F$.size===0)return{stdout:`No active file watchers.
|
|
3554
|
+
`,stderr:``,exitCode:0};let e=``;for(let[,t]of F$)e+=`ID: ${t.id}\n`,e+=` Name: ${t.name}\n`,e+=` Path: ${t.basePath}\n`,e+=` Pattern: ${t.pattern}\n`,t.scoop&&(e+=` Scoop: ${t.scoop}\n`),e+=` Created: ${t.createdAt}\n\n`;return{stdout:e,stderr:``,exitCode:0}}if(t===`delete`){let t=e[1];if(!t)return{stdout:``,stderr:`fswatch: delete requires an ID
|
|
3555
|
+
`,exitCode:1};let n=F$.get(t);return n?(n.unsubscribe(),F$.delete(t),{stdout:`Deleted watcher "${n.name}" (${t})\n`,stderr:``,exitCode:0}):{stdout:``,stderr:`fswatch: watcher not found: ${t}\n`,exitCode:1}}if(t===`create`){let t=``,n=``,r=``,i=``;for(let a=1;a<e.length;a++)e[a]===`--path`&&e[a+1]?t=e[++a]:e[a]===`--pattern`&&e[a+1]?n=e[++a]:e[a]===`--scoop`&&e[a+1]?r=e[++a]:e[a]===`--name`&&e[a+1]&&(i=e[++a]);if(!t||!n)return{stdout:``,stderr:`fswatch: --path and --pattern are required
|
|
3446
3556
|
`,exitCode:1};let a=RegExp(`^`+n.replace(/\./g,`\\.`).replace(/\*/g,`.*`)+`$`),o=e=>{let t=e.split(`/`).pop()??``;return a.test(t)},s=globalThis.__slicc_fs_watcher;if(!s)return{stdout:``,stderr:`fswatch: file system watcher not available
|
|
3447
|
-
`,exitCode:1};let c=`fsw-${++
|
|
3557
|
+
`,exitCode:1};let c=`fsw-${++I$}`;i||=`${n} in ${t}`;let l=globalThis.__slicc_lick_handler,u=s.watch(t,o,e=>{l&&l({type:`fswatch`,fswatchId:c,fswatchName:i,targetScoop:r,timestamp:new Date().toISOString(),changes:e.map(e=>({type:e.type,path:e.path})),body:{changes:e.map(e=>({type:e.type,path:e.path}))}})});F$.set(c,{id:c,name:i,basePath:t,pattern:n,scoop:r,unsubscribe:u,createdAt:new Date().toISOString()});let d=`Created file watcher "${i}"\n`;return d+=`ID: ${c}\n`,d+=`Path: ${t}\n`,d+=`Pattern: ${n}\n`,r&&(d+=`Scoop: ${r}\n`),{stdout:d,stderr:``,exitCode:0}}return{stdout:``,stderr:`fswatch: unknown command: ${t}\n`,exitCode:1}})}const R$=`slicc-sprinkle-routes`;function z$(){try{let e=localStorage.getItem(R$);return e?JSON.parse(e):{}}catch{return{}}}function B$(e){try{localStorage.setItem(R$,JSON.stringify(e))}catch{}}function V$(e){return z$()[e]}function H$(e,t){let n=z$();n[e]=t,B$(n)}function U$(e){let t=z$();delete t[e],B$(t)}function W$(){return z$()}function G$(){return{stdout:`usage: sprinkle <subcommand> [args]
|
|
3448
3558
|
|
|
3449
3559
|
list List available .shtml sprinkles
|
|
3450
3560
|
open <name> Open a sprinkle by name
|
|
@@ -3457,23 +3567,23 @@ Options:
|
|
|
3457
3567
|
chat <html> Show inline HTML in chat (Tool UI)
|
|
3458
3568
|
Use data-action="name" on buttons for callbacks
|
|
3459
3569
|
Pipe HTML: echo "<div>...</div>" | sprinkle chat
|
|
3460
|
-
`,stderr:``,exitCode:0}}function
|
|
3570
|
+
`,stderr:``,exitCode:0}}function K$(){return globalThis.__slicc_sprinkleManager??null}function q$(){return FM(`sprinkle`,async(e,t)=>{if(e.length===0||e[0]===`--help`||e[0]===`-h`)return G$();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
|
|
3461
3571
|
`,exitCode:1};let r=await A({html:n,onAction:async(e,t)=>({action:e,data:t})});return r===null?{stdout:``,stderr:`sprinkle chat: not in tool execution context
|
|
3462
3572
|
`,exitCode:1}:{stdout:JSON.stringify(r)+`
|
|
3463
|
-
`,stderr:``,exitCode:0}}let r=
|
|
3573
|
+
`,stderr:``,exitCode:0}}let r=K$();if(!r)return{stdout:``,stderr:`sprinkle: sprinkle manager not initialized
|
|
3464
3574
|
`,exitCode:1};switch(n){case`list`:{await r.refresh();let e=r.available();if(e.length===0)return{stdout:`No .shtml sprinkles found.
|
|
3465
3575
|
`,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(`
|
|
3466
3576
|
`)+`
|
|
3467
3577
|
`,stderr:``,exitCode:0}}case`open`:{let t=e[1];if(!t)return{stdout:``,stderr:`sprinkle open: name required
|
|
3468
3578
|
`,exitCode:1};try{return await r.open(t),{stdout:`Sprinkle "${t}" opened.\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`sprinkle open: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}case`close`:{let t=e[1];return t?(r.close(t),{stdout:`Sprinkle "${t}" closed.\n`,stderr:``,exitCode:0}):{stdout:``,stderr:`sprinkle close: name required
|
|
3469
|
-
`,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`route`:{let t=e[1];if(!t){let e=
|
|
3579
|
+
`,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`route`:{let t=e[1];if(!t){let e=W$(),t=Object.entries(e);return t.length===0?{stdout:`No sprinkle routes configured (all licks go to cone).
|
|
3470
3580
|
`,stderr:``,exitCode:0}:{stdout:`Sprinkle routes:
|
|
3471
3581
|
`+t.map(([e,t])=>` ${e} -> ${t}`).join(`
|
|
3472
3582
|
`)+`
|
|
3473
|
-
`,stderr:``,exitCode:0}}if(e.includes(`--clear`))return
|
|
3583
|
+
`,stderr:``,exitCode:0}}if(e.includes(`--clear`))return U$(t),{stdout:`Route cleared for sprinkle "${t}" (licks will go to cone).\n`,stderr:``,exitCode:0};let n=e.indexOf(`--scoop`),r=n===-1?void 0:e[n+1];if(!r){let e=V$(t);return e?{stdout:`${t} -> ${e}\n`,stderr:``,exitCode:0}:{stdout:`${t} -> cone (default)\n`,stderr:``,exitCode:0}}return H$(t,r),{stdout:`Sprinkle "${t}" lick events will route to scoop "${r}".\n`,stderr:``,exitCode:0}}case`send`:{let t=e[1];if(!t)return{stdout:``,stderr:`sprinkle send: name required
|
|
3474
3584
|
`,exitCode:1};let n=e.slice(2).join(` `);if(!n)return{stdout:``,stderr:`sprinkle send: JSON data required
|
|
3475
3585
|
`,exitCode:1};let i;try{i=JSON.parse(n)}catch{return{stdout:``,stderr:`sprinkle send: invalid JSON
|
|
3476
|
-
`,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
|
|
3586
|
+
`,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 J$(){return`oauth-token — get an OAuth access token for a provider, or run an
|
|
3477
3587
|
ad-hoc OAuth interception against an arbitrary authorize URL.
|
|
3478
3588
|
|
|
3479
3589
|
Usage:
|
|
@@ -3520,14 +3630,14 @@ Examples:
|
|
|
3520
3630
|
--authorize-url 'https://auth.x.ai/oauth2/auth?...' \\
|
|
3521
3631
|
--redirect-pattern 'http://127.0.0.1:56121/*'
|
|
3522
3632
|
curl -H "Authorization: Bearer $(oauth-token github)" https://api.github.com/user
|
|
3523
|
-
`}function
|
|
3633
|
+
`}function Y$(){return FM(`oauth-token`,async e=>{let{getOAuthAccountInfo:t,getSelectedProvider:n,getAccounts:r}=await import(`./provider-settings-CRaSBF8A.js`).then(e=>e.l),{getRegisteredProviderConfig:i,getRegisteredProviderIds:a}=await import(`./providers-wxzKgKGa.js`).then(e=>e.r);if(e.includes(`--help`)||e.includes(`-h`))return{stdout:J$(),stderr:``,exitCode:0};if(e.includes(`--list`))return $$(r,a,i,t);if(e.includes(`--from-file`)||e.includes(`--intercept`))return X$(e);let o,s=e.indexOf(`--scope`);if(s>=0){if(o=e[s+1]?.trim(),!o||o.startsWith(`-`))return{stdout:``,stderr:`oauth-token: --scope requires a value
|
|
3524
3634
|
`,exitCode:1};e.splice(s,2)}let c,l=e.indexOf(`--provider`);if(l>=0){if(c=e[l+1],!c)return{stdout:``,stderr:`oauth-token: --provider requires a value
|
|
3525
3635
|
`,exitCode:1}}else if(e.length>0)c=e[0];else{let e=n(),t=i(e);if(t?.isOAuth&&(t.onOAuthLogin||t.onOAuthLoginIntercepted))c=e;else if(c=a().find(e=>{let t=i(e);return t?.isOAuth&&(t.onOAuthLogin||t.onOAuthLoginIntercepted)}),!c)return{stdout:``,stderr:`oauth-token: no OAuth providers configured
|
|
3526
3636
|
`,exitCode:1}}let u=i(c);if(!u)return{stdout:``,stderr:`oauth-token: unknown provider "${c}"\n`,exitCode:1};if(!u.isOAuth||!u.onOAuthLogin&&!u.onOAuthLoginIntercepted)return{stdout:``,stderr:`oauth-token: provider "${c}" is not an OAuth provider\n`,exitCode:1};if(!o){let e=t(c);if(e&&!e.expired){let t=e.maskedValue;return t?{stdout:`${t}\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`oauth-token: no masked value for ${c} (try logging in again)\n`,exitCode:1}}}try{if(u.onOAuthLoginIntercepted){let{createInterceptingOAuthLauncherForCurrentRuntime:e}=await import(`./oauth-service-BXo87SGy.js`),t=await e();if(!t)return{stdout:``,stderr:`oauth-token: provider "${c}" needs the controlled-browser interceptor, but no CDP transport is available in this runtime.\n`,exitCode:1};await u.onOAuthLoginIntercepted(t,()=>{},o?{scopes:o}:void 0)}else if(u.onOAuthLogin){let{createOAuthLauncher:e}=await import(`./oauth-service-BXo87SGy.js`),t=e();await u.onOAuthLogin(t,()=>{},o?{scopes:o}:void 0)}else return{stdout:``,stderr:`oauth-token: provider "${c}" has no OAuth login hook\n`,exitCode:1};let e=t(c);if(e&&e.token){let t=e.maskedValue;return t?{stdout:`${t}\n`,stderr:``,exitCode:0}:{stdout:``,stderr:`oauth-token: no masked value for ${c} (try logging in again)\n`,exitCode:1}}return console.error(`[oauth-token] Provider ${c}: login completed but no token was saved`),{stdout:``,stderr:`oauth-token: login completed but no token was saved
|
|
3527
|
-
`,exitCode:1}}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`[oauth-token] Provider ${c}: login failed:`,t),{stdout:``,stderr:`oauth-token: login failed: ${t}\n`,exitCode:1}}})}async function
|
|
3637
|
+
`,exitCode:1}}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`[oauth-token] Provider ${c}: login failed:`,t),{stdout:``,stderr:`oauth-token: login failed: ${t}\n`,exitCode:1}}})}async function X$(e){let{parseInterceptOAuthConfig:t}=await import(`./intercepted-oauth-CnYe4Pun.js`).then(e=>e.n),{createInterceptingOAuthLauncherForCurrentRuntime:n}=await import(`./oauth-service-BXo87SGy.js`),r,i=e.indexOf(`--from-file`);if(i>=0){let t=e[i+1];if(!t)return Q$(`oauth-token: --from-file requires a path`);try{let{VirtualFS:e}=await import(`./fs-DDc-eOO2.js`).then(e=>e.t),{GLOBAL_FS_DB_NAME:n}=await Promise.resolve().then(()=>dK),i=await(await e.create({dbName:n})).readFile(t);r=JSON.parse(typeof i==`string`?i:new TextDecoder().decode(i))}catch(e){return Q$(`oauth-token: failed to read ${t}: ${e instanceof Error?e.message:String(e)}`)}}else{let t=Z$(e,`--authorize-url`),n=Z$(e,`--redirect-pattern`);if(!t)return Q$(`oauth-token: --authorize-url is required`);if(!n)return Q$(`oauth-token: --redirect-pattern is required`);let i=[];for(let t=0;t<e.length;t++){if(e[t]!==`--rewrite`)continue;let n=e[t+1];if(!n)return Q$(`oauth-token: --rewrite requires a value`);let r=n.split(`=`);if(r.length<3)return Q$(`oauth-token: --rewrite "${n}" must be "<match>=<key>=<value>"`);let[a,o,...s]=r;i.push({match:a,appendParams:{[o]:s.join(`=`)}})}r={authorizeUrl:t,redirectUriPattern:n,onCapture:e.includes(`--leave-tab`)?`leave`:`close`,...i.length>0?{rewrite:i}:{}}}let a=t(r);if(!a.ok)return Q$(`oauth-token: invalid intercept config: ${a.error}`);let o=await n();if(!o)return Q$(`oauth-token: no CDP transport available in this runtime; --intercept needs the controlled browser.`);let s=await o(a.config);return s?{stdout:`${s}\n`,stderr:``,exitCode:0}:Q$(`oauth-token: intercept timed out or was cancelled`)}function Z$(e,t){let n=e.indexOf(t);if(n<0)return;let r=e[n+1];if(!(!r||r.startsWith(`--`)))return r}function Q$(e){return{stdout:``,stderr:`${e}\n`,exitCode:1}}function $$(e,t,n,r){let i=t().filter(e=>n(e)?.isOAuth);if(i.length===0)return{stdout:`No OAuth providers configured.
|
|
3528
3638
|
`,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(`
|
|
3529
3639
|
`)+`
|
|
3530
|
-
`,stderr:``,exitCode:0}}const
|
|
3640
|
+
`,stderr:``,exitCode:0}}const e1=Ze.id;function t1(){return`local-llm — inspect and configure the Local LLM provider
|
|
3531
3641
|
|
|
3532
3642
|
Usage:
|
|
3533
3643
|
local-llm Show current config + verify connection
|
|
@@ -3546,14 +3656,14 @@ Common base URLs:
|
|
|
3546
3656
|
llama.cpp http://localhost:8080/v1
|
|
3547
3657
|
vLLM http://localhost:8000/v1
|
|
3548
3658
|
Jan http://localhost:1337/v1
|
|
3549
|
-
`}function
|
|
3550
|
-
`,exitCode:1};let c=await a(s,t(
|
|
3659
|
+
`}function n1(){return FM(e1,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:t1(),stderr:``,exitCode:0};let{getApiKeyForProvider:t,getRawApiKeyForProvider:n,getBaseUrlForProvider:r,addAccount:i}=await import(`./provider-settings-CRaSBF8A.js`).then(e=>e.l),{verifyConnection:a}=await import(`./local-llm-BdgJqTmS.js`).then(e=>e.n),o=e[0]??`status`;if(o!==`status`&&o!==`discover`)return{stdout:``,stderr:`Unknown subcommand: ${o}. See \`local-llm --help\`.\n`,exitCode:2};let s=r(e1);if(!s)return{stdout:``,stderr:`Local LLM is not configured. Open Settings → Providers → Local LLM and set a base URL.
|
|
3660
|
+
`,exitCode:1};let c=await a(s,t(e1)??void 0);if(!c.ok){let e=[`✗ Could not reach ${s}`,` runtime: ${c.runtime.kind}${c.runtime.version?` (${c.runtime.version})`:``}`,` error: ${c.error?.message??`unknown`}`];return c.error?.hint&&e.push(` hint: ${c.error.hint}`),{stdout:``,stderr:e.join(`
|
|
3551
3661
|
`)+`
|
|
3552
|
-
`,exitCode:1}}return o===`discover`?(i(
|
|
3662
|
+
`,exitCode:1}}return o===`discover`?(i(e1,n(e1)??``,s,c.models.join(`, `)),{stdout:[`✓ ${s} (${c.runtime.kind}${c.runtime.version?` ${c.runtime.version}`:``})`,` Saved ${c.models.length} model${c.models.length===1?``:`s`} to Settings:`,...c.models.map(e=>` • ${e}`)].join(`
|
|
3553
3663
|
`)+`
|
|
3554
3664
|
`,stderr:``,exitCode:0}):{stdout:[`✓ ${s}`,` runtime: ${c.runtime.kind}${c.runtime.version?` (${c.runtime.version})`:``}`,` models: ${c.models.length}`,...c.models.map(e=>` • ${e}`)].join(`
|
|
3555
3665
|
`)+`
|
|
3556
|
-
`,stderr:``,exitCode:0}})}function
|
|
3666
|
+
`,stderr:``,exitCode:0}})}function r1(){return`secret — manage secrets for the fetch proxy and mount backends
|
|
3557
3667
|
|
|
3558
3668
|
CLI mode (node-server / swift-server):
|
|
3559
3669
|
secret set <name> --domain <patterns> Show instructions for editing
|
|
@@ -3580,25 +3690,25 @@ Examples:
|
|
|
3580
3690
|
secret list
|
|
3581
3691
|
secret delete GITHUB_TOKEN
|
|
3582
3692
|
secret test GITHUB_TOKEN https://api.github.com/repos
|
|
3583
|
-
`}function
|
|
3584
|
-
`,exitCode:1};let r=
|
|
3693
|
+
`}function i1(){return typeof chrome<`u`&&!!chrome?.runtime?.id}function a1(e){return new Promise((t,n)=>{chrome.runtime.sendMessage(e,e=>{let r=chrome.runtime.lastError;if(r){n(Error(r.message??`chrome.runtime.lastError`));return}t(e)})})}async function o1(){let e=await a1({type:`secrets.list`});if(e?.error)throw Error(e.error);return e?.entries??[]}async function s1(e,t,n){let r=await a1({type:`secrets.set`,name:e,value:t,domains:n});if(!r?.ok)throw Error(r?.error??`secrets.set failed`)}async function c1(e){let t=await a1({type:`secrets.delete`,name:e});if(!t?.ok)throw Error(t?.error??`secrets.delete failed`)}async function l1(){let{ok:e,data:t}=await u1(`GET`,``);return e?t:null}async function u1(e,t,n){if(i1())throw Error(`Secrets CLI is only available in CLI mode`);let r={method:e,headers:{"Content-Type":`application/json`}};n&&(r.body=JSON.stringify(n));let i=await fetch(`/api/secrets${t}`,r),a=await i.json().catch(()=>({}));return{ok:i.ok,status:i.status,data:a}}function d1(e){let t=e.indexOf(`--domain`);return t===-1||!e[t+1]?null:e[t+1].split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}function f1(){return FM(`secret`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return{stdout:r1(),stderr:``,exitCode:0};let t=e[0],n=i1();try{switch(t){case`set`:{let t=e[1];if(!t||t.startsWith(`-`))return{stdout:``,stderr:`secret: set requires a <name>
|
|
3694
|
+
`,exitCode:1};let r=d1(e);if(n){let n=e[2]&&!e[2].startsWith(`-`)&&e[2]!==t?e[2]:void 0;if(!n)return{stdout:``,stderr:`secret: extension mode requires a <value>: secret set <name> <value> --domain <patterns>
|
|
3585
3695
|
`,exitCode:1};if(!r||r.length===0)return{stdout:``,stderr:`secret: --domain is required (comma-separated patterns)
|
|
3586
|
-
`,exitCode:1};try{await
|
|
3696
|
+
`,exitCode:1};try{await s1(t,n,r)}catch(e){return{stdout:``,stderr:`secret: failed to write to chrome.storage.local: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return{stdout:`Stored "${t}" in chrome.storage.local (domains: ${r.join(`, `)})\n`,stderr:``,exitCode:0}}let i=r&&r.length>0?r.join(`,`):`<domain1,domain2>`,a=`To add the secret "${t}", use one of the following methods:\n\n`;return a+=` macOS Keychain (swift-server):
|
|
3587
3697
|
`,a+=` security add-generic-password -s ai.sliccy.slicc -a ${t} -w '<value>' -U -C note -j '${i}'\n\n`,a+=` Environment file (node-server):
|
|
3588
3698
|
`,a+=` Add to ~/.slicc/secrets.env:
|
|
3589
3699
|
`,a+=` ${t}=<value>\n`,a+=` ${t}_DOMAINS=${i}\n\n`,a+=`Then restart the server to pick up changes.
|
|
3590
|
-
`,{stdout:a,stderr:``,exitCode:0}}case`list`:{let e=n?await
|
|
3700
|
+
`,{stdout:a,stderr:``,exitCode:0}}case`list`:{let e=n?await o1():await l1();if(!e)return{stdout:``,stderr:`secret: failed to list secrets
|
|
3591
3701
|
`,exitCode:1};if(e.length===0)return{stdout:`No secrets stored
|
|
3592
3702
|
`,stderr:``,exitCode:0};let t=Math.max(4,...e.map(e=>e.name.length)),r=`${`NAME`.padEnd(t)} DOMAINS\n`;for(let n of e)r+=`${n.name.padEnd(t)} ${n.domains.join(`, `)}\n`;return{stdout:r,stderr:``,exitCode:0}}case`delete`:{let t=e[1];if(!t)return{stdout:``,stderr:`secret: delete requires a <name>
|
|
3593
|
-
`,exitCode:1};if(n){try{await
|
|
3703
|
+
`,exitCode:1};if(n){try{await c1(t)}catch(e){return{stdout:``,stderr:`secret: failed to remove from chrome.storage.local: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return{stdout:`Removed "${t}" from chrome.storage.local\n`,stderr:``,exitCode:0}}let r=`To delete the secret "${t}", use one of the following methods:\n\n`;return r+=` macOS Keychain (swift-server):
|
|
3594
3704
|
`,r+=` security delete-generic-password -s ai.sliccy.slicc -a ${t}\n\n`,r+=` Environment file (node-server):
|
|
3595
3705
|
`,r+=` Remove the ${t}= and ${t}_DOMAINS= lines from ~/.slicc/secrets.env\n\n`,r+=`Then restart the server to pick up changes.
|
|
3596
3706
|
`,{stdout:r,stderr:``,exitCode:0}}case`test`:{let t=e[1],r=e[2];if(!t||!r)return{stdout:``,stderr:`secret: test requires <name> <url>
|
|
3597
|
-
`,exitCode:1};let i;try{i=new URL(r).hostname}catch{return{stdout:``,stderr:`secret: invalid URL "${r}"\n`,exitCode:1}}let a=n?await
|
|
3707
|
+
`,exitCode:1};let i;try{i=new URL(r).hostname}catch{return{stdout:``,stderr:`secret: invalid URL "${r}"\n`,exitCode:1}}let a=n?await o1():await l1();if(!a)return{stdout:``,stderr:`secret: failed to fetch secrets
|
|
3598
3708
|
`,exitCode:1};let o=a.find(e=>e.name===t);return o?se(o.domains,i)?{stdout:`✓ ${t} is allowed for ${i}\n`,stderr:``,exitCode:0}:{stdout:`✗ ${t} is NOT allowed for ${i}\n Allowed domains: ${o.domains.join(`, `)}\n`,stderr:``,exitCode:1}:{stdout:``,stderr:`secret: no secret named "${t}"\n`,exitCode:1}}case`edit`:if(!n)return{stdout:`secret: in CLI mode, edit ~/.slicc/secrets.env directly with your text editor.
|
|
3599
3709
|
(changes are picked up on the next request — no restart needed)
|
|
3600
3710
|
`,stderr:``,exitCode:0};try{return await chrome.runtime.openOptionsPage(),{stdout:`Opened Mount Secrets options page in a new tab.
|
|
3601
|
-
`,stderr:``,exitCode:0}}catch{let e=chrome.runtime.getURL(`secrets.html`);return window.open(e,`_blank`),{stdout:`Opened ${e}\n`,stderr:``,exitCode:0}}default:return{stdout:``,stderr:`secret: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`secret: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function
|
|
3711
|
+
`,stderr:``,exitCode:0}}catch{let e=chrome.runtime.getURL(`secrets.html`);return window.open(e,`_blank`),{stdout:`Opened ${e}\n`,stderr:``,exitCode:0}}default:return{stdout:``,stderr:`secret: unknown command "${t}"\n`,exitCode:1}}}catch(e){return{stdout:``,stderr:`secret: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function p1(){return`oauth-domain — manage extra allowed domains for OAuth-issued tokens
|
|
3602
3712
|
|
|
3603
3713
|
Usage:
|
|
3604
3714
|
oauth-domain list List extra domains for every provider
|
|
@@ -3623,7 +3733,7 @@ Examples:
|
|
|
3623
3733
|
oauth-domain add adobe '*.da.live'
|
|
3624
3734
|
oauth-domain list adobe
|
|
3625
3735
|
oauth-domain remove adobe admin.da.live
|
|
3626
|
-
`}function
|
|
3736
|
+
`}function m1(){return FM(`oauth-domain`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return{stdout:p1(),stderr:``,exitCode:0};let{getExtraOAuthDomains:t,setExtraOAuthDomainsAsync:n,getAllExtraOAuthDomains:r}=await import(`./provider-settings-CRaSBF8A.js`).then(e=>e.l),[i,a,o]=e;try{switch(i){case`list`:{if(a){let e=t(a);return e.length===0?{stdout:`(no extra domains configured for ${a})\n`,stderr:``,exitCode:0}:{stdout:e.join(`
|
|
3627
3737
|
`)+`
|
|
3628
3738
|
`,stderr:``,exitCode:0}}let e=r(),n=Object.entries(e).filter(([,e])=>e.length>0);return n.length===0?{stdout:`(no extra OAuth domains configured)
|
|
3629
3739
|
`,stderr:``,exitCode:0}:{stdout:n.map(([e,t])=>`${e}: ${t.join(`, `)}`).join(`
|
|
@@ -3631,7 +3741,7 @@ Examples:
|
|
|
3631
3741
|
`,stderr:``,exitCode:0}}case`add`:{if(!a||!o)return{stdout:``,stderr:`oauth-domain add: requires <providerId> and <domain>
|
|
3632
3742
|
`,exitCode:1};let e=t(a),r=o.toLowerCase();return e.some(e=>e.toLowerCase()===r)?{stdout:`(${o} already in ${a} extras)\n`,stderr:``,exitCode:0}:(await n(a,[...e,o]),{stdout:`Added ${o} to ${a}. Reload the page to apply.\n`,stderr:``,exitCode:0})}case`remove`:{if(!a||!o)return{stdout:``,stderr:`oauth-domain remove: requires <providerId> and <domain>
|
|
3633
3743
|
`,exitCode:1};let e=t(a),r=o.toLowerCase(),i=e.filter(e=>e.toLowerCase()!==r);return i.length===e.length?{stdout:`(${o} not found in ${a} extras)\n`,stderr:``,exitCode:0}:(await n(a,i),{stdout:`Removed ${o} from ${a}. Reload the page to apply.\n`,stderr:``,exitCode:0})}case`clear`:return a?(await n(a,[]),{stdout:`Cleared extra domains for ${a}. Reload the page to apply.\n`,stderr:``,exitCode:0}):{stdout:``,stderr:`oauth-domain clear: requires <providerId>
|
|
3634
|
-
`,exitCode:1};default:return{stdout:``,stderr:`oauth-domain: unknown subcommand "${i}"\n${
|
|
3744
|
+
`,exitCode:1};default:return{stdout:``,stderr:`oauth-domain: unknown subcommand "${i}"\n${p1()}`,exitCode:1}}}catch(e){return{stdout:``,stderr:`oauth-domain: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function h1(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}}function g1(){return null}function _1(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=v1(r),o=v1(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 v1(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 y1(){return{stdout:`rsync — sync files between local VFS and a remote tray runtime
|
|
3635
3745
|
|
|
3636
3746
|
Usage:
|
|
3637
3747
|
rsync [flags] <local-path> <runtime-id>:<remote-path> # push
|
|
@@ -3647,21 +3757,21 @@ Examples:
|
|
|
3647
3757
|
rsync /workspace follower-abc123:/workspace
|
|
3648
3758
|
rsync --delete /shared leader:/shared
|
|
3649
3759
|
rsync follower-abc123:/workspace/project /workspace/project
|
|
3650
|
-
`,stderr:``,exitCode:0}}async function
|
|
3760
|
+
`,stderr:``,exitCode:0}}async function b1(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 x1(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 S1(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 C1(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 w1(e){let t=e.lastIndexOf(`/`);return t<=0?`/`:e.slice(0,t)}async function T1(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=h1(await b1(e,i),await x1(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(`
|
|
3651
3761
|
`)+`
|
|
3652
|
-
`,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let s=i+`/`+n,c=a+`/`+n;await
|
|
3762
|
+
`,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let s=i+`/`+n,c=a+`/`+n;await C1(t,o,w1(c));let l=await t(o,{op:`writeFile`,path:c,content:D1(await e.readFile(s,{encoding:`binary`})),encoding:`base64`});if(!l[0].ok)return{stdout:r.join(`
|
|
3653
3763
|
`)+`
|
|
3654
3764
|
`,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(`
|
|
3655
3765
|
`)+`
|
|
3656
3766
|
`,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(`
|
|
3657
3767
|
`)+`
|
|
3658
|
-
`,stderr:``,exitCode:0}}async function
|
|
3768
|
+
`,stderr:``,exitCode:0}}async function E1(e,t,n){let r=[],{localPath:i,remotePath:a,runtimeId:o,verbose:s,dryRun:c}=n,l=h1(await x1(t,o,a),await b1(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(`
|
|
3659
3769
|
`)+`
|
|
3660
|
-
`,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let r=a+`/`+n,s=i+`/`+n,c=
|
|
3770
|
+
`,stderr:``,exitCode:0};for(let n of[...l.toAdd,...l.toUpdate]){let r=a+`/`+n,s=i+`/`+n,c=w1(s);await e.exists(c)||await e.mkdir(c,{recursive:!0});let l=O1(await S1(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(`
|
|
3661
3771
|
`)+`
|
|
3662
|
-
`,stderr:``,exitCode:0}}function
|
|
3772
|
+
`,stderr:``,exitCode:0}}function D1(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function O1(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 k1(e={}){let t=e.fs,n=e.getSendFsRequest??g1;return FM(`rsync`,async e=>{if(e.includes(`--help`)||e.includes(`-h`)||e.length===0)return y1();if(!t)return{stdout:``,stderr:`rsync: no filesystem available
|
|
3663
3773
|
`,exitCode:1};let r=n();if(!r)return{stdout:``,stderr:`rsync: not connected to a tray — rsync requires a tray connection
|
|
3664
|
-
`,exitCode:1};let i=
|
|
3774
|
+
`,exitCode:1};let i=_1(e);if(`error`in i)return i.error===`__help__`?y1():{stdout:``,stderr:`rsync: ${i.error}\n`,exitCode:1};try{return i.direction===`push`?await T1(t,r,i):await E1(t,r,i)}catch(e){return{stdout:``,stderr:`rsync: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}const A1=[`/workspace/skills`];async function j1(e){let t=new Map;for(let n of A1)await e.exists(n)&&await M1(e,n,t);return await M1(e,`/`,t),t}async function M1(e,t,n){for await(let r of e.walk(t)){if(!r.endsWith(`.jsh`))continue;let e=N1(r);n.has(e)||n.set(e,r)}}function N1(e){let t=e.split(`/`).pop()??e;return t.endsWith(`.jsh`)?t.slice(0,-4):t}function P1(e={}){let t=e.scriptCatalog!==void 0||e.fs!==void 0?e:typeof e.walk==`function`&&typeof e.exists==`function`?{fs:e}:{};return FM(`which`,async(e,n)=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:`which - locate a command
|
|
3665
3775
|
|
|
3666
3776
|
Usage: which <command> [command...]
|
|
3667
3777
|
|
|
@@ -3671,12 +3781,12 @@ Prints the path of the given command(s).
|
|
|
3671
3781
|
|
|
3672
3782
|
Exit code 0 if all commands found, 1 if any not found.
|
|
3673
3783
|
`,stderr:``,exitCode:0};if(e.length===0)return{stdout:``,stderr:`which: missing argument
|
|
3674
|
-
`,exitCode:1};let r=n.getRegisteredCommands?.()??[],i=new Set(r),a=t.scriptCatalog?await t.scriptCatalog.getJshCommands():t.fs?await
|
|
3784
|
+
`,exitCode:1};let r=n.getRegisteredCommands?.()??[],i=new Set(r),a=t.scriptCatalog?await t.scriptCatalog.getJshCommands():t.fs?await j1(t.fs):new Map,o=[],s=!0;for(let t of e)if(i.has(t))o.push(`/usr/bin/${t}`);else{let e=a.get(t);e?o.push(e):s=!1}return{stdout:o.length>0?o.join(`
|
|
3675
3785
|
`)+`
|
|
3676
|
-
`:``,stderr:``,exitCode:+!s}})}async function
|
|
3677
|
-
`,stderr:``,exitCode:0}}function
|
|
3678
|
-
`,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(/^\.\//,``))||Le(r);if(i.isDirectory&&!n)return{stdout:``,stderr:`zip: ${e} is a directory (use -r)\n`,exitCode:1};s+=await
|
|
3679
|
-
`,exitCode:1};let c=
|
|
3786
|
+
`:``,stderr:``,exitCode:+!s}})}async function F1(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=ze(t,o),s=n?`${n}/${o}`:o;a+=await F1(e,i,s,r)}return a}function I1(){return{stdout:`usage: zip [-r] <archive.zip> <path> [path...]
|
|
3787
|
+
`,stderr:``,exitCode:0}}function L1(){return FM(`zip`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return I1();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
|
|
3788
|
+
`,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(/^\.\//,``))||Le(r);if(i.isDirectory&&!n)return{stdout:``,stderr:`zip: ${e} is a directory (use -r)\n`,exitCode:1};s+=await F1(t,r,a,o)}if(s===0)return{stdout:``,stderr:`zip: nothing to do
|
|
3789
|
+
`,exitCode:1};let c=wJ(o);return await t.fs.writeFile(i,c),{stdout:`created ${i} (${s} file(s))\n`,stderr:``,exitCode:0}})}function R1(){return{stdout:`screencapture - capture screen, window, or tab using browser screen sharing
|
|
3680
3790
|
|
|
3681
3791
|
Usage: screencapture [options] <output-file>
|
|
3682
3792
|
|
|
@@ -3692,29 +3802,29 @@ Examples:
|
|
|
3692
3802
|
screencapture screenshot.png # Capture to file
|
|
3693
3803
|
screencapture -c # Capture to clipboard
|
|
3694
3804
|
screencapture -v capture.png # Capture and return for agent vision
|
|
3695
|
-
`,stderr:``,exitCode:0}}function
|
|
3805
|
+
`,stderr:``,exitCode:0}}function z1(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 B1(e){switch(e.split(`.`).pop()?.toLowerCase()){case`jpg`:case`jpeg`:return`image/jpeg`;case`webp`:return`image/webp`;default:return`image/png`}}async function V1(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`);s.drawImage(r,0,0,i,a);let c=await new Promise((n,r)=>{o.toBlob(e=>e?n(e):r(Error(`Failed to create image blob`)),e,t)});return{bytes:new Uint8Array(await c.arrayBuffer()),mimeType:e}}finally{n.getTracks().forEach(e=>e.stop())}}function H1(){return FM(`screencapture`,async(e,t)=>{if(e.includes(`--help`)||e.includes(`-h`))return R1();let n=N(),r=P();if(!n&&!r)return{stdout:``,stderr:`screencapture: browser APIs are unavailable in this environment
|
|
3696
3806
|
`,exitCode:1};if(n&&!navigator.mediaDevices?.getDisplayMedia)return{stdout:``,stderr:`screencapture: screen capture is not supported in this browser
|
|
3697
3807
|
`,exitCode:1};let i=e.includes(`--clipboard`)||e.includes(`-c`),a=e.includes(`--view`)||e.includes(`-v`),o=[`--clipboard`,`-c`,`--view`,`-v`,`--help`,`-h`],s=e.indexOf(`--`),c=(s>=0?e.slice(s+1):e.filter(e=>!o.includes(e)))[0];if(!i&&!c)return{stdout:``,stderr:`screencapture: output file required (or use -c for clipboard)
|
|
3698
|
-
`,exitCode:1};let l=c||`screenshot.png`,u=
|
|
3699
|
-
`,exitCode:1}:{stdout:``,stderr:`screencapture: ${t}\n`,exitCode:1}}if(i)try{if(n){let e=await
|
|
3808
|
+
`,exitCode:1};let l=c||`screenshot.png`,u=B1(l),d=u===`image/png`?1:.92,f;try{if(n)f=(await V1(u,d)).bytes;else{let e=await r.call(`screencapture`,{mimeType:u,quality:d},{timeoutMs:5*6e4});f=new Uint8Array(e.bytes)}}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
|
|
3809
|
+
`,exitCode:1}:{stdout:``,stderr:`screencapture: ${t}\n`,exitCode:1}}if(i)try{if(n){let e=await U1(f,u),t=new ArrayBuffer(e.byteLength);new Uint8Array(t).set(e);let n=new Blob([t],{type:`image/png`});return await W1(),await navigator.clipboard.write([new ClipboardItem({"image/png":n})]),{stdout:`captured ${Math.round(n.size/1024)} KB to clipboard\n`,stderr:``,exitCode:0}}return await r.call(`clipboard-write-image`,{bytes:f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength),mimeType:u},{timeoutMs:5*6e4}),{stdout:`captured ${Math.round(f.byteLength/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,l);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 a?{stdout:`${p} (${m} KB)\n<img:data:${u};base64,${z1(f)}>`,stderr:``,exitCode:0}:{stdout:`captured ${m} KB to ${Le(p)}\n`,stderr:``,exitCode:0}})}async function U1(e,t){if(t===`image/png`)return e;let n=new ArrayBuffer(e.byteLength);new Uint8Array(n).set(e);let r=new Blob([n],{type:t}),i=URL.createObjectURL(r);try{let e=new Image;await new Promise((t,n)=>{e.onload=()=>t(),e.onerror=()=>n(Error(`Failed to load image for conversion`)),e.src=i});let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);if(!n)throw Error(`Failed to get canvas context`);n.drawImage(e,0,0);let r=await new Promise((e,n)=>{t.toBlob(t=>t?e(t):n(Error(`Failed to create PNG blob`)),`image/png`)});return new Uint8Array(await r.arrayBuffer())}finally{URL.revokeObjectURL(i)}}async function W1(e=5*6e4){typeof document>`u`||typeof document.hasFocus==`function`&&(document.hasFocus()||await new Promise((t,n)=>{let r=()=>{window.removeEventListener(`focus`,i),document.removeEventListener(`visibilitychange`,a),clearTimeout(o)},i=()=>{document.hasFocus()&&(r(),t())},a=()=>{document.visibilityState===`visible`&&document.hasFocus()&&(r(),t())},o=setTimeout(()=>{r(),n(Error(`timed out waiting for window focus`))},e);window.addEventListener(`focus`,i),document.addEventListener(`visibilitychange`,a)}))}function G1(e){return e instanceof Error?e.message:String(e)}function K1(){return{stdout:`usage: pbcopy
|
|
3700
3810
|
|
|
3701
3811
|
Copy stdin to the clipboard.
|
|
3702
3812
|
Example: echo hello | pbcopy
|
|
3703
|
-
`,stderr:``,exitCode:0}}function
|
|
3813
|
+
`,stderr:``,exitCode:0}}function q1(){return{stdout:`usage: pbpaste
|
|
3704
3814
|
|
|
3705
3815
|
Paste clipboard contents to stdout.
|
|
3706
|
-
`,stderr:``,exitCode:0}}function
|
|
3816
|
+
`,stderr:``,exitCode:0}}function J1(e){return{stdout:`usage: ${e} [-i|-o]\n\n -i Force copy mode (read from stdin)
|
|
3707
3817
|
-o Force paste mode (write to stdout)
|
|
3708
3818
|
(default) Auto-detect: stdin present = copy, no stdin = paste
|
|
3709
|
-
Example: echo hello | ${e}\n Example: ${e} -o > file.txt\n`,stderr:``,exitCode:0}}async function
|
|
3819
|
+
Example: echo hello | ${e}\n Example: ${e} -o > file.txt\n`,stderr:``,exitCode:0}}async function Y1(e,t){let n=!!globalThis.navigator?.clipboard,r=n?null:P();if(!n&&!r)return{stdout:``,stderr:`${t}: clipboard API is unavailable\n`,exitCode:1};try{return n?await navigator.clipboard.writeText(e):await r.call(`clipboard-write-text`,{text:e}),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`${t}: failed to write to clipboard: ${G1(e)}\n`,exitCode:1}}}async function X1(e){let t=!!globalThis.navigator?.clipboard,n=t?null:P();if(!t&&!n)return{stdout:``,stderr:`${e}: clipboard API is unavailable\n`,exitCode:1};try{return{stdout:t?await navigator.clipboard.readText():(await n.call(`clipboard-read-text`,void 0)).text,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`${e}: failed to read from clipboard: ${G1(t)}\n`,exitCode:1}}}function Z1(){return FM(`pbcopy`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?K1():Y1(t.stdin,`pbcopy`))}function Q1(){return FM(`pbpaste`,async e=>e.includes(`--help`)||e.includes(`-h`)?q1():X1(`pbpaste`))}function $1(e){return FM(e,async(t,n)=>{if(t.includes(`--help`)||t.includes(`-h`))return J1(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?X1(e):r||n.stdin.length>0?Y1(n.stdin,e):X1(e)})}function e0(){return{stdout:`usage: say [-v voice] [-r rate] [-l lang] [--list] <text>
|
|
3710
3820
|
|
|
3711
3821
|
Speaks the given text using the Web Speech API.
|
|
3712
3822
|
-v voice Voice name (partial match supported)
|
|
3713
3823
|
-r rate Speech rate (0.1 to 10, default 1)
|
|
3714
3824
|
-l lang Language tag (required, BCP 47, e.g. en-US, de-DE, fr-FR)
|
|
3715
3825
|
--list List available voices
|
|
3716
|
-
`,stderr:``,exitCode:0}}let
|
|
3717
|
-
`,exitCode:1};if(e.includes(`--list`)){if(t)return{stdout:(await
|
|
3826
|
+
`,stderr:``,exitCode:0}}let t0=!1,n0=null;function r0(){return t0?Promise.resolve(speechSynthesis.getVoices()):(n0||=new Promise(e=>{let t=speechSynthesis.getVoices();if(t.length>0){t0=!0,e(t);return}let n=()=>{t0=!0,speechSynthesis.removeEventListener(`voiceschanged`,n),e(speechSynthesis.getVoices())};speechSynthesis.addEventListener(`voiceschanged`,n),setTimeout(()=>{speechSynthesis.removeEventListener(`voiceschanged`,n),t0=!0,e(speechSynthesis.getVoices())},1e3)}),n0)}function i0(){return FM(`say`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return e0();let t=typeof window<`u`&&typeof speechSynthesis<`u`,n=P();if(!t&&!n)return{stdout:``,stderr:`say: Web Speech API unavailable in this environment
|
|
3827
|
+
`,exitCode:1};if(e.includes(`--list`)){if(t)return{stdout:(await r0()).map(e=>`${e.name} (${e.lang})${e.default?` [default]`:``}`).join(`
|
|
3718
3828
|
`)+`
|
|
3719
3829
|
`,stderr:``,exitCode:0};try{return{stdout:(await n.call(`list-voices`,void 0)).voices.map(e=>`${e.name} (${e.lang})${e.default?` [default]`:``}`).join(`
|
|
3720
3830
|
`)+`
|
|
@@ -3722,23 +3832,23 @@ Examples:
|
|
|
3722
3832
|
`,exitCode:1};r=e[++t]}else if(n===`-r`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`say: -r requires a rate value
|
|
3723
3833
|
`,exitCode:1};if(i=parseFloat(e[++t]),isNaN(i)||i<.1||i>10)return{stdout:``,stderr:`say: rate must be between 0.1 and 10
|
|
3724
3834
|
`,exitCode:1}}else if(n===`-l`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`say: -l requires a language tag
|
|
3725
|
-
`,exitCode:1};a=e[++t]}else if(n.startsWith(`-`)&&n!==`--list`)return{stdout:``,stderr:`say: unknown option: ${n}\n`,exitCode:1};else n.startsWith(`-`)||o.push(n)}let s=o.join(` `);if(!s)return
|
|
3726
|
-
`,exitCode:1};let c;if(r){let e=(t?await
|
|
3835
|
+
`,exitCode:1};a=e[++t]}else if(n.startsWith(`-`)&&n!==`--list`)return{stdout:``,stderr:`say: unknown option: ${n}\n`,exitCode:1};else n.startsWith(`-`)||o.push(n)}let s=o.join(` `);if(!s)return e0();if(!a)return{stdout:``,stderr:`say: -l language tag is required
|
|
3836
|
+
`,exitCode:1};let c;if(r){let e=(t?await r0().then(e=>e.map(e=>({name:e.name,lang:e.lang,default:e.default}))):(await n.call(`list-voices`,void 0)).voices).find(e=>e.name.toLowerCase().includes(r.toLowerCase()));if(!e)return{stdout:``,stderr:`say: voice "${r}" not found. Use --list to see available voices.\n`,exitCode:1};c=e.name}if(t){let e=new SpeechSynthesisUtterance(s);if(e.rate=i,e.lang=a,c){let t=(await r0()).find(e=>e.name===c);t&&(e.voice=t)}return new Promise(t=>{e.onend=()=>t({stdout:``,stderr:``,exitCode:0}),e.onerror=e=>t({stdout:``,stderr:`say: speech synthesis error: ${e.error}\n`,exitCode:1}),speechSynthesis.speak(e)})}try{return await n.call(`speak-text`,{text:s,lang:a,voice:c,rate:i}),{stdout:``,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`say: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}})}function a0(){return{stdout:`usage: afplay [-v volume] [-r rate] <file>
|
|
3727
3837
|
|
|
3728
3838
|
Plays an audio file using the Web Audio API.
|
|
3729
3839
|
-v volume Volume level (0 to 1, default 1)
|
|
3730
3840
|
-r rate Playback rate (0.25 to 4, default 1)
|
|
3731
|
-
`,stderr:``,exitCode:0}}let
|
|
3732
|
-
`,exitCode:1};let o=r.fs.resolvePath(r.cwd,e),s;try{s=new Uint8Array(await r.fs.readFileBuffer(o))}catch{return{stdout:``,stderr:`afplay: cannot open ${e}: No such file\n`,exitCode:1}}let c=je(o);if(!c.startsWith(`audio/`))return{stdout:``,stderr:`afplay: ${e} is not an audio file\n`,exitCode:1};if(!i)try{let e=new ArrayBuffer(s.byteLength);return new Uint8Array(e).set(s),await a.call(`play-audio`,{bytes:e,mimeType:c,volume:t},{timeoutMs:5*6e4}),{stdout:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`afplay: failed to play ${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}try{let e
|
|
3841
|
+
`,stderr:``,exitCode:0}}let o0=null;function s0(){return(!o0||o0.state===`closed`)&&(o0=new AudioContext),o0}async function c0(e,t,n,r){let i=N()&&typeof AudioContext<`u`,a=P();if(!i&&!a)return{stdout:``,stderr:`afplay: Web Audio API unavailable in this environment
|
|
3842
|
+
`,exitCode:1};let o=r.fs.resolvePath(r.cwd,e),s;try{s=new Uint8Array(await r.fs.readFileBuffer(o))}catch{return{stdout:``,stderr:`afplay: cannot open ${e}: No such file\n`,exitCode:1}}let c=je(o);if(!c.startsWith(`audio/`))return{stdout:``,stderr:`afplay: ${e} is not an audio file\n`,exitCode:1};if(!i)try{let e=new ArrayBuffer(s.byteLength);return new Uint8Array(e).set(s),await a.call(`play-audio`,{bytes:e,mimeType:c,volume:t},{timeoutMs:5*6e4}),{stdout:``,stderr:``,exitCode:0}}catch(t){return{stdout:``,stderr:`afplay: failed to play ${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}try{let e=s0();e.state===`suspended`&&await e.resume();let r=new ArrayBuffer(s.byteLength);new Uint8Array(r).set(s);let i=await e.decodeAudioData(r),a=e.createBufferSource();a.buffer=i,a.playbackRate.value=n;let o=e.createGain();return o.gain.value=t,a.connect(o),o.connect(e.destination),new Promise(e=>{a.onended=()=>{e({stdout:``,stderr:``,exitCode:0})},a.start()})}catch(t){return{stdout:``,stderr:`afplay: failed to play ${e}: ${t instanceof Error?t.message:String(t)}\n`,exitCode:1}}}function l0(){return FM(`afplay`,async(e,t)=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return a0();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
|
|
3733
3843
|
`,exitCode:1};if(n=parseFloat(e[++t]),isNaN(n)||n<0||n>1)return{stdout:``,stderr:`afplay: volume must be between 0 and 1
|
|
3734
3844
|
`,exitCode:1}}else if(a===`-r`){if(t+1>=e.length||e[t+1].startsWith(`-`))return{stdout:``,stderr:`afplay: -r requires a rate value
|
|
3735
3845
|
`,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
|
|
3736
3846
|
`,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
|
|
3737
|
-
`,exitCode:1};i=a}}return i?
|
|
3847
|
+
`,exitCode:1};i=a}}return i?c0(i,n,r,t):a0()})}function u0(){return FM(`chime`,async(e,t)=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`usage: chime
|
|
3738
3848
|
|
|
3739
3849
|
Plays a notification chime sound.
|
|
3740
3850
|
Alias for: afplay /shared/sounds/chime.mp3
|
|
3741
|
-
`,stderr:``,exitCode:0}:
|
|
3851
|
+
`,stderr:``,exitCode:0}:c0(`/shared/sounds/chime.mp3`,1,1,t))}const d0=`/.cache/artificial-analysis.json`;async function f0(e,t=!1){if(e&&!t)try{let t=await e.readFile(d0),n=JSON.parse(t);if(Date.now()-n.fetchedAt<864e5)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=DK(),a;try{a=await i(`https://artificialanalysis.ai/api/v2/data/llms/models`,{method:`GET`,headers:r})}catch{return[]}if(a.status===401||a.status<200||a.status>=300)return[];let o;try{let e=new TextDecoder().decode(a.body);o=JSON.parse(e)}catch{return[]}let s=(Array.isArray(o)?o:o?.data??o?.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&&s.length>0){let t={fetchedAt:Date.now(),models:s};try{await e.mkdir(`/.cache`,{recursive:!0}),await e.writeFile(d0,JSON.stringify(t))}catch{}}return s}function p0(e){return e.toLowerCase().replace(/\./g,`-`).replace(/-\d{8}$/,``).replace(/-\d{4}$/,``)}function m0(e,t){let n=e.toLowerCase(),r=t.find(e=>e.slug===n);if(r)return r;let i=p0(e),a=t.find(e=>p0(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 h0(){return`models - list available LLM models
|
|
3742
3852
|
|
|
3743
3853
|
Usage: models [options]
|
|
3744
3854
|
|
|
@@ -3750,37 +3860,37 @@ Options:
|
|
|
3750
3860
|
--refresh Force re-fetch benchmark data from Artificial Analysis
|
|
3751
3861
|
--no-benchmarks Skip benchmark data enrichment (faster, works offline)
|
|
3752
3862
|
-h, --help Show this help message
|
|
3753
|
-
`}function
|
|
3863
|
+
`}function g0(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`.replace(`.0M`,`M`):e>=1e3?`${(e/1e3).toFixed(0)}K`:`${e}`}function _0(e){return`$${e.toFixed(2)}`}const v0=/\b(embedding|embed|tts|whisper|dall-e|image-gen|audio|vision-preview)\b/i;function y0(e){let t=`${e.id} ${e.name??``}`;return!v0.test(t)}function b0(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 x0(e){let t=new Map;for(let n of e){let e=b0(n.id);t.has(e)||t.set(e,n)}return[...t.values()]}function S0(e,t,n,r,i){let a=i?m0(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 C0(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=`${_0(e.cost.input)} / ${_0(e.cost.output)}`,a=`${g0(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(`
|
|
3754
3864
|
`)+`
|
|
3755
|
-
`}function
|
|
3756
|
-
`,exitCode:1};let v;f||(v=await
|
|
3865
|
+
`}function w0(e){return FM(`models`,async t=>{let{getAccounts:n,getAvailableProviders:r,getProviderConfig:i,getProviderModels:a,getSelectedProvider:o,getSelectedModelId:s}=await import(`./provider-settings-CRaSBF8A.js`).then(e=>e.l);if(t.includes(`--help`)||t.includes(`-h`))return{stdout:h0(),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.
|
|
3866
|
+
`,exitCode:1};let v;f||(v=await f0(e,d),v.length===0&&(v=void 0));let y;if(m){let e=r();if(!e.includes(m))return{stdout:``,stderr:`Unknown provider: ${m}. Available: ${e.join(`, `)}\n`,exitCode:1};y=[m]}else y=l?[...new Set(_.map(e=>e.providerId))]:[h];let b=[],x=[];for(let e of y){let t=a(e).filter(y0);if(t.length===0){if(!l)return{stdout:``,stderr:`No models available for provider ${e}.\n`,exitCode:1};continue}let n=t.map(t=>S0(t,e,g,h,v)).sort((e,t)=>t.cost.input-e.cost.input);if(u||(n=x0(n)),b.push(...n),!c){let t=i(e);x.push(C0(t.name,e,n,!!v))}}return c?{stdout:JSON.stringify(b,null,2)+`
|
|
3757
3867
|
`,stderr:``,exitCode:0}:(!u&&!c&&x.push(`Showing latest versions only. Use --all-versions to see all.
|
|
3758
3868
|
`),{stdout:x.join(`
|
|
3759
|
-
`),stderr:``,exitCode:0})})}var
|
|
3869
|
+
`),stderr:``,exitCode:0})})}var T0=n({createCostCommand:()=>P0,registerSessionCostsProvider:()=>D0});let E0=null;function D0(e){E0=e}function O0(){return`cost - show session cost breakdown
|
|
3760
3870
|
|
|
3761
3871
|
Usage: cost [options]
|
|
3762
3872
|
|
|
3763
3873
|
Options:
|
|
3764
3874
|
--json Output as JSON (for programmatic use)
|
|
3765
3875
|
-h, --help Show this help message
|
|
3766
|
-
`}function
|
|
3767
|
-
`);let n=` `+`Agent`.padEnd(16)+`Model`.padEnd(18)+`MTok (in/out)`.padEnd(15)+`Cache (r/w)`.padEnd(15)+`Cost`.padStart(10)+`$/hour`.padStart(10),r=` `+`─`.repeat(84);t.push(n),t.push(r);let i=0,a=0,o=0,s=0,c=0;for(let n of e){let e=n.name.padEnd(16),r=
|
|
3876
|
+
`}function k0(e){let t=e/1e6;return t<.01?`<0.01`:t.toFixed(2)}function A0(e){return`$${e.toFixed(2)}`}function j0(e,t){if(!t||t===0)return`-`;let n=t/(1e3*60*60);return n===0?`-`:`$${(e/n).toFixed(2)}`}function M0(e,t){return e.length<=t?e:e.slice(0,t-3)+`...`}function N0(e){let t=[];t.push(`Session Cost Breakdown:
|
|
3877
|
+
`);let n=` `+`Agent`.padEnd(16)+`Model`.padEnd(18)+`MTok (in/out)`.padEnd(15)+`Cache (r/w)`.padEnd(15)+`Cost`.padStart(10)+`$/hour`.padStart(10),r=` `+`─`.repeat(84);t.push(n),t.push(r);let i=0,a=0,o=0,s=0,c=0;for(let n of e){let e=n.name.padEnd(16),r=M0(n.model,18).padEnd(18),l=`${k0(n.usage.input).padStart(5)} / ${k0(n.usage.output).padStart(5)}`.padEnd(15),u=`${k0(n.usage.cacheRead).padStart(5)} / ${k0(n.usage.cacheWrite).padStart(5)}`.padEnd(15),d=A0(n.usage.cost.total).padStart(10),f=j0(n.usage.cost.total,n.activeTimeMs).padStart(10);t.push(` ${e}${r}${l}${u}${d}${f}`),i+=n.usage.input,a+=n.usage.output,o+=n.usage.cacheRead,s+=n.usage.cacheWrite,c+=n.usage.cost.total}t.push(r);let l=`Total`.padEnd(16),u=``.padEnd(18),d=`${k0(i).padStart(5)} / ${k0(a).padStart(5)}`.padEnd(15),f=`${k0(o).padStart(5)} / ${k0(s).padStart(5)}`.padEnd(15),p=A0(c).padStart(10),m=``.padStart(10);return t.push(` ${l}${u}${d}${f}${p}${m}`),t.join(`
|
|
3768
3878
|
`)+`
|
|
3769
|
-
`}function
|
|
3770
|
-
`,exitCode:1};let t=await
|
|
3879
|
+
`}function P0(){return FM(`cost`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:O0(),stderr:``,exitCode:0};if(!E0)return{stdout:``,stderr:`Cost data not available.
|
|
3880
|
+
`,exitCode:1};let t=await E0();return t.length===0?{stdout:`No session cost data yet.
|
|
3771
3881
|
`,stderr:``,exitCode:0}:e.includes(`--json`)?{stdout:JSON.stringify(t,null,2)+`
|
|
3772
|
-
`,stderr:``,exitCode:0}:{stdout:
|
|
3882
|
+
`,stderr:``,exitCode:0}:{stdout:N0(t),stderr:``,exitCode:0}})}const F0=[`slicc:welcome-flow-fired`,`slicc.trayJoinUrl`,`slicc.trayWorkerBaseUrl`];function I0(){return FM(`nuke`,async e=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`Usage: nuke <launch-code>
|
|
3773
3883
|
|
|
3774
3884
|
Completely reset the environment by deleting all local data and reloading.
|
|
3775
3885
|
Destroys the file system, chat history, and scoops database.
|
|
3776
3886
|
Requires the secret launch code to proceed.
|
|
3777
|
-
`,stderr:``,exitCode:0}:e.join(``).includes(`1234`)?((async()=>{try{let e=await navigator.serviceWorker?.getRegistrations?.();e&&await Promise.all(e.map(e=>e.unregister().catch(()=>!1)))}catch{}try{let e=await indexedDB.databases();await Promise.all(e.filter(e=>!!e.name).map(e=>new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()})))}catch{}
|
|
3887
|
+
`,stderr:``,exitCode:0}:e.join(``).includes(`1234`)?((async()=>{try{let e=await navigator.serviceWorker?.getRegistrations?.();e&&await Promise.all(e.map(e=>e.unregister().catch(()=>!1)))}catch{}try{let e=await indexedDB.databases();await Promise.all(e.filter(e=>!!e.name).map(e=>new Promise(t=>{let n=indexedDB.deleteDatabase(e.name);n.onsuccess=()=>t(),n.onerror=()=>t(),n.onblocked=()=>t()})))}catch{}L0(F0)})(),{stdout:`Nuking everything…
|
|
3778
3888
|
`,stderr:``,exitCode:0}):{stdout:``,stderr:`⚠️ WARNING: this will reset the entire environment, file system, chats, and scoops.
|
|
3779
3889
|
Run nuke again with the secret launch code to proceed.
|
|
3780
|
-
`,exitCode:1})}function
|
|
3890
|
+
`,exitCode:1})}function L0(e=[]){let t=[...e];try{if(typeof BroadcastChannel==`function`){let e=new BroadcastChannel(`slicc-nuke-control`);e.postMessage({type:`nuke-reload`,keysToRemove:t}),setTimeout(()=>e.close(),100)}}catch{}for(let e of t)try{globalThis.localStorage?.removeItem(e)}catch{}try{globalThis.location?.reload?.()}catch{}}const R0=i(`agent-command`);function z0(e){let t=[],n=!1,r,i,a,o=0;for(;o<e.length;){let s=e[o];if(t.length===2){t.push(s),o+=1;continue}if(s===`-h`||s===`--help`){n=!0,o+=1;continue}if(s===`--model`){let t=e[o+1];if(t===void 0||t.length>0&&t.startsWith(`-`))return{help:!1,error:`agent: --model requires a value`};if(t===``)return{help:!1,error:`agent: --model requires a non-empty value`};r=t,o+=2;continue}if(s===`--thinking`||s===`--effort`){let t=e[o+1];if(t===void 0||t.length>0&&t.startsWith(`-`))return{help:!1,error:`agent: ${s} requires a value`};if(t===``)return{help:!1,error:`agent: ${s} requires a non-empty value`};if(!Ot(t))return{help:!1,error:`agent: ${s} must be one of: ${Dt.join(`, `)}`};a=t,o+=2;continue}if(s===`--read-only`){let t=e[o+1];if(t===void 0||t.length>0&&t.startsWith(`-`))return{help:!1,error:`agent: --read-only requires a value`};if(t===``)return{help:!1,error:`agent: --read-only requires a non-empty value`};let n=B0(t);if(n.length===0)return{help:!1,error:`agent: --read-only requires a non-empty value`};i=n,o+=2;continue}if(s.length>0&&s.startsWith(`-`))return{help:!1,error:`agent: unknown flag '${s}'`};t.push(s),o+=1}if(n)return{help:!0};if(t.length<3)return{help:!1,error:`agent: missing required argument ${[`<cwd>`,`<allowed-commands>`,`<prompt>`][t.length]}`};if(t.length>3)return{help:!1,error:`agent: too many arguments`};let[s,c,l]=t;return{help:!1,cwd:s,allowedCommandsRaw:c,prompt:l,modelId:r,visiblePaths:i,thinkingLevel:a}}function B0(e){return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}function V0(e,t){return e.startsWith(`/`)?j(e):j(`${t.length>0?t:`/`}/${e}`)}function H0(e){return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}function U0(e){return e==null?`
|
|
3781
3891
|
`:e.replace(/\n+$/,``)+`
|
|
3782
|
-
`}function
|
|
3783
|
-
`}function
|
|
3892
|
+
`}function W0(e){return e==null||e===``?``:e.replace(/\n+$/,``)+`
|
|
3893
|
+
`}function G0(){let e=globalThis.__slicc_agent;if(!(!e||typeof e.spawn!=`function`))return e}function K0(e={}){let{getParentJid:t}=e;return FM(`agent`,async(e,n)=>{let r=z0(e);if(r.help)return{stdout:`usage: agent <cwd> <allowed-commands> <prompt>
|
|
3784
3894
|
|
|
3785
3895
|
Spawns a sub-scoop, feeds it a task, blocks until the agent loop completes,
|
|
3786
3896
|
then prints the scoop's final message on stdout.
|
|
@@ -3826,8 +3936,8 @@ Examples:
|
|
|
3826
3936
|
agent --thinking high . "*" "design a careful plan first"
|
|
3827
3937
|
agent --read-only /workspace/,/shared/assets/ . "*" "review the docs"
|
|
3828
3938
|
`,stderr:``,exitCode:0};if(r.error)return{stdout:``,stderr:`${r.error}\n`,exitCode:1};let i=r.cwd??``;if(i===``)return{stdout:``,stderr:`agent: <cwd> must not be empty
|
|
3829
|
-
`,exitCode:1};let a=
|
|
3830
|
-
`,exitCode:1};let u={cwd:a,allowedCommands:o,prompt:s};r.modelId!==void 0&&(u.modelId=r.modelId),r.visiblePaths!==void 0&&(u.visiblePaths=r.visiblePaths),r.thinkingLevel!==void 0&&(u.thinkingLevel=r.thinkingLevel),n.cwd&&n.cwd.length>0&&(u.invokingCwd=n.cwd);let d=t?.();d!==void 0&&d.length>0&&(u.parentJid=d);try{let e=await l.spawn(u),t=typeof e?.exitCode==`number`?e.exitCode:0,n=e?.finalText;return t===0?{stdout:
|
|
3939
|
+
`,exitCode:1};let a=V0(i,n.cwd),o=H0(r.allowedCommandsRaw??``),s=r.prompt??``;try{if(!(await n.fs.stat(a)).isDirectory)return{stdout:``,stderr:`agent: cwd not a directory: ${i}\n`,exitCode:1}}catch{return{stdout:``,stderr:`agent: cwd not found: ${i}\n`,exitCode:1}}let c=n.fs;if(typeof c.canWrite==`function`&&!c.canWrite(a))return{stdout:``,stderr:`agent: cwd not writable: ${i}\n`,exitCode:1};let l=G0();if(!l)return{stdout:``,stderr:`agent: orchestrator bridge not available
|
|
3940
|
+
`,exitCode:1};let u={cwd:a,allowedCommands:o,prompt:s};r.modelId!==void 0&&(u.modelId=r.modelId),r.visiblePaths!==void 0&&(u.visiblePaths=r.visiblePaths),r.thinkingLevel!==void 0&&(u.thinkingLevel=r.thinkingLevel),n.cwd&&n.cwd.length>0&&(u.invokingCwd=n.cwd);let d=t?.();d!==void 0&&d.length>0&&(u.parentJid=d);try{let e=await l.spawn(u),t=typeof e?.exitCode==`number`?e.exitCode:0,n=e?.finalText;return t===0?{stdout:U0(n),stderr:``,exitCode:0}:{stdout:``,stderr:W0(n),exitCode:t}}catch(e){let t=e instanceof Error?e.message:String(e);return R0.error(`agent bridge threw`,e),{stdout:``,stderr:`${t}\n`,exitCode:1}}})}function q0(e){return async(t,n)=>{let r=await e(typeof t==`string`?t:t instanceof URL?t.toString():t.url,{method:n?.method??`GET`});return new Response(r.body,{status:r.status,statusText:r.statusText,headers:r.headers})}}function J0(){return`discover — fetch a URL and parse RFC 8288 Link headers
|
|
3831
3941
|
|
|
3832
3942
|
Usage:
|
|
3833
3943
|
discover <url> Print parsed links (and any SLICC handoff match)
|
|
@@ -3841,13 +3951,13 @@ Output is always JSON.
|
|
|
3841
3951
|
Examples:
|
|
3842
3952
|
discover https://www.sliccy.ai/handoff?handoff=demo
|
|
3843
3953
|
discover --follow https://www.sliccy.ai/llms.txt
|
|
3844
|
-
`}function
|
|
3845
|
-
`,exitCode:2};let r=n[0],i=DK(),a;try{a=await i(r,{method:`GET`})}catch(e){return{stdout:``,stderr:`discover: fetch failed: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=[];for(let[e,t]of Object.entries(a.headers))e.toLowerCase()===`link`&&typeof t==`string`&&t.length>0&&o.push(t);let s=WK(o,r),c=aq(s),l={url:r,status:a.status,links:s,handoff:c};if(t&&s.length>0){let e=await dq(s,{fetchImpl:
|
|
3846
|
-
`,stderr:``,exitCode:0}})}const
|
|
3847
|
-
`,exitCode:1};let r=
|
|
3848
|
-
`,exitCode:2};let a=
|
|
3954
|
+
`}function Y0(){return FM(`discover`,async e=>{if(e.includes(`--help`)||e.includes(`-h`)||e.length===0)return{stdout:J0(),stderr:``,exitCode:0};let t=e.includes(`--follow`),n=e.filter(e=>!e.startsWith(`-`));if(n.length!==1)return{stdout:``,stderr:`discover: expected exactly one URL argument
|
|
3955
|
+
`,exitCode:2};let r=n[0],i=DK(),a;try{a=await i(r,{method:`GET`})}catch(e){return{stdout:``,stderr:`discover: fetch failed: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=[];for(let[e,t]of Object.entries(a.headers))e.toLowerCase()===`link`&&typeof t==`string`&&t.length>0&&o.push(t);let s=WK(o,r),c=aq(s),l={url:r,status:a.status,links:s,handoff:c};if(t&&s.length>0){let e=await dq(s,{fetchImpl:q0(i)});l.discovery={catalog:e.catalog,serviceDesc:e.serviceDesc,serviceMeta:e.serviceMeta,status:e.status,llmsTxt:e.llmsTxt,failures:e.failures}}return{stdout:JSON.stringify(l,null,2)+`
|
|
3956
|
+
`,stderr:``,exitCode:0}})}const X0=[`pid`,`ppid`,`kind`,`stat`,`start`,`scoop`,`command`],Z0=[`pid`,`ppid`,`stat`,`start`,`scoop`,`command`],Q0={running:`R`,pending:`S`,exited:`Z`,killed:`K`};function $0(e={}){return FM(`ps`,async t=>{if(t.includes(`--help`)||t.includes(`-h`))return d2();let n=e.processManager??e2();if(!n)return{stdout:``,stderr:`ps: no process manager available in this runtime
|
|
3957
|
+
`,exitCode:1};let r=Z0,i=!1,a=!1;for(let e=0;e<t.length;e++){let n=t[e];if(n===`-a`||n===`-A`||n===`-e`||n===`--all`){a=!0;continue}if(n===`-T`||n===`--tree`){i=!0;continue}if(n===`-o`||n.startsWith(`--columns=`)||n.startsWith(`-o=`)){let i=n.startsWith(`-o=`)?n.slice(3):n.startsWith(`--columns=`)?n.slice(10):t[++e];if(typeof i!=`string`)return{stdout:``,stderr:`ps: -o requires an argument
|
|
3958
|
+
`,exitCode:2};let a=t2(i);if(a instanceof Error)return{stdout:``,stderr:`ps: ${a.message}\n`,exitCode:2};r=a;continue}return{stdout:``,stderr:`ps: unrecognized argument '${n}'\n`,exitCode:2}}let o=n.list().sort((e,t)=>e.pid-t.pid),s=a?o:o.filter(e=>e.status===`running`||e.status===`pending`),c=(i?u2(s):s.map(e=>({proc:e,depth:0}))).map(({proc:e,depth:t})=>i2(e,r,t,i));return{stdout:[n2(r),...c].join(`
|
|
3849
3959
|
`)+`
|
|
3850
|
-
`,stderr:``,exitCode:0}})}function
|
|
3960
|
+
`,stderr:``,exitCode:0}})}function e2(){let e=globalThis.__slicc_pm;return e instanceof Object&&typeof e.list==`function`?e:null}function t2(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean);if(t.length===0)return Error(`-o requires at least one column`);let n=[];for(let e of t){if(!X0.includes(e))return Error(`unknown column '${e}'; supported: ${X0.join(`, `)}`);n.push(e)}return n}function n2(e){return e.map(e=>r2(e)).join(` `)}function r2(e){switch(e){case`pid`:return`PID`.padStart(5);case`ppid`:return`PPID`.padStart(5);case`kind`:return`KIND`.padEnd(10);case`stat`:return`STAT`;case`start`:return`START`;case`scoop`:return`SCOOP`.padEnd(10);case`command`:return`COMMAND`}}function i2(e,t,n,r){return t.map(t=>a2(e,t,n,r)).join(` `)}function a2(e,t,n,r){switch(t){case`pid`:return String(e.pid).padStart(5);case`ppid`:return String(e.ppid).padStart(5);case`kind`:return e.kind.padEnd(10);case`stat`:return Q0[e.status];case`start`:return o2(e.startedAt);case`scoop`:return s2(e).padEnd(10);case`command`:return c2(e,n,r)}}function o2(e){let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}:${String(t.getSeconds()).padStart(2,`0`)}`}function s2(e){return e.owner.kind===`cone`?`cone`:e.owner.kind===`system`?`system`:e.owner.scoopJid?.slice(0,10)??`scoop`}function c2(e,t,n){let r=n&&t>0?` `.repeat(t-1)+`└─ `:``,i=e.argv.length===0?`[${e.kind}]`:e.argv.map(l2).join(` `);return r+(i.length>80?i.slice(0,79)+`…`:i)}function l2(e){return e===``?`''`:/^[A-Za-z0-9_./:=@%+-]+$/.test(e)?e:e.includes(`"`)&&!e.includes(`'`)?`'${e}'`:`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function u2(e){let t=new Map;for(let n of e)t.set(n.pid,n);let n=new Map,r=[];for(let i of e)if(t.has(i.ppid)){let e=n.get(i.ppid)??[];e.push(i),n.set(i.ppid,e)}else r.push(i);let i=[],a=new Set,o=(e,t)=>{if(a.has(e.pid))return;a.add(e.pid),i.push({proc:e,depth:t});let r=n.get(e.pid)??[];for(let e of r.sort((e,t)=>e.pid-t.pid))o(e,t+1)};for(let e of r.sort((e,t)=>e.pid-t.pid))o(e,0);return i}function d2(){return{stdout:`Usage: ps [-a] [-T] [-o col[,col…]]
|
|
3851
3961
|
|
|
3852
3962
|
List processes tracked by the kernel.
|
|
3853
3963
|
|
|
@@ -3877,12 +3987,12 @@ Examples:
|
|
|
3877
3987
|
ps -T live tree
|
|
3878
3988
|
ps -a -T full tree
|
|
3879
3989
|
ps -o pid,kind,stat just three columns
|
|
3880
|
-
`,stderr:``,exitCode:0}}const
|
|
3990
|
+
`,stderr:``,exitCode:0}}const f2=new Set([`SIGINT`,`SIGTERM`,`SIGKILL`,`SIGSTOP`,`SIGCONT`]);function p2(e={}){return FM(`kill`,async t=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return _2();let n=e.processManager??m2();if(!n)return{stdout:``,stderr:`kill: no process manager available in this runtime
|
|
3881
3991
|
`,exitCode:1};let r=`SIGTERM`,i=[];for(let e=0;e<t.length;e++){let n=t[e];if(n===`-s`||n===`--signal`){let n=t[++e];if(!n)return{stdout:``,stderr:`kill: -s requires a signal name
|
|
3882
|
-
`,exitCode:2};let i=
|
|
3883
|
-
`,exitCode:2};if(!
|
|
3992
|
+
`,exitCode:2};let i=h2(n);if(i instanceof Error)return{stdout:``,stderr:`kill: ${i.message}\n`,exitCode:2};r=i;continue}if(n.startsWith(`-`)){let e=g2(n);if(e instanceof Error)return{stdout:``,stderr:`kill: ${e.message}\n`,exitCode:2};r=e;continue}let a=Number.parseInt(n,10);if(!Number.isFinite(a)||String(a)!==n)return{stdout:``,stderr:`kill: invalid pid '${n}'\n`,exitCode:2};i.push(a)}if(i.length===0)return{stdout:``,stderr:`kill: no pids supplied
|
|
3993
|
+
`,exitCode:2};if(!f2.has(r))return{stdout:``,stderr:`kill: signal ${r} not supported\n`,exitCode:2};let a=!0,o=[];for(let e of i)n.signal(e,r)||(a=!1,n.get(e)?o.push(`kill: (${e}) - process already terminated`):o.push(`kill: (${e}) - no such process`));return{stdout:``,stderr:o.length?o.join(`
|
|
3884
3994
|
`)+`
|
|
3885
|
-
`:``,exitCode:+!a}})}function
|
|
3995
|
+
`:``,exitCode:+!a}})}function m2(){let e=globalThis.__slicc_pm;return e instanceof Object&&typeof e.signal==`function`?e:null}function h2(e){let t=e.toUpperCase(),n=t.startsWith(`SIG`)?t:`SIG${t}`;return n===`SIGINT`||n===`SIGTERM`||n===`SIGKILL`||n===`SIGSTOP`||n===`SIGCONT`?n:Error(`unknown signal '${e}'`)}function g2(e){return e===`-9`?`SIGKILL`:h2(e.slice(1))}function _2(){return{stdout:`Usage: kill [-s SIGNAL | -INT | -TERM | -KILL | -STOP | -CONT | -9] PID [PID …]
|
|
3886
3996
|
|
|
3887
3997
|
Send a signal to one or more processes tracked by the kernel.
|
|
3888
3998
|
|
|
@@ -3904,110 +4014,15 @@ Examples:
|
|
|
3904
4014
|
kill -INT 1024 1025 SIGINT both
|
|
3905
4015
|
kill -STOP 1024 pause; \`kill -CONT 1024\` resumes
|
|
3906
4016
|
kill -s SIGKILL 1024 explicit signal name
|
|
3907
|
-
`,stderr:``,exitCode:0}}function
|
|
3908
|
-
`}function M0(e){switch(e){case`native`:return`native`;case`agents`:return`.agents`;case`claude`:return`.claude`}}function N0(e,t){let n=`${t}:\n\n`;n+=` NAME SOURCE DESCRIPTION
|
|
3909
|
-
`,n+=` ─────────────────────────────────────────────────────────────
|
|
3910
|
-
`;for(let t of e){let e=t.description||``;n+=` ${t.name.padEnd(20)} ${M0(t.source).padEnd(9)} ${e}\n`}return n+=`\n${j0()}`,n}function P0(e){let t=`Skill: ${e.name}\n`;if(t+=`Description: ${e.description||`(none)`}\n`,t+=`Source: ${M0(e.source)}\n`,t+=`Source root: ${e.sourceRoot}\n`,e.skillFilePath&&(t+=`Instructions: ${e.skillFilePath}\n`),e.shadowedPaths?.length){t+=`Shadowed paths:
|
|
3911
|
-
`;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function F0(){return{stdout:`usage: upskill <command> [options]
|
|
3912
|
-
|
|
3913
|
-
Install skills from GitHub repositories, ClawHub, or Tessl registry.
|
|
3914
|
-
|
|
3915
|
-
Commands:
|
|
3916
|
-
search <query> Search ClawHub + Tessl for skills
|
|
3917
|
-
list List discoverable local skills
|
|
3918
|
-
info <name> Show details about a discoverable local skill
|
|
3919
|
-
read <name> Read the SKILL.md instructions
|
|
3920
|
-
<owner/repo> Install skill(s) from GitHub repository
|
|
3921
|
-
<clawhub-url> Install skill from ClawHub URL
|
|
3922
|
-
tessl:<name> Install skill from Tessl registry
|
|
3923
|
-
|
|
3924
|
-
${j0()}
|
|
3925
|
-
GitHub Installation:
|
|
3926
|
-
upskill owner/repo List available skills in repo
|
|
3927
|
-
upskill owner/repo --skill name Install specific skill
|
|
3928
|
-
upskill owner/repo --all Install all skills from repo
|
|
3929
|
-
upskill owner/repo --path subdir Restrict to subfolder
|
|
3930
|
-
upskill owner/repo@branch Install from a specific branch
|
|
3931
|
-
upskill owner/repo --branch name Same, using flag syntax
|
|
3932
|
-
|
|
3933
|
-
Recommendations:
|
|
3934
|
-
upskill recommendations Show skills matching your profile
|
|
3935
|
-
upskill recommendations --install Install all recommended skills
|
|
3936
|
-
|
|
3937
|
-
Registry Search:
|
|
3938
|
-
upskill search "pdf conversion" Search all registries
|
|
3939
|
-
upskill https://clawhub.ai/user/skill Install from ClawHub URL
|
|
3940
|
-
upskill clawhub:user/skill Install from ClawHub shorthand
|
|
3941
|
-
upskill tessl:postgres-pro Install from Tessl (via GitHub)
|
|
3942
|
-
|
|
3943
|
-
Options:
|
|
3944
|
-
--skill <name> Install specific skill (repeatable)
|
|
3945
|
-
--all Install all skills from source
|
|
3946
|
-
--path <subfolder> Only discover skills under this subfolder
|
|
3947
|
-
--branch, -b <name> Install from a specific branch (default: main)
|
|
3948
|
-
--list List available skills without installing
|
|
3949
|
-
--force Overwrite existing skills
|
|
3950
|
-
-h, --help Show help
|
|
3951
|
-
|
|
3952
|
-
GitHub rate limits:
|
|
3953
|
-
On shared VPNs or corporate IPs, anonymous GitHub access may be rate-limited.
|
|
3954
|
-
Configure a token to avoid shared-IP limits: git config github.token <PAT>
|
|
3955
|
-
|
|
3956
|
-
Examples:
|
|
3957
|
-
upskill search "browser automation"
|
|
3958
|
-
upskill anthropics/skills --list
|
|
3959
|
-
upskill anthropics/skills --skill pdf --skill xlsx
|
|
3960
|
-
upskill adobe/skills --path skills/aem --all
|
|
3961
|
-
upskill aemcoder/skills@fix/stateless-tab-targeting --all
|
|
3962
|
-
upskill https://clawhub.ai/arun-8687/tavily-search
|
|
3963
|
-
upskill tessl:postgres-pro
|
|
3964
|
-
`,stderr:``,exitCode:0}}async function I0(e,t){let n=await t(`${d0}/search?q=${encodeURIComponent(e)}`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`ClawHub returned HTTP ${n.status}`);let r=hK(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 L0(e){let t=e.match(/github\.com\/([^\/?#]+)\/([^\/?#]+)/);return t?{owner:t[1],repo:t[2].replace(/\.git$/,``)}:null}async function R0(e,t){let n=await t(`${f0}/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=hK(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=L0(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())}async function z0(e,t,n=1){let[r,i]=await Promise.allSettled([I0(e,t),R0(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
|
|
3965
|
-
`),{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/10),f=Math.max(1,Math.min(n,d)),p=(f-1)*10,m=s.slice(p,p+10),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+=`
|
|
3966
|
-
`}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:
|
|
3967
|
-
`,a.length>0&&(h+=` From ClawHub: upskill clawhub:<slug>
|
|
3968
|
-
`),o.length>0&&(h+=` From Tessl: upskill <owner/repo> --skill <name>
|
|
3969
|
-
`),{stdout:h,stderr:``,exitCode:0}}async function B0(e,t,n,r=!1,i){try{let a=`${p0}/${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=`${d0}/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=ZR(o);l||=gK(s.body);let u;try{u=aQ(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(` `);return{stdout:``,stderr:`upskill: failed to unzip: ${t}\nContent-Type: ${c}\nBody: ${l.length} bytes\nHex: ${n}\n`,exitCode:1}}await t.mkdir(a,{recursive:!0});let d=0;for(let[e,n]of Object.entries(u)){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),d++}let f=V0(u,i);return await Y0(),{stdout:`Installed skill "${e}" from ClawHub (${d} files)\n${f}`,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 V0(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=H0(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 H0(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 U0(e,t){let n=await t(`${f0}/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=hK(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=L0(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 W0(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`?W0(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=ZR(i);o||=gK(a.body);try{return{status:`ok`,files:aQ(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function G0(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 K0(e,t,n,r,i,a){if(i){let n=await W0(e,t,i,a);if(n.status===`ok`){let e=G0(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(A0(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=hK(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 q0(e,t,n,r,i,a,o=!1,s,c){try{let l=`${p0}/${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 W0(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=G0(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 $0(),await Z0(),{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: ${A0(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=hK(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(A0(n,`${e}/${t}/${o.path}`,a.hasToken));let s=ZR(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(A0(l,`${e}/${t}/${o.path}`,a.hasToken));let u=hK(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 Y0(),{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 J0(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 Y0(){await $0(),await Z0()}async function X0(e,t,n,r,i=!1){let a=`${p0}/${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 Z0(){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 Q0(e){let t=e.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+?)(?:\/(.+?))?)?\/?$/);if(t)return{owner:t[1],repo:t[2],branch:t[3],path:t[4]};let n=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return n?{owner:n[1],repo:n[2],branch:n[3]}:null}async function $0(){try{let e=globalThis.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}function e2(e){return{purpose:e.purpose??``,role:e.role??``,tasks:Array.isArray(e.tasks)?e.tasks:[],apps:Array.isArray(e.apps)?e.apps:[],name:e.name??``}}async function t2(e,t,n){let r=Date.now(),i=(e,t=[])=>({installedNames:[],errors:t,skipped:e,log:``,elapsedSeconds:(Date.now()-r)/1e3}),a=null;if(n)a=e2(n);else try{let t=await e.readDir(`/home`);for(let n of t)try{let t=await e.readTextFile(`/home/${n.name}/.welcome.json`);a=e2(JSON.parse(t));break}catch{}}catch{}if(!a)return i(`no-profile`);let o,s;try{let[n,r]=await Promise.all([(async()=>{let e=await t(h0,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return v0(hK(e.body).data)})(),S0(e)]);o=n,s=r}catch(e){return i(`catalog-fetch`,[`upskill: failed to fetch skill catalog from ${h0}: ${e instanceof Error?e.message:String(e)}`])}let c=b0(o,a).filter(e=>!s.has(e.entry.name));if(c.length===0)return i(`all-installed`);let l=new Map;for(let e of c){let t=e.entry.source.repo,n=l.get(t);n?n.push(e):l.set(t,[e])}let u=c.length,d=0,f=``,p=[],m=[],h=await Promise.allSettled(Array.from(l.entries()).map(async([n,i])=>{let[a,o]=n.split(`/`),c=await W0(a,o,t);if(c.status===`not_found`||c.status===`error`){let e=c.status===`not_found`?`upskill: repository ${n} not found`:`upskill: failed to fetch ${n}: ${c.message}`,t=[];for(let e of i){d++;let i=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${e.entry.name}" from ${n}: repo fetch failed${i}\n`,t.push({ok:!1,name:e.entry.name,error:`repo fetch failed for ${n}`})}return{errors:[e],results:t}}let l=G0(c.files),p=[],m=new Map;for(let e of Object.keys(l))if(e.endsWith(`/SKILL.md`)){let t=e.replace(/\/SKILL\.md$/,``),n=t.split(`/`).pop()||t;m.set(n,t)}for(let t of i){let i=t.entry.source;if(i.installAll&&i.path){let a=i.path.replace(/^\/|\/$/g,``),o=[];for(let[e,t]of m)(t===a||t.startsWith(a+`/`))&&o.push({name:e,path:t});d++;let c=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;if(o.length===0){let e=`no skills found under "${i.path}" in ${n}`;p.push({ok:!1,name:t.entry.name,error:e}),f+=`[${d}/${u}] Failed "${t.entry.name}" bundle from ${n}: ${e}${c}\n`;continue}let h=Date.now(),g=0,_=0;for(let t of o){if(s.has(t.name))continue;let n=await X0(t.path,t.name,l,e,!1);n.ok?(p.push({ok:!0,name:t.name}),g++):(p.push({ok:!1,name:t.name,error:n.error}),_++)}let v=((Date.now()-h)/1e3).toFixed(1);g===0&&_===0?f+=`[${d}/${u}] Skipped "${t.entry.name}" bundle from ${n}: all sub-skills already installed${c}\n`:_===0?f+=`[${d}/${u}] Installed "${t.entry.name}" bundle (${g} skill(s)) from ${n} (${v}s)${c}\n`:f+=`[${d}/${u}] Installed "${t.entry.name}" bundle (${g}/${g+_} skill(s)) from ${n} (${v}s)${c}\n`;continue}let a,o;if(i.skill){let e=m.get(i.skill);if(e)a=e,o=i.skill;else if(i.path)a=i.path.replace(/^\/|\/$/g,``),o=i.skill;else{let e=`skill "${i.skill}" not found in ${n}`;p.push({ok:!1,name:t.entry.name,error:e}),d++;let a=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${t.entry.name}" from ${n}: ${e}${a}\n`;continue}}else if(i.path)a=i.path.replace(/^\/|\/$/g,``),o=t.entry.name;else{let e=m.get(t.entry.name);if(e)a=e,o=t.entry.name;else{let e=`skill "${t.entry.name}" not found in ${n} and no explicit path provided`;p.push({ok:!1,name:t.entry.name,error:e}),d++;let i=d<u?` (~${Math.round((u-d)*(Date.now()-r)/d/1e3)}s remaining)`:``;f+=`[${d}/${u}] Failed "${t.entry.name}" from ${n}: ${e}${i}\n`;continue}}let c=Date.now(),h=await X0(a,o,l,e,!1);d++;let g=((Date.now()-c)/1e3).toFixed(1),_=(Date.now()-r)/d,v=Math.round((u-d)*_/1e3),y=d<u?` (~${v}s remaining)`:``;h.ok?(p.push({ok:!0,name:o}),f+=`[${d}/${u}] Installed "${o}" from ${n} (${g}s)${y}\n`):(p.push({ok:!1,name:o,error:h.error}),f+=`[${d}/${u}] Failed "${o}" from ${n}: ${h.error}${y}\n`)}return{errors:[],results:p}}));for(let e of h){if(e.status===`rejected`){p.push(`upskill: unexpected error: ${e.reason}`);continue}for(let t of e.value.errors)p.push(t);for(let t of e.value.results)t.ok?m.push(t.name):t.error&&p.push(`upskill: ${t.error}`)}m.length>0&&await Y0();let g=(Date.now()-r)/1e3;return m.length>0&&(f+=`\nInstalled ${m.length} recommended skill(s) in ${g.toFixed(1)}s\n`),{installedNames:m,errors:p,skipped:null,log:f,elapsedSeconds:g}}async function n2(e,t,n){if(n){let n=await t2(e,t);return n.skipped===`no-profile`?{stdout:``,stderr:`upskill: no user profile found. Complete the welcome onboarding first, or create /home/<name>/.welcome.json manually.
|
|
3970
|
-
`,exitCode:1}:n.skipped===`catalog-fetch`?{stdout:``,stderr:n.errors.map(e=>`${e}\n`).join(``),exitCode:1}:n.skipped===`all-installed`?{stdout:`No new skill recommendations — all matching skills are already installed.
|
|
3971
|
-
`,stderr:``,exitCode:0}:{stdout:n.log,stderr:n.errors.map(e=>`${e}\n`).join(``),exitCode:+(n.errors.length>0)}}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.
|
|
3972
|
-
`,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(h0,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return v0(hK(e.body).data)})(),S0(e)]);i=n,a=r}catch(e){return{stdout:``,stderr:`upskill: failed to fetch skill catalog from ${h0}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=b0(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.
|
|
3973
|
-
`,stderr:``,exitCode:0};let s=`Recommended skills for you:
|
|
3974
|
-
|
|
3975
|
-
`,c=0;for(let e of o){c++;let t=x0(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
|
|
3976
|
-
`,{stdout:s,stderr:``,exitCode:0}}function r2(e,t){return FM(`upskill`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return F0();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 n2(e,t,n.includes(`--install`));else if(r===`list`){let t=await(await Promise.resolve().then(()=>E4)).discoverSkills(e);return t.length===0?{stdout:`No discoverable local skills found.\n\n${j0()}`,stderr:``,exitCode:0}:{stdout:N0(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 Promise.resolve().then(()=>E4);if(r===`info`){let n=await i.getSkillInfo(e,t);return n?{stdout:P0(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+`
|
|
3977
|
-
`,stderr:``,exitCode:0}}}else if(r===`--skill`)i.push(n[++p]);else if(r===`--path`||r===`-p`){let e=n[++p];if(typeof e!=`string`||!iq(e))return{stdout:``,stderr:`upskill: --path must be a repo-relative sub-path of [A-Za-z0-9._/-]+ with no "..", leading "-"/"/", or shell metacharacters
|
|
3978
|
-
`,exitCode:1};a=e}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
|
|
3979
|
-
`,exitCode:1};if(!rq(e))return{stdout:``,stderr:`upskill: --branch must be a git ref of [A-Za-z0-9._/-]+ with no "..", leading "-"/"/", trailing "/" or ".lock", or shell metacharacters
|
|
3980
|
-
`,exitCode:1};u=n[++p]}else r.startsWith(`-`)||(l=r);p++}if(d)return z0(d,t,f);if(!l)return F0();let m=J0(l);if(m){let n=r.getRegisteredCommands?.()??[];return B0(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
|
|
3981
|
-
`,exitCode:1};let r=await U0(n,t);if(`error`in r)return{stdout:``,stderr:`upskill: ${r.error}\n`,exitCode:1};let i=await D0(t);return q0(r.owner,r.repo,r.skillPath,r.skillName,e,i,c,t)}let h=Q0(l);if(h){let{owner:n,repo:r}=h,d=u??h.branch,f=a??h.path,p=await D0(t),m=await K0(n,r,p,f,t,d);if(m.error)return{stdout:``,stderr:`upskill: failed to list skills: ${m.error}\n`,exitCode:1};if(m.skills.length===0)return{stdout:`No skills found in ${n}/${r}${f?`/`+f:``}\n`,stderr:``,exitCode:0};if(o){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of m.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${m.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 g=m.skills;if(i.length>0){g=m.skills.filter(e=>i.includes(e.name));for(let e of i)if(!m.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 m.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${m.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 _=``,v=``,y=0,b=g.length,x=Date.now();if(b>1){let i=await W0(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=G0(i.files);for(let t=0;t<g.length;t++){let i=g[t],o=await X0(i.path,i.name,a,e,c),s=t+1,l=((Date.now()-x)/1e3).toFixed(1),u=(Date.now()-x)/s,d=Math.round((b-s)*u/1e3),f=s<b?` (~${d}s remaining)`:``;o.ok?(_+=`[${s}/${b}] Installed "${i.name}" from ${n}/${r} (${l}s)${f}\n`,y++):(_+=`[${s}/${b}] Failed "${i.name}": ${o.error}${f}\n`,v+=`upskill: ${o.error}\n`)}}else for(let i of g){let a=await q0(n,r,i.path,i.name,e,p,c,t,d);a.exitCode===0?(_+=a.stdout,y++):v+=a.stderr}let S=((Date.now()-x)/1e3).toFixed(1);return y>0&&(_+=`\nInstalled ${y} skill(s)${b>1?` in ${S}s`:``}\n`,await Y0()),{stdout:_,stderr:v,exitCode:+!!v}}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 i2(e){return FM(`skill`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return{stdout:`usage: skill <command> [options]
|
|
3982
|
-
|
|
3983
|
-
Commands:
|
|
3984
|
-
list List discoverable skills
|
|
3985
|
-
info <name> Show details about a skill
|
|
3986
|
-
read <name> Read the SKILL.md instructions
|
|
3987
|
-
|
|
3988
|
-
${j0()}
|
|
3989
|
-
For installing skills from registries or GitHub, use 'upskill':
|
|
3990
|
-
upskill search "query" Search ClawHub + Tessl
|
|
3991
|
-
upskill owner/repo --list List skills in GitHub repo
|
|
3992
|
-
upskill owner/repo --all Install from GitHub
|
|
3993
|
-
upskill tessl:<name> Install from Tessl registry
|
|
3994
|
-
|
|
3995
|
-
Examples:
|
|
3996
|
-
skill list
|
|
3997
|
-
skill info bluebubbles
|
|
3998
|
-
skill read bluebubbles
|
|
3999
|
-
`,stderr:``,exitCode:0};let r=t[0],i=await Promise.resolve().then(()=>E4);try{switch(r){case`list`:{let t=await i.discoverSkills(e);return t.length===0?{stdout:`No discoverable skills found.\n\n${j0()}Install skills with: upskill owner/repo --all\n`,stderr:``,exitCode:0}:{stdout:N0(t,`Discoverable skills`),stderr:``,exitCode:0}}case`info`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: info requires a skill name
|
|
4000
|
-
`,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:P0(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
|
|
4001
|
-
`,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+`
|
|
4002
|
-
`,stderr:``,exitCode:0}}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 a2(e){let t={positional:[],noProbe:!1,clearCache:!1,bodies:!1};for(let n=0;n<e.length;n++){let r=e[n];r===`--source`?t.source=e[++n]:r===`--profile`?t.profile=e[++n]:r===`--no-probe`?t.noProbe=!0:r===`--max-body-mb`?t.maxBodyMb=Number(e[++n]):r===`--clear-cache`?t.clearCache=!0:r===`--bodies`?t.bodies=!0:t.positional.push(r)}return t}var o2=class{options;signedFetchS3;signedFetchDa;constructor(e){this.options=e,this.signedFetchS3=e.signedFetchS3,this.signedFetchDa=e.signedFetchDa}async execute(e,t){let n=e[0];if(n===`--help`||n===`-h`)return this.help();if(n===`unmount`||n===`-u`)return this.handleUnmount(e.slice(1),t);if(n===`list`||n===`-l`)return this.handleList();if(n===`refresh`)return this.handleRefresh(e.slice(1),t);let r=a2(e);if(r.positional.length===0)return this.usageError(`mount: mount point required`);let i=this.resolvePath(r.positional[0],t);return r.source?r.source.startsWith(`s3://`)?this.mountS3(i,r):r.source.startsWith(`da://`)?this.mountDa(i,r):this.usageError(`mount: invalid source '${r.source}' — expected s3://... or da://...`):this.mountLocal(i)}async mountLocal(e){try{let t=this.options.isScoop??(()=>!1),n=me();if(!n){let t=await s2(e);if(t)return await this.options.fs.mount(e,t),{stdout:`Mounted '${t.describe().displayName}' → ${e}\nIndexing in background for fast file discovery.\nNote: External changes are not auto-detected — use 'mount refresh ${e}' after modifying files outside the browser.\n`,stderr:``,exitCode:0}}let r=await xe.create({mountId:Ce(),isScoop:t,toolContext:n??void 0,isExtension:typeof chrome<`u`&&!!chrome?.runtime?.id});return await this.options.fs.mount(e,r),{stdout:`Mounted '${r.describe().displayName}' → ${e}\nIndexing in background for fast file discovery.\nNote: External changes are not auto-detected — use 'mount refresh ${e}' after modifying files outside the browser.\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}async mountS3(e,t){if(!t.source)return this.usageError(`mount: --source required`);let n=t.profile??`default`,r=Ce(),i=new nt({mountId:r,ttlMs:3e4}),a=new Qe({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchS3??tt(n)});if(!t.noProbe)try{await a.readDir(`/`)}catch(e){return await a.close(),{stdout:``,stderr:`mount: probe failed for ${t.source} — ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return await this.options.fs.mount(e,a),{stdout:`Mounted '${a.describe().displayName}' → ${e} (profile: ${n})\n`,stderr:``,exitCode:0}}async mountDa(e,t){if(!t.source)return this.usageError(`mount: --source required`);let n=t.profile??`default`,r=Ce(),i=new nt({mountId:r,ttlMs:3e4}),a=new $e({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchDa??et()});if(!t.noProbe)try{await a.readDir(`/`)}catch(e){return await a.close(),{stdout:``,stderr:`mount: probe failed for ${t.source} — ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return await this.options.fs.mount(e,a),{stdout:`Mounted '${a.describe().displayName}' → ${e} (profile: ${n})\n`,stderr:``,exitCode:0}}async handleUnmount(e,t){let n=a2(e);if(n.positional.length===0)return{stdout:``,stderr:`mount unmount: path required
|
|
4017
|
+
`,stderr:``,exitCode:0}}function v2(e={}){let t=[PX({getJshCommands:e.getJshCommands}),GX(),o$(e.browserAPI,e.fs),iQ(),JX(e),L1(),h$(),c$(`sqlite3`),c$(`sqllite`),eQ(),gQ(`python3`),gQ(`python`),QQ(),v$(),D$(),P$(),L$(),q$(),pQ(`pdftk`),pQ(`pdf`),LX(`convert`),LX(`magick`),P1({fs:e.fs,scriptCatalog:e.scriptCatalog}),u$(),p$(),Y$(),m1(),n1(),f1(),k1({fs:e.fs}),H1(),Z1(),Q1(),$1(`xclip`),$1(`xsel`),i0(),l0(),u0(),w0(e.fs),P0(),I0(),K0({getParentJid:e.getParentJid}),Y0(),$0({processManager:e.processManager}),p2({processManager:e.processManager})];return e.fs&&t.push(...PY.map(t=>jX(t,e.browserAPI,e.fs))),t}function y2(e){let t={positional:[],noProbe:!1,clearCache:!1,bodies:!1};for(let n=0;n<e.length;n++){let r=e[n];r===`--source`?t.source=e[++n]:r===`--profile`?t.profile=e[++n]:r===`--no-probe`?t.noProbe=!0:r===`--max-body-mb`?t.maxBodyMb=Number(e[++n]):r===`--clear-cache`?t.clearCache=!0:r===`--bodies`?t.bodies=!0:t.positional.push(r)}return t}var b2=class{options;signedFetchS3;signedFetchDa;constructor(e){this.options=e,this.signedFetchS3=e.signedFetchS3,this.signedFetchDa=e.signedFetchDa}async execute(e,t){let n=e[0];if(n===`--help`||n===`-h`)return this.help();if(n===`unmount`||n===`-u`)return this.handleUnmount(e.slice(1),t);if(n===`list`||n===`-l`)return this.handleList();if(n===`refresh`)return this.handleRefresh(e.slice(1),t);let r=y2(e);if(r.positional.length===0)return this.usageError(`mount: mount point required`);let i=this.resolvePath(r.positional[0],t);return r.source?r.source.startsWith(`s3://`)?this.mountS3(i,r):r.source.startsWith(`da://`)?this.mountDa(i,r):this.usageError(`mount: invalid source '${r.source}' — expected s3://... or da://...`):this.mountLocal(i)}async mountLocal(e){try{let t=this.options.isScoop??(()=>!1),n=me();if(!n){let t=await x2(e);if(t)return await this.options.fs.mount(e,t),{stdout:`Mounted '${t.describe().displayName}' → ${e}\nIndexing in background for fast file discovery.\nNote: External changes are not auto-detected — use 'mount refresh ${e}' after modifying files outside the browser.\n`,stderr:``,exitCode:0}}let r=await xe.create({mountId:Ce(),isScoop:t,toolContext:n??void 0,isExtension:typeof chrome<`u`&&!!chrome?.runtime?.id});return await this.options.fs.mount(e,r),{stdout:`Mounted '${r.describe().displayName}' → ${e}\nIndexing in background for fast file discovery.\nNote: External changes are not auto-detected — use 'mount refresh ${e}' after modifying files outside the browser.\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}async mountS3(e,t){if(!t.source)return this.usageError(`mount: --source required`);let n=t.profile??`default`,r=Ce(),i=new nt({mountId:r,ttlMs:3e4}),a=new Qe({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchS3??tt(n)});if(!t.noProbe)try{await a.readDir(`/`)}catch(e){return await a.close(),{stdout:``,stderr:`mount: probe failed for ${t.source} — ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return await this.options.fs.mount(e,a),{stdout:`Mounted '${a.describe().displayName}' → ${e} (profile: ${n})\n`,stderr:``,exitCode:0}}async mountDa(e,t){if(!t.source)return this.usageError(`mount: --source required`);let n=t.profile??`default`,r=Ce(),i=new nt({mountId:r,ttlMs:3e4}),a=new $e({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchDa??et()});if(!t.noProbe)try{await a.readDir(`/`)}catch(e){return await a.close(),{stdout:``,stderr:`mount: probe failed for ${t.source} — ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}return await this.options.fs.mount(e,a),{stdout:`Mounted '${a.describe().displayName}' → ${e} (profile: ${n})\n`,stderr:``,exitCode:0}}async handleUnmount(e,t){let n=y2(e);if(n.positional.length===0)return{stdout:``,stderr:`mount unmount: path required
|
|
4003
4018
|
`,exitCode:1};let r=this.resolvePath(n.positional[0],t);try{let e,t;if(n.clearCache){let{getAllMountEntries:n}=await import(`./mount-table-store-BDnU4NqG.js`).then(e=>e.r),i=(await n()).find(e=>e.targetPath===r);i&&(i.descriptor.kind===`s3`||i.descriptor.kind===`da`)&&(e=i.descriptor.mountId,t=i.descriptor.kind)}await this.options.fs.unmount(r);let i=``;if(n.clearCache&&e&&t){let{RemoteMountCache:t}=await import(`./remote-cache-Cd8CL8Mo.js`).then(e=>e.n);await new t({mountId:e,ttlMs:3e4}).clearMount(),i=` (cache cleared)`}else n.clearCache&&(i=` (no remote cache to clear)`);return{stdout:`Unmounted ${r}${i}\n`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount unmount: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}async handleList(){try{let e=this.options.fs.listMounts();if(e.length===0)return{stdout:`No active mounts
|
|
4004
4019
|
`,stderr:``,exitCode:0};let t=this.options.fs.getMountIndex();return{stdout:e.map(e=>{let n=t.getState(e);return n?n.status===`ready`?`${e} (indexed: ${n.indexed} entries)`:n.status===`indexing`?`${e} (indexing: ${n.indexed} entries...)`:n.status===`error`?`${e} (index error: ${n.error})`:`${e} (pending index)`:e}).join(`
|
|
4005
4020
|
`)+`
|
|
4006
|
-
`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount list: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}async handleRefresh(e,t){let n=
|
|
4021
|
+
`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`mount list: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}async handleRefresh(e,t){let n=y2(e);if(n.positional.length===0)return{stdout:``,stderr:`mount refresh: path required
|
|
4007
4022
|
`,exitCode:1};let r=this.resolvePath(n.positional[0],t);try{let e=await this.options.fs.refreshMount(r,{bodies:n.bodies});return{stdout:`Refreshed ${r}: +${e.added.length} -${e.removed.length} ~${e.changed.length} (${e.unchanged} unchanged, ${e.errors.length} errors)\n`,stderr:e.errors.map(e=>` ${e.path}: ${e.message}\n`).join(``),exitCode:+(e.errors.length>0)}}catch(e){return{stdout:``,stderr:`mount refresh: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}}resolvePath(e,t){let n;return n=e.startsWith(`/`)?e:`${t.replace(/\/$/,``)}/${e}`,n.length>1&&(n=n.replace(/\/+$/,``)),n}usageError(e){return{stdout:``,stderr:`${e}\n`,exitCode:1}}help(){return{stdout:[`Usage: mount [OPTIONS] <target-path>`,` mount unmount [--clear-cache] <path>`,` mount list`,` mount refresh [--bodies] <path>`,``,`Mount a local directory, S3 bucket, or DA repository into the virtual filesystem.`,``,`Without --source, opens a directory picker (local mount). With --source, mounts`,`a remote source (S3-compatible or da.live).`,``,`Options:`,` --source <url> Remote source: s3://bucket[/prefix] or da://org/repo`,` --profile <name> Profile name (default: "default")`,` --no-probe Skip the root-level probe on mount`,` --max-body-mb <n> Override body size limit (MB)`,``,`Sub-commands:`,` unmount [--clear-cache] <path> Remove a mount point`,` list Show active mount points`,` refresh [--bodies] <path> Re-index or revalidate a mount`,``,`Examples:`,` mount /mnt/myapp`,` mount --source s3://my-bucket --profile default /mnt/s3`,` mount --source da://my-org/my-repo /mnt/da`,` mount list`,` mount refresh /mnt/myapp`,` mount unmount /mnt/myapp`].join(`
|
|
4008
4023
|
`)+`
|
|
4009
|
-
`,stderr:``,exitCode:0}}};async function
|
|
4010
|
-
`).slice(0,10),n=[];for(let e of t){let t=e.match(/^\s*\/\/\s*@match\s+(.+)$/);t&&n.push(t[1].trim())}return n}function m2(e,t){if(t.startsWith(`*.`)){let n=t.slice(1);return e===t.slice(2)||e.endsWith(n)&&e.length>n.length}return e===t}function h2(e,t){try{let n=new URL(e),r=t.match(/^(\*|https?):\/\/([^/]+)(\/.*)?$/);if(!r)return!1;let[,i,a,o]=r;return i!==`*`&&n.protocol.slice(0,-1)!==i||!m2(n.hostname,a)?!1:o?g2(n.pathname+n.search,o):!0}catch{return!1}}function g2(e,t){let n=`^`+t.replace(/[.+^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`.*`)+`$`;return new RegExp(n).test(e)}function _2(e,t){try{let n=new URL(t);return e.filter(e=>m2(n.hostname,e.hostnamePattern)?e.matchPatterns.length>0?e.matchPatterns.some(e=>h2(t,e)):!0:!1)}catch{return[]}}var v2=n({ScriptCatalog:()=>T2});const y2=[`/workspace`,`/shared`];function b2(e){return new Map(e)}function x2(e){return e.map(e=>({...e,matchPatterns:[...e.matchPatterns]}))}function S2(e){if(e&&typeof e.listMounts==`function`)return e;if(e&&typeof e.getUnderlyingFS==`function`){let t=e.getUnderlyingFS?.();if(t&&typeof t.listMounts==`function`)return t}return null}function C2(e){return(S2(e)?.listMounts?.().length??0)>0}function w2(e){return e?(S2(e)?.listMounts?.()??[]).some(e=>y2.some(t=>e===t||e.startsWith(t+`/`))):!1}var T2=class{jshFs;bshFs;watcher;watcherUnsubs=[];jshCache=null;jshInflight=null;bshCache=null;bshInflight=null;jshGeneration=0;bshGeneration=0;constructor(e){if(this.jshFs=e.jshFs,this.bshFs=e.bshFs,this.watcher=e.watcher??null,this.watcher&&(this.watcherUnsubs.push(this.watcher.watch(`/`,()=>!0,()=>this.invalidateJsh())),this.bshFs))for(let e of y2)this.watcherUnsubs.push(this.watcher.watch(e,()=>!0,()=>this.invalidateBsh()))}dispose(){for(let e of this.watcherUnsubs)e();this.watcherUnsubs.length=0,this.invalidateAll()}invalidateAll(){this.invalidateJsh(),this.invalidateBsh()}invalidateJsh(){this.jshGeneration++,this.jshCache=null,this.jshInflight=null}invalidateBsh(){this.bshGeneration++,this.bshCache=null,this.bshInflight=null}async getJshCommands(){return b2(await this.loadJshCommands())}async getJshCommandNames(){return[...(await this.getJshCommands()).keys()]}async getBshEntries(){return this.bshFs?x2(await this.loadBshEntries()):[]}async findMatchingBshScripts(e){return this.bshFs?x2(_2(await this.loadBshEntries(),e)):[]}shouldCacheJsh(){return!!this.watcher&&!C2(this.jshFs)}shouldCacheBsh(){return!!this.watcher&&!!this.bshFs&&!w2(this.bshFs)}async loadJshCommands(){let e=this.shouldCacheJsh();if(e&&this.jshCache)return this.jshCache;if(!this.jshInflight){let t=this.jshGeneration,n=C$(this.jshFs).then(n=>{let r=b2(n);return e&&this.jshGeneration===t&&(this.jshCache=r),r}).finally(()=>{this.jshInflight===n&&(this.jshInflight=null)});this.jshInflight=n}return this.jshInflight}async loadBshEntries(){if(!this.bshFs)return[];let e=this.shouldCacheBsh();if(e&&this.bshCache)return this.bshCache;if(!this.bshInflight){let t=this.bshGeneration,n=u2(this.bshFs).then(n=>{let r=x2(n);return e&&this.bshGeneration===t&&(this.bshCache=r),r}).finally(()=>{this.bshInflight===n&&(this.bshInflight=null)});this.bshInflight=n}return this.bshInflight}};function E2(e){return e&&typeof e.getWatcher==`function`?e.getWatcher?.()??null:e&&typeof e.getUnderlyingFS==`function`?E2(e.getUnderlyingFS?.()):null}var D2=class{options;bash;vfsAdapter;gitCommands;mountCommands;lastEnv;cwd;builtinCommandNames;allowedCommands;scriptCatalog;ownsScriptCatalog;registeredJshCommands=new Map;jshSyncInflight=null;jshSyncDirty=!1;constructor(e){this.options=e,this.vfsAdapter=new $R(e.fs),this.allowedCommands=e.allowedCommands&&!e.allowedCommands.includes(`*`)?new Set(e.allowedCommands):null;let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new BK({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new o2({fs:e.fs,isScoop:e.isScoop});let r=e.jshDiscoveryFs??e.fs,i=e.bshDiscoveryFs??e.fs,a=E2(r)??E2(i);this.scriptCatalog=e.scriptCatalog??new T2({jshFs:r,bshFs:i,watcher:a}),this.ownsScriptCatalog=!e.scriptCatalog,a&&a.watch(`/`,e=>e.endsWith(`.jsh`),()=>{this.syncJshCommands().catch(()=>void 0)});let o=this.createGitCustomCommand(),s=u0({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,scriptCatalog:this.scriptCatalog,browserAPI:e.browserAPI,getParentJid:e.getParentJid,processManager:e.processManager}),c=this.createMountCustomCommand(),l=DK(),u=[o,c,i2(e.fs),r2(e.fs,l),...s].filter(e=>this.isCommandAllowed(e.name)),d=[...OM(),...kM()],f=this.allowedCommands?d.filter(e=>this.isCommandAllowed(e)):void 0;if(this.bash=new HR({fs:this.vfsAdapter,cwd:t,env:n,fetch:l,commands:f,customCommands:u}),this.allowedCommands!==null){let e=this.bash;for(let t of kM())this.isCommandAllowed(t)||e.commands.delete(t)}let p=u.map(e=>e.name),m=f??[...OM(),...kM()];this.builtinCommandNames=new Set([...m,...p]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t,this.syncJshCommands().catch(()=>void 0)}getBash(){return this.bash}getCwd(){return this.cwd}getScriptCatalog(){return this.scriptCatalog}getEnv(){return{...this.lastEnv}}async getJshCommandNames(){return[...(await this.getFilteredJshCommands()).keys()]}async syncJshCommands(){return this.jshSyncInflight?(this.jshSyncDirty=!0,this.jshSyncInflight):(this.jshSyncInflight=this.doSyncJshCommands(),this.jshSyncInflight)}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 EY(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})},this.buildJshProcessConfig())}dispose(){this.ownsScriptCatalog&&this.scriptCatalog.dispose()}async renderMediaPreview(e){throw Error(`terminal preview is unavailable in headless mode`)}async runCommand(e,t){ae(e.trim().split(/\s+/)[0]||`unknown`);let n={env:this.lastEnv,cwd:this.cwd,signal:t},r=await this.bash.exec(e,n);if(r.env&&(this.lastEnv={...r.env}),r.env?.PWD&&(this.cwd=r.env.PWD),r.exitCode===127){let t=await this.tryJshFallback(e);if(t)return this.syncJshCommands().catch(()=>void 0),t}return r}isCommandAllowed(e){return this.allowedCommands===null||this.allowedCommands.has(e)}async doSyncJshCommands(){try{let e=await this.scriptCatalog.getJshCommands(),t=this.options.jshDiscoveryFs??this.options.fs;for(let[n,r]of e){if(!this.isCommandAllowed(n)||this.builtinCommandNames.has(n)&&!this.registeredJshCommands.has(n)||this.registeredJshCommands.get(n)===r)continue;let e=this.scriptCatalog,i=this,a=n,o={name:n,async execute(n,r){let o=(await e.getJshCommands()).get(a);if(!o)return{stdout:``,stderr:`jsh: command '${a}' no longer exists\n`,exitCode:127};let s;try{let e=await t.readFile(o,{encoding:`utf-8`});s=typeof e==`string`?e:new TextDecoder().decode(e)}catch{return{stdout:``,stderr:`jsh: cannot read script '${o}'\n`,exitCode:127}}let c=[`node`,o,...n],l=r.exec??((e,t)=>i.bash.exec(e,{env:Object.fromEntries(r.env),cwd:t?.cwd??r.cwd}));return DY(s,c,{fs:r.fs,cwd:r.cwd,env:r.env,stdin:r.stdin,exec:l},i.buildJshProcessConfig())}};this.bash.registerCommand(o),this.registeredJshCommands.set(n,r),this.builtinCommandNames.add(n)}}finally{this.jshSyncInflight=null,this.jshSyncDirty&&(this.jshSyncDirty=!1,this.syncJshCommands().catch(()=>void 0))}}createGitCustomCommand(){let e=this.gitCommands;return FM(`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 FM(`mount`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}async getFilteredJshCommands(){let e=await this.scriptCatalog.getJshCommands(),t=new Map;for(let[n,r]of e)this.builtinCommandNames.has(n)||this.isCommandAllowed(n)&&t.set(n,r);return t}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?c2(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 DY(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})},this.buildJshProcessConfig());return{stdout:u.stdout,stderr:u.stderr,exitCode:u.exitCode,env:this.lastEnv}}buildJshProcessConfig(){if(!(!this.options.processManager||!this.options.processOwner))return{processManager:this.options.processManager,owner:this.options.processOwner,getParentPid:this.options.getCurrentShellPid}}};function O2(e){let t=e.length>1&&e.endsWith(`/`)?e.slice(0,-1):e,n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}var k2=class extends D2{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=``;constructor(e){super(e)}async runCommand(e,t){return super.runCommand(e,t??this.execAbort?.signal)}async mount(e){let t=e??this.options.container;if(!t)throw Error(`No container element provided`);let{Terminal:n}=await import(`./xterm-CguO-Jtb.js`),{FitAddon:r}=await import(`./addon-fit-CBYO9uVb.js`);await Promise.resolve({ });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
|
|
4024
|
+
`,stderr:``,exitCode:0}}};async function x2(e){let t=`pendingMount:term:${e}`,n;try{n=await ye(t)}catch{return null}if(!n)return null;try{await be(n)}catch{return null}return xe.fromHandle(n,{mountId:Ce()})}function S2(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}const C2=[`/workspace`,`/shared`];async function w2(e){let t=[],n=new Set;for(let r of C2)await e.exists(r)&&await T2(e,r,t,n);return t}async function T2(e,t,n,r){for await(let i of e.walk(t)){if(!i.endsWith(`.bsh`)||r.has(i))continue;r.add(i);let t=E2(i);if(!t)continue;let a=await e.readFile(i,{encoding:`utf-8`}),o=D2(typeof a==`string`?a:new TextDecoder().decode(a));n.push({path:i,hostnamePattern:t,matchPatterns:o})}}function E2(e){let t=e.split(`/`).pop()??``;if(!t.endsWith(`.bsh`))return null;let n=t.slice(0,-4);return n?n.startsWith(`-.`)?`*`+n.slice(1):n:null}function D2(e){let t=e.split(`
|
|
4025
|
+
`).slice(0,10),n=[];for(let e of t){let t=e.match(/^\s*\/\/\s*@match\s+(.+)$/);t&&n.push(t[1].trim())}return n}function O2(e,t){if(t.startsWith(`*.`)){let n=t.slice(1);return e===t.slice(2)||e.endsWith(n)&&e.length>n.length}return e===t}function k2(e,t){try{let n=new URL(e),r=t.match(/^(\*|https?):\/\/([^/]+)(\/.*)?$/);if(!r)return!1;let[,i,a,o]=r;return i!==`*`&&n.protocol.slice(0,-1)!==i||!O2(n.hostname,a)?!1:o?A2(n.pathname+n.search,o):!0}catch{return!1}}function A2(e,t){let n=`^`+t.replace(/[.+^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`.*`)+`$`;return new RegExp(n).test(e)}function j2(e,t){try{let n=new URL(t);return e.filter(e=>O2(n.hostname,e.hostnamePattern)?e.matchPatterns.length>0?e.matchPatterns.some(e=>k2(t,e)):!0:!1)}catch{return[]}}var M2=n({ScriptCatalog:()=>z2});const N2=[`/workspace`,`/shared`];function P2(e){return new Map(e)}function F2(e){return e.map(e=>({...e,matchPatterns:[...e.matchPatterns]}))}function I2(e){if(e&&typeof e.listMounts==`function`)return e;if(e&&typeof e.getUnderlyingFS==`function`){let t=e.getUnderlyingFS?.();if(t&&typeof t.listMounts==`function`)return t}return null}function L2(e){return(I2(e)?.listMounts?.().length??0)>0}function R2(e){return e?(I2(e)?.listMounts?.()??[]).some(e=>N2.some(t=>e===t||e.startsWith(t+`/`))):!1}var z2=class{jshFs;bshFs;watcher;watcherUnsubs=[];jshCache=null;jshInflight=null;bshCache=null;bshInflight=null;jshGeneration=0;bshGeneration=0;constructor(e){if(this.jshFs=e.jshFs,this.bshFs=e.bshFs,this.watcher=e.watcher??null,this.watcher&&(this.watcherUnsubs.push(this.watcher.watch(`/`,()=>!0,()=>this.invalidateJsh())),this.bshFs))for(let e of N2)this.watcherUnsubs.push(this.watcher.watch(e,()=>!0,()=>this.invalidateBsh()))}dispose(){for(let e of this.watcherUnsubs)e();this.watcherUnsubs.length=0,this.invalidateAll()}invalidateAll(){this.invalidateJsh(),this.invalidateBsh()}invalidateJsh(){this.jshGeneration++,this.jshCache=null,this.jshInflight=null}invalidateBsh(){this.bshGeneration++,this.bshCache=null,this.bshInflight=null}async getJshCommands(){return P2(await this.loadJshCommands())}async getJshCommandNames(){return[...(await this.getJshCommands()).keys()]}async getBshEntries(){return this.bshFs?F2(await this.loadBshEntries()):[]}async findMatchingBshScripts(e){return this.bshFs?F2(j2(await this.loadBshEntries(),e)):[]}shouldCacheJsh(){return!!this.watcher&&!L2(this.jshFs)}shouldCacheBsh(){return!!this.watcher&&!!this.bshFs&&!R2(this.bshFs)}async loadJshCommands(){let e=this.shouldCacheJsh();if(e&&this.jshCache)return this.jshCache;if(!this.jshInflight){let t=this.jshGeneration,n=j1(this.jshFs).then(n=>{let r=P2(n);return e&&this.jshGeneration===t&&(this.jshCache=r),r}).finally(()=>{this.jshInflight===n&&(this.jshInflight=null)});this.jshInflight=n}return this.jshInflight}async loadBshEntries(){if(!this.bshFs)return[];let e=this.shouldCacheBsh();if(e&&this.bshCache)return this.bshCache;if(!this.bshInflight){let t=this.bshGeneration,n=w2(this.bshFs).then(n=>{let r=F2(n);return e&&this.bshGeneration===t&&(this.bshCache=r),r}).finally(()=>{this.bshInflight===n&&(this.bshInflight=null)});this.bshInflight=n}return this.bshInflight}};function B2(e){return e&&typeof e.getWatcher==`function`?e.getWatcher?.()??null:e&&typeof e.getUnderlyingFS==`function`?B2(e.getUnderlyingFS?.()):null}var V2=class{options;bash;vfsAdapter;gitCommands;mountCommands;lastEnv;cwd;builtinCommandNames;allowedCommands;scriptCatalog;ownsScriptCatalog;registeredJshCommands=new Map;jshSyncInflight=null;jshSyncDirty=!1;constructor(e){this.options=e,this.vfsAdapter=new $R(e.fs),this.allowedCommands=e.allowedCommands&&!e.allowedCommands.includes(`*`)?new Set(e.allowedCommands):null;let t=e.cwd??`/`,n={HOME:`/`,PATH:`/usr/bin`,USER:`user`,SHELL:`/bin/bash`,PWD:t,...e.env};this.gitCommands=new BK({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new b2({fs:e.fs,isScoop:e.isScoop});let r=e.jshDiscoveryFs??e.fs,i=e.bshDiscoveryFs??e.fs,a=B2(r)??B2(i);this.scriptCatalog=e.scriptCatalog??new z2({jshFs:r,bshFs:i,watcher:a}),this.ownsScriptCatalog=!e.scriptCatalog,a&&a.watch(`/`,e=>e.endsWith(`.jsh`),()=>{this.syncJshCommands().catch(()=>void 0)});let o=this.createGitCustomCommand(),s=v2({onMediaPreview:async e=>this.renderMediaPreview(e),getJshCommands:()=>this.getJshCommandNames(),fs:e.fs,scriptCatalog:this.scriptCatalog,browserAPI:e.browserAPI,getParentJid:e.getParentJid,processManager:e.processManager}),c=this.createMountCustomCommand(),l=DK(),u=[o,c,jY(e.fs),AY(e.fs,l,e.browserAPI),...s].filter(e=>this.isCommandAllowed(e.name)),d=[...OM(),...kM()],f=this.allowedCommands?d.filter(e=>this.isCommandAllowed(e)):void 0;if(this.bash=new HR({fs:this.vfsAdapter,cwd:t,env:n,fetch:l,commands:f,customCommands:u}),this.allowedCommands!==null){let e=this.bash;for(let t of kM())this.isCommandAllowed(t)||e.commands.delete(t)}let p=u.map(e=>e.name),m=f??[...OM(),...kM()];this.builtinCommandNames=new Set([...m,...p]),this.vfsAdapter.setRegisteredCommandsFn(()=>[...this.builtinCommandNames]),this.lastEnv={...n},this.cwd=t,this.syncJshCommands().catch(()=>void 0)}getBash(){return this.bash}getCwd(){return this.cwd}getScriptCatalog(){return this.scriptCatalog}getEnv(){return{...this.lastEnv}}async getJshCommandNames(){return[...(await this.getFilteredJshCommands()).keys()]}async syncJshCommands(){return this.jshSyncInflight?(this.jshSyncDirty=!0,this.jshSyncInflight):(this.jshSyncInflight=this.doSyncJshCommands(),this.jshSyncInflight)}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 KZ(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})},this.buildJshProcessConfig())}dispose(){this.ownsScriptCatalog&&this.scriptCatalog.dispose()}async renderMediaPreview(e){throw Error(`terminal preview is unavailable in headless mode`)}async runCommand(e,t){ae(e.trim().split(/\s+/)[0]||`unknown`);let n={env:this.lastEnv,cwd:this.cwd,signal:t},r=await this.bash.exec(e,n);if(r.env&&(this.lastEnv={...r.env}),r.env?.PWD&&(this.cwd=r.env.PWD),r.exitCode===127){let t=await this.tryJshFallback(e);if(t)return this.syncJshCommands().catch(()=>void 0),t}return r}isCommandAllowed(e){return this.allowedCommands===null||this.allowedCommands.has(e)}async doSyncJshCommands(){try{let e=await this.scriptCatalog.getJshCommands(),t=this.options.jshDiscoveryFs??this.options.fs;for(let[n,r]of e){if(!this.isCommandAllowed(n)||this.builtinCommandNames.has(n)&&!this.registeredJshCommands.has(n)||this.registeredJshCommands.get(n)===r)continue;let e=this.scriptCatalog,i=this,a=n,o={name:n,async execute(n,r){let o=(await e.getJshCommands()).get(a);if(!o)return{stdout:``,stderr:`jsh: command '${a}' no longer exists\n`,exitCode:127};let s;try{let e=await t.readFile(o,{encoding:`utf-8`});s=typeof e==`string`?e:new TextDecoder().decode(e)}catch{return{stdout:``,stderr:`jsh: cannot read script '${o}'\n`,exitCode:127}}let c=[`node`,o,...n],l=r.exec??((e,t)=>i.bash.exec(e,{env:Object.fromEntries(r.env),cwd:t?.cwd??r.cwd}));return qZ(s,c,{fs:r.fs,cwd:r.cwd,env:r.env,stdin:r.stdin,exec:l},i.buildJshProcessConfig())}};this.bash.registerCommand(o),this.registeredJshCommands.set(n,r),this.builtinCommandNames.add(n)}}finally{this.jshSyncInflight=null,this.jshSyncDirty&&(this.jshSyncDirty=!1,this.syncJshCommands().catch(()=>void 0))}}createGitCustomCommand(){let e=this.gitCommands;return FM(`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 FM(`mount`,async(t,n)=>{let r=n.cwd,i=await e.execute(t,r);return{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode}})}async getFilteredJshCommands(){let e=await this.scriptCatalog.getJshCommands(),t=new Map;for(let[n,r]of e)this.builtinCommandNames.has(n)||this.isCommandAllowed(n)&&t.set(n,r);return t}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?S2(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 qZ(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})},this.buildJshProcessConfig());return{stdout:u.stdout,stderr:u.stderr,exitCode:u.exitCode,env:this.lastEnv}}buildJshProcessConfig(){if(!(!this.options.processManager||!this.options.processOwner))return{processManager:this.options.processManager,owner:this.options.processOwner,getParentPid:this.options.getCurrentShellPid}}};function H2(e){let t=e.length>1&&e.endsWith(`/`)?e.slice(0,-1):e,n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}var U2=class extends V2{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=``;constructor(e){super(e)}async runCommand(e,t){return super.runCommand(e,t??this.execAbort?.signal)}async mount(e){let t=e??this.options.container;if(!t)throw Error(`No container element provided`);let{Terminal:n}=await import(`./xterm-CguO-Jtb.js`),{FitAddon:r}=await import(`./addon-fit-CBYO9uVb.js`);await Promise.resolve({ });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
|
|
4011
4026
|
`),this.showPrompt(),this.setupInputHandler()}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
|
|
4012
4027
|
`,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,super.dispose()}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(`
|
|
4013
4028
|
`).entries()){if(e+n.length>=this.cursorPos)return t;e+=n.length+1}return 0}positionTerminalCursor(){let e=this.currentLine.split(`
|
|
@@ -4022,9 +4037,9 @@ Examples:
|
|
|
4022
4037
|
`,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(`
|
|
4023
4038
|
`).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(`
|
|
4024
4039
|
`);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+`
|
|
4025
|
-
`+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=`${
|
|
4040
|
+
`+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=`${H2(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=H2(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())}};const W2=i(`tool:fs`);function G2(e){return[K2(e),q2(e),J2(e)]}function K2(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;W2.debug(`Read`,{path:n,offset:r,limit:i});try{let t=(await e.readTextFile(n)).split(`
|
|
4026
4041
|
`),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(`
|
|
4027
|
-
`)}}catch(e){let t=e instanceof Error?e.message:String(e);return
|
|
4042
|
+
`)}}catch(e){let t=e instanceof Error?e.message:String(e);return W2.error(`Read failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function q2(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;W2.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 W2.error(`Write failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function J2(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;W2.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 W2.error(`Edit failed`,{path:n,error:t}),{content:t,isError:!0}}}}}const Y2=i(`tool:bash`),X2=/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)*(?:command\s+)?(?:grep|egrep|fgrep|rg)\b/;function Z2(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 Q2(e,t,n){return t!==1||n.trim()?!1:X2.test(Z2(e))}function $2(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;Y2.debug(`Execute`,{command:r});try{let t=await e.executeCommand(r,n);Y2.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&&!Q2(r,t.exitCode,t.stderr)}}catch(e){let t=e instanceof Error?e.message:String(e);return Y2.error(`Error`,{command:r,error:t}),{content:`Shell error: ${t}`,isError:!0}}}}}i(`tool:search`);var e4="# 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- Mechanism: RFC 8288 `Link` response header carrying `https://www.sliccy.ai/rel/handoff` or `https://www.sliccy.ai/rel/upskill` on a main-frame document response → `navigate` lick → cone approval card.\n- Agent-facing flow: `packages/vfs-root/workspace/skills/handoff/SKILL.md` (bundled to `/workspace/skills/handoff/SKILL.md`) and the trigger line in `shared/CLAUDE.md` (bundled to `/shared/CLAUDE.md`).\n- Protocol reference: `docs/slicc-handoff.md`.\n- When handoff behavior changes, keep the skill, `shared/CLAUDE.md`, and `docs/slicc-handoff.md` aligned — do not duplicate their content here.\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",t4='# sliccy\n\nPersonal assistant running in the browser inside SLICC — a browser-native AI agent runtime. You code, automate, browse, and orchestrate parallel agents.\n\n## Vocabulary\n\n- **Cone**: You. Orchestrates scoops, talks to the human, full filesystem access.\n- **Scoops**: Isolated sub-agents (`scoop_scoop`, `feed_scoop`, `drop_scoop`, or `agent` one-shot).\n- **Sprinkles**: Persistent UI panels (`.shtml`); owned by a long-lived scoop.\n- **Dips**: Inline `shtml` widgets in chat — ephemeral, lick-only.\n- **Licks**: Events routed to scoops (see Licks below).\n- **Trays**: Remote runtimes. `host` lists; `--runtime=<id>` targets.\n\n## Explore first\n\nYou have 100+ shell commands. When unsure if something is possible:\n\n1. `commands` — full list\n2. `<cmd> --help` — usage\n3. `man <topic>` — deep docs (e.g., `man delegation`, `man sprinkle`)\n4. `skill list` — installed skills\n\n**Never say "I can\'t" without checking.** If you truly can\'t, offer `upskill search "<query>"` to find a skill that can. For browser-tab work, `upskill tabs` lists origin-advertised and browse.sh skills for whatever is open.\n\n## SLICC-native commands\n\nEasy to miss. Try before DevTools, env vars, or external tools:\n\n- `oauth-token <provider>` / `--list` — stored OAuth tokens (adobe, github, …)\n- `webhook` / `crontask` — register HTTP-webhook or cron lick handlers\n- `agent <cwd> <cmds> <prompt>` — one-shot fire-and-forget scoop\n- `serve <dir>` — host a VFS dir over HTTP\n- `ffmpeg` — on-demand WASM; `-f avfoundation` captures img/vid/mic\n\n## Principles\n\n- **Scoops do the heavy lifting. The cone orchestrates and synthesizes.** See `man delegation`.\n- When something fails, try another approach. You have many tools.\n- New capabilities = skills (`skill list`, `upskill search`), not hardcoded features. Author via `/workspace/skills/skill-authoring/SKILL.md`.\n\n## Sprinkles\n\nOne scoop per sprinkle, named identically. Cone MUST NOT write `.shtml` or run `sprinkle` commands — delegate via `feed_scoop`. See `man sprinkle`.\n\n## Dips\n\nInline `shtml` blocks in chat that hydrate into sandboxed widgets. Ephemeral, lick-only (no state). Cone may write these directly:\n\n```shtml\n<button onclick="slicc.lick({action:\'choose\',data:{value:42}})">Pick 42</button>\n```\n\nFor persistent UI, use Sprinkles instead. See `/workspace/skills/dips/SKILL.md`.\n\n## Licks\n\nExternal events arrive as `[<Event>: <name>]` with JSON body:\n\n- **Navigate** (handoff) — `man handoff`\n- **Webhook / Cron / File Watch** — `/workspace/skills/automation/SKILL.md`\n- **Sprinkle** — route to owning scoop\n- **Session Reload / Upgrade** — handler instructions inline\n\nScoops return on `scoop-notify` / `scoop-idle` / `scoop-wait`.\n\n## Style\n\nProfessional tool, not chatbot. No emoji.\n\n## Memory\n\nPersists across sessions. Add durable user prefs and working-style cues; prune stale entries. Each scoop has its own `CLAUDE.md` for scoop-local context.\n',n4=`<html lang="en">
|
|
4028
4043
|
<head>
|
|
4029
4044
|
<title>Connect an LLM</title>
|
|
4030
4045
|
<meta charset="utf-8" />
|
|
@@ -4499,7 +4514,7 @@ Examples:
|
|
|
4499
4514
|
<\/script>
|
|
4500
4515
|
</body>
|
|
4501
4516
|
</html>
|
|
4502
|
-
`,
|
|
4517
|
+
`,r4=`<!DOCTYPE html>
|
|
4503
4518
|
<html lang="en">
|
|
4504
4519
|
<head>
|
|
4505
4520
|
<title>Welcome</title>
|
|
@@ -5119,7 +5134,7 @@ Examples:
|
|
|
5119
5134
|
<\/script>
|
|
5120
5135
|
</body>
|
|
5121
5136
|
</html>
|
|
5122
|
-
`,
|
|
5137
|
+
`,i4=`---
|
|
5123
5138
|
name: automation
|
|
5124
5139
|
description: |
|
|
5125
5140
|
Use this when setting up event-driven automation in SLICC — webhooks, cron
|
|
@@ -5197,7 +5212,7 @@ Events include the change type (\`create\`, \`modify\`, \`delete\`) and the file
|
|
|
5197
5212
|
- Don't poll on a \`crontask\` to do work the cone could do reactively. Cron is for genuinely recurring jobs (digests, refreshes); reactive work belongs on \`fswatch\` or \`webhook\`.
|
|
5198
5213
|
- Don't leave watchers/webhooks/crons orphaned. If the owning scoop is gone, the lick has nowhere to go — \`... list\` and \`... delete\` to clean up.
|
|
5199
5214
|
- Don't fan a single trigger out to multiple scoops by registering N near-identical entries. Register once, let the receiving scoop dispatch.
|
|
5200
|
-
`,
|
|
5215
|
+
`,a4=`---
|
|
5201
5216
|
name: delegation
|
|
5202
5217
|
description: |
|
|
5203
5218
|
Use this when deciding whether to do work yourself or delegate to a scoop, when
|
|
@@ -5447,7 +5462,7 @@ scoop_scoop({ name: "architect", model: "claude-opus-4-6", prompt: "Design the n
|
|
|
5447
5462
|
## Browser tabs
|
|
5448
5463
|
|
|
5449
5464
|
Browser-tab handling rules (track your IDs, never close tabs you didn't open, handle "tab not found" gracefully) live in \`/workspace/skills/playwright-cli/SKILL.md\` under "Multi-Agent Tab Behavior". Read that skill before delegating browser work.
|
|
5450
|
-
`,
|
|
5465
|
+
`,o4=`---
|
|
5451
5466
|
name: dips
|
|
5452
5467
|
description: |
|
|
5453
5468
|
Use this whenever a response could benefit from richer visualization, guided
|
|
@@ -5597,7 +5612,7 @@ slicc.lick({ action: 'sort-complete', data: { algorithm: algo, comparisons: n }
|
|
|
5597
5612
|
> predictable shape. The canonical form works identically in both.
|
|
5598
5613
|
|
|
5599
5614
|
The agent receives the lick as a structured message and can respond with prose, another dip, or spawn a scoop.
|
|
5600
|
-
`,
|
|
5615
|
+
`,s4=`# Dip patterns
|
|
5601
5616
|
|
|
5602
5617
|
A gallery of 10 ready-to-adapt patterns for inline \`shtml\` widgets. Each pattern is a self-contained example you can copy and modify. See \`SKILL.md\` for the design rules, card structure, and pre-styled elements that apply to all of them.
|
|
5603
5618
|
|
|
@@ -5763,7 +5778,7 @@ N sliders → proportional stacked bar → over/under budget indicator.
|
|
|
5763
5778
|
Textarea input → parsed recursive DOM tree with collapse/expand.
|
|
5764
5779
|
|
|
5765
5780
|
**Use for**: JSON explorers, config viewers, log parsers, schema inspectors, AST browsers.
|
|
5766
|
-
`,
|
|
5781
|
+
`,c4=`---
|
|
5767
5782
|
name: handoff
|
|
5768
5783
|
description: |
|
|
5769
5784
|
Use this when you receive a Navigate Event lick — emitted whenever the user
|
|
@@ -5861,7 +5876,7 @@ Use this shtml block verbatim, substituting the origin URL, verb, target, and in
|
|
|
5861
5876
|
- Do not fetch the target URL until the user has accepted. Even a \`HEAD\` request is too eager — the origin may use fetch-beacon side effects.
|
|
5862
5877
|
- Do not execute the instruction as a shell command without thinking about it. It is prose intent, not code.
|
|
5863
5878
|
- Do not render more than one approval card for a single navigate event. If you already showed the card, wait for the user.
|
|
5864
|
-
`,
|
|
5879
|
+
`,l4=`---
|
|
5865
5880
|
name: mount
|
|
5866
5881
|
description: |
|
|
5867
5882
|
Use this whenever the user asks to mount anything — local folders, S3
|
|
@@ -6003,7 +6018,7 @@ For DA specifically: the \`/list\` endpoint doesn't include file sizes, so \`ls
|
|
|
6003
6018
|
- Don't try to \`cd\` into a remote mount before mounting; \`bash\`'s working directory is independent of mount setup.
|
|
6004
6019
|
- Don't ask "do you have credentials" if the user has already named a service — try the mount first, surface the actionable error from the probe, and walk them through the specific \`secret set\` commands.
|
|
6005
6020
|
- Don't fall back to a local mount if the user mentioned a remote service. Default to clarifying which remote backend, not which directory to pick.
|
|
6006
|
-
`,
|
|
6021
|
+
`,u4=`---
|
|
6007
6022
|
name: playwright-cli
|
|
6008
6023
|
description: |
|
|
6009
6024
|
Use this whenever the user asks to browse, navigate, click, fill a form,
|
|
@@ -6258,7 +6273,7 @@ echo 'Page.navigate {"url":"https://example.com"}' \\
|
|
|
6258
6273
|
\`\`\`
|
|
6259
6274
|
|
|
6260
6275
|
Run \`websocat --help\` for the full flag list. Use this only when \`playwright-cli\` has no wrapper for the CDP method you need.
|
|
6261
|
-
`,Z2="---\nname: skill-authoring\ndescription: |\n Use this when the user wants to write a new skill, edit an existing one, or\n understand SLICC's skill system. Covers SKILL.md frontmatter (name,\n description, allowed-tools), how to write a description that triggers\n reliably, native `/workspace/skills/` vs compatibility `.agents/` /\n `.claude/skills/` discovery, and when to ship companion files like `.jsh`\n scripts or `.bsh` browser hooks.\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Skill authoring\n\nA skill is a folder with a `SKILL.md` (and optional companion files) that loads into the agent's system prompt when the description matches the user's intent. This skill is about authoring those folders well.\n\n## Discovery\n\nSLICC discovers three kinds of skill roots:\n\n| Root | Source | Mutability |\n| ------------------------------------------- | ------------------------------------ | ----------------------------------- |\n| `/workspace/skills/<name>/SKILL.md` | Bundled or installed via `upskill` | Install-managed; you can edit them |\n| `.agents/skills/<name>/SKILL.md` (anywhere) | Compatibility (Cursor / SuperClaude) | Read-only (discovered, not managed) |\n| `.claude/skills/<name>/SKILL.md` (anywhere) | Compatibility (Claude Code) | Read-only (discovered, not managed) |\n\nWhen you create a new skill **for SLICC**, put it in `/workspace/skills/<name>/`. The `.agents/` and `.claude/` paths exist so SLICC can pick up skills authored for other agents without modification — don't create new skills there.\n\n## SKILL.md structure\n\n```markdown\n---\nname: <slug>\ndescription: |\n Use this when ...\n ... (1–3 sentences explaining trigger conditions, what's covered, and what's\n NOT covered if there's a sibling skill that handles related topics.)\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Title (matches `name`)\n\n... body ...\n```\n\n### Frontmatter fields\n\n- **`name`** — lowercase, kebab-case. Must match the folder name. This is what `skill list` shows.\n- **`description`** — the trigger string. The agent uses this to decide whether to load the skill. Get this right; everything else is secondary.\n- **`allowed-tools`** — comma-separated list of tools the skill needs. Without this, the agent may load the skill but find it can't execute the steps. Common values:\n - `bash` — almost every skill.\n - `read_file, write_file, edit_file` — for skills that author files (sprinkles, config edits, three-way merges).\n - Omit only for purely informational skills.\n\n### Writing a good description\n\nThe description is a trigger, not a summary. It runs through the agent at every turn — too vague and the skill loads when irrelevant; too narrow and it doesn't load when needed.\n\n**Pattern that works**: \"Use this when \\<user-facing trigger\\>. Covers \\<topics\\>. \\[For \\<adjacent topic\\> use \\<sibling skill\\>.\\]\"\n\nCompare:\n\n- ❌ `description: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding`\n Keyword soup. The agent has to guess what \"licks\" or \"screencapture\" mean for this user.\n- ✅ `description: Use this when setting up event-driven automation in SLICC — webhooks, cron tasks, or filesystem watchers that route events to scoops. Covers webhook, crontask, and fswatch. Read this BEFORE wiring anything that should fire on a schedule, an HTTP call, or a VFS change.`\n Names the user intent (\"setting up event-driven automation\"), names the commands the agent will reach for, and tells the agent when to load it.\n\nRules of thumb:\n\n- Lead with **\"Use this when...\"** or **\"Use this whenever...\"**.\n- Name the **user-facing trigger** (what the user said), not just the implementation.\n- If there's a closely-named sibling skill (dips vs sprinkles, mount vs other storage), say which is which inside the description so the agent doesn't load both.\n- Multi-line YAML scalars are fine for longer descriptions — use the `|` block style.\n\n## Body conventions\n\n- Lead with one sentence stating what the skill is. No preamble.\n- Use tables for option matrices (commands × flags, tradeoffs, etc.).\n- Code blocks are bash unless otherwise needed.\n- Include a \"Don't\" or \"Common errors\" section near the end if the skill is failure-prone — the agent will read it before acting.\n- If the skill is large (> ~150 lines), split a reference table or example gallery into a companion `<topic>.md` and have the SKILL.md `read_file` it on demand. The `sprinkles/` skill (style-guide.md) and `dips/` skill (patterns.md) follow this pattern.\n\n## Companion files\n\n### `.jsh` — 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 the extension). A skill can ship its own commands by including a `.jsh` next to `SKILL.md`.\n- **Node-like globals**: `process`, `console`, `fs` — a VFS bridge with `readFile`, `writeFile`, `readFileBinary`, `writeFileBinary`, `readDir`, `exists`, `stat`, `mkdir`, `rm`, `fetchToFile`.\n- **Dual-mode**: works in both the CLI server and the Chrome extension.\n- **Top-level `await`**: scripts are wrapped in `AsyncFunction`. Always `await` fs methods. Don't use `.then()`.\n\nShip a `.jsh` when the skill needs deterministic, parameterizable behavior the agent shouldn't have to re-derive each time (e.g. a `slicc-handoff` helper, a custom diff formatter, a domain-specific lint).\n\n### `.bsh` — 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 the first 10 lines.\n- Same execution engine as `.jsh`.\n\nUse `.bsh` for site-specific automations — auto-fillers, lick-emitters, or page transforms that should run whenever the user lands on a particular host.\n\n## Filesystem at a glance\n\nThe VFS is stored in IndexedDB; it survives tab closes and refreshes. The `mount` shell command bridges remote storage (local folders, S3-compatible, Adobe DA) into VFS paths — see `/workspace/skills/mount/SKILL.md`.\n\nThe VFS supports symbolic links transparently:\n\n```bash\nln -s /workspace/skills /workspace/skill-link # Create symlink\nreadlink /workspace/skill-link # Read link target\nls -la /workspace/ # Shows symlinks with -> target\n```\n\n`cat`, `read_file`, `write_file` etc. follow symlinks automatically.\n\n**Mount points must be empty.** Mounting over existing files is blocked so built-in skills and scripts stay discoverable. `ln -s` mounted files into the place where you need them.\n\n## Don't\n\n- Don't ship a skill without a description that starts with \"Use this when...\" — the trigger field IS the skill from the agent's perspective.\n- Don't put `name:` in Title Case. Lowercase kebab-case. Match the folder.\n- Don't dump shell-command catalogs into a SKILL.md just because they're related — `commands` already lists them. Skills are for **patterns and policy**, not reference material.\n- Don't author skills under `.agents/skills/` or `.claude/skills/`. Those roots are for compatibility discovery from other agents.\n",Q2='---\nname: sprinkles\ndescription: |\n Use this when the user wants a persistent UI panel — a dashboard, form,\n editor, report, or visualization that lives alongside the chat. Sprinkles are\n `.shtml` files under `/shared/sprinkles/` rendered in the side rail or as a\n full-screen tab. For ephemeral inline widgets, use dips instead. Covers\n creation, modification, layout constraints, the cone-to-scoop orchestration\n rules, the `slicc.*` bridge API, and `sprinkle chat` for blocking inline\n prompts.\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Sprinkles\n\n`.shtml` files in `/shared/sprinkles/` become interactive UI panels. Use them for dashboards, forms, and visualizations that persist alongside the chat.\n\n## Two rendering modes\n\n- **Fragment mode** (default): plain HTML fragments injected into the sidebar. Do NOT use `<!DOCTYPE html>`, `<html>`, `<head>`, `<body>`, or custom CSS — use the built-in `.sprinkle-*` classes. Scripts get a `slicc` bridge object automatically.\n- **Full-document mode**: complete HTML documents (starting with `<!DOCTYPE html>` or `<html>`) render inside sandboxed iframes. Use this for complex layouts with custom CSS, sidebars, split panes, modals, or canvas/SVG visualizations. The bridge script is auto-injected — `window.slicc` and `window.bridge` are available. The parent page\'s S2 theme tokens are injected automatically.\n\nPick full-document mode when you need custom CSS beyond `.sprinkle-*` classes, complex layouts (sidebar + main, split panes, tabs), or interactive canvas/SVG.\n\n## Layout & viewport\n\nSprinkles open in **one of four viewport contexts**, and you must design for the narrowest:\n\n| Float | Default viewport | Multi-column safe? |\n| -------------------------------- | -------------------------------------- | ----------------------- |\n| Desktop (CLI / Electron) sidebar | Narrow rail (≈ 360 px) | No — single column only |\n| Desktop full-screen pop-out | Full window | Yes |\n| iOS / Sliccstart app frame | Full-width but always single-column UX | No |\n| Chrome extension side panel | Narrow (≈ 360 px, fixed by Chrome) | No |\n\n**Default to a single-column layout.** Multi-column layouts (sidebar + main, split panes, three-up grids) only render usefully when the user explicitly pops the sprinkle to full-screen on desktop. They look broken in the rail and on iOS.\n\nIf you genuinely need multi-column UI, do all of the following:\n\n1. Build it in **full-document mode** so you can use grid / flex / media queries cleanly.\n2. Use `@media (max-width: 600px)` (or similar) to collapse to single column at narrow widths so the sidebar/iOS view still works.\n3. Tell the user in your reply that this sprinkle is "best viewed full-screen — pop it out from the rail header."\n\nFor dashboards with many widgets, prefer a vertical stack of `.sprinkle-card` blocks over a grid. The card stack is responsive by default and looks good in both rail and full-screen.\n\n## Creating a sprinkle\n\n1. `read_file /workspace/skills/sprinkles/style-guide.md` — **always read first** before writing any sprinkle.\n2. **Pick a rail icon** that matches the sprinkle\'s purpose (see "Sprinkle icon" below). Every new sprinkle MUST declare an icon — the generic Sparkles default is reserved for sprinkles that genuinely have no thematic anchor.\n3. `write_file` to `/shared/sprinkles/<name>/<name>.shtml` (follow the style guide templates).\n4. `bash` → `sprinkle open <name>`.\n5. **CRITICAL: do NOT finish or send a completion message.** You own this sprinkle for its entire lifetime. The cone will send you follow-up instructions (modifications, lick events) via `feed_scoop`. If you finish, you lose your context and cannot handle future work on this sprinkle.\n\n### Updating a sprinkle (when you receive follow-up instructions)\n\n1. Edit `/shared/sprinkles/<name>/<name>.shtml` with the requested changes.\n2. Reload: `sprinkle close <name> && sprinkle open <name>`.\n3. Do NOT finish — stay ready for more instructions.\n\n### Handling lick events (when the cone forwards a user interaction)\n\nThe cone will send you a message with the lick action and your sprinkle name. Only modify YOUR sprinkle — the one matching your scoop name. Process the action and push updates:\n\n- `bash` → `sprinkle send <name> \'{"key":"value"}\'` to push data to the sprinkle\'s `slicc.on(\'update\', ...)` handler.\n- Or edit the `.shtml` file and reload if the UI structure needs to change.\n- Do NOT finish — stay ready for more events.\n\n## Sprinkle icon\n\nEach sprinkle gets its own glyph in the rail so users can tell them apart at a glance. Declare it in the `.shtml`. Three formats, in order of preference:\n\n**1. Lucide icon name** (preferred — covers ~1500 icons from [lucide.dev/icons](https://lucide.dev/icons)):\n\n```html\n<link rel="icon" href="music" />\n```\n\nUse the kebab-case name from lucide.dev. Common picks: `music`, `code`, `terminal`, `chart-bar`, `chart-line`, `calendar`, `calendar-clock`, `clock`, `image`, `file-text`, `globe`, `book-open`, `compass`, `gauge`, `wrench`, `palette`, `bug`, `flask-conical`, `database`, `cloud`, `package`, `shopping-cart`, `dollar-sign`, `mail`, `message-square`, `bell`, `users`, `user`, `settings`, `sparkles`.\n\n**2. SVG file in the sprinkle\'s directory** (when no Lucide icon fits):\n\n```html\n<link rel="icon" href="/shared/sprinkles/<name>/icon.svg" />\n```\n\nAuthor the SVG with `viewBox="0 0 24 24"`. Keep paths simple — the rail renders at 16×16. **Note**: only Lucide icons inherit `currentColor` from the rail; author-supplied SVGs render through `<img>` (script-disabled), so set explicit colors in the SVG itself.\n\n**3. Inline SVG or data URL** (one-off icons, no extra file):\n\n```html\n<link\n rel="icon"\n href=\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="..."/></svg>\'\n/>\n```\n\n**Where to put it**: inside `<head>` for full-document mode, or as the very first element in fragment mode.\n\n**Quoting tip**: when the `href` value contains quotes (inline-SVG data URLs do), wrap the attribute in single quotes: `href=\'data:image/svg+xml;utf8,<svg xmlns="...">...\'`.\n\n**Fallback**: if the icon spec is missing or unresolvable, the rail uses a generic Sparkles glyph.\n\n## Cone orchestration rules\n\nThese are the rules the cone follows when sprinkles are involved. They are absolute.\n\n### Rule 1: One scoop per sprinkle, named identically\n\nScoop name MUST match sprinkle name. Sprinkle `giro-winners` = scoop `giro-winners`.\n\n### Rule 2: Cone never touches sprinkle files or commands\n\nThe cone MUST NOT: write/edit `.shtml` files, run `sprinkle open / close / send`, or handle lick events directly. ALL sprinkle work goes through scoops via `feed_scoop`. **Never handle a lick in the cone.**\n\n### Rule 3: Creating sprinkles\n\nCreate a scoop, then feed it a complete, self-contained brief:\n\n```\nscoop_scoop("giro-winners")\nfeed_scoop("giro-winners", "You own the sprinkle \'giro-winners\'. Your job:\n1. Run: read_file /workspace/skills/sprinkles/style-guide.md\n2. Research the last 3 Giro d\'Italia winners\n3. Pick a rail icon — for cycling, use <link rel=\\"icon\\" href=\\"bike\\" /> in <head>. See the sprinkles SKILL.md \\"Sprinkle icon\\" section for the full list.\n4. Write the sprinkle to /shared/sprinkles/giro-winners/giro-winners.shtml\n5. Run: sprinkle open giro-winners\n6. IMPORTANT: After opening the sprinkle, do NOT finish. Stay ready — you will receive follow-up instructions and lick events for this sprinkle via feed_scoop. Do not send a completion message.")\n```\n\n### Rule 4: Modifying sprinkles\n\nFeed the EXISTING scoop that owns it. Do NOT create a new scoop:\n\n```\nfeed_scoop("giro-winners", "Modify YOUR sprinkle \'giro-winners\' at /shared/sprinkles/giro-winners/giro-winners.shtml:\nAdd an \'Add Previous Year\' button with onclick=\\"slicc.lick({action: \'add-year\'})\\"\nThen reload: sprinkle close giro-winners && sprinkle open giro-winners\nStay ready for more work.")\n```\n\n### Rule 5: Lick events\n\nForward to the owning scoop, never handle yourself:\n\n```\nfeed_scoop("giro-winners", "Lick event on YOUR sprinkle \'giro-winners\' (/shared/sprinkles/giro-winners/giro-winners.shtml):\nAction: \'add-year\'\nLook up the next previous year\'s Giro d\'Italia winner and update the sprinkle.\nUse: sprinkle send giro-winners \'<json>\' to push data, or edit the .shtml and reload.\nStay ready for more lick events.")\n```\n\n## Cheap interactions via `agent`\n\nWhen a sprinkle button needs to do real work but the owning scoop should NOT be pulled into a turn (it\'s busy, or the work is purely transactional), route the lick handler through `agent` instead.\n\nPattern:\n\n1. User clicks → `slicc.lick({action: \'lookup\', data: {q: \'foo\'}})`.\n2. Cone sees the lick, forwards to the owning scoop with `feed_scoop`.\n3. The scoop\'s reply runs `agent` against a tight allow-list and writes the result back via `sprinkle send`.\n\n```bash\n# Inside the owning scoop\'s reply to a lick:\nresult=$(agent /tmp "curl,jq" "Look up \'$Q\' in <api>, return the price.")\nsprinkle send giro-winners "$(jq -n --arg r "$result" \'{result:$r}\')"\n```\n\nWhy this matters: a busy scoop that owns a sprinkle can shell to `agent` to handle a click without growing its own conversation. `agent` is **handoff-free** — the ephemeral sub-scoop doesn\'t notify the cone or the owning scoop on completion. See `/workspace/skills/delegation/SKILL.md` for the full `agent` reference.\n\nThis is the difference between "every click adds a turn to your owning scoop" (expensive, drifts) and "every click is a clean transaction" (predictable, cheap).\n\n## Managing sprinkles via bash\n\n- `sprinkle list` — see available sprinkles.\n- `sprinkle open <name>` — show a sprinkle in the sidebar.\n- `sprinkle close <name>` — remove it.\n- `sprinkle send <name> \'<json>\'` — push data (single-quote the JSON!).\n- `sprinkle chat \'<html>\'` — show inline HTML in the chat (for quick confirmations / choices). Blocks until the user clicks; returns the lick result as JSON. Use when a tool needs user input mid-execution.\n- `open /path/to/file.shtml` — also opens as a sprinkle.\n\n```bash\nsprinkle chat \'<div class="sprinkle-action-card">\n <div class="sprinkle-action-card__header">Deploy to production?</div>\n <div class="sprinkle-action-card__actions">\n <button class="sprinkle-btn sprinkle-btn--secondary" onclick="slicc.lick({action:\\"cancel\\"})">Cancel</button>\n <button class="sprinkle-btn sprinkle-btn--primary" onclick="slicc.lick({action:\\"deploy\\",data:{env:\\"prod\\"}})">Deploy</button>\n </div>\n</div>\'\n```\n\n## Bridge API\n\nAvailable as `slicc` in `<script>` tags and `onclick` attributes:\n\n- `slicc.lick(event)` — send a lick event to the cone (cone routes to the right scoop). Accepts a string shortcut (`slicc.lick(\'cancel\')` → `{ action: \'cancel\' }`) or `{ action, data? }`. See payload-shape note below.\n- `slicc.on(\'update\', function(data) {...})` — receive data sent via `sprinkle send`.\n\n> **Payload shape:** the cone reads `event.data` as the payload — top-level extras outside `action` and `data` are silently dropped by the sprinkle bridge. Always use `slicc.lick({ action: \'deploy\', data: { env: \'prod\' } })`, not `slicc.lick({ action: \'deploy\', env: \'prod\' })`.\n\n- `slicc.name` — the sprinkle\'s name.\n- `slicc.close()` — close the sprinkle.\n- `slicc.stopCone()` — stop the cone agent.\n- `slicc.readFile(path)` — read a VFS file (returns `Promise<string>`).\n- `slicc.writeFile(path, content)` — write text content to a VFS file.\n- `slicc.readDir(path)` — list directory entries (returns `Promise<Array<{name, type}>>`).\n- `slicc.exists(path)` — check if path exists (returns `Promise<boolean>`).\n- `slicc.stat(path)` — get file metadata (returns `Promise<{type, size}>`).\n- `slicc.mkdir(path)` — create a directory (recursive).\n- `slicc.rm(path)` — remove a file.\n- `slicc.screenshot(selector?)` — capture sprinkle DOM as base64 PNG data URL. Note: the screenshot captures a DOM clone using SVG foreignObject. External stylesheets and some computed styles may not be fully reproduced. For best results, use inline styles on elements you intend to screenshot.\n\n**onclick attributes**: always use `slicc` — e.g. `onclick="slicc.lick({action: \'add-year\'})"`. The `slicc` variable is automatically resolved per-sprinkle, so multiple sprinkles won\'t collide. Do NOT use `bridge` or any other variable name in onclick.\n\n**CSS components**: do NOT write custom CSS. Use the built-in `.sprinkle-*` classes: cards, tables, badges, buttons, text fields, progress bars, meters, layout utilities, and more. For inputs use `class="sprinkle-text-field"`, never inline border/padding styles. Run `read_file /workspace/skills/sprinkles/style-guide.md` for the full component reference with markup examples.\n\n## Built-in sprinkles\n\nSLICC no longer ships with a catalog of pre-built sprinkles. The only `.shtml` under `/shared/sprinkles/` is `welcome/`, which backs the inline first-run welcome dip — not a panel sprinkle. **Always create sprinkles from scratch** for what the user is asking for, following the "Creating a sprinkle" flow above. Do not assume a built-in sprinkle name exists.\n',$2=`# Lucide Icons Example
|
|
6276
|
+
`,d4="---\nname: skill-authoring\ndescription: |\n Use this when the user wants to write a new skill, edit an existing one, or\n understand SLICC's skill system. Covers SKILL.md frontmatter (name,\n description, allowed-tools), how to write a description that triggers\n reliably, native `/workspace/skills/` vs compatibility `.agents/` /\n `.claude/skills/` discovery, and when to ship companion files like `.jsh`\n scripts or `.bsh` browser hooks.\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Skill authoring\n\nA skill is a folder with a `SKILL.md` (and optional companion files) that loads into the agent's system prompt when the description matches the user's intent. This skill is about authoring those folders well.\n\n## Discovery\n\nSLICC discovers three kinds of skill roots:\n\n| Root | Source | Mutability |\n| ------------------------------------------- | ------------------------------------ | ----------------------------------- |\n| `/workspace/skills/<name>/SKILL.md` | Bundled or installed via `upskill` | Install-managed; you can edit them |\n| `.agents/skills/<name>/SKILL.md` (anywhere) | Compatibility (Cursor / SuperClaude) | Read-only (discovered, not managed) |\n| `.claude/skills/<name>/SKILL.md` (anywhere) | Compatibility (Claude Code) | Read-only (discovered, not managed) |\n\nWhen you create a new skill **for SLICC**, put it in `/workspace/skills/<name>/`. The `.agents/` and `.claude/` paths exist so SLICC can pick up skills authored for other agents without modification — don't create new skills there.\n\n## SKILL.md structure\n\n```markdown\n---\nname: <slug>\ndescription: |\n Use this when ...\n ... (1–3 sentences explaining trigger conditions, what's covered, and what's\n NOT covered if there's a sibling skill that handles related topics.)\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Title (matches `name`)\n\n... body ...\n```\n\n### Frontmatter fields\n\n- **`name`** — lowercase, kebab-case. Must match the folder name. This is what `skill list` shows.\n- **`description`** — the trigger string. The agent uses this to decide whether to load the skill. Get this right; everything else is secondary.\n- **`allowed-tools`** — comma-separated list of tools the skill needs. Without this, the agent may load the skill but find it can't execute the steps. Common values:\n - `bash` — almost every skill.\n - `read_file, write_file, edit_file` — for skills that author files (sprinkles, config edits, three-way merges).\n - Omit only for purely informational skills.\n\n### Writing a good description\n\nThe description is a trigger, not a summary. It runs through the agent at every turn — too vague and the skill loads when irrelevant; too narrow and it doesn't load when needed.\n\n**Pattern that works**: \"Use this when \\<user-facing trigger\\>. Covers \\<topics\\>. \\[For \\<adjacent topic\\> use \\<sibling skill\\>.\\]\"\n\nCompare:\n\n- ❌ `description: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding`\n Keyword soup. The agent has to guess what \"licks\" or \"screencapture\" mean for this user.\n- ✅ `description: Use this when setting up event-driven automation in SLICC — webhooks, cron tasks, or filesystem watchers that route events to scoops. Covers webhook, crontask, and fswatch. Read this BEFORE wiring anything that should fire on a schedule, an HTTP call, or a VFS change.`\n Names the user intent (\"setting up event-driven automation\"), names the commands the agent will reach for, and tells the agent when to load it.\n\nRules of thumb:\n\n- Lead with **\"Use this when...\"** or **\"Use this whenever...\"**.\n- Name the **user-facing trigger** (what the user said), not just the implementation.\n- If there's a closely-named sibling skill (dips vs sprinkles, mount vs other storage), say which is which inside the description so the agent doesn't load both.\n- Multi-line YAML scalars are fine for longer descriptions — use the `|` block style.\n\n## Body conventions\n\n- Lead with one sentence stating what the skill is. No preamble.\n- Use tables for option matrices (commands × flags, tradeoffs, etc.).\n- Code blocks are bash unless otherwise needed.\n- Include a \"Don't\" or \"Common errors\" section near the end if the skill is failure-prone — the agent will read it before acting.\n- If the skill is large (> ~150 lines), split a reference table or example gallery into a companion `<topic>.md` and have the SKILL.md `read_file` it on demand. The `sprinkles/` skill (style-guide.md) and `dips/` skill (patterns.md) follow this pattern.\n\n## Companion files\n\n### `.jsh` — 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 the extension). A skill can ship its own commands by including a `.jsh` next to `SKILL.md`.\n- **Node-like globals**: `process`, `console`, `fs` — a VFS bridge with `readFile`, `writeFile`, `readFileBinary`, `writeFileBinary`, `readDir`, `exists`, `stat`, `mkdir`, `rm`, `fetchToFile`.\n- **Dual-mode**: works in both the CLI server and the Chrome extension.\n- **Top-level `await`**: scripts are wrapped in `AsyncFunction`. Always `await` fs methods. Don't use `.then()`.\n\nShip a `.jsh` when the skill needs deterministic, parameterizable behavior the agent shouldn't have to re-derive each time (e.g. a `slicc-handoff` helper, a custom diff formatter, a domain-specific lint).\n\n### `.bsh` — 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 the first 10 lines.\n- Same execution engine as `.jsh`.\n\nUse `.bsh` for site-specific automations — auto-fillers, lick-emitters, or page transforms that should run whenever the user lands on a particular host.\n\n## Filesystem at a glance\n\nThe VFS is stored in IndexedDB; it survives tab closes and refreshes. The `mount` shell command bridges remote storage (local folders, S3-compatible, Adobe DA) into VFS paths — see `/workspace/skills/mount/SKILL.md`.\n\nThe VFS supports symbolic links transparently:\n\n```bash\nln -s /workspace/skills /workspace/skill-link # Create symlink\nreadlink /workspace/skill-link # Read link target\nls -la /workspace/ # Shows symlinks with -> target\n```\n\n`cat`, `read_file`, `write_file` etc. follow symlinks automatically.\n\n**Mount points must be empty.** Mounting over existing files is blocked so built-in skills and scripts stay discoverable. `ln -s` mounted files into the place where you need them.\n\n## Don't\n\n- Don't ship a skill without a description that starts with \"Use this when...\" — the trigger field IS the skill from the agent's perspective.\n- Don't put `name:` in Title Case. Lowercase kebab-case. Match the folder.\n- Don't dump shell-command catalogs into a SKILL.md just because they're related — `commands` already lists them. Skills are for **patterns and policy**, not reference material.\n- Don't author skills under `.agents/skills/` or `.claude/skills/`. Those roots are for compatibility discovery from other agents.\n",f4='---\nname: sprinkles\ndescription: |\n Use this when the user wants a persistent UI panel — a dashboard, form,\n editor, report, or visualization that lives alongside the chat. Sprinkles are\n `.shtml` files under `/shared/sprinkles/` rendered in the side rail or as a\n full-screen tab. For ephemeral inline widgets, use dips instead. Covers\n creation, modification, layout constraints, the cone-to-scoop orchestration\n rules, the `slicc.*` bridge API, and `sprinkle chat` for blocking inline\n prompts.\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Sprinkles\n\n`.shtml` files in `/shared/sprinkles/` become interactive UI panels. Use them for dashboards, forms, and visualizations that persist alongside the chat.\n\n## Two rendering modes\n\n- **Fragment mode** (default): plain HTML fragments injected into the sidebar. Do NOT use `<!DOCTYPE html>`, `<html>`, `<head>`, `<body>`, or custom CSS — use the built-in `.sprinkle-*` classes. Scripts get a `slicc` bridge object automatically.\n- **Full-document mode**: complete HTML documents (starting with `<!DOCTYPE html>` or `<html>`) render inside sandboxed iframes. Use this for complex layouts with custom CSS, sidebars, split panes, modals, or canvas/SVG visualizations. The bridge script is auto-injected — `window.slicc` and `window.bridge` are available. The parent page\'s S2 theme tokens are injected automatically.\n\nPick full-document mode when you need custom CSS beyond `.sprinkle-*` classes, complex layouts (sidebar + main, split panes, tabs), or interactive canvas/SVG.\n\n## Layout & viewport\n\nSprinkles open in **one of four viewport contexts**, and you must design for the narrowest:\n\n| Float | Default viewport | Multi-column safe? |\n| -------------------------------- | -------------------------------------- | ----------------------- |\n| Desktop (CLI / Electron) sidebar | Narrow rail (≈ 360 px) | No — single column only |\n| Desktop full-screen pop-out | Full window | Yes |\n| iOS / Sliccstart app frame | Full-width but always single-column UX | No |\n| Chrome extension side panel | Narrow (≈ 360 px, fixed by Chrome) | No |\n\n**Default to a single-column layout.** Multi-column layouts (sidebar + main, split panes, three-up grids) only render usefully when the user explicitly pops the sprinkle to full-screen on desktop. They look broken in the rail and on iOS.\n\nIf you genuinely need multi-column UI, do all of the following:\n\n1. Build it in **full-document mode** so you can use grid / flex / media queries cleanly.\n2. Use `@media (max-width: 600px)` (or similar) to collapse to single column at narrow widths so the sidebar/iOS view still works.\n3. Tell the user in your reply that this sprinkle is "best viewed full-screen — pop it out from the rail header."\n\nFor dashboards with many widgets, prefer a vertical stack of `.sprinkle-card` blocks over a grid. The card stack is responsive by default and looks good in both rail and full-screen.\n\n## Creating a sprinkle\n\n1. `read_file /workspace/skills/sprinkles/style-guide.md` — **always read first** before writing any sprinkle.\n2. **Pick a rail icon** that matches the sprinkle\'s purpose (see "Sprinkle icon" below). Every new sprinkle MUST declare an icon — the generic Sparkles default is reserved for sprinkles that genuinely have no thematic anchor.\n3. `write_file` to `/shared/sprinkles/<name>/<name>.shtml` (follow the style guide templates).\n4. `bash` → `sprinkle open <name>`.\n5. **CRITICAL: do NOT finish or send a completion message.** You own this sprinkle for its entire lifetime. The cone will send you follow-up instructions (modifications, lick events) via `feed_scoop`. If you finish, you lose your context and cannot handle future work on this sprinkle.\n\n### Updating a sprinkle (when you receive follow-up instructions)\n\n1. Edit `/shared/sprinkles/<name>/<name>.shtml` with the requested changes.\n2. Reload: `sprinkle close <name> && sprinkle open <name>`.\n3. Do NOT finish — stay ready for more instructions.\n\n### Handling lick events (when the cone forwards a user interaction)\n\nThe cone will send you a message with the lick action and your sprinkle name. Only modify YOUR sprinkle — the one matching your scoop name. Process the action and push updates:\n\n- `bash` → `sprinkle send <name> \'{"key":"value"}\'` to push data to the sprinkle\'s `slicc.on(\'update\', ...)` handler.\n- Or edit the `.shtml` file and reload if the UI structure needs to change.\n- Do NOT finish — stay ready for more events.\n\n## Sprinkle icon\n\nEach sprinkle gets its own glyph in the rail so users can tell them apart at a glance. Declare it in the `.shtml`. Three formats, in order of preference:\n\n**1. Lucide icon name** (preferred — covers ~1500 icons from [lucide.dev/icons](https://lucide.dev/icons)):\n\n```html\n<link rel="icon" href="music" />\n```\n\nUse the kebab-case name from lucide.dev. Common picks: `music`, `code`, `terminal`, `chart-bar`, `chart-line`, `calendar`, `calendar-clock`, `clock`, `image`, `file-text`, `globe`, `book-open`, `compass`, `gauge`, `wrench`, `palette`, `bug`, `flask-conical`, `database`, `cloud`, `package`, `shopping-cart`, `dollar-sign`, `mail`, `message-square`, `bell`, `users`, `user`, `settings`, `sparkles`.\n\n**2. SVG file in the sprinkle\'s directory** (when no Lucide icon fits):\n\n```html\n<link rel="icon" href="/shared/sprinkles/<name>/icon.svg" />\n```\n\nAuthor the SVG with `viewBox="0 0 24 24"`. Keep paths simple — the rail renders at 16×16. **Note**: only Lucide icons inherit `currentColor` from the rail; author-supplied SVGs render through `<img>` (script-disabled), so set explicit colors in the SVG itself.\n\n**3. Inline SVG or data URL** (one-off icons, no extra file):\n\n```html\n<link\n rel="icon"\n href=\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="..."/></svg>\'\n/>\n```\n\n**Where to put it**: inside `<head>` for full-document mode, or as the very first element in fragment mode.\n\n**Quoting tip**: when the `href` value contains quotes (inline-SVG data URLs do), wrap the attribute in single quotes: `href=\'data:image/svg+xml;utf8,<svg xmlns="...">...\'`.\n\n**Fallback**: if the icon spec is missing or unresolvable, the rail uses a generic Sparkles glyph.\n\n## Cone orchestration rules\n\nThese are the rules the cone follows when sprinkles are involved. They are absolute.\n\n### Rule 1: One scoop per sprinkle, named identically\n\nScoop name MUST match sprinkle name. Sprinkle `giro-winners` = scoop `giro-winners`.\n\n### Rule 2: Cone never touches sprinkle files or commands\n\nThe cone MUST NOT: write/edit `.shtml` files, run `sprinkle open / close / send`, or handle lick events directly. ALL sprinkle work goes through scoops via `feed_scoop`. **Never handle a lick in the cone.**\n\n### Rule 3: Creating sprinkles\n\nCreate a scoop, then feed it a complete, self-contained brief:\n\n```\nscoop_scoop("giro-winners")\nfeed_scoop("giro-winners", "You own the sprinkle \'giro-winners\'. Your job:\n1. Run: read_file /workspace/skills/sprinkles/style-guide.md\n2. Research the last 3 Giro d\'Italia winners\n3. Pick a rail icon — for cycling, use <link rel=\\"icon\\" href=\\"bike\\" /> in <head>. See the sprinkles SKILL.md \\"Sprinkle icon\\" section for the full list.\n4. Write the sprinkle to /shared/sprinkles/giro-winners/giro-winners.shtml\n5. Run: sprinkle open giro-winners\n6. IMPORTANT: After opening the sprinkle, do NOT finish. Stay ready — you will receive follow-up instructions and lick events for this sprinkle via feed_scoop. Do not send a completion message.")\n```\n\n### Rule 4: Modifying sprinkles\n\nFeed the EXISTING scoop that owns it. Do NOT create a new scoop:\n\n```\nfeed_scoop("giro-winners", "Modify YOUR sprinkle \'giro-winners\' at /shared/sprinkles/giro-winners/giro-winners.shtml:\nAdd an \'Add Previous Year\' button with onclick=\\"slicc.lick({action: \'add-year\'})\\"\nThen reload: sprinkle close giro-winners && sprinkle open giro-winners\nStay ready for more work.")\n```\n\n### Rule 5: Lick events\n\nForward to the owning scoop, never handle yourself:\n\n```\nfeed_scoop("giro-winners", "Lick event on YOUR sprinkle \'giro-winners\' (/shared/sprinkles/giro-winners/giro-winners.shtml):\nAction: \'add-year\'\nLook up the next previous year\'s Giro d\'Italia winner and update the sprinkle.\nUse: sprinkle send giro-winners \'<json>\' to push data, or edit the .shtml and reload.\nStay ready for more lick events.")\n```\n\n## Cheap interactions via `agent`\n\nWhen a sprinkle button needs to do real work but the owning scoop should NOT be pulled into a turn (it\'s busy, or the work is purely transactional), route the lick handler through `agent` instead.\n\nPattern:\n\n1. User clicks → `slicc.lick({action: \'lookup\', data: {q: \'foo\'}})`.\n2. Cone sees the lick, forwards to the owning scoop with `feed_scoop`.\n3. The scoop\'s reply runs `agent` against a tight allow-list and writes the result back via `sprinkle send`.\n\n```bash\n# Inside the owning scoop\'s reply to a lick:\nresult=$(agent /tmp "curl,jq" "Look up \'$Q\' in <api>, return the price.")\nsprinkle send giro-winners "$(jq -n --arg r "$result" \'{result:$r}\')"\n```\n\nWhy this matters: a busy scoop that owns a sprinkle can shell to `agent` to handle a click without growing its own conversation. `agent` is **handoff-free** — the ephemeral sub-scoop doesn\'t notify the cone or the owning scoop on completion. See `/workspace/skills/delegation/SKILL.md` for the full `agent` reference.\n\nThis is the difference between "every click adds a turn to your owning scoop" (expensive, drifts) and "every click is a clean transaction" (predictable, cheap).\n\n## Managing sprinkles via bash\n\n- `sprinkle list` — see available sprinkles.\n- `sprinkle open <name>` — show a sprinkle in the sidebar.\n- `sprinkle close <name>` — remove it.\n- `sprinkle send <name> \'<json>\'` — push data (single-quote the JSON!).\n- `sprinkle chat \'<html>\'` — show inline HTML in the chat (for quick confirmations / choices). Blocks until the user clicks; returns the lick result as JSON. Use when a tool needs user input mid-execution.\n- `open /path/to/file.shtml` — also opens as a sprinkle.\n\n```bash\nsprinkle chat \'<div class="sprinkle-action-card">\n <div class="sprinkle-action-card__header">Deploy to production?</div>\n <div class="sprinkle-action-card__actions">\n <button class="sprinkle-btn sprinkle-btn--secondary" onclick="slicc.lick({action:\\"cancel\\"})">Cancel</button>\n <button class="sprinkle-btn sprinkle-btn--primary" onclick="slicc.lick({action:\\"deploy\\",data:{env:\\"prod\\"}})">Deploy</button>\n </div>\n</div>\'\n```\n\n## Bridge API\n\nAvailable as `slicc` in `<script>` tags and `onclick` attributes:\n\n- `slicc.lick(event)` — send a lick event to the cone (cone routes to the right scoop). Accepts a string shortcut (`slicc.lick(\'cancel\')` → `{ action: \'cancel\' }`) or `{ action, data? }`. See payload-shape note below.\n- `slicc.on(\'update\', function(data) {...})` — receive data sent via `sprinkle send`.\n\n> **Payload shape:** the cone reads `event.data` as the payload — top-level extras outside `action` and `data` are silently dropped by the sprinkle bridge. Always use `slicc.lick({ action: \'deploy\', data: { env: \'prod\' } })`, not `slicc.lick({ action: \'deploy\', env: \'prod\' })`.\n\n- `slicc.name` — the sprinkle\'s name.\n- `slicc.close()` — close the sprinkle.\n- `slicc.stopCone()` — stop the cone agent.\n- `slicc.readFile(path)` — read a VFS file (returns `Promise<string>`).\n- `slicc.writeFile(path, content)` — write text content to a VFS file.\n- `slicc.readDir(path)` — list directory entries (returns `Promise<Array<{name, type}>>`).\n- `slicc.exists(path)` — check if path exists (returns `Promise<boolean>`).\n- `slicc.stat(path)` — get file metadata (returns `Promise<{type, size}>`).\n- `slicc.mkdir(path)` — create a directory (recursive).\n- `slicc.rm(path)` — remove a file.\n- `slicc.screenshot(selector?)` — capture sprinkle DOM as base64 PNG data URL. Note: the screenshot captures a DOM clone using SVG foreignObject. External stylesheets and some computed styles may not be fully reproduced. For best results, use inline styles on elements you intend to screenshot.\n\n**onclick attributes**: always use `slicc` — e.g. `onclick="slicc.lick({action: \'add-year\'})"`. The `slicc` variable is automatically resolved per-sprinkle, so multiple sprinkles won\'t collide. Do NOT use `bridge` or any other variable name in onclick.\n\n**CSS components**: do NOT write custom CSS. Use the built-in `.sprinkle-*` classes: cards, tables, badges, buttons, text fields, progress bars, meters, layout utilities, and more. For inputs use `class="sprinkle-text-field"`, never inline border/padding styles. Run `read_file /workspace/skills/sprinkles/style-guide.md` for the full component reference with markup examples.\n\n## Built-in sprinkles\n\nSLICC no longer ships with a catalog of pre-built sprinkles. The only `.shtml` under `/shared/sprinkles/` is `welcome/`, which backs the inline first-run welcome dip — not a panel sprinkle. **Always create sprinkles from scratch** for what the user is asking for, following the "Creating a sprinkle" flow above. Do not assume a built-in sprinkle name exists.\n',p4=`# Lucide Icons Example
|
|
6262
6277
|
|
|
6263
6278
|
This shows how to use Lucide icons in inline sprinkles instead of emojis.
|
|
6264
6279
|
|
|
@@ -6368,7 +6383,7 @@ This shows how to use Lucide icons in inline sprinkles instead of emojis.
|
|
|
6368
6383
|
**UI**: \`settings\`, \`menu\`, \`more-vertical\`, \`more-horizontal\`, \`eye\`, \`eye-off\`, \`lock\`, \`unlock\`
|
|
6369
6384
|
|
|
6370
6385
|
Browse all icons at [lucide.dev/icons](https://lucide.dev/icons)
|
|
6371
|
-
`,
|
|
6386
|
+
`,m4=`# Sprinkle Component Reference
|
|
6372
6387
|
|
|
6373
6388
|
Use these CSS classes in \`.shtml\` sprinkles. Do NOT write custom CSS — these components cover all common UI patterns.
|
|
6374
6389
|
|
|
@@ -7160,7 +7175,7 @@ background: color-mix(in srgb, var(--s2-accent) 6%, transparent); /* blue tint *
|
|
|
7160
7175
|
| \`--s2-spacing-400\` | 24px |
|
|
7161
7176
|
| \`--s2-spacing-500\` | 32px |
|
|
7162
7177
|
| \`--s2-spacing-600\` | 40px |
|
|
7163
|
-
`,
|
|
7178
|
+
`,h4='---\nname: upgrade\ndescription: |\n Use this when you receive an `[Upgrade Event: x.y.z→a.b.c]` lick — fired on\n boot whenever the bundled SLICC version differs from the previous run. This\n skill renders the approval card, fetches the changelog from GitHub, and\n performs a three-way merge of bundled `vfs-root` files (skills, sprinkles)\n against the user\'s local edits. Never auto-applies; user must explicitly\n click `Update workspace files`.\nallowed-tools: bash, read_file, write_file, edit_file\n---\n\n# Upgrade\n\nWhen SLICC boots and discovers that the bundled version (baked into the build at release time from the root `package.json`) differs from the version it was last seen running, it emits an `upgrade` lick to the cone. This skill describes how to react.\n\n## Event shape\n\nYou receive a message like:\n\n```text\n[Upgrade Event: 0.4.1→0.5.0]\n\nSLICC was upgraded from `0.4.1` to `0.5.0`.\nReleased: 2026-04-15T12:00:00Z\n\nUse the **upgrade** skill (...)\n```\n\nThe two version strings (`from`, `to`) are valid git tags on `https://github.com/ai-ecoverse/slicc` — the public source repository.\n\n## What to do when you receive an upgrade lick\n\nRender a single inline `.sprinkle-action-card` with two primary buttons. Quote both versions verbatim; never auto-run anything.\n\n```shtml\n<div class="sprinkle-action-card">\n <div class="sprinkle-action-card__header">\n SLICC upgraded\n <span class="sprinkle-badge sprinkle-badge--notice">FROM_VERSION → TO_VERSION</span>\n </div>\n <div class="sprinkle-action-card__body">\n <p style="margin:0 0 8px">SLICC was upgraded. You can review what changed and optionally pull the new bundled workspace files into your VFS.</p>\n </div>\n <div class="sprinkle-action-card__actions">\n <button class="sprinkle-btn sprinkle-btn--secondary" onclick="slicc.lick({action:\'dismiss\'})">Dismiss</button>\n <button class="sprinkle-btn sprinkle-btn--secondary" onclick="slicc.lick({action:\'review-changelog\'})">Review changelog</button>\n <button class="sprinkle-btn sprinkle-btn--primary" onclick="slicc.lick({action:\'merge-vfs-root\'})">Update workspace files</button>\n </div>\n</div>\n```\n\n## Changelog review (`action: \'review-changelog\'`)\n\nFetch the GitHub compare API for the two tags and summarize the result for the user.\n\n```bash\n# The repo is public — no auth required for the compare endpoint.\ncurl -sSL "https://api.github.com/repos/ai-ecoverse/slicc/compare/v${FROM_VERSION}...v${TO_VERSION}" \\\n | node -e \'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const j=JSON.parse(s);console.log(j.commits.map(c=>"- "+c.commit.message.split("\\n")[0]).join("\\n"))})\'\n```\n\nShow the conventional-commit messages grouped by type (`feat`, `fix`, `chore`, ...). If the compare returns 404 (tags missing), fall back to the GitHub releases page URL: `https://github.com/ai-ecoverse/slicc/releases/tag/v${TO_VERSION}`.\n\n## Three-way merge (`action: \'merge-vfs-root\'`)\n\nThe user\'s VFS may have local edits to bundled skills, sprinkles, or scripts. The three inputs to the merge are:\n\n- **base** = the bundled vfs-root file at the **previous** release tag (`v${FROM_VERSION}`). This is what the user originally received and is the common ancestor of both sides.\n- **ours** = the file currently in the user\'s VFS (which may equal `base` if untouched, or may carry local edits).\n- **theirs** = the bundled vfs-root file at the **new** release tag (`v${TO_VERSION}`).\n\nConcretely:\n\n1. Identify candidate paths under `/workspace/skills/` and `/shared/sprinkles/` that match bundled files. Per file:\n - Fetch `base` from `https://raw.githubusercontent.com/ai-ecoverse/slicc/v${FROM_VERSION}/packages/vfs-root/<rest-of-path>`.\n - Fetch `theirs` from `https://raw.githubusercontent.com/ai-ecoverse/slicc/v${TO_VERSION}/packages/vfs-root/<rest-of-path>`.\n - Read `ours` from the user\'s VFS at the equivalent runtime path (e.g. `/workspace/skills/<name>/SKILL.md`).\n2. Decide per file:\n - If `base == theirs`: nothing changed upstream → leave the user\'s file alone (no merge needed).\n - If `ours == base` and `base != theirs`: the user has not edited this file → safe fast-forward to `theirs`.\n - If `ours != base` and `base != theirs`: real 3-way merge. Write the three sides to `/tmp` and let `git merge-file` produce the result:\n ```bash\n git merge-file --stdout /tmp/ours /tmp/base /tmp/theirs > /tmp/merged\n ```\n Exit code 0 → clean merge; write `/tmp/merged` back to the VFS path. Non-zero exit means conflicts (`<<<<<<<` markers in the output) — surface the conflicting hunks and let the user pick.\n3. Present the per-file outcome as a summary table (`auto-applied`, `kept-local`, `needs-review`) and stop. Do not silently overwrite anything.\n\n## Do not\n\n- Do not run a merge without showing the action card first. The user must explicitly click `Update workspace files`.\n- Do not delete files that no longer exist in the new release — many users name-collide their own scripts with bundled ones; deletion is too dangerous to automate.\n- Do not modify files outside `/workspace/skills/`, `/shared/sprinkles/`, and `/shared/sounds/` without the user explicitly extending the scope.\n- Do not advance the bundled version marker yourself. The runtime advances it automatically once this lick has been routed; if the user dismisses, the lick will not fire again until the next upgrade.\n',g4=`---
|
|
7164
7179
|
name: welcome
|
|
7165
7180
|
description: |
|
|
7166
7181
|
Use this when you receive a \`[Sprinkle Event: welcome]\` lick with
|
|
@@ -7216,7 +7231,7 @@ Your one and only job is to send a single short reply (≤ 6 sentences total) th
|
|
|
7216
7231
|
Do **not** print a capability table, do **not** call \`update_global_memory\`, do **not** install other skills beyond the \`upskill recommendations --install\` step below, do **not** edit \`/shared/CLAUDE.md\`.
|
|
7217
7232
|
|
|
7218
7233
|
After sending the reply, silently run \`upskill recommendations --install\` (do **not** show the output to the user) to land the user's recommended skill set. The command is profile-driven (it reads \`/home/<user>/.welcome.json\`, which the webapp persisted when the wizard finished) and idempotent.
|
|
7219
|
-
`,
|
|
7234
|
+
`,_4=`---
|
|
7220
7235
|
name: x-search
|
|
7221
7236
|
description: |
|
|
7222
7237
|
Search X (formerly Twitter) for real-time posts, sentiment, and citations
|
|
@@ -7284,7 +7299,7 @@ Sources:
|
|
|
7284
7299
|
toggles bloat the response.
|
|
7285
7300
|
- This skill is a slicc-native shell command — \`pi.registerTool\` does not
|
|
7286
7301
|
apply here. The behavior matches stnly/pi-grok's \`x_search\` tool.
|
|
7287
|
-
`,
|
|
7302
|
+
`,v4=`// x_search — proxy xAI's server-side \`x_search\` tool via the Responses API.
|
|
7288
7303
|
//
|
|
7289
7304
|
// Resolves the bearer token through \`oauth-token xai-grok\` so any model can
|
|
7290
7305
|
// pull X (Twitter) results regardless of which provider is steering the cone.
|
|
@@ -7412,10 +7427,10 @@ if (citations.length) {
|
|
|
7412
7427
|
console.log(\`- \${title}\${c.url}\`);
|
|
7413
7428
|
}
|
|
7414
7429
|
}
|
|
7415
|
-
`,
|
|
7430
|
+
`,y4=`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=`;const b4=`/workspace/skills`,x4=`SKILL.md`,S4=[`native`,`agents`,`claude`],C4=new Map([[`.agents`,`agents`],[`.claude`,`claude`]]),w4=new Set([`.git`,`.slicc`]),T4=[`mkdir`,`mount`,`rename`,`rm`,`unmount`,`writeFile`],E4=new WeakMap,D4=new WeakSet;async function O4(e,t=b4){let n=await j4(e,t),r=await k4(e);return[...S4.flatMap(e=>(e===`native`?n:r.filter(t=>t.source===e)).sort((e,t)=>e.path.localeCompare(t.path)))]}async function k4(e){N4(e);let t=e,n=E4.get(t);if(n)return n.map(e=>({...e}));let r=await M4(e);return E4.set(t,r),r.map(e=>({...e}))}function A4(e,t){let n=new Map,r=new Map;for(let i of e){let e=t(i);if(!n.has(e)){n.set(e,i);continue}let a=r.get(e)??{name:e,winner:n.get(e),shadowed:[]};a.shadowed.push(i),r.set(e,a)}return{winners:Array.from(n.values()),collisions:Array.from(r.values())}}async function j4(e,t){let n=await F4(e,t),r=[];for(let i of n){if(i.type!==`directory`)continue;let n=`${t}/${i.name}`,a=`${n}/${x4}`;await P4(e,a)&&r.push({source:`native`,sourceRoot:t,path:n,skillFilePath:a})}return r}async function M4(e){let t=[],n=new Set,r=[`/`];for(let i=0;i<r.length;i+=1){let a=r[i],o=await F4(e,a);for(let i of o){if(i.type!==`directory`)continue;let o=a===`/`?`/${i.name}`:`${a}/${i.name}`,s=C4.get(i.name);if(s){let r=`${o}/skills`,i=await F4(e,r);for(let a of i){if(a.type!==`directory`)continue;let i=`${r}/${a.name}`,o=`${i}/${x4}`;!await P4(e,o)||n.has(i)||(n.add(i),t.push({source:s,sourceRoot:r,path:i,skillFilePath:o}))}}w4.has(i.name)||r.push(o)}}return t}function N4(e){let t=e;if(D4.has(t))return;D4.add(t);let n=e;for(let r of T4){let i=n[r];if(typeof i!=`function`)continue;let a=i;try{n[r]=async(...n)=>{let r=await a.apply(e,n);return E4.delete(t),r}}catch{}}}async function P4(e,t){try{return await e.stat(t),!0}catch{return!1}}async function F4(e,t){try{return[...await e.readDir(t)].sort((e,t)=>e.name.localeCompare(t.name))}catch{return[]}}async function I4(e,t=`/workspace/skills`){let n=await O4(e,t),r=[];for(let t of n){let n=t.path.split(`/`).pop()??t.path,i=``;if(t.skillFilePath)try{i=z4(await e.readTextFile(t.skillFilePath))??``}catch{}r.push({name:n,source:t.source,sourceRoot:t.sourceRoot,path:t.path,skillFilePath:t.skillFilePath,description:i})}let{winners:i,collisions:a}=A4(r,e=>e.name),o=new Map(a.map(e=>[e.winner.path,e.shadowed.map(e=>e.path)]));return i.map(e=>({...e,shadowedPaths:o.get(e.path)}))}async function L4(e,t,n=`/workspace/skills`){return(await I4(e,n)).find(e=>e.name===t)||null}async function R4(e,t,n=`/workspace/skills`){let r=await L4(e,t,n);if(!r?.skillFilePath)return null;try{return await e.readTextFile(r.skillFilePath)}catch{return null}}function z4(e){let t=e.replace(/^\uFEFF/,``).replace(/\r\n?/g,`
|
|
7416
7431
|
`).trimStart().match(/^---\s*\n([\s\S]*?)\n---/);if(!t)return null;for(let e of t[1].split(`
|
|
7417
|
-
`)){let t=e.match(/^description:\s*(.*)$/);if(t)return t[1].trim()}return null}var
|
|
7418
|
-
`)){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
|
|
7432
|
+
`)){let t=e.match(/^description:\s*(.*)$/);if(t)return t[1].trim()}return null}var B4=n({MAX_SKILL_ARCHIVE_SIZE_BYTES:()=>MAX_SKILL_ARCHIVE_SIZE_BYTES,SKILLS_DIR:()=>OJ,SKILL_ARCHIVE_EXTENSION:()=>SKILL_ARCHIVE_EXTENSION,SKILL_FILE:()=>x4,WORKSPACE_SKILLS_PATH:()=>b4,discoverSkills:()=>I4,getSkillInfo:()=>L4,readSkillInstructions:()=>R4});const V4=i(`skills`),H4=Object.assign({"/packages/vfs-root/AGENTS.md":e4,"/packages/vfs-root/CLAUDE.md":e4,"/packages/vfs-root/shared/CLAUDE.md":t4,"/packages/vfs-root/shared/sprinkles/welcome/connect-llm.shtml":n4,"/packages/vfs-root/shared/sprinkles/welcome/welcome.shtml":r4,"/packages/vfs-root/workspace/skills/automation/SKILL.md":i4,"/packages/vfs-root/workspace/skills/delegation/SKILL.md":a4,"/packages/vfs-root/workspace/skills/dips/SKILL.md":o4,"/packages/vfs-root/workspace/skills/dips/patterns.md":s4,"/packages/vfs-root/workspace/skills/handoff/SKILL.md":c4,"/packages/vfs-root/workspace/skills/mount/SKILL.md":l4,"/packages/vfs-root/workspace/skills/playwright-cli/SKILL.md":u4,"/packages/vfs-root/workspace/skills/skill-authoring/SKILL.md":d4,"/packages/vfs-root/workspace/skills/sprinkles/SKILL.md":f4,"/packages/vfs-root/workspace/skills/sprinkles/icon-example.md":p4,"/packages/vfs-root/workspace/skills/sprinkles/style-guide.md":m4,"/packages/vfs-root/workspace/skills/upgrade/SKILL.md":h4,"/packages/vfs-root/workspace/skills/welcome/SKILL.md":g4,"/packages/vfs-root/workspace/skills/x-search/SKILL.md":_4,"/packages/vfs-root/workspace/skills/x-search/x_search.jsh":v4}),U4=Object.assign({"/packages/vfs-root/shared/sounds/chime.mp3":y4});function W4(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 G4(){let e={};for(let[t,n]of Object.entries(H4))e[t]=n;for(let[t,n]of Object.entries(U4))e[t]=W4(n);return e}function K4(e){let t=new Map;for(let n of e){if(t.has(n.metadata.name)){V4.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 q4(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(`
|
|
7433
|
+
`)){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 J4(e,t){let n=await Y4(e,t),r=await X4(e,t),i=n.filter(e=>e.source===`native`),a=n.filter(e=>e.source!==`native`),o=K4([...i,...r,...a]);return V4.info(`Skills loaded`,{count:o.length,dir:t}),o}async function Y4(e,t){let n=await I4(e,t),r=[];for(let t of n)if(t.skillFilePath)try{let{metadata:n,body:i}=q4(await e.readTextFile(t.skillFilePath)),a=n.name||t.name;r.push({metadata:{name:a,description:n.description||t.description||``,allowedTools:n.allowedTools},content:i,path:t.skillFilePath,source:t.source}),V4.debug(`Loaded discovered skill`,{name:a,path:t.skillFilePath,source:t.source})}catch{V4.debug(`Failed to load discovered skill`,{name:t.name,path:t.skillFilePath})}return r}async function X4(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}=q4(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}),V4.debug(`Loaded standalone skill`,{name:s,path:r})}catch{}}}catch{V4.debug(`Standalone skills directory not found`,{dir:t})}return n}function Z4(e){return e.length===0?``:`
|
|
7419
7434
|
---
|
|
7420
7435
|
AVAILABLE SKILLS
|
|
7421
7436
|
|
|
@@ -7424,10 +7439,10 @@ The following skills are available. To use a skill, first read its full instruct
|
|
|
7424
7439
|
|
|
7425
7440
|
${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(`
|
|
7426
7441
|
`)}
|
|
7427
|
-
---`}async function
|
|
7428
|
-
`)}`}}}),o&&p.push({name:`scoop_scoop`,description:`Create a new scoop. Optionally specify a model, a prompt, and per-scoop sandbox shape (visible/writable paths + command allow-list). 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.`},visiblePaths:{type:`array`,items:{type:`string`},description:`VFS paths the scoop can READ (not write). Pure replace — what you set is what you get. Omit to use the default ["/workspace/"] which exposes the shared skills tree. Pass [] for no extra read-only paths. Note: the scoop's writablePaths are always readable too, so a true read-nothing sandbox also requires writablePaths: []. Mounts remain readable regardless. Trailing slash recommended (e.g. "/shared/data/").`},writablePaths:{type:`array`,items:{type:`string`},description:`VFS paths the scoop can READ AND WRITE. Pure replace. Omit to use the default ["/scoops/<folder>/", "/shared/"] which gives the scoop its own sandbox plus shared space. Pass [] to block all writes. Trailing slash recommended.`},allowedCommands:{type:`array`,items:{type:`string`},description:`Shell command allow-list. Omit for unrestricted access to every built-in, custom, and .jsh command (the default). Pass a list of command names to restrict the scoop's shell — e.g. ["echo","cat","grep"] for a read-only text-processing scoop. Pass ["*"] for explicit unrestricted. Applies to pipelines, substitutions, and network commands too.`},thinking:{type:`string`,enum:[...Dt],description:`Reasoning / thinking-level for this scoop (pi-ai effort). One of: off, minimal, low, medium, high, xhigh. Omit to inherit the global default ("off"). Non-reasoning models always clamp to "off"; "xhigh" clamps to "high" on models that do not support the max tier.`}},required:[`name`]},execute:async e=>{let{name:t,model:n,prompt:i,visiblePaths:a,writablePaths:s,allowedCommands:c,thinking:l}=e,u;if(l!==void 0){if(!Ot(l))return{content:`Invalid thinking level "${l}". Must be one of: ${Dt.join(`, `)}.`,isError:!0};u=l}let d=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,50)+`-scoop`;try{let e=await o({name:t,folder:d,trigger:`@${d}`,isCone:!1,type:`scoop`,requiresTrigger:!0,assistantLabel:d,addedAt:new Date().toISOString(),config:{...n?{modelId:n}:{},visiblePaths:a??[`/workspace/`],writablePaths:s??[`/scoops/${d}/`,`/shared/`],...c?{allowedCommands:c}:{},...u?{thinkingLevel:u}:{}},configSchemaVersion:2});if(
|
|
7429
|
-
`)}}}),f&&p.push({name:`scoop_wait`,description:"Schedule a non-blocking wait for the given scoops. Returns immediately — the cone keeps its turn — and a `scoop-wait` lick is delivered when every listed scoop completes or the optional timeout fires. Use this to coordinate parallel work without freezing the cone: feed several scoops, call scoop_wait, then continue with other work; you'll be woken by the lick with all per-scoop summaries in one shot. Already-completed scoops (including those whose completion arrived while you were processing your previous turn) are folded into the same lick.",inputSchema:{type:`object`,properties:{scoop_names:{type:`array`,items:{type:`string`},description:`Folder or display names of scoops to wait for (e.g., ["writer-scoop", "reviewer-scoop"]).`},timeout_ms:{type:`number`,description:"Optional timeout in milliseconds. If any listed scoop has not completed by the deadline, it is reported as timed-out in the eventual `scoop-wait` lick. Omit for no timeout."}},required:[`scoop_names`]},execute:async e=>{let{scoop_names:t,timeout_ms:n}=e;if(!Array.isArray(t)||t.length===0)return{content:`scoop_names must be a non-empty array.`,isError:!0};if(n!==void 0&&(typeof n!=`number`||!Number.isFinite(n)||n<0))return{content:`timeout_ms must be a non-negative finite number (or omitted).`,isError:!0};let{resolved:r,unknown:a}=H4(t,i);if(r.length===0)return{content:`No matching scoops found. Unknown: ${a.join(`, `)}`,isError:!0};let o=f(r.map(e=>e.jid),n),s=new Map(r.map(e=>[e.jid,e.folder])),c=o.scheduled.map(e=>s.get(e)??e).join(`, `),l=o.unknown.map(e=>s.get(e)??e).join(`, `);return V4.info(`Wait scheduled`,{scheduled:o.scheduled.map(e=>s.get(e)??e),droppedAtSchedule:l?l.split(`, `):[],unknownNames:a,timeout_ms:n}),o.scheduled.length===0?{content:`scoop_wait could not be scheduled — every listed scoop was unregistered before the wait could start (dropped: ${l||o.unknown.join(`, `)}).${a.length>0?` Unknown names: ${a.join(`, `)}.`:``}`,isError:!0}:{content:`scoop_wait scheduled for: ${c}${n===void 0?` (no timeout)`:` (timeout: ${n}ms)`}.${a.length>0?` Unknown (skipped): ${a.join(`, `)}.`:``}${l?` Dropped before schedule (skipped): ${l}.`:``} Continue with other work — a 'scoop-wait' lick will be delivered when all listed scoops complete or the timeout fires.`}}}),c&&l&&p.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 c(t),V4.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}}}})),p}const W4=new Map;function G4(){return new Date().toISOString().slice(0,10)}function K4(){try{let e=globalThis.localStorage;return!e||typeof e.getItem!=`function`||typeof e.setItem!=`function`?null:e}catch{return null}}function q4(e){let t=G4(),n=K4(),r=`slicc:adobe-daily-uuid:`+e;if(n){let e=null;try{e=n.getItem(r)}catch{e=null}if(e)try{let n=JSON.parse(e);if(n.date===t&&typeof n.uuid==`string`)return n.uuid}catch{}let i=crypto.randomUUID();try{n.setItem(r,JSON.stringify({uuid:i,date:t}))}catch{}return i}let i=W4.get(e);if(i&&i.date===t)return i.uuid;let a=crypto.randomUUID();return W4.set(e,{uuid:a,date:t}),a}async function J4(e,t){let n=new TextEncoder().encode(`${t}:${e}`),r=await crypto.subtle.digest(`SHA-256`,n);return Array.from(new Uint8Array(r).slice(0,8)).map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function Y4(e,t){let n=q4(t??e.jid);return e.isCone?n:`${n}/${await J4(e.folder,n)}`}const X4=i(`secret-env`);function Z4(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}async function Q4(){if(typeof chrome<`u`&&chrome?.runtime?.id)return new Promise(e=>{chrome.runtime.sendMessage({type:`secrets.list-masked-entries`},t=>{let n=t,r={};for(let e of n?.entries??[])e.name&&e.maskedValue&&Z4(e.name)&&(r[e.name]=e.maskedValue);Object.keys(r).length>0&&X4.info(`Loaded masked secrets into shell env from SW`,{count:Object.keys(r).length}),e(r)})});try{let e=await fetch(`/api/secrets/masked`);if(!e.ok)return X4.warn(`Failed to fetch masked secrets`,{status:e.status}),{};let t=await e.json();if(!Array.isArray(t)||t.length===0)return{};let n={};for(let e of t)e.name&&e.maskedValue&&Z4(e.name)&&(n[e.name]=e.maskedValue);return Object.keys(n).length>0&&X4.info(`Loaded masked secrets into shell env`,{count:Object.keys(n).length}),n}catch(e){return X4.debug(`Could not fetch masked secrets (server may be unavailable)`,{error:e instanceof Error?e.message:String(e)}),{}}}const $4=i(`scoop-context`);function e3(e,t){return!t.reasoning||e===void 0?`off`:e===`xhigh`&&!Ye(t).includes(`xhigh`)?`high`:e}function t3(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)}function n3(e){return/\b(401|403|404|405|410|422)\b/.test(e)||/unauthorized|forbidden|authentication.*failed|invalid.*api.?key/i.test(e)||/model.*not.*found|invalid.*model|unknown.*model|does.*not.*exist/i.test(e)||/insufficient.*quota|billing|payment.*required|account.*suspended/i.test(e)||/invalid.*request|malformed|bad.*request/i.test(e)}function r3(e){return/\b429\b|rate.*limit|too.*many.*requests|quota.*exceeded/i.test(e)||/\b(500|502|503|504)\b|internal.*server|bad.*gateway|service.*unavailable|gateway.*timeout/i.test(e)||/network.*error|failed to fetch|connection.*refused|timeout|econnreset|socket.*hang.*up/i.test(e)||/overloaded|temporarily.*unavailable|try.*again/i.test(e)}function i3(e,t){return t?.aborted?Promise.resolve(!0):new Promise(n=>{let r=()=>{clearTimeout(i),n(!0)},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n(!1)},e);t?.addEventListener(`abort`,r,{once:!0})})}var a3=class{scoop;callbacks;fs=null;shell=null;agent=null;status=`initializing`;isProcessing=!1;disposed=!1;didStreamDeltas=!1;promptStreamErrorMessage=null;unsubscribe=null;promptAbortController=null;processManager=null;currentTurnProcess=null;sessionStore=null;sessionId;sessionCreatedAt=0;isRecovering=!1;coneJid;skillsFs=null;skillsDir=`/workspace/skills`;constructor(e,t,n,r,i,a,o){this.scoop=e,this.callbacks=t,this.fs=n,this.sessionStore=r??null,this.skillsFs=i??null,this.coneJid=a,this.processManager=o??null,this.sessionId=e.jid}async init(){this.setStatus(`initializing`);try{if(!this.fs)throw Error(`Filesystem not provided`);$4.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 R4(this.fs,this.skillsDir);let n=this.skillsFs??this.fs,r=await Q4();this.shell=new k2({fs:this.fs,cwd:e,env:Object.keys(r).length>0?r:void 0,browserAPI:t,jshDiscoveryFs:this.skillsFs?n:void 0,allowedCommands:this.scoop.config?.allowedCommands,getParentJid:()=>this.scoop.jid,isScoop:()=>!this.scoop.isCone}),$4.info(`WasmShell initialized`,{folder:this.scoop.folder});let i=await P4(n,this.skillsDir),a=U4({scoop:this.scoop,onSendMessage:this.callbacks.onSendMessage,getScoops:this.callbacks.getScoops,getScoopTabState:this.callbacks.getScoopTabState,onFeedScoop:this.callbacks.onFeedScoop,onScoopScoop:this.callbacks.onScoopScoop,onDropScoop:this.callbacks.onDropScoop,onMuteScoops:this.callbacks.onMuteScoops,onUnmuteScoops:this.callbacks.onUnmuteScoops,onScheduleScoopWait:this.callbacks.onScheduleScoopWait,onSetGlobalMemory:this.callbacks.setGlobalMemory,getGlobalMemory:this.callbacks.getGlobalMemory}),o=[...j2(this.fs),z2(this.shell),...a],s=this.processManager?fe(o,{processManager:this.processManager,owner:{kind:this.scoop.isCone?`cone`:`scoop`,scoopJid:this.scoop.jid},getParentPid:()=>this.currentTurnProcess?.pid}):fe(o),c=this.scoop.isCone?`/workspace/CLAUDE.md`:`/scoops/${this.scoop.folder}/CLAUDE.md`,l=``;try{let e=await this.fs.readFile(c,{encoding:`utf-8`});l=typeof e==`string`?e:new TextDecoder().decode(e)}catch{}let u=await this.callbacks.getGlobalMemory();if(u)try{this.scoop.isCone&&await(`getUnderlyingFS`in this.fs?this.fs.getUnderlyingFS():this.fs).writeFile(`/shared/CLAUDE.md`,u)}catch{}if(!ce()){$4.info(`ScoopContext init deferred — no API key yet`,{folder:this.scoop.folder}),this.setStatus(`ready`);return}let d=this.scoop.config?.modelId?k(this.scoop.config.modelId):le(),f=this.scoop.isCone?`Cone`:`Scoop "${this.scoop.name}"`;console.log(`[model] ${f} using model: ${d.id} (provider: ${d.provider})`);let p=this.buildSystemPrompt(u,l,i),m=[];if(this.sessionStore)try{let e=await this.sessionStore.load(this.sessionId);e&&(m=ue(e.messages),this.sessionCreatedAt=e.createdAt,$4.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:m.length,droppedOrphans:e.messages.length-m.length}))}catch(e){$4.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 h=await Y4(this.scoop,this.coneJid),g=(e,t,n)=>e.provider===`adobe`?qe(e,t,{...n,headers:{...n?.headers,"X-Session-Id":h}}):qe(e,t,n),_=ee({model:d,getApiKey:()=>ce()??void 0,headers:d.provider===`adobe`?{"X-Session-Id":h}:void 0,onMemoryUpdates:this.scoop.isCone&&this.callbacks.appendGlobalMemory?e=>this.callbacks.appendGlobalMemory(e,{source:`compaction`}):void 0,onCompactionStateChange:this.callbacks.onCompactionStateChange});if(this.disposed)return;let v=e3(this.scoop.config?.thinkingLevel,d);this.agent=new de({initialState:{model:d,tools:s,systemPrompt:p,messages:m,thinkingLevel:v},getApiKey:()=>ce()??void 0,transformContext:_,streamFn:g}),this.unsubscribe=this.agent.subscribe(e=>this.handleAgentEvent(e)),this.setStatus(`ready`),$4.info(`ScoopContext initialized`,{folder:this.scoop.folder,toolCount:s.length})}catch(e){if(this.disposed)return;let t=e instanceof Error?e.message:String(e);$4.error(`ScoopContext init failed`,{folder:this.scoop.folder,error:t}),this.setStatus(`error`),this.callbacks.onError(`Failed to initialize: ${t}`)}}async prompt(e,t=[]){if(!this.agent&&(await this.init(),!this.agent)){let e=``;try{e=ne()}catch{}this.callbacks.onError(e?`No API key configured for provider "${e}". Open Settings to add one.`:`No API key configured. Open Settings to add one.`);return}let n=this.agent.state?.isStreaming??!1;if(this.isProcessing||n){$4.info(`Queueing prompt via followUp while processing`,{folder:this.scoop.folder,isProcessing:this.isProcessing,agentIsStreaming:n}),this.agent.followUp({role:`user`,content:[{type:`text`,text:e},...t],timestamp:Date.now()});return}let r=this.agent;this.promptAbortController?.abort();let i=new AbortController;this.promptAbortController=i;let a=i.signal;this.isProcessing=!0,this.setStatus(`processing`);let o=[`prompt`,e.length>200?e.slice(0,197)+`…`:e],s=this.processManager?this.processManager.spawn({kind:`scoop-turn`,argv:o,cwd:this.scoop.isCone?`/`:`/scoops/${this.scoop.folder}/workspace`,owner:{kind:this.scoop.isCone?`cone`:`scoop`,scoopJid:this.scoop.jid},adoptAbort:i}):null;this.currentTurnProcess=s;let c=1e3,l=null;try{for(let n=1;n<=3;n++){if(this.disposed||a.aborted)return;this.didStreamDeltas=!1;try{if(this.promptStreamErrorMessage=null,await r.prompt(e,t),this.promptStreamErrorMessage){let e=this.promptStreamErrorMessage;throw this.promptStreamErrorMessage=null,Error(e)}l=null;break}catch(e){if(this.disposed||a.aborted)return;l=e instanceof Error?e:Error(String(e));let t=l.message;if(n3(t)){$4.error(`Non-retryable agent error`,{folder:this.scoop.folder,error:t,attempt:n}),this.setStatus(`error`),this.callbacks.onFatalError?this.callbacks.onFatalError(`Scoop "${this.scoop.name}" failed with unrecoverable error: ${t}`):this.callbacks.onError(t);return}if(r3(t)&&n<3){let e=c*2**(n-1);if($4.warn(`Retryable agent error, will retry`,{folder:this.scoop.folder,error:t,attempt:n,maxRetries:3,delayMs:e}),await i3(e,a)||this.disposed)return;continue}if($4.error(`Agent error`,{folder:this.scoop.folder,error:t,attempt:n,isRetryable:r3(t)}),n===3)break;if(await i3(c*2**(n-1),a)||this.disposed)return}}if(l&&!this.disposed&&!a.aborted){let e=l.message;$4.error(`Agent error after retries exhausted`,{folder:this.scoop.folder,error:e,maxRetries:3}),this.setStatus(`error`),this.callbacks.onFatalError?this.callbacks.onFatalError(`Scoop "${this.scoop.name}" failed after 3 attempts: ${e}`):this.callbacks.onError(e);return}!this.disposed&&!a.aborted&&this.setStatus(`ready`)}finally{this.isProcessing=!1,!this.disposed&&this.status===`processing`&&this.setStatus(`ready`),this.promptAbortController===i&&(this.promptAbortController=null),s&&this.processManager&&(l&&!a.aborted?this.processManager.exit(s.pid,1):this.processManager.exit(s.pid,a.aborted?null:0)),this.currentTurnProcess===s&&(this.currentTurnProcess=null)}}stop(){this.currentTurnProcess&&this.processManager?this.processManager.signal(this.currentTurnProcess.pid,`SIGINT`):this.promptAbortController?.abort(),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=le();this.agent.state.model=e;let t=this.scoop.config?.thinkingLevel;this.agent.state.thinkingLevel=e3(t,e),$4.info(`Model updated on running agent`,{folder:this.scoop.folder,model:e.id,thinkingLevel:this.agent.state.thinkingLevel})}async reloadSkills(){if(!this.agent)return;let e=await P4(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,$4.info(`Skills reloaded`,{folder:this.scoop.folder,skillCount:e.length})}setThinkingLevel(e){if(!this.agent)return`off`;let t=e3(e,this.agent.state.model);return this.agent.state.thinkingLevel=t,t}getThinkingLevel(){return this.agent?.state.thinkingLevel??`off`}dispose(){this.disposed=!0,this.currentTurnProcess&&this.processManager?this.processManager.signal(this.currentTurnProcess.pid,`SIGTERM`):this.promptAbortController?.abort(),this.promptAbortController=null,this.agent?.clearAllQueues?.(),this.agent?.abort?.(),this.unsubscribe?.(),this.shell?.dispose(),this.agent=null,this.shell=null,this.fs=null}setStatus(e){this.disposed||(this.status=e,this.callbacks.onStatusChange(e))}handleAgentEvent(e){if(!this.disposed)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(`
|
|
7430
|
-
`),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&&
|
|
7442
|
+
---`}async function Q4(e,t=`/workspace/skills`){let n=G4();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),V4.info(`Created default file`,{path:s})}}}const $4=new Set([`/shared/sprinkles/welcome/welcome.shtml`,`/shared/sprinkles/welcome/connect-llm.shtml`]);async function e3(e){let t=G4();for(let[n,r]of Object.entries(t)){let t=n.slice(18);if(!t.startsWith(`/shared/`))continue;let i=$4.has(t);if(!i)try{await e.stat(t);continue}catch{}let a=t.substring(0,t.lastIndexOf(`/`));try{await e.mkdir(a,{recursive:!0})}catch{}await e.writeFile(t,r),V4.info(i?`Refreshed bundled shared file`:`Created default shared file`,{path:t})}}const t3=i(`scoop-management-tools`);function n3(e,t){let n=t(),r=[],i=[];for(let t of e){let e=n.find(e=>!e.isCone&&(e.folder===t||e.name===t));e?r.push(e):i.push(t)}return{resolved:r,unknown:i}}function r3(e){let{scoop:t,onSendMessage:n,onFeedScoop:r,getScoops:i,getScoopTabState:a,onScoopScoop:o,onDropScoop:s,onSetGlobalMemory:c,getGlobalMemory:l,onMuteScoops:u,onUnmuteScoops:d,onScheduleScoopWait:f}=e,p=[];return p.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),t3.info(`Message sent`,{scoopFolder:t.folder,textLength:r.length}),{content:`Message sent.`}}}),t.isCone&&r&&p.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),t3.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&&(p.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=>{let t=a?.(e.jid),n=t?.status??`unknown`,r=t?.lastActivity?new Date(t.lastActivity).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hour12:!0}):``,i=r?` — ${n} (since ${r})`:` — ${n}`;return e.isCone?`- ${e.assistantLabel} (${e.folder}) [CONE]${i}`:`- ${e.name} (${e.folder})${i}`}).join(`
|
|
7443
|
+
`)}`}}}),o&&p.push({name:`scoop_scoop`,description:`Create a new scoop. Optionally specify a model, a prompt, and per-scoop sandbox shape (visible/writable paths + command allow-list). 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.`},visiblePaths:{type:`array`,items:{type:`string`},description:`VFS paths the scoop can READ (not write). Pure replace — what you set is what you get. Omit to use the default ["/workspace/"] which exposes the shared skills tree. Pass [] for no extra read-only paths. Note: the scoop's writablePaths are always readable too, so a true read-nothing sandbox also requires writablePaths: []. Mounts remain readable regardless. Trailing slash recommended (e.g. "/shared/data/").`},writablePaths:{type:`array`,items:{type:`string`},description:`VFS paths the scoop can READ AND WRITE. Pure replace. Omit to use the default ["/scoops/<folder>/", "/shared/"] which gives the scoop its own sandbox plus shared space. Pass [] to block all writes. Trailing slash recommended.`},allowedCommands:{type:`array`,items:{type:`string`},description:`Shell command allow-list. Omit for unrestricted access to every built-in, custom, and .jsh command (the default). Pass a list of command names to restrict the scoop's shell — e.g. ["echo","cat","grep"] for a read-only text-processing scoop. Pass ["*"] for explicit unrestricted. Applies to pipelines, substitutions, and network commands too.`},thinking:{type:`string`,enum:[...Dt],description:`Reasoning / thinking-level for this scoop (pi-ai effort). One of: off, minimal, low, medium, high, xhigh. Omit to inherit the global default ("off"). Non-reasoning models always clamp to "off"; "xhigh" clamps to "high" on models that do not support the max tier.`}},required:[`name`]},execute:async e=>{let{name:t,model:n,prompt:i,visiblePaths:a,writablePaths:s,allowedCommands:c,thinking:l}=e,u;if(l!==void 0){if(!Ot(l))return{content:`Invalid thinking level "${l}". Must be one of: ${Dt.join(`, `)}.`,isError:!0};u=l}let d=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,50)+`-scoop`;try{let e=await o({name:t,folder:d,trigger:`@${d}`,isCone:!1,type:`scoop`,requiresTrigger:!0,assistantLabel:d,addedAt:new Date().toISOString(),config:{...n?{modelId:n}:{},visiblePaths:a??[`/workspace/`],writablePaths:s??[`/scoops/${d}/`,`/shared/`],...c?{allowedCommands:c}:{},...u?{thinkingLevel:u}:{}},configSchemaVersion:2});if(t3.info(`Scoop created`,{name:t,folder:d}),i&&r){try{await r(e.jid,i)}catch(e){let n=e instanceof Error?e.message:String(e);return t3.error(`Auto-feed failed`,{name:t,error:n}),{content:`Scoop "${t}" created as "${d}" but the initial task could not be sent: ${n}. Use feed_scoop to retry.`,isError:!0}}return{content:`Scoop "${t}" created as "${d}" and task sent. It is now working on it.`}}return{content:`Scoop "${t}" created as "${d}". 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}}}}),s&&p.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 s(n.jid),t3.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}}}}),u&&p.push({name:`scoop_mute`,description:`Suspend scoop→cone notifications for the given scoops. While muted, a scoop's completion is stashed and will be delivered to the cone when you call scoop_unmute (or scoop_wait which consumes it). Use this when coordinating parallel work so each scoop's completion does not trigger its own cone turn.`,inputSchema:{type:`object`,properties:{scoop_names:{type:`array`,items:{type:`string`},description:`Folder or display names of scoops to mute (e.g., ["writer-scoop", "reviewer-scoop"]).`}},required:[`scoop_names`]},execute:async e=>{let{scoop_names:t}=e;if(!Array.isArray(t)||t.length===0)return{content:`scoop_names must be a non-empty array.`,isError:!0};let{resolved:n,unknown:r}=n3(t,i);return n.length===0?{content:`No matching scoops found. Unknown: ${r.join(`, `)}`,isError:!0}:(u(n.map(e=>e.jid)),t3.info(`Scoops muted`,{names:n.map(e=>e.folder)}),{content:`Muted: ${n.map(e=>e.folder).join(`, `)}${r.length>0?` (unknown: ${r.join(`, `)})`:``}`})}}),d&&p.push({name:`scoop_unmute`,description:`Resume scoop→cone notifications for the given scoops. Any completion that landed while a scoop was muted is returned in this tool result (NOT dispatched as a new cone turn), so you can read all stashed summaries in the current turn. Scoops with no stashed completion are simply unmuted.`,inputSchema:{type:`object`,properties:{scoop_names:{type:`array`,items:{type:`string`},description:`Folder or display names of scoops to unmute (e.g., ["writer-scoop"]).`}},required:[`scoop_names`]},execute:async e=>{let{scoop_names:t}=e;if(!Array.isArray(t)||t.length===0)return{content:`scoop_names must be a non-empty array.`,isError:!0};let{resolved:n,unknown:r}=n3(t,i);if(n.length===0)return{content:`No matching scoops found. Unknown: ${r.join(`, `)}`,isError:!0};let a=n.map(e=>e.jid),o=new Map(n.map(e=>[e.jid,e.folder])),s=await d(a);t3.info(`Scoops unmuted`,{names:n.map(e=>e.folder),stashedCount:s.length});let c=[`Unmuted: ${n.map(e=>e.folder).join(`, `)}${r.length>0?` (unknown: ${r.join(`, `)})`:``}`];if(s.length===0)c.push(`No stashed completions.`);else{c.push(``,`Stashed completions:`);for(let e of s){let t=o.get(e.jid)??e.jid;c.push(`--- ${t} ---`),e.notificationPath&&c.push(`VFS path: ${e.notificationPath}`),c.push(e.summary)}}return{content:c.join(`
|
|
7444
|
+
`)}}}),f&&p.push({name:`scoop_wait`,description:"Schedule a non-blocking wait for the given scoops. Returns immediately — the cone keeps its turn — and a `scoop-wait` lick is delivered when every listed scoop completes or the optional timeout fires. Use this to coordinate parallel work without freezing the cone: feed several scoops, call scoop_wait, then continue with other work; you'll be woken by the lick with all per-scoop summaries in one shot. Already-completed scoops (including those whose completion arrived while you were processing your previous turn) are folded into the same lick.",inputSchema:{type:`object`,properties:{scoop_names:{type:`array`,items:{type:`string`},description:`Folder or display names of scoops to wait for (e.g., ["writer-scoop", "reviewer-scoop"]).`},timeout_ms:{type:`number`,description:"Optional timeout in milliseconds. If any listed scoop has not completed by the deadline, it is reported as timed-out in the eventual `scoop-wait` lick. Omit for no timeout."}},required:[`scoop_names`]},execute:async e=>{let{scoop_names:t,timeout_ms:n}=e;if(!Array.isArray(t)||t.length===0)return{content:`scoop_names must be a non-empty array.`,isError:!0};if(n!==void 0&&(typeof n!=`number`||!Number.isFinite(n)||n<0))return{content:`timeout_ms must be a non-negative finite number (or omitted).`,isError:!0};let{resolved:r,unknown:a}=n3(t,i);if(r.length===0)return{content:`No matching scoops found. Unknown: ${a.join(`, `)}`,isError:!0};let o=f(r.map(e=>e.jid),n),s=new Map(r.map(e=>[e.jid,e.folder])),c=o.scheduled.map(e=>s.get(e)??e).join(`, `),l=o.unknown.map(e=>s.get(e)??e).join(`, `);return t3.info(`Wait scheduled`,{scheduled:o.scheduled.map(e=>s.get(e)??e),droppedAtSchedule:l?l.split(`, `):[],unknownNames:a,timeout_ms:n}),o.scheduled.length===0?{content:`scoop_wait could not be scheduled — every listed scoop was unregistered before the wait could start (dropped: ${l||o.unknown.join(`, `)}).${a.length>0?` Unknown names: ${a.join(`, `)}.`:``}`,isError:!0}:{content:`scoop_wait scheduled for: ${c}${n===void 0?` (no timeout)`:` (timeout: ${n}ms)`}.${a.length>0?` Unknown (skipped): ${a.join(`, `)}.`:``}${l?` Dropped before schedule (skipped): ${l}.`:``} Continue with other work — a 'scoop-wait' lick will be delivered when all listed scoops complete or the timeout fires.`}}}),c&&l&&p.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 c(t),t3.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}}}})),p}const i3=new Map;function a3(){return new Date().toISOString().slice(0,10)}function o3(){try{let e=globalThis.localStorage;return!e||typeof e.getItem!=`function`||typeof e.setItem!=`function`?null:e}catch{return null}}function s3(e){let t=a3(),n=o3(),r=`slicc:adobe-daily-uuid:`+e;if(n){let e=null;try{e=n.getItem(r)}catch{e=null}if(e)try{let n=JSON.parse(e);if(n.date===t&&typeof n.uuid==`string`)return n.uuid}catch{}let i=crypto.randomUUID();try{n.setItem(r,JSON.stringify({uuid:i,date:t}))}catch{}return i}let i=i3.get(e);if(i&&i.date===t)return i.uuid;let a=crypto.randomUUID();return i3.set(e,{uuid:a,date:t}),a}async function c3(e,t){let n=new TextEncoder().encode(`${t}:${e}`),r=await crypto.subtle.digest(`SHA-256`,n);return Array.from(new Uint8Array(r).slice(0,8)).map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function l3(e,t){let n=s3(t??e.jid);return e.isCone?n:`${n}/${await c3(e.folder,n)}`}const u3=i(`secret-env`);function d3(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}async function f3(){if(typeof chrome<`u`&&chrome?.runtime?.id)return new Promise(e=>{chrome.runtime.sendMessage({type:`secrets.list-masked-entries`},t=>{let n=t,r={};for(let e of n?.entries??[])e.name&&e.maskedValue&&d3(e.name)&&(r[e.name]=e.maskedValue);Object.keys(r).length>0&&u3.info(`Loaded masked secrets into shell env from SW`,{count:Object.keys(r).length}),e(r)})});try{let e=await fetch(`/api/secrets/masked`);if(!e.ok)return u3.warn(`Failed to fetch masked secrets`,{status:e.status}),{};let t=await e.json();if(!Array.isArray(t)||t.length===0)return{};let n={};for(let e of t)e.name&&e.maskedValue&&d3(e.name)&&(n[e.name]=e.maskedValue);return Object.keys(n).length>0&&u3.info(`Loaded masked secrets into shell env`,{count:Object.keys(n).length}),n}catch(e){return u3.debug(`Could not fetch masked secrets (server may be unavailable)`,{error:e instanceof Error?e.message:String(e)}),{}}}const p3=i(`scoop-context`);function m3(e,t){return!t.reasoning||e===void 0?`off`:e===`xhigh`&&!Ye(t).includes(`xhigh`)?`high`:e}function h3(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)}function g3(e){return/\b(401|403|404|405|410|422)\b/.test(e)||/unauthorized|forbidden|authentication.*failed|invalid.*api.?key/i.test(e)||/model.*not.*found|invalid.*model|unknown.*model|does.*not.*exist/i.test(e)||/insufficient.*quota|billing|payment.*required|account.*suspended/i.test(e)||/invalid.*request|malformed|bad.*request/i.test(e)}function _3(e){return/\b429\b|rate.*limit|too.*many.*requests|quota.*exceeded/i.test(e)||/\b(500|502|503|504)\b|internal.*server|bad.*gateway|service.*unavailable|gateway.*timeout/i.test(e)||/network.*error|failed to fetch|connection.*refused|timeout|econnreset|socket.*hang.*up/i.test(e)||/overloaded|temporarily.*unavailable|try.*again/i.test(e)}function v3(e,t){return t?.aborted?Promise.resolve(!0):new Promise(n=>{let r=()=>{clearTimeout(i),n(!0)},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n(!1)},e);t?.addEventListener(`abort`,r,{once:!0})})}var y3=class{scoop;callbacks;fs=null;shell=null;agent=null;status=`initializing`;isProcessing=!1;disposed=!1;didStreamDeltas=!1;promptStreamErrorMessage=null;unsubscribe=null;promptAbortController=null;processManager=null;currentTurnProcess=null;sessionStore=null;sessionId;sessionCreatedAt=0;isRecovering=!1;coneJid;skillsFs=null;skillsDir=`/workspace/skills`;constructor(e,t,n,r,i,a,o){this.scoop=e,this.callbacks=t,this.fs=n,this.sessionStore=r??null,this.skillsFs=i??null,this.coneJid=a,this.processManager=o??null,this.sessionId=e.jid}async init(){this.setStatus(`initializing`);try{if(!this.fs)throw Error(`Filesystem not provided`);p3.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 Q4(this.fs,this.skillsDir);let n=this.skillsFs??this.fs,r=await f3();this.shell=new U2({fs:this.fs,cwd:e,env:Object.keys(r).length>0?r:void 0,browserAPI:t,jshDiscoveryFs:this.skillsFs?n:void 0,allowedCommands:this.scoop.config?.allowedCommands,getParentJid:()=>this.scoop.jid,isScoop:()=>!this.scoop.isCone}),p3.info(`WasmShell initialized`,{folder:this.scoop.folder});let i=await J4(n,this.skillsDir),a=r3({scoop:this.scoop,onSendMessage:this.callbacks.onSendMessage,getScoops:this.callbacks.getScoops,getScoopTabState:this.callbacks.getScoopTabState,onFeedScoop:this.callbacks.onFeedScoop,onScoopScoop:this.callbacks.onScoopScoop,onDropScoop:this.callbacks.onDropScoop,onMuteScoops:this.callbacks.onMuteScoops,onUnmuteScoops:this.callbacks.onUnmuteScoops,onScheduleScoopWait:this.callbacks.onScheduleScoopWait,onSetGlobalMemory:this.callbacks.setGlobalMemory,getGlobalMemory:this.callbacks.getGlobalMemory}),o=[...G2(this.fs),$2(this.shell),...a],s=this.processManager?fe(o,{processManager:this.processManager,owner:{kind:this.scoop.isCone?`cone`:`scoop`,scoopJid:this.scoop.jid},getParentPid:()=>this.currentTurnProcess?.pid}):fe(o),c=this.scoop.isCone?`/workspace/CLAUDE.md`:`/scoops/${this.scoop.folder}/CLAUDE.md`,l=``;try{let e=await this.fs.readFile(c,{encoding:`utf-8`});l=typeof e==`string`?e:new TextDecoder().decode(e)}catch{}let u=await this.callbacks.getGlobalMemory();if(u)try{this.scoop.isCone&&await(`getUnderlyingFS`in this.fs?this.fs.getUnderlyingFS():this.fs).writeFile(`/shared/CLAUDE.md`,u)}catch{}if(!ce()){p3.info(`ScoopContext init deferred — no API key yet`,{folder:this.scoop.folder}),this.setStatus(`ready`);return}let d=this.scoop.config?.modelId?k(this.scoop.config.modelId):le(),f=this.scoop.isCone?`Cone`:`Scoop "${this.scoop.name}"`;console.log(`[model] ${f} using model: ${d.id} (provider: ${d.provider})`);let p=this.buildSystemPrompt(u,l,i),m=[];if(this.sessionStore)try{let e=await this.sessionStore.load(this.sessionId);e&&(m=ue(e.messages),this.sessionCreatedAt=e.createdAt,p3.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:m.length,droppedOrphans:e.messages.length-m.length}))}catch(e){p3.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 h=await l3(this.scoop,this.coneJid),g=(e,t,n)=>e.provider===`adobe`?Je(e,t,{...n,headers:{...n?.headers,"X-Session-Id":h}}):Je(e,t,n),_=ee({model:d,getApiKey:()=>ce()??void 0,headers:d.provider===`adobe`?{"X-Session-Id":h}:void 0,onMemoryUpdates:this.scoop.isCone&&this.callbacks.appendGlobalMemory?e=>this.callbacks.appendGlobalMemory(e,{source:`compaction`}):void 0,onCompactionStateChange:this.callbacks.onCompactionStateChange});if(this.disposed)return;let v=m3(this.scoop.config?.thinkingLevel,d);this.agent=new de({initialState:{model:d,tools:s,systemPrompt:p,messages:m,thinkingLevel:v},getApiKey:()=>ce()??void 0,transformContext:_,streamFn:g}),this.unsubscribe=this.agent.subscribe(e=>this.handleAgentEvent(e)),this.setStatus(`ready`),p3.info(`ScoopContext initialized`,{folder:this.scoop.folder,toolCount:s.length})}catch(e){if(this.disposed)return;let t=e instanceof Error?e.message:String(e);p3.error(`ScoopContext init failed`,{folder:this.scoop.folder,error:t}),this.setStatus(`error`),this.callbacks.onError(`Failed to initialize: ${t}`)}}async prompt(e,t=[]){if(!this.agent&&(await this.init(),!this.agent)){let e=``;try{e=ne()}catch{}this.callbacks.onError(e?`No API key configured for provider "${e}". Open Settings to add one.`:`No API key configured. Open Settings to add one.`);return}let n=this.agent.state?.isStreaming??!1;if(this.isProcessing||n){p3.info(`Queueing prompt via followUp while processing`,{folder:this.scoop.folder,isProcessing:this.isProcessing,agentIsStreaming:n}),this.agent.followUp({role:`user`,content:[{type:`text`,text:e},...t],timestamp:Date.now()});return}let r=this.agent;this.promptAbortController?.abort();let i=new AbortController;this.promptAbortController=i;let a=i.signal;this.isProcessing=!0,this.setStatus(`processing`);let o=[`prompt`,e.length>200?e.slice(0,197)+`…`:e],s=this.processManager?this.processManager.spawn({kind:`scoop-turn`,argv:o,cwd:this.scoop.isCone?`/`:`/scoops/${this.scoop.folder}/workspace`,owner:{kind:this.scoop.isCone?`cone`:`scoop`,scoopJid:this.scoop.jid},adoptAbort:i}):null;this.currentTurnProcess=s;let c=1e3,l=null;try{for(let n=1;n<=3;n++){if(this.disposed||a.aborted)return;this.didStreamDeltas=!1;try{if(this.promptStreamErrorMessage=null,await r.prompt(e,t),this.promptStreamErrorMessage){let e=this.promptStreamErrorMessage;throw this.promptStreamErrorMessage=null,Error(e)}l=null;break}catch(e){if(this.disposed||a.aborted)return;l=e instanceof Error?e:Error(String(e));let t=l.message;if(g3(t)){p3.error(`Non-retryable agent error`,{folder:this.scoop.folder,error:t,attempt:n}),this.setStatus(`error`),this.callbacks.onFatalError?this.callbacks.onFatalError(`Scoop "${this.scoop.name}" failed with unrecoverable error: ${t}`):this.callbacks.onError(t);return}if(_3(t)&&n<3){let e=c*2**(n-1);if(p3.warn(`Retryable agent error, will retry`,{folder:this.scoop.folder,error:t,attempt:n,maxRetries:3,delayMs:e}),await v3(e,a)||this.disposed)return;continue}if(p3.error(`Agent error`,{folder:this.scoop.folder,error:t,attempt:n,isRetryable:_3(t)}),n===3)break;if(await v3(c*2**(n-1),a)||this.disposed)return}}if(l&&!this.disposed&&!a.aborted){let e=l.message;p3.error(`Agent error after retries exhausted`,{folder:this.scoop.folder,error:e,maxRetries:3}),this.setStatus(`error`),this.callbacks.onFatalError?this.callbacks.onFatalError(`Scoop "${this.scoop.name}" failed after 3 attempts: ${e}`):this.callbacks.onError(e);return}!this.disposed&&!a.aborted&&this.setStatus(`ready`)}finally{this.isProcessing=!1,!this.disposed&&this.status===`processing`&&this.setStatus(`ready`),this.promptAbortController===i&&(this.promptAbortController=null),s&&this.processManager&&(l&&!a.aborted?this.processManager.exit(s.pid,1):this.processManager.exit(s.pid,a.aborted?null:0)),this.currentTurnProcess===s&&(this.currentTurnProcess=null)}}stop(){this.currentTurnProcess&&this.processManager?this.processManager.signal(this.currentTurnProcess.pid,`SIGINT`):this.promptAbortController?.abort(),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=le();this.agent.state.model=e;let t=this.scoop.config?.thinkingLevel;this.agent.state.thinkingLevel=m3(t,e),p3.info(`Model updated on running agent`,{folder:this.scoop.folder,model:e.id,thinkingLevel:this.agent.state.thinkingLevel})}async reloadSkills(){if(!this.agent)return;let e=await J4(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,p3.info(`Skills reloaded`,{folder:this.scoop.folder,skillCount:e.length})}setThinkingLevel(e){if(!this.agent)return`off`;let t=m3(e,this.agent.state.model);return this.agent.state.thinkingLevel=t,t}getThinkingLevel(){return this.agent?.state.thinkingLevel??`off`}dispose(){this.disposed=!0,this.currentTurnProcess&&this.processManager?this.processManager.signal(this.currentTurnProcess.pid,`SIGTERM`):this.promptAbortController?.abort(),this.promptAbortController=null,this.agent?.clearAllQueues?.(),this.agent?.abort?.(),this.unsubscribe?.(),this.shell?.dispose(),this.agent=null,this.shell=null,this.fs=null}setStatus(e){this.disposed||(this.status=e,this.callbacks.onStatusChange(e))}handleAgentEvent(e){if(!this.disposed)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(`
|
|
7445
|
+
`),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&&h3(n)){this.recoverFromImageError(t);break}if(!this.isRecovering&&qe(e)){this.recoverFromOverflow(t);break}if(!this.isRecovering&&this.isProcessing&&!this.didStreamDeltas){this.promptStreamErrorMessage=n;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=>{p3.error(`Failed to save agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)})});break}}}recoverFromOverflow(e){if(this.agent){p3.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++,p3.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=>{p3.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){p3.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){p3.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=>{p3.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){p3.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
|
|
7431
7446
|
|
|
7432
7447
|
${this.scoop.isCone?`Role: Cone (main orchestrator)`:`Scoop: ${this.scoop.name}`}
|
|
7433
7448
|
Folder: ${this.scoop.folder}
|
|
@@ -7438,7 +7453,7 @@ Created: ${new Date().toISOString()}
|
|
|
7438
7453
|
|
|
7439
7454
|
## Context
|
|
7440
7455
|
(Add important context here)
|
|
7441
|
-
`;try{await this.fs.writeFile(t,e)}catch(e){if(e?.code===`EACCES`)
|
|
7456
|
+
`;try{await this.fs.writeFile(t,e)}catch(e){if(e?.code===`EACCES`)p3.debug(`Skipping default memory write (sandbox is read-only)`,{folder:this.scoop.folder,path:t});else throw e}}}buildSystemPrompt(e,t,n){let r=this.scoop.config?.assistantName||this.scoop.assistantLabel,i=`# ${r}
|
|
7442
7457
|
|
|
7443
7458
|
You are ${r}, ${this.scoop.isCone?`the main assistant (cone)`:`a scoop assistant`} in SLICC (Self-Licking Ice Cream Cone).
|
|
7444
7459
|
|
|
@@ -7506,26 +7521,26 @@ ${e}
|
|
|
7506
7521
|
---
|
|
7507
7522
|
${this.scoop.isCone?`CONE`:`SCOOP`} MEMORY (${this.scoop.name}):
|
|
7508
7523
|
${t}
|
|
7509
|
-
---`);let a=
|
|
7510
|
-
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}let
|
|
7511
|
-
`)}const
|
|
7524
|
+
---`);let a=Z4(n);return a&&(i+=a),i}};const b3=i(`scheduler`);var x3=class{callbacks;pollInterval=null;running=!1;constructor(e){this.callbacks=e}start(){this.running||(this.running=!0,this.pollInterval=setInterval(()=>this.checkTasks(),6e4),this.checkTasks(),b3.info(`Scheduler started`))}stop(){this.pollInterval&&=(clearInterval(this.pollInterval),null),this.running=!1,b3.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 c(i),b3.info(`Task created`,{id:i.id,groupFolder:e,scheduleType:n}),i}async updateTask(e,t){let n=await p(e);if(!n)return null;let r={...n,...t};return(t.scheduleType||t.scheduleValue)&&(r.nextRun=this.calculateNextRun(r.scheduleType,r.scheduleValue)),await c(r),b3.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 p(e)?(await this.updateTask(e,{status:`active`}),!0):!1}async deleteTask(e){return await p(e)?(await v(e),b3.info(`Task deleted`,{id:e}),!0):!1}async getTasksByScoop(e){return(await C()).filter(t=>t.groupFolder===e)}async getAllTasks(){return C()}async checkTasks(){let e=await C(),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){b3.warn(`Task scoop not found`,{taskId:e.id,groupFolder:e.groupFolder});return}b3.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 c({...e,lastRun:n,nextRun:r,status:i}),await this.callbacks.onTaskRun(e,t),b3.info(`Task completed`,{id:e.id})}catch(t){b3.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}},S3=n({LickManager:()=>w3,buildActiveLicksError:()=>T3,getLickManager:()=>D3});const C3=i(`lick-manager`);var w3=class{webhooks=new Map;crontasks=new Map;cronInterval=null;eventHandler=null;async init(){await f();let e=await u();for(let t of e)this.webhooks.set(t.id,t);C3.info(`Loaded webhooks`,{count:this.webhooks.size});let t=await l();for(let e of t)this.crontasks.set(e.id,e);C3.info(`Loaded crontasks`,{count:this.crontasks.size}),this.cronInterval=setInterval(()=>this.runCronScheduler(),6e4),C3.info(`Cron scheduler started`)}dispose(){this.cronInterval&&=(clearInterval(this.cronInterval),null)}setEventHandler(e){this.eventHandler=e}emitEvent(e){C3.info(`External lick event`,{type:e.type,target:e.targetScoop}),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 T(i),C3.info(`Webhook created`,{id:r,name:e,scoop:t}),i}async deleteWebhook(e){return this.webhooks.has(e)?(this.webhooks.delete(e),await x(e),C3.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){C3.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){C3.debug(`Webhook event dropped by filter`,{webhookId:e,name:r.name});return}typeof t==`object`&&t&&(i=t)}catch(t){C3.error(`Webhook filter error`,{webhookId:e,error:t instanceof Error?t.message:String(t)})}C3.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(),s={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,s),await o(s),C3.info(`Cron task created`,{id:a,name:e,cron:t,scoop:n}),s}async deleteCronTask(e){return this.crontasks.has(e)?(this.crontasks.delete(e),await b(e),C3.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){C3.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 o(t);continue}typeof r==`object`&&r&&(n=r)}catch(e){C3.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};C3.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 o(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 T3(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(`
|
|
7525
|
+
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}let E3=null;function D3(){return E3||=new w3,E3}var O3=n({formatMountRecoveryPrompt:()=>M3,mdInlineCode:()=>j3,recoverMounts:()=>k3,shellQuote:()=>A3});async function k3(e,t,n){let r=[],i=[];for(let a of e){let{targetPath:e,descriptor:o}=a;if(o.kind===`local`){let a=await we(o.idbHandleKey),s=typeof a?.name==`string`?a.name:``;if(!a||!(`queryPermission`in a)){i.push({kind:`local`,path:e,dirName:s});continue}let c;try{c=await a.queryPermission({mode:`readwrite`})}catch(t){n?.warn?.(`queryPermission threw on persisted handle`,{path:e,error:t instanceof Error?t.message:String(t)}),i.push({kind:`local`,path:e,dirName:s});continue}if(c!==`granted`){i.push({kind:`local`,path:e,dirName:s});continue}try{let i=xe.fromHandle(a,{mountId:o.mountId});await t.mount(e,i),n?.info?.(`Restored mount from previous session`,{path:e,name:s}),r.push({kind:`local`,path:e,dirName:s})}catch(t){n?.warn?.(`Failed to re-mount persisted handle`,{path:e,error:t instanceof Error?t.message:String(t)}),i.push({kind:`local`,path:e,dirName:s})}continue}if(o.kind===`s3`){try{let i=new nt({mountId:o.mountId,ttlMs:3e4}),a=new Qe({source:o.source,profile:o.profile,cache:i,mountId:o.mountId,signedFetch:tt(o.profile)});await t.mount(e,a),n?.info?.(`Restored S3 mount from previous session`,{path:e,source:o.source}),r.push({kind:`s3`,path:e,source:o.source,profile:o.profile,reason:``})}catch(t){let r=t instanceof Error?t.message:String(t);n?.warn?.(`Failed to restore S3 mount`,{path:e,error:r}),i.push({kind:`s3`,path:e,source:o.source,profile:o.profile,reason:r})}continue}if(o.kind===`da`){try{let i=new nt({mountId:o.mountId,ttlMs:3e4}),a=new $e({source:o.source,profile:o.profile,cache:i,mountId:o.mountId,signedFetch:et()});await t.mount(e,a),n?.info?.(`Restored DA mount from previous session`,{path:e,source:o.source}),r.push({kind:`da`,path:e,source:o.source,profile:o.profile,reason:``})}catch(t){let r=t instanceof Error?t.message:String(t);n?.warn?.(`Failed to restore DA mount`,{path:e,error:r}),i.push({kind:`da`,path:e,source:o.source,profile:o.profile,reason:r})}continue}}return{restored:r,needsRecovery:i}}function A3(e){return`'${e.replace(/'/g,`'\\''`)}'`}function j3(e){let t=e.replace(/\r\n|[\r\n]/g,` `),n=t.match(/`+/g),r=n?Math.max(...n.map(e=>e.length))+1:1,i="`".repeat(r);return`${i}${t.startsWith("`")||t.endsWith("`")?` ${t} `:t}${i}`}function M3(e){if(!Array.isArray(e)||e.length===0)return null;let t=e.length===1?`mount point`:`mount points`,n=e.length===1?`it`:`them`,r=e.filter(e=>e.kind===`local`),i=e.filter(e=>e.kind===`s3`||e.kind===`da`),a=[`[Session Reload] Mount recovery required for ${e.length} ${t}.`,``];if(r.length>0){let e=r.map(({path:e,dirName:t})=>{let n=t?` (previously mounted from ${j3(t)})`:``;return`- ${j3(e)}${n}`}),i=r.map(({path:e})=>` mount ${A3(e)}`);a.push(`The page was reloaded and the following local ${t} lost filesystem permission. The browser cannot restore access without a fresh user gesture, so ${n} cannot be used until the user re-authorizes:`,``,...e,``,`Please tell the user what happened and ask whether they want to re-mount. If yes, run the corresponding command(s) so the folder picker opens and they can re-select the same directory:`,``,...i,``)}if(i.length>0){let e=i.map(({path:e,source:t,profile:n,reason:r})=>{let i=n===`default`?``:` --profile ${A3(n)}`,a=`mount --source ${A3(t)}${i} ${A3(e)}`;return`- ${j3(e)} (${j3(t)}, profile ${j3(n)}) — ${r}\n Retry: ${j3(a)}`});a.push(`The following remote ${t} could not be auto-restored:`,``,...e,``)}return a.push("If the user no longer needs a mount, run `mount unmount <path>` (with the path shell-quoted the same way) to clear the stale entry instead."),a.join(`
|
|
7526
|
+
`)}const N3=new Set([`webhook`,`cron`,`sprinkle`,`fswatch`,`session-reload`,`navigate`,`upgrade`]);function P3(e){return e!=null&&N3.has(e)}function F3(e){let t=e.type===`webhook`,n=e.type===`sprinkle`,r=e.type===`fswatch`,i=e.type===`session-reload`,a=e.type===`navigate`,o=e.type===`upgrade`,s=t?e.webhookName:n?e.sprinkleName:r?e.fswatchName:i?`mount-recovery`:a?e.navigateUrl:o?`${e.upgradeFromVersion??`unknown`}→${e.upgradeToVersion??`unknown`}`:e.cronName,c=t?`Webhook Event`:n?`Sprinkle Event`:r?`File Watch Event`:i?`Session Reload`:a?`Navigate Event`:o?`Upgrade Event`:`Cron Event`;if(i){let t=e.body;if(t?.reason===`mount-recovery`){let e=M3(t.mounts??[]);return e===null?null:{label:c,content:e}}}if(o){let t=e.upgradeFromVersion??`unknown`,n=e.upgradeToVersion??`unknown`,r=e.body?.releasedAt??null;return{label:c,content:`[${c}: ${t}→${n}]\n\nSLICC was upgraded from \`${t}\` to \`${n}\`.${r?`\nReleased: ${r}`:``}\n\nUse the **upgrade** skill (\`/workspace/skills/upgrade/SKILL.md\`) to:\n- Show the user the changelog between these tags from GitHub\n- Offer to merge new bundled vfs-root content into their workspace (three-way merge: bundled snapshot vs user's VFS, reconciled with the GitHub tag-to-tag diff).`}}return{label:c,content:`[${c}: ${s}]\n\`\`\`json\n${JSON.stringify(e.body,null,2)}\n\`\`\``}}const $=i(`orchestrator`),I3=`/shared/scoop-notifications`,L3=1e3;function R3(e){let t=e.replace(/\r\n?/g,`
|
|
7512
7527
|
`);if(t.length===0)return 0;let n=1;for(let e=0;e<t.length;e++)t[e]===`
|
|
7513
7528
|
`&&n++;return t.endsWith(`
|
|
7514
|
-
`)?n-1:n}var
|
|
7529
|
+
`)?n-1:n}var z3=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;fsWatcher=null;idleTimers=new Map;droppedScoopCosts=[];scoopObservers=new Map;mutedScoops=new Set;pendingCompletions=new Map;completionWaiters=new Map;processManager=null;constructor(e,t,n={name:`sliccy`,triggerPattern:/^@sliccy\b/i}){this.container=e,this.callbacks=t,this.config=n}setProcessManager(e){this.processManager=e}getProcessManager(){return this.processManager}async init(){await f(),this.sharedFs=await he.create({dbName:`slicc-fs`}),this.sessionStore=new te,this.fsWatcher=new ge,this.sharedFs.setWatcher(this.fsWatcher),globalThis.__slicc_fs_watcher=this.fsWatcher,await this.ensureRootStructure();let e=await h();for(let t of Object.values(e)){t.isCone&&(t.trigger=void 0,t.requiresTrigger=!1,t.assistantLabel=t.assistantLabel||`sliccy`),this.migrateScoopConfig(t),this.scoops.set(t.jid,t),this.messageQueues.set(t.jid,[]);let e=await g(`lastAgentTs_${t.jid}`);e&&this.lastAgentTimestamp.set(t.jid,e)}await this.ensureGlobalMemory(),this.scheduler=new x3({onTaskRun:async(e,t)=>{$.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(),$.info(`Orchestrator initialized`,{scoopCount:this.scoops.size});for(let e of this.scoops.values())await this.createScoopTab(e.jid);D0(()=>this.getSessionCosts()),this.startMessageLoop()}migrateScoopConfig(e){if(e.isCone)return;let t=e.configSchemaVersion??0;t>=2||(t<1&&(e.config={...e.config,visiblePaths:e.config?.visiblePaths??[`/workspace/`]}),t<2&&(e.config={...e.config,writablePaths:e.config?.writablePaths??[`/scoops/${e.folder}/`,`/shared/`]}),e.configSchemaVersion=2)}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 e3(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{$.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,$.info(`Global memory updated`))}async appendGlobalMemory(e,t){if(!this.sharedFs)return;let n=e.trim();if(!n)return;let r=await this.getGlobalMemory(),i=`## Auto-extracted (${new Date().toISOString().slice(0,10)}, ${t.source})`,a=`${r.length===0||r.endsWith(`
|
|
7515
7530
|
`)?``:`
|
|
7516
7531
|
`}\n${i}\n\n${n}\n`;await this.setGlobalMemory(r+a),$.info(`Global memory appended`,{source:t.source,length:n.length})}getSharedFS(){return this.sharedFs}getSessionStore(){return this.sessionStore}setLickManager(e){this.lickManager=e,globalThis.__slicc_lick_handler=e=>{this.lickManager?.emitEvent(e)}}handleWebhookEvent(e,t,n){this.lickManager?.handleWebhookEvent(e,t,n)}observeScoop(e,t){let n=this.scoopObservers.get(e);return n||(n=new Set,this.scoopObservers.set(e,n)),n.add(t),()=>{let n=this.scoopObservers.get(e);n&&(n.delete(t),n.size===0&&this.scoopObservers.delete(e))}}async maybeNotifyConeOnScoopComplete(e){let t=this.scoops.get(e);if(!t||t.isCone)return;let n=this.scoopResponseBuffer.get(e);if(this.scoopResponseBuffer.delete(e),!n||t.notifyOnComplete===!1)return;let r=this.completionWaiters.get(e);if(r&&r.length>0){this.completionWaiters.delete(e);let t=n.length>2e4?n.slice(0,2e4)+`
|
|
7517
|
-
... (truncated)`:n;for(let n of r)try{n(t)}catch(t){$.warn(`completion waiter threw`,{jid:e,error:t instanceof Error?t.message:String(t)})}return}if(this.mutedScoops.has(e)){this.pendingCompletions.set(e,{responseText:n,timestamp:new Date().toISOString()}),$.info(`Scoop completion stashed (muted)`,{scoop:t.folder,responseLength:n.length});return}await this.deliverCompletionToCone(t,n)}async deliverCompletionToCone(e,t){let n=Array.from(this.scoops.values()).find(e=>e.isCone);if(!n)return;let r=
|
|
7518
|
-
`)}formatScoopCompletionFallbackNotification(e,t,n,r){return[`[@${e} completed]`,`VFS path: unavailable`,`Artifact persistence error: ${r}`,`Total lines: ${t}`,`Preview (up to ${
|
|
7532
|
+
... (truncated)`:n;for(let n of r)try{n(t)}catch(t){$.warn(`completion waiter threw`,{jid:e,error:t instanceof Error?t.message:String(t)})}return}if(this.mutedScoops.has(e)){this.pendingCompletions.set(e,{responseText:n,timestamp:new Date().toISOString()}),$.info(`Scoop completion stashed (muted)`,{scoop:t.folder,responseLength:n.length});return}await this.deliverCompletionToCone(t,n)}async deliverCompletionToCone(e,t){let n=Array.from(this.scoops.values()).find(e=>e.isCone);if(!n)return;let r=R3(t),i=t.slice(0,L3),a,o=null,s=null;try{s=await this.writeScoopCompletionArtifact(e,t),$.info(`Routing scoop completion to cone`,{scoop:e.folder,responseLength:t.length,lineCount:r,notificationPath:s})}catch(t){o=t instanceof Error?t.message:String(t),$.warn(`Failed to persist scoop completion artifact, falling back to inline preview`,{scoop:e.folder,error:o})}a=o===null?this.formatScoopCompletionNotification(e.assistantLabel,s??`unavailable`,r,i):this.formatScoopCompletionFallbackNotification(e.assistantLabel,r,i,o);let c={id:`scoop-done-${e.jid}-${Date.now()}`,chatJid:n.jid,senderId:e.folder,senderName:e.assistantLabel,content:a,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-notify`};try{this.callbacks.onIncomingMessage?.(n.jid,c)}catch(t){$.warn(`onIncomingMessage for scoop-notify threw`,{scoop:e.folder,error:t instanceof Error?t.message:String(t)})}try{await this.handleMessage(c)}catch(t){let r=t instanceof Error?t.message:String(t);$.error(`Failed to route scoop completion to cone`,{scoop:e.folder,error:r}),this.callbacks.onError(n.jid,`Scoop ${e.folder} completed but notification failed: ${r}`)}}async writeScoopCompletionArtifact(e,t){if(!this.sharedFs)throw Error(`Shared filesystem not initialized`);await this.sharedFs.mkdir(I3,{recursive:!0}),await this.pruneScoopCompletionArtifacts(199);let n=new Date().toISOString().replace(/[:.]/g,`-`),r=Math.random().toString(36).slice(2,8),i=`${I3}/${n}-${e.folder}-${r}.md`;return await this.sharedFs.writeFile(i,t),await this.pruneScoopCompletionArtifacts(),i}async pruneScoopCompletionArtifacts(e=200){if(!this.sharedFs)return;let t;try{t=await this.sharedFs.readDir(I3)}catch{return}let n=t.filter(e=>e.type===`file`).map(e=>e.name).sort(),r=n.length-e;if(!(r<=0))for(let e of n.slice(0,r)){let t=`${I3}/${e}`;try{await this.sharedFs.rm(t)}catch(e){$.warn(`Failed to prune scoop completion artifact`,{path:t,error:e instanceof Error?e.message:String(e)})}}}formatScoopCompletionNotification(e,t,n,r){return[`[@${e} completed]`,`VFS path: ${t}`,`Total lines: ${n}`,`Preview (up to ${L3} chars):`,r].join(`
|
|
7533
|
+
`)}formatScoopCompletionFallbackNotification(e,t,n,r){return[`[@${e} completed]`,`VFS path: unavailable`,`Artifact persistence error: ${r}`,`Total lines: ${t}`,`Preview (up to ${L3} chars):`,n].join(`
|
|
7519
7534
|
`)}muteScoops(e){for(let t of e)this.mutedScoops.add(t);$.info(`Scoops muted`,{count:e.length})}async unmuteScoops(e){let t=[],n=[];for(let r of e){this.mutedScoops.delete(r);let e=this.pendingCompletions.get(r);if(!e)continue;this.pendingCompletions.delete(r);let i=this.scoops.get(r);if(!i||i.isCone)continue;let a={jid:r,summary:e.responseText.length>2e4?e.responseText.slice(0,2e4)+`
|
|
7520
7535
|
... (truncated)`:e.responseText,timestamp:e.timestamp,notificationPath:null};t.push(a),n.push(this.writeScoopCompletionArtifact(i,e.responseText).then(e=>{a.notificationPath=e}).catch(e=>{$.warn(`unmute artifact persist failed`,{jid:r,error:e instanceof Error?e.message:String(e)})}))}return await Promise.all(n),$.info(`Scoops unmuted`,{count:e.length,consumed:t.length}),t}isScoopMuted(e){return this.mutedScoops.has(e)}async waitForScoops(e,t){if(e.length===0)return[];let n=Array.from(new Set(e)),r=new Map,i=[];for(let e of n)this.mutedScoops.has(e)||(this.mutedScoops.add(e),i.push(e));for(let e of n){let t=this.pendingCompletions.get(e);if(t){this.pendingCompletions.delete(e);let n=t.responseText.length>2e4?t.responseText.slice(0,2e4)+`
|
|
7521
7536
|
... (truncated)`:t.responseText;r.set(e,{summary:n,timedOut:!1})}}let a=n.filter(e=>!r.has(e)),o=a.filter(e=>this.scoops.has(e)),s=a.filter(e=>!this.scoops.has(e));for(let e of s)r.set(e,{summary:null,timedOut:!0});let c=[],l=o.map(e=>new Promise(t=>{let n=n=>{r.has(e)||(r.set(e,{summary:n,timedOut:n===null}),t())};c.push({jid:e,waiter:n});let i=this.completionWaiters.get(e);i||(i=[],this.completionWaiters.set(e,i)),i.push(n)})),u=null;try{l.length>0&&(t!=null&&t>=0?await Promise.race([Promise.all(l),new Promise(e=>{u=setTimeout(()=>e(),t)})]):await Promise.all(l))}finally{u&&clearTimeout(u);for(let{jid:e,waiter:t}of c){let n=this.completionWaiters.get(e);if(!n)continue;let r=n.indexOf(t);r!==-1&&n.splice(r,1),n.length===0&&this.completionWaiters.delete(e)}for(let e of i)this.mutedScoops.delete(e)}for(let e of o)r.has(e)||r.set(e,{summary:null,timedOut:!0});return e.map(e=>{let t=r.get(e)??{summary:null,timedOut:!0};return{jid:e,summary:t.summary,timedOut:t.timedOut}})}scheduleScoopWait(e,t){let n=Array.from(new Set(e)),r=n.filter(e=>this.scoops.has(e)),i=n.filter(e=>!this.scoops.has(e));return this.waitForScoops(r,t).then(e=>this.deliverWaitResultsToCone(e)).catch(e=>{$.error(`scheduleScoopWait failed`,{error:e instanceof Error?e.message:String(e)})}),{scheduled:r,unknown:i}}async deliverWaitResultsToCone(e){if(e.length===0)return;let t=Array.from(this.scoops.values()).find(e=>e.isCone);if(!t)return;let n=[`[scoop_wait completed]`],r=0,i=0;for(let t of e){let e=this.scoops.get(t.jid)?.folder??t.jid;t.timedOut?(r+=1,n.push(`--- ${e} (timed out) ---`)):(i+=1,n.push(`--- ${e} ---`),n.push(t.summary??`(no output)`))}let a=`${i} completed, ${r} timed out`;n.splice(1,0,a);let o={id:`scoop-wait-${Date.now()}-${Math.random().toString(36).slice(2,10)}`,chatJid:t.jid,senderId:`scoop-wait`,senderName:`scoop-wait`,content:n.join(`
|
|
7522
|
-
`),timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-wait`};try{this.callbacks.onIncomingMessage?.(t.jid,o)}catch(e){$.warn(`onIncomingMessage for scoop-wait threw`,{error:e instanceof Error?e.message:String(e)})}try{await this.handleMessage(o)}catch(e){let n=e instanceof Error?e.message:String(e);$.error(`Failed to route scoop-wait result to cone`,{error:n}),this.callbacks.onError(t.jid,`scoop_wait completed but notification failed: ${n}`)}}dispatchScoopEvent(e,t,...n){let r=this.scoopObservers.get(e);if(r)for(let i of r){let r=i[t];if(r)try{r(...n)}catch(n){$.warn(`scoop observer threw`,{jid:e,event:t,error:n instanceof Error?n.message:String(n)})}}}async registerScoop(e){await E(e),this.scoops.set(e.jid,e),this.messageQueues.set(e.jid,[]),$.info(`Scoop registered`,{jid:e.jid,name:e.name});try{await this.createScoopTab(e.jid)}catch(t){throw $.error(`Scoop init failed`,{jid:e.jid,name:e.name,error:t instanceof Error?t.message:String(t)}),await this.destroyScoopTab(e.jid).catch(()=>{}),this.scoops.delete(e.jid),this.messageQueues.delete(e.jid),await s(e.jid).catch(t=>{$.warn(`Failed to rollback scoop registration`,{jid:e.jid,name:e.name,error:t instanceof Error?t.message:String(t)})}),t}}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=d3(t.folder,e,n);if(r)throw r}this.snapshotScoopCost(e),this.clearIdleTimer(e),await this.destroyScoopTab(e),this.sessionStore?.delete(e).catch(t=>{$.warn(`Failed to delete agent session`,{jid:e,error:t instanceof Error?t.message:String(t)})}),await s(e),this.scoops.delete(e),this.messageQueues.delete(e),this.lastAgentTimestamp.delete(e),this.scoopResponseBuffer.delete(e),this.scoopObservers.delete(e);let n=this.completionWaiters.get(e);if(n){this.completionWaiters.delete(e);for(let t of n)try{t(null)}catch(t){$.warn(`completion waiter threw on unregister`,{jid:e,error:t instanceof Error?t.message:String(t)})}}this.mutedScoops.delete(e),this.pendingCompletions.delete(e),$.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())this.clearIdleTimer(e),t.stop(),this.contexts.delete(e);this.sharedFs=await he.create({dbName:`slicc-fs`,wipe:!0}),this.fsWatcher&&this.sharedFs.setWatcher(this.fsWatcher),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await R4(this.sharedFs).catch(e=>{$.warn(`Failed to re-seed default skills`,{error:e instanceof Error?e.message:String(e)})}),this.droppedScoopCosts=[],$.info(`Filesystem reset and defaults re-seeded`)}async clearScoopMessages(e){let t=this.contexts.get(e);if(t&&(t.clearMessages(),this.sessionStore)){let n=t.getSessionId();await this.sessionStore.delete(n).catch(t=>{$.warn(`Failed to clear agent session for scoop`,{jid:e,error:t instanceof Error?t.message:String(t)})})}await _(e).catch(t=>{$.warn(`Failed to clear persisted channel history for scoop`,{jid:e,error:t instanceof Error?t.message:String(t)})}),this.lastAgentTimestamp.delete(e),this.messageQueues.set(e,[]),$.info(`Scoop messages cleared`,{jid:e})}async clearAllMessages(){await S(),this.sessionStore&&await this.sessionStore.clearAll().catch(e=>{$.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,[]);this.droppedScoopCosts=[],$.info(`All messages cleared`)}async handleMessage(e){if($.info(`handleMessage`,{id:e.id,chatJid:e.chatJid,sender:e.senderName,channel:e.channel,contentPreview:e.content.slice(0,80)}),b3(e.channel))try{this.callbacks.onIncomingMessage?.(e.chatJid,e)}catch(t){$.warn(`onIncomingMessage for external lick channel threw`,{channel:e.channel,error:t instanceof Error?t.message:String(t)})}await w(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 w(i),this.callbacks.onIncomingMessage?.(e,i),$.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);$.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){$.info(`routeToScoop: unregistered target`,{chatJid:e.chatJid});return}let n=e.channel===`webhook`||e.channel===`cron`||e.channel===`fswatch`||e.channel===`sprinkle`;if(!t.isCone&&t.requiresTrigger&&t.trigger&&!n&&!e.content.includes(t.trigger)){$.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($.debug(`routeToScoop: queued`,{chatJid:e.chatJid,scoopName:t.name,tabStatus:i?.status??`no-tab`,queueLength:r.length}),i?.status===`error`){$.info(`routeToScoop: tab in error state, retrying init`,{chatJid:e.chatJid});try{await this.createScoopTab(e.chatJid),i=this.tabs.get(e.chatJid)}catch{$.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`)$.info(`Re-creating context after error`,{jid:e}),this.contexts.get(e)?.dispose(),this.contexts.delete(e),this.tabs.delete(e);else{$.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 _e(this.sharedFs,t.config?.writablePaths?[...t.config.writablePaths]:[],t.config?.visiblePaths?[...t.config.visiblePaths]:[]),i={onResponse:(n,r)=>{if(this.scoops.has(e)&&(this.callbacks.onResponse(e,n,r),this.dispatchScoopEvent(e,`onResponse`,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:()=>{if(!this.scoops.has(e))return;let t=this.tabs.get(e);t&&(t.lastActivity=new Date().toISOString(),this.tabs.set(e,t)),this.callbacks.onResponseDone(e)},onError:t=>{if(!this.scoops.has(e))return;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`),this.dispatchScoopEvent(e,`onError`,t),this.dispatchScoopEvent(e,`onStatusChange`,`error`)},onFatalError:t=>{if(!this.scoops.has(e))return;let n=this.scoops.get(e);$.error(`Fatal scoop error`,{jid:e,folder:n.folder,error:t});let r=this.tabs.get(e);if(r&&(r.status=`error`,r.error=t,this.tabs.set(e,r)),this.callbacks.onError(e,t),this.callbacks.onStatusChange(e,`error`),this.dispatchScoopEvent(e,`onError`,t),this.dispatchScoopEvent(e,`onStatusChange`,`error`),n.isCone)return;this.mutedScoops.delete(e),this.pendingCompletions.delete(e),this.scoopResponseBuffer.delete(e);let i=this.completionWaiters.get(e);if(i&&i.length>0){this.completionWaiters.delete(e);for(let t of i)try{t(null)}catch(t){$.warn(`completion waiter threw on fatal error`,{jid:e,error:t instanceof Error?t.message:String(t)})}}let a=Array.from(this.scoops.values()).find(e=>e.isCone);if(!a)return;let o={id:`scoop-error-${e}-${Date.now()}`,chatJid:a.jid,senderId:n.folder,senderName:n.assistantLabel,content:`[@${n.assistantLabel} FAILED]: ${t}`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-error`};try{this.callbacks.onIncomingMessage?.(a.jid,o)}catch(e){$.warn(`onIncomingMessage for scoop-error threw`,{scoop:n.folder,error:e instanceof Error?e.message:String(e)})}this.handleMessage(o).catch(e=>{$.error(`Failed to route fatal error to cone`,{scoop:n.folder,error:e instanceof Error?e.message:String(e)})})},onStatusChange:n=>{if(!this.scoops.has(e))return;let r=this.tabs.get(e);r&&(r.status=n,r.lastActivity=new Date().toISOString(),this.tabs.set(e,r)),this.callbacks.onStatusChange(e,n),this.dispatchScoopEvent(e,`onStatusChange`,n),n===`ready`&&!t.isCone&&this.maybeNotifyConeOnScoopComplete(e)},onCompactionStateChange:t=>{this.callbacks.onCompactionStateChange?.(e,t)},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)=>{let r=`${n?`[${n}] `:``}${t}`;this.callbacks.onSendMessage(e,r),this.dispatchScoopEvent(e,`onSendMessage`,t)},getScoops:()=>this.getScoops(),getScoopTabState:t.isCone?e=>this.tabs.get(e):void 0,onFeedScoop:t.isCone?(e,n)=>this.delegateToScoop(e,n,t.assistantLabel):void 0,onScoopScoop:t.isCone?async e=>{let t={...e,jid:`scoop_${e.folder}_${Date.now()}`};return await this.registerScoop(t),t}:void 0,onDropScoop:t.isCone?async e=>{await this.unregisterScoop(e)}:void 0,onMuteScoops:t.isCone?e=>this.muteScoops(e):void 0,onUnmuteScoops:t.isCone?e=>this.unmuteScoops(e):void 0,onScheduleScoopWait:t.isCone?(e,t)=>this.scheduleScoopWait(e,t):void 0,getGlobalMemory:()=>this.getGlobalMemory(),setGlobalMemory:t.isCone?e=>this.setGlobalMemory(e):void 0,appendGlobalMemory:t.isCone?(e,t)=>this.appendGlobalMemory(e,t):void 0,getBrowserAPI:()=>this.callbacks.getBrowserAPI()},a=Array.from(this.scoops.values()).find(e=>e.isCone)?.jid,o=new a3(t,i,r,this.sessionStore??void 0,this.sharedFs??void 0,a,this.processManager??void 0);this.contexts.set(e,o),this.tabs.set(e,{jid:e,contextId:n,status:`initializing`,lastActivity:new Date().toISOString()}),await o.init();let s=this.tabs.get(e);s&&s.status===`initializing`&&(s.status=`ready`,this.tabs.set(e,s),this.callbacks.onStatusChange(e,`ready`),this.dispatchScoopEvent(e,`onStatusChange`,`ready`));let c=this.scoops.get(e);c&&!c.isCone&&this.startIdleTimer(e),$.info(`Scoop context created`,{jid:e,contextId:n})}async destroyScoopTab(e){this.clearIdleTimer(e);let t=this.contexts.get(e);t&&(t.dispose(),this.contexts.delete(e),this.tabs.delete(e),this.scoopObservers.delete(e),$.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 m(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 m(t)}async getMessagesForScoop(e){return d(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 $.warn(`Timed out waiting for tab to become ready`,{jid:e}),!1}async sendPrompt(e,t,n,r,i=[]){let a=this.contexts.get(e);a||=(await this.createScoopTab(e),this.contexts.get(e));let o=this.tabs.get(e);if(o?.status===`initializing`){if($.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){$.error(`Context did not become ready in time, dropping prompt`,{jid:e});return}a=this.contexts.get(e),o=this.tabs.get(e)}if(!a){$.error(`Context not found after creation`,{jid:e});return}this.clearIdleTimer(e),this.scoopResponseBuffer.delete(e),o&&(o.status=`processing`,o.lastActivity=new Date().toISOString(),this.tabs.set(e,o),this.callbacks.onStatusChange(e,`processing`),this.dispatchScoopEvent(e,`onStatusChange`,`processing`)),$.debug(`Prompt sent to scoop`,{jid:e,textLength:t.length,imageCount:i.length}),await a.prompt(t,i)}async processScoopQueue(e){let t=this.messageQueues.get(e);if(!t||t.length===0){$.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){$.debug(`processScoopQueue: tab not ready`,{jid:e,status:n?.status??`no-tab`});return}let r=this.scoops.get(e),i=r?.assistantLabel??e,o=this.lastAgentTimestamp.get(e)??``,s=await y(e,o,i);if($.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:o,dbMessageCount:s.length,queueLength:t.length}),s.length===0){$.debug(`processScoopQueue: no messages from DB, clearing queue`,{jid:e}),this.messageQueues.set(e,[]);return}let c=s.map(e=>`[${new Date(e.timestamp).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hour12:!0})}] ${e.senderName}: ${ie(e.content,e.attachments)}`).join(`
|
|
7523
|
-
`),l=s.flatMap(e=>re(e.attachments));this.messageQueues.set(e,[]);let u=s[s.length-1];this.lastAgentTimestamp.set(e,u.timestamp),await a(`lastAgentTs_${e}`,u.timestamp),await this.sendPrompt(e,c,u.senderId,u.senderName,l)}startMessageLoop(){this.pollInterval||=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);$.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();$.info(`Model updated on all active contexts`,{contextCount:this.contexts.size})}async setScoopThinkingLevel(e,t){let n=this.scoops.get(e);if(!n)return null;let r=this.contexts.get(e),i=r?r.setThinkingLevel(t):null;if(t===void 0){if(n.config&&n.config.thinkingLevel!==void 0){let{thinkingLevel:e,...t}=n.config;n.config=t}}else n.config={...n.config??{},thinkingLevel:t};try{await E(n)}catch(t){$.warn(`Failed to persist thinkingLevel`,{jid:e,error:t instanceof Error?t.message:String(t)})}return i}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=>{$.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),$.info(`Skills reloaded across all contexts`,{count:e.length})}stopScoop(e){let t=this.contexts.get(e);t&&t.stop()}buildScoopCost(e,t){let n=t.getAgentMessages().filter(e=>e.role===`assistant`);if(n.length===0)return null;let r={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},i=new Map;for(let e of n)r.input+=e.usage.input,r.output+=e.usage.output,r.cacheRead+=e.usage.cacheRead,r.cacheWrite+=e.usage.cacheWrite,r.totalTokens+=e.usage.totalTokens,r.cost.input+=e.usage.cost.input,r.cost.output+=e.usage.cost.output,r.cost.cacheRead+=e.usage.cost.cacheRead,r.cost.cacheWrite+=e.usage.cost.cacheWrite,r.cost.total+=e.usage.cost.total,i.set(e.model,(i.get(e.model)??0)+1);let a=``,o=0;for(let[e,t]of i)t>o&&(a=e,o=t);let s=n.map(e=>e.timestamp).sort((e,t)=>e-t),c=s[0],l=s[s.length-1],u=900*1e3,d=l-c,f=Math.max(1,Math.ceil(d/u))*u;return{name:e.assistantLabel,type:e.isCone?`cone`:`scoop`,model:a,usage:r,turns:n.length,firstActivity:c,lastActivity:l,activeTimeMs:f}}snapshotScoopCost(e){let t=this.scoops.get(e),n=this.contexts.get(e);if(!t||!n)return;let r=this.buildScoopCost(t,n);r&&this.droppedScoopCosts.push(r)}getSessionCosts(){let e=[];for(let t of this.scoops.values()){let n=this.contexts.get(t.jid);if(!n)continue;let r=this.buildScoopCost(t,n);r&&e.push(r)}return e.push(...this.droppedScoopCosts),e}startIdleTimer(e){if(this.clearIdleTimer(e),this.tabs.get(e)?.status===`processing`)return;let t=setTimeout(()=>{this.idleTimers.delete(e);let t=this.scoops.get(e);if(!t||t.isCone||this.tabs.get(e)?.status!==`ready`)return;let n=Array.from(this.scoops.values()).find(e=>e.isCone);if(!n)return;let r={id:`scoop-idle-${e}-${Date.now()}`,chatJid:n.jid,senderId:t.folder,senderName:t.assistantLabel,content:`[@${t.assistantLabel} idle]: Scoop "${t.name}" has been ready for 2 minutes without receiving any work. This is expected if the scoop is waiting for webhooks or cron tasks. If you intended to delegate work, use feed_scoop to send a prompt.`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-idle`};$.info(`Scoop idle timeout`,{jid:e,scoop:t.folder});try{this.callbacks.onIncomingMessage?.(n.jid,r)}catch(t){$.warn(`onIncomingMessage for scoop-idle threw`,{jid:e,error:t instanceof Error?t.message:String(t)})}this.handleMessage(r).catch(t=>{let n=t instanceof Error?t.message:String(t);$.error(`Failed to send idle notification`,{jid:e,error:n})})},12e4);this.idleTimers.set(e,t)}clearIdleTimer(e){let t=this.idleTimers.get(e);t&&(clearTimeout(t),this.idleTimers.delete(e))}async shutdown(){this.stopMessageLoop();for(let e of this.idleTimers.keys())this.clearIdleTimer(e);this.scheduler?.stop(),this.scheduler=null;for(let e of this.completionWaiters.values())for(let t of e)try{t(null)}catch(e){$.warn(`completion waiter threw during shutdown`,{error:e instanceof Error?e.message:String(e)})}this.completionWaiters.clear(),this.mutedScoops.clear(),this.pendingCompletions.clear();for(let e of this.contexts.keys())await this.destroyScoopTab(e);$.info(`Orchestrator shutdown`)}};const E3=i(`agent-bridge`);function D3(e,t,n=null,r={}){let i=r.generateName??M3,a=r.generateUid??k3,o=r.resolveModel??P3;function s(){for(let t=0;t<8;t++){let t=i(),n=`agent_${N3(t)}`;if(!e.getScoops().some(e=>e.jid===n))return t}return a()}function c(t){if(t===void 0)return null;let n=e.getScoops().find(e=>e.jid===t);if(!n)return null;let r=n.config?.modelId;return r&&r.length>0?r:null}function l(t){if(t===void 0)return null;let n=e.getScoops().find(e=>e.jid===t);if(!n)return null;let r=n.config?.thinkingLevel;return r&&Ot(r)?r:null}async function u(r){let i=r.modelId;if(i!==void 0&&(i===``||o(i)===null))return{finalText:`agent: unknown model: ${i}`,exitCode:1};let a=i??c(r.parentJid)??``,u=r.thinkingLevel;if(u!==void 0&&!Ot(u))return{finalText:`agent: invalid thinking level: ${String(u)} (one of: ${Dt.join(`, `)})`,exitCode:1};let d=u??l(r.parentJid)??void 0,f=s(),p=`agent-${f}`,m=`agent_${N3(f)}`,h=`/scoops/${p}`,g=F3(r.cwd),_={visiblePaths:I3(r),writablePaths:L3([g,`/shared/`,`${h}/`,`/tmp/`]),allowedCommands:r.allowedCommands};a&&(_.modelId=a),d!==void 0&&(_.thinkingLevel=d);let v={jid:m,name:p,folder:p,isCone:!1,type:`scoop`,requiresTrigger:!1,assistantLabel:p,addedAt:new Date().toISOString(),config:_,configSchemaVersion:2,notifyOnComplete:!1},y=[],b=``,x=null,S=e.observeScoop(m,{onSendMessage:e=>{y.push(e)},onResponse:(e,t)=>{t?b+=e:b=e},onError:e=>{x===null&&(x=e)}});try{try{await e.registerScoop(v)}catch(e){return{finalText:x??R3(e),exitCode:1}}return await e.sendPrompt(m,r.prompt,`agent`,`agent`),x===null?{finalText:y.length>0?y[y.length-1]:b,exitCode:0}:{finalText:x,exitCode:1}}catch(e){return{finalText:x??R3(e),exitCode:1}}finally{S();try{await e.unregisterScoop(m)}catch(e){E3.warn(`unregisterScoop failed`,{jid:m,error:R3(e)})}try{await t.rm(h,{recursive:!0})}catch(e){z3(e,`ENOENT`)||E3.warn(`scratch folder cleanup failed`,{folder:p,error:R3(e)})}if(n)try{await n.delete(m)}catch(e){E3.warn(`sessionStore.delete failed`,{jid:m,error:R3(e)})}}}return{spawn:u}}function O3(e,t,n=null,r={}){let i=D3(e,t,n,r);return globalThis.__slicc_agent=i,E3.info(`agent bridge published on globalThis.__slicc_agent`),i}function k3(){let e=globalThis;return typeof e.crypto?.randomUUID==`function`?e.crypto.randomUUID().replace(/-/g,``).slice(0,12):`${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`}const A3=`amber.bouncy.breezy.bubbly.cheeky.chilly.cozy.dapper.dreamy.eager.exuberant.fluffy.frosty.gentle.giddy.glossy.jolly.lucky.mellow.merry.nimble.plucky.quirky.salty.sleepy.snappy.sparkly.spiffy.sunny.sweet.toasty.velvety.whimsy.zesty`.split(`.`),j3=`blueberry.butterscotch.caramel.cherry.chocolate.cinnamon.coconut.coffee.cookies.custard.espresso.fudge.gelato.hazelnut.honeycomb.lavender.lemon.mango.maple.marzipan.matcha.mint.mocha.neapolitan.nougat.peach.pecan.pistachio.praline.raspberry.sherbet.sorbet.stracciatella.strawberry.tiramisu.toffee.vanilla`.split(`.`);function M3(){return`${A3[Math.floor(Math.random()*A3.length)]}-${j3[Math.floor(Math.random()*j3.length)]}`}function N3(e){return e.replace(/-/g,`_`)}function P3(e){try{let t=oe();for(let n of t)if(n.models.some(t=>t.id===e))return e;return null}catch{return null}}function F3(e){let t=j(e);return t.endsWith(`/`)?t:`${t}/`}function I3(e){if(e.visiblePaths!==void 0)return e.visiblePaths.map(F3);let t=[`/workspace/`];return e.invokingCwd&&e.invokingCwd.length>0&&t.push(F3(e.invokingCwd)),L3(t)}function L3(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function R3(e){return e instanceof Error?e.message:String(e)}function z3(e,t){if(typeof e!=`object`||!e)return!1;let n=e.code;return typeof n==`string`&&n===t}var B3=class{kind=`proc`;source=void 0;profile=void 0;mountId;pm;closed=!1;constructor(e,t={}){this.pm=e,this.mountId=t.mountId??`proc-${Date.now().toString(36)}`}async readDir(e){this.assertOpen(e);let t=H3(e);if(t.length===0){let e=this.pm.list(),t=e.map(e=>({name:String(e.pid),kind:`directory`}));return e.some(e=>e.pid===1)||t.push({name:`1`,kind:`directory`}),t.sort((e,t)=>Number(e.name)-Number(t.name))}if(t.length===1){let n=U3(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);return V3.map(e=>({name:e,kind:`file`,size:this.fileSize(n,e),lastModified:this.fileMtime(n)}))}throw new ve(`ENOTDIR`,`not a directory`,e)}async readFile(e){this.assertOpen(e);let t=H3(e);if(t.length!==2)throw new ve(`EISDIR`,`is a directory`,e);let n=U3(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!V3.includes(r))throw new ve(`ENOENT`,`no such file or directory`,e);let i=this.renderProcFile(n,r);return new TextEncoder().encode(i)}async writeFile(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async stat(e){this.assertOpen(e);let t=H3(e);if(t.length===0)return{kind:`directory`,size:0,mtime:0};if(t.length===1){let n=U3(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);return{kind:`directory`,size:0,mtime:this.fileMtime(n)}}if(t.length===2){let n=U3(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!V3.includes(r))throw new ve(`ENOENT`,`no such file or directory`,e);return{kind:`file`,size:this.fileSize(n,r),mtime:this.fileMtime(n)}}throw new ve(`ENOENT`,`no such file or directory`,e)}async mkdir(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async remove(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async refresh(){return{added:[],removed:[],changed:[],unchanged:0,errors:[]}}describe(){return{displayName:`/proc`,extra:`kernel processes (read-only)`}}async close(){this.closed=!0}assertOpen(e){if(this.closed)throw new ve(`EBADF`,`mount closed`,e)}pidExists(e){return e===1?!0:this.pm.get(e)!==null}fileSize(e,t){return this.renderProcFile(e,t).length}fileMtime(e){if(e===1)return 0;let t=this.pm.get(e);return t?t.finishedAt??t.startedAt:0}renderProcFile(e,t){if(e===1)return X3(t);let n=this.pm.get(e);switch(t){case`status`:return W3(n);case`cmdline`:return G3(n);case`cwd`:return K3(n);case`stat`:return q3(n)}}};const V3=[`status`,`cmdline`,`cwd`,`stat`];function H3(e){return e.replace(/^\/+/,``).replace(/\/+$/,``).split(`/`).filter(Boolean)}function U3(e){let t=Number.parseInt(e,10);return!Number.isFinite(t)||String(t)!==e?null:t}function W3(e){let t=[`Name:\t${e.kind}`,`Pid:\t${e.pid}`,`PPid:\t${e.ppid}`,`State:\t${J3(e.status)} (${e.status})`,`Owner:\t${Y3(e)}`,`StartedAt:\t${new Date(e.startedAt).toISOString()}`];return e.finishedAt!==null&&t.push(`FinishedAt:\t${new Date(e.finishedAt).toISOString()}`),e.terminatedBy!==null&&t.push(`TerminatedBy:\t${e.terminatedBy}`),e.exitCode!==null&&t.push(`ExitCode:\t${e.exitCode}`),t.push(`Cmdline:\t${e.argv.join(` `)}`),t.join(`
|
|
7537
|
+
`),timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-wait`};try{this.callbacks.onIncomingMessage?.(t.jid,o)}catch(e){$.warn(`onIncomingMessage for scoop-wait threw`,{error:e instanceof Error?e.message:String(e)})}try{await this.handleMessage(o)}catch(e){let n=e instanceof Error?e.message:String(e);$.error(`Failed to route scoop-wait result to cone`,{error:n}),this.callbacks.onError(t.jid,`scoop_wait completed but notification failed: ${n}`)}}dispatchScoopEvent(e,t,...n){let r=this.scoopObservers.get(e);if(r)for(let i of r){let r=i[t];if(r)try{r(...n)}catch(n){$.warn(`scoop observer threw`,{jid:e,event:t,error:n instanceof Error?n.message:String(n)})}}}async registerScoop(e){await E(e),this.scoops.set(e.jid,e),this.messageQueues.set(e.jid,[]),$.info(`Scoop registered`,{jid:e.jid,name:e.name});try{await this.createScoopTab(e.jid)}catch(t){throw $.error(`Scoop init failed`,{jid:e.jid,name:e.name,error:t instanceof Error?t.message:String(t)}),await this.destroyScoopTab(e.jid).catch(()=>{}),this.scoops.delete(e.jid),this.messageQueues.delete(e.jid),await s(e.jid).catch(t=>{$.warn(`Failed to rollback scoop registration`,{jid:e.jid,name:e.name,error:t instanceof Error?t.message:String(t)})}),t}}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=T3(t.folder,e,n);if(r)throw r}this.snapshotScoopCost(e),this.clearIdleTimer(e),await this.destroyScoopTab(e),this.sessionStore?.delete(e).catch(t=>{$.warn(`Failed to delete agent session`,{jid:e,error:t instanceof Error?t.message:String(t)})}),await s(e),this.scoops.delete(e),this.messageQueues.delete(e),this.lastAgentTimestamp.delete(e),this.scoopResponseBuffer.delete(e),this.scoopObservers.delete(e);let n=this.completionWaiters.get(e);if(n){this.completionWaiters.delete(e);for(let t of n)try{t(null)}catch(t){$.warn(`completion waiter threw on unregister`,{jid:e,error:t instanceof Error?t.message:String(t)})}}this.mutedScoops.delete(e),this.pendingCompletions.delete(e),$.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())this.clearIdleTimer(e),t.stop(),this.contexts.delete(e);this.sharedFs=await he.create({dbName:`slicc-fs`,wipe:!0}),this.fsWatcher&&this.sharedFs.setWatcher(this.fsWatcher),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await Q4(this.sharedFs).catch(e=>{$.warn(`Failed to re-seed default skills`,{error:e instanceof Error?e.message:String(e)})}),this.droppedScoopCosts=[],$.info(`Filesystem reset and defaults re-seeded`)}async clearScoopMessages(e){let t=this.contexts.get(e);if(t&&(t.clearMessages(),this.sessionStore)){let n=t.getSessionId();await this.sessionStore.delete(n).catch(t=>{$.warn(`Failed to clear agent session for scoop`,{jid:e,error:t instanceof Error?t.message:String(t)})})}await _(e).catch(t=>{$.warn(`Failed to clear persisted channel history for scoop`,{jid:e,error:t instanceof Error?t.message:String(t)})}),this.lastAgentTimestamp.delete(e),this.messageQueues.set(e,[]),$.info(`Scoop messages cleared`,{jid:e})}async clearAllMessages(){await S(),this.sessionStore&&await this.sessionStore.clearAll().catch(e=>{$.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,[]);this.droppedScoopCosts=[],$.info(`All messages cleared`)}async handleMessage(e){if($.info(`handleMessage`,{id:e.id,chatJid:e.chatJid,sender:e.senderName,channel:e.channel,contentPreview:e.content.slice(0,80)}),P3(e.channel))try{this.callbacks.onIncomingMessage?.(e.chatJid,e)}catch(t){$.warn(`onIncomingMessage for external lick channel threw`,{channel:e.channel,error:t instanceof Error?t.message:String(t)})}await w(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 w(i),this.callbacks.onIncomingMessage?.(e,i),$.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);$.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){$.info(`routeToScoop: unregistered target`,{chatJid:e.chatJid});return}let n=e.channel===`webhook`||e.channel===`cron`||e.channel===`fswatch`||e.channel===`sprinkle`;if(!t.isCone&&t.requiresTrigger&&t.trigger&&!n&&!e.content.includes(t.trigger)){$.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($.debug(`routeToScoop: queued`,{chatJid:e.chatJid,scoopName:t.name,tabStatus:i?.status??`no-tab`,queueLength:r.length}),i?.status===`error`){$.info(`routeToScoop: tab in error state, retrying init`,{chatJid:e.chatJid});try{await this.createScoopTab(e.chatJid),i=this.tabs.get(e.chatJid)}catch{$.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`)$.info(`Re-creating context after error`,{jid:e}),this.contexts.get(e)?.dispose(),this.contexts.delete(e),this.tabs.delete(e);else{$.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 _e(this.sharedFs,t.config?.writablePaths?[...t.config.writablePaths]:[],t.config?.visiblePaths?[...t.config.visiblePaths]:[]),i={onResponse:(n,r)=>{if(this.scoops.has(e)&&(this.callbacks.onResponse(e,n,r),this.dispatchScoopEvent(e,`onResponse`,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:()=>{if(!this.scoops.has(e))return;let t=this.tabs.get(e);t&&(t.lastActivity=new Date().toISOString(),this.tabs.set(e,t)),this.callbacks.onResponseDone(e)},onError:t=>{if(!this.scoops.has(e))return;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`),this.dispatchScoopEvent(e,`onError`,t),this.dispatchScoopEvent(e,`onStatusChange`,`error`)},onFatalError:t=>{if(!this.scoops.has(e))return;let n=this.scoops.get(e);$.error(`Fatal scoop error`,{jid:e,folder:n.folder,error:t});let r=this.tabs.get(e);if(r&&(r.status=`error`,r.error=t,this.tabs.set(e,r)),this.callbacks.onError(e,t),this.callbacks.onStatusChange(e,`error`),this.dispatchScoopEvent(e,`onError`,t),this.dispatchScoopEvent(e,`onStatusChange`,`error`),n.isCone)return;this.mutedScoops.delete(e),this.pendingCompletions.delete(e),this.scoopResponseBuffer.delete(e);let i=this.completionWaiters.get(e);if(i&&i.length>0){this.completionWaiters.delete(e);for(let t of i)try{t(null)}catch(t){$.warn(`completion waiter threw on fatal error`,{jid:e,error:t instanceof Error?t.message:String(t)})}}let a=Array.from(this.scoops.values()).find(e=>e.isCone);if(!a)return;let o={id:`scoop-error-${e}-${Date.now()}`,chatJid:a.jid,senderId:n.folder,senderName:n.assistantLabel,content:`[@${n.assistantLabel} FAILED]: ${t}`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-error`};try{this.callbacks.onIncomingMessage?.(a.jid,o)}catch(e){$.warn(`onIncomingMessage for scoop-error threw`,{scoop:n.folder,error:e instanceof Error?e.message:String(e)})}this.handleMessage(o).catch(e=>{$.error(`Failed to route fatal error to cone`,{scoop:n.folder,error:e instanceof Error?e.message:String(e)})})},onStatusChange:n=>{if(!this.scoops.has(e))return;let r=this.tabs.get(e);r&&(r.status=n,r.lastActivity=new Date().toISOString(),this.tabs.set(e,r)),this.callbacks.onStatusChange(e,n),this.dispatchScoopEvent(e,`onStatusChange`,n),n===`ready`&&!t.isCone&&this.maybeNotifyConeOnScoopComplete(e)},onCompactionStateChange:t=>{this.callbacks.onCompactionStateChange?.(e,t)},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)=>{let r=`${n?`[${n}] `:``}${t}`;this.callbacks.onSendMessage(e,r),this.dispatchScoopEvent(e,`onSendMessage`,t)},getScoops:()=>this.getScoops(),getScoopTabState:t.isCone?e=>this.tabs.get(e):void 0,onFeedScoop:t.isCone?(e,n)=>this.delegateToScoop(e,n,t.assistantLabel):void 0,onScoopScoop:t.isCone?async e=>{let t={...e,jid:`scoop_${e.folder}_${Date.now()}`};return await this.registerScoop(t),t}:void 0,onDropScoop:t.isCone?async e=>{await this.unregisterScoop(e)}:void 0,onMuteScoops:t.isCone?e=>this.muteScoops(e):void 0,onUnmuteScoops:t.isCone?e=>this.unmuteScoops(e):void 0,onScheduleScoopWait:t.isCone?(e,t)=>this.scheduleScoopWait(e,t):void 0,getGlobalMemory:()=>this.getGlobalMemory(),setGlobalMemory:t.isCone?e=>this.setGlobalMemory(e):void 0,appendGlobalMemory:t.isCone?(e,t)=>this.appendGlobalMemory(e,t):void 0,getBrowserAPI:()=>this.callbacks.getBrowserAPI()},a=Array.from(this.scoops.values()).find(e=>e.isCone)?.jid,o=new y3(t,i,r,this.sessionStore??void 0,this.sharedFs??void 0,a,this.processManager??void 0);this.contexts.set(e,o),this.tabs.set(e,{jid:e,contextId:n,status:`initializing`,lastActivity:new Date().toISOString()}),await o.init();let s=this.tabs.get(e);s&&s.status===`initializing`&&(s.status=`ready`,this.tabs.set(e,s),this.callbacks.onStatusChange(e,`ready`),this.dispatchScoopEvent(e,`onStatusChange`,`ready`));let c=this.scoops.get(e);c&&!c.isCone&&this.startIdleTimer(e),$.info(`Scoop context created`,{jid:e,contextId:n})}async destroyScoopTab(e){this.clearIdleTimer(e);let t=this.contexts.get(e);t&&(t.dispose(),this.contexts.delete(e),this.tabs.delete(e),this.scoopObservers.delete(e),$.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 m(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 m(t)}async getMessagesForScoop(e){return d(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 $.warn(`Timed out waiting for tab to become ready`,{jid:e}),!1}async sendPrompt(e,t,n,r,i=[]){let a=this.contexts.get(e);a||=(await this.createScoopTab(e),this.contexts.get(e));let o=this.tabs.get(e);if(o?.status===`initializing`){if($.debug(`Context initializing, waiting to send message`,{jid:e}),!await this.waitForTabReady(e)){$.error(`Context did not become ready in time, dropping prompt`,{jid:e});return}a=this.contexts.get(e),o=this.tabs.get(e)}if(!a){$.error(`Context not found after creation`,{jid:e});return}this.clearIdleTimer(e),this.scoopResponseBuffer.delete(e),o&&(o.status=`processing`,o.lastActivity=new Date().toISOString(),this.tabs.set(e,o),this.callbacks.onStatusChange(e,`processing`),this.dispatchScoopEvent(e,`onStatusChange`,`processing`)),$.debug(`Prompt sent to scoop`,{jid:e,textLength:t.length,imageCount:i.length}),await a.prompt(t,i)}async processScoopQueue(e){let t=this.messageQueues.get(e);if(!t||t.length===0){$.debug(`processScoopQueue: empty queue`,{jid:e});return}let n=this.tabs.get(e);if(n?.status!==`ready`){$.debug(`processScoopQueue: tab not ready`,{jid:e,status:n?.status??`no-tab`});return}let r=this.scoops.get(e),i=r?.assistantLabel??e,o=this.lastAgentTimestamp.get(e)??``,s=await y(e,o,i);if($.debug(`processScoopQueue: DB query`,{jid:e,scoopName:r?.name,excludeName:i,since:o,dbMessageCount:s.length,queueLength:t.length}),s.length===0){$.debug(`processScoopQueue: no messages from DB, clearing queue`,{jid:e}),this.messageQueues.set(e,[]);return}let c=s.map(e=>`[${new Date(e.timestamp).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hour12:!0})}] ${e.senderName}: ${ie(e.content,e.attachments)}`).join(`
|
|
7538
|
+
`),l=s.flatMap(e=>re(e.attachments));this.messageQueues.set(e,[]);let u=s[s.length-1];this.lastAgentTimestamp.set(e,u.timestamp),await a(`lastAgentTs_${e}`,u.timestamp),await this.sendPrompt(e,c,u.senderId,u.senderName,l)}startMessageLoop(){this.pollInterval||=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);$.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();$.info(`Model updated on all active contexts`,{contextCount:this.contexts.size})}async setScoopThinkingLevel(e,t){let n=this.scoops.get(e);if(!n)return null;let r=this.contexts.get(e),i=r?r.setThinkingLevel(t):null;if(t===void 0){if(n.config&&n.config.thinkingLevel!==void 0){let{thinkingLevel:e,...t}=n.config;n.config=t}}else n.config={...n.config??{},thinkingLevel:t};try{await E(n)}catch(t){$.warn(`Failed to persist thinkingLevel`,{jid:e,error:t instanceof Error?t.message:String(t)})}return i}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=>{$.warn(`Failed to reload skills for scoop`,{jid:t,error:e instanceof Error?e.message:String(e)})}))}await Promise.all(e),$.info(`Skills reloaded across all contexts`,{count:e.length})}stopScoop(e){let t=this.contexts.get(e);t&&t.stop()}buildScoopCost(e,t){let n=t.getAgentMessages().filter(e=>e.role===`assistant`);if(n.length===0)return null;let r={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},i=new Map;for(let e of n)r.input+=e.usage.input,r.output+=e.usage.output,r.cacheRead+=e.usage.cacheRead,r.cacheWrite+=e.usage.cacheWrite,r.totalTokens+=e.usage.totalTokens,r.cost.input+=e.usage.cost.input,r.cost.output+=e.usage.cost.output,r.cost.cacheRead+=e.usage.cost.cacheRead,r.cost.cacheWrite+=e.usage.cost.cacheWrite,r.cost.total+=e.usage.cost.total,i.set(e.model,(i.get(e.model)??0)+1);let a=``,o=0;for(let[e,t]of i)t>o&&(a=e,o=t);let s=n.map(e=>e.timestamp).sort((e,t)=>e-t),c=s[0],l=s[s.length-1],u=900*1e3,d=l-c,f=Math.max(1,Math.ceil(d/u))*u;return{name:e.assistantLabel,type:e.isCone?`cone`:`scoop`,model:a,usage:r,turns:n.length,firstActivity:c,lastActivity:l,activeTimeMs:f}}snapshotScoopCost(e){let t=this.scoops.get(e),n=this.contexts.get(e);if(!t||!n)return;let r=this.buildScoopCost(t,n);r&&this.droppedScoopCosts.push(r)}getSessionCosts(){let e=[];for(let t of this.scoops.values()){let n=this.contexts.get(t.jid);if(!n)continue;let r=this.buildScoopCost(t,n);r&&e.push(r)}return e.push(...this.droppedScoopCosts),e}startIdleTimer(e){if(this.clearIdleTimer(e),this.tabs.get(e)?.status===`processing`)return;let t=setTimeout(()=>{this.idleTimers.delete(e);let t=this.scoops.get(e);if(!t||t.isCone||this.tabs.get(e)?.status!==`ready`)return;let n=Array.from(this.scoops.values()).find(e=>e.isCone);if(!n)return;let r={id:`scoop-idle-${e}-${Date.now()}`,chatJid:n.jid,senderId:t.folder,senderName:t.assistantLabel,content:`[@${t.assistantLabel} idle]: Scoop "${t.name}" has been ready for 2 minutes without receiving any work. This is expected if the scoop is waiting for webhooks or cron tasks. If you intended to delegate work, use feed_scoop to send a prompt.`,timestamp:new Date().toISOString(),fromAssistant:!1,channel:`scoop-idle`};$.info(`Scoop idle timeout`,{jid:e,scoop:t.folder});try{this.callbacks.onIncomingMessage?.(n.jid,r)}catch(t){$.warn(`onIncomingMessage for scoop-idle threw`,{jid:e,error:t instanceof Error?t.message:String(t)})}this.handleMessage(r).catch(t=>{let n=t instanceof Error?t.message:String(t);$.error(`Failed to send idle notification`,{jid:e,error:n})})},12e4);this.idleTimers.set(e,t)}clearIdleTimer(e){let t=this.idleTimers.get(e);t&&(clearTimeout(t),this.idleTimers.delete(e))}async shutdown(){this.stopMessageLoop();for(let e of this.idleTimers.keys())this.clearIdleTimer(e);this.scheduler?.stop(),this.scheduler=null;for(let e of this.completionWaiters.values())for(let t of e)try{t(null)}catch(e){$.warn(`completion waiter threw during shutdown`,{error:e instanceof Error?e.message:String(e)})}this.completionWaiters.clear(),this.mutedScoops.clear(),this.pendingCompletions.clear();for(let e of this.contexts.keys())await this.destroyScoopTab(e);$.info(`Orchestrator shutdown`)}};const B3=i(`agent-bridge`);function V3(e,t,n=null,r={}){let i=r.generateName??K3,a=r.generateUid??U3,o=r.resolveModel??J3;function s(){for(let t=0;t<8;t++){let t=i(),n=`agent_${q3(t)}`;if(!e.getScoops().some(e=>e.jid===n))return t}return a()}function c(t){if(t===void 0)return null;let n=e.getScoops().find(e=>e.jid===t);if(!n)return null;let r=n.config?.modelId;return r&&r.length>0?r:null}function l(t){if(t===void 0)return null;let n=e.getScoops().find(e=>e.jid===t);if(!n)return null;let r=n.config?.thinkingLevel;return r&&Ot(r)?r:null}async function u(r){let i=r.modelId;if(i!==void 0&&(i===``||o(i)===null))return{finalText:`agent: unknown model: ${i}`,exitCode:1};let a=i??c(r.parentJid)??``,u=r.thinkingLevel;if(u!==void 0&&!Ot(u))return{finalText:`agent: invalid thinking level: ${String(u)} (one of: ${Dt.join(`, `)})`,exitCode:1};let d=u??l(r.parentJid)??void 0,f=s(),p=`agent-${f}`,m=`agent_${q3(f)}`,h=`/scoops/${p}`,g=Y3(r.cwd),_={visiblePaths:X3(r),writablePaths:Z3([g,`/shared/`,`${h}/`,`/tmp/`]),allowedCommands:r.allowedCommands};a&&(_.modelId=a),d!==void 0&&(_.thinkingLevel=d);let v={jid:m,name:p,folder:p,isCone:!1,type:`scoop`,requiresTrigger:!1,assistantLabel:p,addedAt:new Date().toISOString(),config:_,configSchemaVersion:2,notifyOnComplete:!1},y=[],b=``,x=null,S=e.observeScoop(m,{onSendMessage:e=>{y.push(e)},onResponse:(e,t)=>{t?b+=e:b=e},onError:e=>{x===null&&(x=e)}});try{try{await e.registerScoop(v)}catch(e){return{finalText:x??Q3(e),exitCode:1}}return await e.sendPrompt(m,r.prompt,`agent`,`agent`),x===null?{finalText:y.length>0?y[y.length-1]:b,exitCode:0}:{finalText:x,exitCode:1}}catch(e){return{finalText:x??Q3(e),exitCode:1}}finally{S();try{await e.unregisterScoop(m)}catch(e){B3.warn(`unregisterScoop failed`,{jid:m,error:Q3(e)})}try{await t.rm(h,{recursive:!0})}catch(e){$3(e,`ENOENT`)||B3.warn(`scratch folder cleanup failed`,{folder:p,error:Q3(e)})}if(n)try{await n.delete(m)}catch(e){B3.warn(`sessionStore.delete failed`,{jid:m,error:Q3(e)})}}}return{spawn:u}}function H3(e,t,n=null,r={}){let i=V3(e,t,n,r);return globalThis.__slicc_agent=i,B3.info(`agent bridge published on globalThis.__slicc_agent`),i}function U3(){let e=globalThis;return typeof e.crypto?.randomUUID==`function`?e.crypto.randomUUID().replace(/-/g,``).slice(0,12):`${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`}const W3=`amber.bouncy.breezy.bubbly.cheeky.chilly.cozy.dapper.dreamy.eager.exuberant.fluffy.frosty.gentle.giddy.glossy.jolly.lucky.mellow.merry.nimble.plucky.quirky.salty.sleepy.snappy.sparkly.spiffy.sunny.sweet.toasty.velvety.whimsy.zesty`.split(`.`),G3=`blueberry.butterscotch.caramel.cherry.chocolate.cinnamon.coconut.coffee.cookies.custard.espresso.fudge.gelato.hazelnut.honeycomb.lavender.lemon.mango.maple.marzipan.matcha.mint.mocha.neapolitan.nougat.peach.pecan.pistachio.praline.raspberry.sherbet.sorbet.stracciatella.strawberry.tiramisu.toffee.vanilla`.split(`.`);function K3(){return`${W3[Math.floor(Math.random()*W3.length)]}-${G3[Math.floor(Math.random()*G3.length)]}`}function q3(e){return e.replace(/-/g,`_`)}function J3(e){try{let t=oe();for(let n of t)if(n.models.some(t=>t.id===e))return e;return null}catch{return null}}function Y3(e){let t=j(e);return t.endsWith(`/`)?t:`${t}/`}function X3(e){if(e.visiblePaths!==void 0)return e.visiblePaths.map(Y3);let t=[`/workspace/`];return e.invokingCwd&&e.invokingCwd.length>0&&t.push(Y3(e.invokingCwd)),Z3(t)}function Z3(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function Q3(e){return e instanceof Error?e.message:String(e)}function $3(e,t){if(typeof e!=`object`||!e)return!1;let n=e.code;return typeof n==`string`&&n===t}var e6=class{kind=`proc`;source=void 0;profile=void 0;mountId;pm;closed=!1;constructor(e,t={}){this.pm=e,this.mountId=t.mountId??`proc-${Date.now().toString(36)}`}async readDir(e){this.assertOpen(e);let t=n6(e);if(t.length===0){let e=this.pm.list(),t=e.map(e=>({name:String(e.pid),kind:`directory`}));return e.some(e=>e.pid===1)||t.push({name:`1`,kind:`directory`}),t.sort((e,t)=>Number(e.name)-Number(t.name))}if(t.length===1){let n=r6(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);return t6.map(e=>({name:e,kind:`file`,size:this.fileSize(n,e),lastModified:this.fileMtime(n)}))}throw new ve(`ENOTDIR`,`not a directory`,e)}async readFile(e){this.assertOpen(e);let t=n6(e);if(t.length!==2)throw new ve(`EISDIR`,`is a directory`,e);let n=r6(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!t6.includes(r))throw new ve(`ENOENT`,`no such file or directory`,e);let i=this.renderProcFile(n,r);return new TextEncoder().encode(i)}async writeFile(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async stat(e){this.assertOpen(e);let t=n6(e);if(t.length===0)return{kind:`directory`,size:0,mtime:0};if(t.length===1){let n=r6(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);return{kind:`directory`,size:0,mtime:this.fileMtime(n)}}if(t.length===2){let n=r6(t[0]);if(n===null||!this.pidExists(n))throw new ve(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!t6.includes(r))throw new ve(`ENOENT`,`no such file or directory`,e);return{kind:`file`,size:this.fileSize(n,r),mtime:this.fileMtime(n)}}throw new ve(`ENOENT`,`no such file or directory`,e)}async mkdir(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async remove(e){throw new ve(`EACCES`,`read-only filesystem`,e)}async refresh(){return{added:[],removed:[],changed:[],unchanged:0,errors:[]}}describe(){return{displayName:`/proc`,extra:`kernel processes (read-only)`}}async close(){this.closed=!0}assertOpen(e){if(this.closed)throw new ve(`EBADF`,`mount closed`,e)}pidExists(e){return e===1?!0:this.pm.get(e)!==null}fileSize(e,t){return this.renderProcFile(e,t).length}fileMtime(e){if(e===1)return 0;let t=this.pm.get(e);return t?t.finishedAt??t.startedAt:0}renderProcFile(e,t){if(e===1)return u6(t);let n=this.pm.get(e);switch(t){case`status`:return i6(n);case`cmdline`:return a6(n);case`cwd`:return o6(n);case`stat`:return s6(n)}}};const t6=[`status`,`cmdline`,`cwd`,`stat`];function n6(e){return e.replace(/^\/+/,``).replace(/\/+$/,``).split(`/`).filter(Boolean)}function r6(e){let t=Number.parseInt(e,10);return!Number.isFinite(t)||String(t)!==e?null:t}function i6(e){let t=[`Name:\t${e.kind}`,`Pid:\t${e.pid}`,`PPid:\t${e.ppid}`,`State:\t${c6(e.status)} (${e.status})`,`Owner:\t${l6(e)}`,`StartedAt:\t${new Date(e.startedAt).toISOString()}`];return e.finishedAt!==null&&t.push(`FinishedAt:\t${new Date(e.finishedAt).toISOString()}`),e.terminatedBy!==null&&t.push(`TerminatedBy:\t${e.terminatedBy}`),e.exitCode!==null&&t.push(`ExitCode:\t${e.exitCode}`),t.push(`Cmdline:\t${e.argv.join(` `)}`),t.join(`
|
|
7524
7539
|
`)+`
|
|
7525
|
-
`}function
|
|
7526
|
-
`}function
|
|
7527
|
-
`}function
|
|
7540
|
+
`}function a6(e){return e.argv.join(`\0`)+`\0`}function o6(e){return e.cwd+`
|
|
7541
|
+
`}function s6(e){return[e.pid,`(${e.kind})`,c6(e.status),e.ppid,e.exitCode??`-`,e.startedAt,e.finishedAt??`-`].join(` `)+`
|
|
7542
|
+
`}function c6(e){switch(e){case`running`:return`R`;case`pending`:return`S`;case`exited`:return`Z`;case`killed`:return`K`}}function l6(e){return e.owner.kind===`cone`?`cone`:e.owner.kind===`system`?`system`:e.owner.scoopJid?`scoop/${e.owner.scoopJid}`:`scoop`}function u6(e){switch(e){case`status`:return[`Name: kernel-host`,`Pid: 1`,`PPid: 0`,`State: R (running)`,`Owner: system`].join(`
|
|
7528
7543
|
`)+`
|
|
7529
7544
|
`;case`cmdline`:return`kernel-host\0`;case`cwd`:return`/
|
|
7530
7545
|
`;case`stat`:return`1 (kernel-host) R 0 - 0 -
|
|
7531
|
-
`}}function Z3(e,{orchestrator:t,log:n}){let r=x3(e);if(r===null){n.debug?.(`dropping lick event with no renderable content`,{type:e.type});return}let i=e.type===`webhook`,a=e.type===`sprinkle`,o=e.type===`fswatch`,s=e.type===`navigate`,c=e.type===`upgrade`,l=e.type===`session-reload`,u=i?e.webhookName:a?e.sprinkleName:o?e.fswatchName:s?e.navigateUrl:c?`${e.upgradeFromVersion??`unknown`}→${e.upgradeToVersion??`unknown`}`:l?`mount-recovery`:e.cronName,d=i?e.webhookId:a?e.sprinkleName:o?e.fswatchId:s?e.navigateUrl:c?`upgrade-${e.upgradeToVersion??`unknown`}`:l?`session-reload-${e.timestamp}`:e.cronId,f=e.type,p=t.getScoops(),m;if(m=e.targetScoop?p.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`):p.find(e=>e.isCone),!m){n.warn(`Lick target scoop not found`,e.targetScoop);return}let h={id:`${f}-${d}-${Date.now()}`,chatJid:m.jid,senderId:f,senderName:`${f}:${u}`,content:r.content,timestamp:e.timestamp,fromAssistant:!1,channel:f};t.handleMessage(h)}async function Q3(e){let{container:t,browser:n,bridge:r,callbacks:i,skipConeBootstrap:a=!1,isExtension:o=!1}=e,s=e.logger??console,c=new PJ,l=new T3(t,{...i,getBrowserAPI:()=>n});l.setProcessManager(c),globalThis.__slicc_pm=c,globalThis.__slicc_browser=n,await r.bind(l,n);let u=_t(()=>r.emitTrayRuntimeStatus()),d=D(()=>r.emitTrayRuntimeStatus());await l.init();let f=l.getSharedFS();if(f?O3(l,f,l.getSessionStore()):s.warn(`AgentBridge not published — orchestrator.getSharedFS() returned null`),f)try{await f.mountInternal(`/proc`,new B3(c))}catch(e){s.warn(`Failed to mount /proc`,e)}let{registerSessionCostsProvider:p}=await Promise.resolve().then(()=>_1);p(()=>l.getSessionCosts());let{getLickManager:m}=await Promise.resolve().then(()=>c3),h=m();await h.init(),l.setLickManager(h);let g=e.lickEventHandler??Z3,_={orchestrator:l,lickManager:h,log:s};h.setEventHandler(e=>g(e,_)),globalThis.__slicc_lickManager=h;let v=null;if(!o)try{let e=new lq(n.getTransport(),e=>{let t={url:e.url,verb:e.verb,target:e.target};e.instruction!=null&&(t.instruction=e.instruction),e.branch!=null&&(t.branch=e.branch),e.path!=null&&(t.path=e.path),e.title!=null&&(t.title=e.title),h.emitEvent({type:`navigate`,navigateUrl:e.url,targetScoop:void 0,timestamp:new Date().toISOString(),body:t})});e.start(),v=()=>e.stop()}catch(e){s.warn(`Failed to start NavigationWatcher`,e)}f&&(async()=>{try{let{getAllMountEntries:e}=await import(`./mount-table-store-BDnU4NqG.js`).then(e=>e.r),{recoverMounts:t}=await Promise.resolve().then(()=>m3),n=await e();if(n.length===0)return;let{needsRecovery:r}=await t(n,f,s);if(r.length===0)return;h.emitEvent({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:r}})}catch(e){s.warn(`mount recovery failed`,e)}})(),a||l.getScoops().some(e=>e.isCone)||await l.registerScoop({jid:`cone_${Date.now()}`,name:`Cone`,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()}),f&&(async()=>{try{let{detectUpgrade:e,recordVersionSeen:t}=await import(`./upgrade-detection-DSxLFlVR.js`),n=await e();if(!n.isUpgrade||n.lastSeen===null)return;h.emitEvent({type:`upgrade`,targetScoop:void 0,timestamp:new Date().toISOString(),upgradeFromVersion:n.lastSeen,upgradeToVersion:n.bundled.version,body:{from:n.lastSeen,to:n.bundled.version,releasedAt:n.bundled.releasedAt}}),await t(n.bundled.version)}catch(e){s.warn(`Upgrade detection failed`,e)}})();let y=null,b=null;if(f)try{let{BshWatchdog:e}=await import(`./bsh-watchdog-0KPLx0BS.js`),{ScriptCatalog:t}=await Promise.resolve().then(()=>v2),r=new t({jshFs:f,bshFs:f,watcher:f.getWatcher()}),i=new e({browserAPI:n,scriptCatalog:r,fs:f});i.start(),y=()=>i.stop(),b=()=>r.dispose()}catch(e){s.warn(`Failed to start BSH watchdog`,e)}let x=!1;return{orchestrator:l,browser:n,bridge:r,lickManager:h,sharedFs:f??null,processManager:c,async dispose(){if(!x){if(x=!0,u?.(),d?.(),y?.(),b?.(),v)try{await v()}catch(e){s.warn(`NavigationWatcher.stop() failed`,e)}if(f)try{await f.unmountInternal(`/proc`)}catch{}$3({processManager:c,lickManager:h,browser:n})}}}}function $3(e){let t=globalThis;t.__slicc_pm===e.processManager&&delete t.__slicc_pm,t.__slicc_lickManager===e.lickManager&&delete t.__slicc_lickManager,e.browser&&t.__slicc_browser===e.browser&&delete t.__slicc_browser}function e6(e){let t=!1,n=()=>{t||(t=!0,typeof e.start==`function`&&e.start())};return{onMessage:t=>{let r=e=>{t(e.data)};return e.addEventListener(`message`,r),n(),()=>{e.removeEventListener(`message`,r)}},send:t=>{e.postMessage(t)}}}function t6(e){let t=e6(e);return{onMessage:e=>t.onMessage(e),send:e=>{t.send({source:`offscreen`,payload:e})}}}var n6=class extends VK{constructor(e){let t=e6(e);super({label:`WorkerCdpProxy`,buildCommandEnvelope:(e,t,n,r)=>({type:`cdp-cmd`,id:e,method:t,params:n,sessionId:r}),sendEnvelope:e=>(t.send(e),Promise.resolve()),subscribeIncoming:e=>t.onMessage(e),parseResponse:e=>{let t=e;if(t?.type!==`cdp-response`)return null;if(typeof t.id!=`number`||!Number.isFinite(t.id))return console.warn(`[WorkerCdpProxy] dropping cdp-response with invalid id`,t),null;let n=e;return{id:n.id,result:n.result,error:n.error}},parseEvent:e=>{let t=e;if(t?.type!==`cdp-event`)return null;if(typeof t.method!=`string`)return console.warn(`[WorkerCdpProxy] dropping cdp-event with invalid method`,t),null;let n=e;return{method:n.method,params:n.params}},onSubscribeEvent:e=>{t.send({type:`cdp-subscribe`,event:e})},onUnsubscribeEvent:e=>{t.send({type:`cdp-unsubscribe`,event:e})}})}},r6=class{transport;createShell;log;pm;defaultOwner;sessions=new Map;unsubscribe=null;constructor(e){this.transport=e.transport,this.createShell=e.createShell,this.log=e.logger??console,this.pm=e.processManager??null,this.defaultOwner=e.defaultOwner??{kind:`system`}}start(){return this.unsubscribe||=this.transport.onMessage(e=>{if(!i6(e)||e.source!==`panel`)return;let t=e.payload;o6(t)&&this.handleControl(t).catch(e=>{this.log.warn(`[terminal-session-host] handler error`,e)})}),()=>this.dispose()}dispose(){this.unsubscribe?.(),this.unsubscribe=null;for(let[,e]of this.sessions)e.currentProcess&&this.pm?(this.pm.signal(e.currentProcess.pid,`SIGTERM`),this.pm.exit(e.currentProcess.pid,null)):e.currentExec?.abort(),e.shell.dispose?.();this.sessions.clear()}async handleControl(e){switch(e.type){case`terminal-open`:return this.handleOpen(e);case`terminal-close`:return this.handleClose(e);case`terminal-exec`:return this.handleExec(e);case`terminal-signal`:return this.handleSignal(e);case`terminal-stdin`:case`terminal-resize`:return}}async handleOpen(e){if(this.sessions.has(e.sid)){this.emitStatus(e.sid,`error`,`session already open`);return}try{let t=this.createShell(e.sid,{cwd:e.cwd,env:e.env});this.sessions.set(e.sid,{shell:t,currentExec:null,currentProcess:null}),this.emitStatus(e.sid,`opened`)}catch(t){this.emitStatus(e.sid,`error`,t instanceof Error?t.message:String(t))}}async handleClose(e){let t=this.sessions.get(e.sid);t&&(t.currentProcess&&this.pm?(this.pm.signal(t.currentProcess.pid,`SIGTERM`),this.pm.exit(t.currentProcess.pid,null)):t.currentExec?.abort(),t.shell.dispose?.(),this.sessions.delete(e.sid),this.emitStatus(e.sid,`closed`))}async handleExec(e){let t=this.sessions.get(e.sid);if(!t){this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:127}),this.log.warn(`[terminal-session-host] exec on unknown session`,e.sid);return}if(t.currentExec){this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:130});return}let n=new AbortController;t.currentExec=n;let r=this.pm?this.pm.spawn({kind:`shell`,argv:[e.command],cwd:t.shell.getCwd?.()??void 0,owner:this.defaultOwner,adoptAbort:n}):null;t.currentProcess=r;try{let i=await t.shell.executeCommand(e.command,n.signal),a=n.signal.aborted?130:i.exitCode;n.signal.aborted||(r&&await r.gate.wait(),i.stdout&&this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stdout`,data:i.stdout}),i.stderr&&this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stderr`,data:i.stderr})),this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:a}),r&&this.pm&&this.pm.exit(r.pid,n.signal.aborted?null:i.exitCode)}catch(t){if(n.signal.aborted){let t=a6(r?.terminatedBy??`SIGINT`);this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:t}),r&&this.pm&&this.pm.exit(r.pid,null)}else{let n=t instanceof Error?t.message:String(t);this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stderr`,data:`Error: ${n}\n`}),this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:1}),r&&this.pm&&this.pm.exit(r.pid,1)}}finally{t.currentExec===n&&(t.currentExec=null,t.currentProcess=null)}}async handleSignal(e){let t=this.sessions.get(e.sid);if(!t){this.log.warn(`[terminal-session-host] signal on unknown session`,e.sid);return}(e.signal===`SIGINT`||e.signal===`SIGTERM`||e.signal===`SIGKILL`)&&(t.currentProcess&&this.pm?this.pm.signal(t.currentProcess.pid,e.signal):t.currentExec?.abort())}emit(e){this.transport.send(e)}emitStatus(e,t,n){let r=n?{type:`terminal-status`,sid:e,state:t,error:n}:{type:`terminal-status`,sid:e,state:t};this.emit(r)}};function i6(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function a6(e){switch(e){case`SIGINT`:return 130;case`SIGTERM`:return 143;case`SIGKILL`:return 137;case`SIGSTOP`:case`SIGCONT`:return 130}}function o6(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`terminal-open`||t===`terminal-close`||t===`terminal-exec`||t===`terminal-signal`||t===`terminal-stdin`||t===`terminal-resize`}function s6(e){let{transport:t,fs:n,browser:r,processManager:i}=e,a=new r6({transport:t,processManager:i,createShell:(e,t)=>new D2({fs:n,cwd:t.cwd,env:t.env,browserAPI:r,processManager:i,processOwner:{kind:`system`}}),logger:e.logger??console});return{host:a,stop:a.start()}}function c6(e,t={}){let n=t.onError??(e=>console.error(`[kernel-worker] boot failed`,e)),r=t.onDuplicate??(()=>console.warn(`[kernel-worker] received duplicate kernel-worker-init; ignoring`)),i=!1;return{handle(t){if(i){r();return}i=!0,e(t).catch(e=>{i=!1,n(e)})},isInitialized(){return i}}}const l6=`x-bypass-llm-proxy`;function u6(e,t){return t?(n,r)=>{if(!d6(n,t))return e(n,r);let i=new Headers(r?.headers);return i.has(l6)||i.set(l6,`1`),e(n,{...r,headers:i})}:e}function d6(e,t){let n;n=typeof e==`string`?e:e instanceof URL?e.href:e.url;try{return new URL(n,t).origin===t}catch{return!0}}function f6(){let e=globalThis.fetch;if(!e)return;let t=typeof self<`u`&&self.location?self.location.origin:void 0;globalThis.fetch=u6(e.bind(globalThis),t)}function p6(e){let t=new Map(Object.entries(e));Object.defineProperty(globalThis,`localStorage`,{value:{get length(){return t.size},key(e){return Array.from(t.keys())[e]??null},getItem(e){return t.has(e)?t.get(e):null},setItem(e,n){t.set(e,n)},removeItem(e){t.delete(e)},clear(){t.clear()}},configurable:!0,writable:!0})}let m6=null,h6=null,g6=null;const _6=c6(e=>v6(e));self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-init`&&_6.handle(e.data)});async function v6(e){f6(),p6(e.localStorageSeed??{}),await Xe();let t=t6(e.kernelPort),n=new Tt(t),r=Tt.createCallbacks(n),i=new n6(e.cdpPort);await i.connect();let a=new lt(i);m6=await Q3({container:{},browser:a,bridge:n,callbacks:r,logger:console});let{createSprinkleManagerProxyOverChannel:o}=await import(`./sprinkle-bridge-channel-B_tegUwc.js`);globalThis.__slicc_sprinkleManager=o({instanceId:e.instanceId});let{createPanelRpcClient:s}=await import(`./panel-rpc-uLhnFoXD.js`).then(e=>e.r);g6=s({instanceId:e.instanceId}),globalThis.__slicc_panelRpc=g6;let c=m6.processManager,l=m6.sharedFs;l?h6=s6({transport:t,fs:l,browser:a,processManager:c,logger:console}).stop:console.warn(`[kernel-worker] shared FS unavailable; terminal sessions will fail to open`),e.kernelPort.postMessage({type:`kernel-worker-ready`})}self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-shutdown`&&(h6?.(),h6=null,g6?.dispose(),g6=null,m6?.dispose())});export{vt as i,fK as n,SB as r,q4 as t};
|
|
7546
|
+
`}}function d6(e,{orchestrator:t,log:n}){let r=F3(e);if(r===null){n.debug?.(`dropping lick event with no renderable content`,{type:e.type});return}let i=e.type===`webhook`,a=e.type===`sprinkle`,o=e.type===`fswatch`,s=e.type===`navigate`,c=e.type===`upgrade`,l=e.type===`session-reload`,u=i?e.webhookName:a?e.sprinkleName:o?e.fswatchName:s?e.navigateUrl:c?`${e.upgradeFromVersion??`unknown`}→${e.upgradeToVersion??`unknown`}`:l?`mount-recovery`:e.cronName,d=i?e.webhookId:a?e.sprinkleName:o?e.fswatchId:s?e.navigateUrl:c?`upgrade-${e.upgradeToVersion??`unknown`}`:l?`session-reload-${e.timestamp}`:e.cronId,f=e.type,p=t.getScoops(),m;if(m=e.targetScoop?p.find(t=>t.name===e.targetScoop||t.folder===e.targetScoop||t.folder===`${e.targetScoop}-scoop`):p.find(e=>e.isCone),!m){n.warn(`Lick target scoop not found`,e.targetScoop);return}let h={id:`${f}-${d}-${Date.now()}`,chatJid:m.jid,senderId:f,senderName:`${f}:${u}`,content:r.content,timestamp:e.timestamp,fromAssistant:!1,channel:f};t.handleMessage(h)}async function f6(e){let{container:t,browser:n,bridge:r,callbacks:i,skipConeBootstrap:a=!1,isExtension:o=!1}=e,s=e.logger??console,c=new eZ,l=new z3(t,{...i,getBrowserAPI:()=>n});l.setProcessManager(c),globalThis.__slicc_pm=c,globalThis.__slicc_browser=n,await r.bind(l,n);let u=_t(()=>r.emitTrayRuntimeStatus()),d=D(()=>r.emitTrayRuntimeStatus());await l.init();let f=l.getSharedFS();if(f?H3(l,f,l.getSessionStore()):s.warn(`AgentBridge not published — orchestrator.getSharedFS() returned null`),f)try{await f.mountInternal(`/proc`,new e6(c))}catch(e){s.warn(`Failed to mount /proc`,e)}let{registerSessionCostsProvider:p}=await Promise.resolve().then(()=>T0);p(()=>l.getSessionCosts());let{getLickManager:m}=await Promise.resolve().then(()=>S3),h=m();await h.init(),l.setLickManager(h);let g=e.lickEventHandler??d6,_={orchestrator:l,lickManager:h,log:s};h.setEventHandler(e=>g(e,_)),globalThis.__slicc_lickManager=h;let v=null;if(!o)try{let e=new lq(n.getTransport(),e=>{let t={url:e.url,verb:e.verb,target:e.target};e.instruction!=null&&(t.instruction=e.instruction),e.branch!=null&&(t.branch=e.branch),e.path!=null&&(t.path=e.path),e.title!=null&&(t.title=e.title),h.emitEvent({type:`navigate`,navigateUrl:e.url,targetScoop:void 0,timestamp:new Date().toISOString(),body:t})});e.start(),v=()=>e.stop()}catch(e){s.warn(`Failed to start NavigationWatcher`,e)}f&&(async()=>{try{let{getAllMountEntries:e}=await import(`./mount-table-store-BDnU4NqG.js`).then(e=>e.r),{recoverMounts:t}=await Promise.resolve().then(()=>O3),n=await e();if(n.length===0)return;let{needsRecovery:r}=await t(n,f,s);if(r.length===0)return;h.emitEvent({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:r}})}catch(e){s.warn(`mount recovery failed`,e)}})(),a||l.getScoops().some(e=>e.isCone)||await l.registerScoop({jid:`cone_${Date.now()}`,name:`Cone`,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()}),f&&(async()=>{try{let{detectUpgrade:e,recordVersionSeen:t}=await import(`./upgrade-detection-DonNu3ys.js`),n=await e();if(!n.isUpgrade||n.lastSeen===null)return;h.emitEvent({type:`upgrade`,targetScoop:void 0,timestamp:new Date().toISOString(),upgradeFromVersion:n.lastSeen,upgradeToVersion:n.bundled.version,body:{from:n.lastSeen,to:n.bundled.version,releasedAt:n.bundled.releasedAt}}),await t(n.bundled.version)}catch(e){s.warn(`Upgrade detection failed`,e)}})();let y=null,b=null;if(f)try{let{BshWatchdog:e}=await import(`./bsh-watchdog-0KPLx0BS.js`),{ScriptCatalog:t}=await Promise.resolve().then(()=>M2),r=new t({jshFs:f,bshFs:f,watcher:f.getWatcher()}),i=new e({browserAPI:n,scriptCatalog:r,fs:f});i.start(),y=()=>i.stop(),b=()=>r.dispose()}catch(e){s.warn(`Failed to start BSH watchdog`,e)}let x=!1;return{orchestrator:l,browser:n,bridge:r,lickManager:h,sharedFs:f??null,processManager:c,async dispose(){if(!x){if(x=!0,u?.(),d?.(),y?.(),b?.(),v)try{await v()}catch(e){s.warn(`NavigationWatcher.stop() failed`,e)}if(f)try{await f.unmountInternal(`/proc`)}catch{}p6({processManager:c,lickManager:h,browser:n})}}}}function p6(e){let t=globalThis;t.__slicc_pm===e.processManager&&delete t.__slicc_pm,t.__slicc_lickManager===e.lickManager&&delete t.__slicc_lickManager,e.browser&&t.__slicc_browser===e.browser&&delete t.__slicc_browser}function m6(e){let t=!1,n=()=>{t||(t=!0,typeof e.start==`function`&&e.start())};return{onMessage:t=>{let r=e=>{t(e.data)};return e.addEventListener(`message`,r),n(),()=>{e.removeEventListener(`message`,r)}},send:t=>{e.postMessage(t)}}}function h6(e){let t=m6(e);return{onMessage:e=>t.onMessage(e),send:e=>{t.send({source:`offscreen`,payload:e})}}}var g6=class extends VK{constructor(e){let t=m6(e);super({label:`WorkerCdpProxy`,buildCommandEnvelope:(e,t,n,r)=>({type:`cdp-cmd`,id:e,method:t,params:n,sessionId:r}),sendEnvelope:e=>(t.send(e),Promise.resolve()),subscribeIncoming:e=>t.onMessage(e),parseResponse:e=>{let t=e;if(t?.type!==`cdp-response`)return null;if(typeof t.id!=`number`||!Number.isFinite(t.id))return console.warn(`[WorkerCdpProxy] dropping cdp-response with invalid id`,t),null;let n=e;return{id:n.id,result:n.result,error:n.error}},parseEvent:e=>{let t=e;if(t?.type!==`cdp-event`)return null;if(typeof t.method!=`string`)return console.warn(`[WorkerCdpProxy] dropping cdp-event with invalid method`,t),null;let n=e;return{method:n.method,params:n.params}},onSubscribeEvent:e=>{t.send({type:`cdp-subscribe`,event:e})},onUnsubscribeEvent:e=>{t.send({type:`cdp-unsubscribe`,event:e})}})}},_6=class{transport;createShell;log;pm;defaultOwner;sessions=new Map;unsubscribe=null;constructor(e){this.transport=e.transport,this.createShell=e.createShell,this.log=e.logger??console,this.pm=e.processManager??null,this.defaultOwner=e.defaultOwner??{kind:`system`}}start(){return this.unsubscribe||=this.transport.onMessage(e=>{if(!v6(e)||e.source!==`panel`)return;let t=e.payload;b6(t)&&this.handleControl(t).catch(e=>{this.log.warn(`[terminal-session-host] handler error`,e)})}),()=>this.dispose()}dispose(){this.unsubscribe?.(),this.unsubscribe=null;for(let[,e]of this.sessions)e.currentProcess&&this.pm?(this.pm.signal(e.currentProcess.pid,`SIGTERM`),this.pm.exit(e.currentProcess.pid,null)):e.currentExec?.abort(),e.shell.dispose?.();this.sessions.clear()}async handleControl(e){switch(e.type){case`terminal-open`:return this.handleOpen(e);case`terminal-close`:return this.handleClose(e);case`terminal-exec`:return this.handleExec(e);case`terminal-signal`:return this.handleSignal(e);case`terminal-stdin`:case`terminal-resize`:return}}async handleOpen(e){if(this.sessions.has(e.sid)){this.emitStatus(e.sid,`error`,`session already open`);return}try{let t=this.createShell(e.sid,{cwd:e.cwd,env:e.env});this.sessions.set(e.sid,{shell:t,currentExec:null,currentProcess:null}),this.emitStatus(e.sid,`opened`)}catch(t){this.emitStatus(e.sid,`error`,t instanceof Error?t.message:String(t))}}async handleClose(e){let t=this.sessions.get(e.sid);t&&(t.currentProcess&&this.pm?(this.pm.signal(t.currentProcess.pid,`SIGTERM`),this.pm.exit(t.currentProcess.pid,null)):t.currentExec?.abort(),t.shell.dispose?.(),this.sessions.delete(e.sid),this.emitStatus(e.sid,`closed`))}async handleExec(e){let t=this.sessions.get(e.sid);if(!t){this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:127}),this.log.warn(`[terminal-session-host] exec on unknown session`,e.sid);return}if(t.currentExec){this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:130});return}let n=new AbortController;t.currentExec=n;let r=this.pm?this.pm.spawn({kind:`shell`,argv:[e.command],cwd:t.shell.getCwd?.()??void 0,owner:this.defaultOwner,adoptAbort:n}):null;t.currentProcess=r;try{let i=await t.shell.executeCommand(e.command,n.signal),a=n.signal.aborted?130:i.exitCode;n.signal.aborted||(r&&await r.gate.wait(),i.stdout&&this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stdout`,data:i.stdout}),i.stderr&&this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stderr`,data:i.stderr})),this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:a}),r&&this.pm&&this.pm.exit(r.pid,n.signal.aborted?null:i.exitCode)}catch(t){if(n.signal.aborted){let t=y6(r?.terminatedBy??`SIGINT`);this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:t}),r&&this.pm&&this.pm.exit(r.pid,null)}else{let n=t instanceof Error?t.message:String(t);this.emit({type:`terminal-output`,sid:e.sid,execId:e.execId,stream:`stderr`,data:`Error: ${n}\n`}),this.emit({type:`terminal-exit`,sid:e.sid,execId:e.execId,exitCode:1}),r&&this.pm&&this.pm.exit(r.pid,1)}}finally{t.currentExec===n&&(t.currentExec=null,t.currentProcess=null)}}async handleSignal(e){let t=this.sessions.get(e.sid);if(!t){this.log.warn(`[terminal-session-host] signal on unknown session`,e.sid);return}(e.signal===`SIGINT`||e.signal===`SIGTERM`||e.signal===`SIGKILL`)&&(t.currentProcess&&this.pm?this.pm.signal(t.currentProcess.pid,e.signal):t.currentExec?.abort())}emit(e){this.transport.send(e)}emitStatus(e,t,n){let r=n?{type:`terminal-status`,sid:e,state:t,error:n}:{type:`terminal-status`,sid:e,state:t};this.emit(r)}};function v6(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function y6(e){switch(e){case`SIGINT`:return 130;case`SIGTERM`:return 143;case`SIGKILL`:return 137;case`SIGSTOP`:case`SIGCONT`:return 130}}function b6(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`terminal-open`||t===`terminal-close`||t===`terminal-exec`||t===`terminal-signal`||t===`terminal-stdin`||t===`terminal-resize`}function x6(e){let{transport:t,fs:n,browser:r,processManager:i}=e,a=new _6({transport:t,processManager:i,createShell:(e,t)=>new V2({fs:n,cwd:t.cwd,env:t.env,browserAPI:r,processManager:i,processOwner:{kind:`system`}}),logger:e.logger??console});return{host:a,stop:a.start()}}function S6(e,t={}){let n=t.onError??(e=>console.error(`[kernel-worker] boot failed`,e)),r=t.onDuplicate??(()=>console.warn(`[kernel-worker] received duplicate kernel-worker-init; ignoring`)),i=!1;return{handle(t){if(i){r();return}i=!0,e(t).catch(e=>{i=!1,n(e)})},isInitialized(){return i}}}const C6=`x-bypass-llm-proxy`;function w6(e,t){return t?(n,r)=>{if(!T6(n,t))return e(n,r);let i=new Headers(r?.headers);return i.has(C6)||i.set(C6,`1`),e(n,{...r,headers:i})}:e}function T6(e,t){let n;n=typeof e==`string`?e:e instanceof URL?e.href:e.url;try{return new URL(n,t).origin===t}catch{return!0}}function E6(){let e=globalThis.fetch;if(!e)return;let t=typeof self<`u`&&self.location?self.location.origin:void 0;globalThis.fetch=w6(e.bind(globalThis),t)}function D6(e){let t=new Map(Object.entries(e));Object.defineProperty(globalThis,`localStorage`,{value:{get length(){return t.size},key(e){return Array.from(t.keys())[e]??null},getItem(e){return t.has(e)?t.get(e):null},setItem(e,n){t.set(e,n)},removeItem(e){t.delete(e)},clear(){t.clear()}},configurable:!0,writable:!0})}let O6=null,k6=null,A6=null;const j6=S6(e=>M6(e));self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-init`&&j6.handle(e.data)});async function M6(e){E6(),D6(e.localStorageSeed??{}),await Xe();let t=h6(e.kernelPort),n=new Tt(t),r=Tt.createCallbacks(n),i=new g6(e.cdpPort);await i.connect();let a=new lt(i);O6=await f6({container:{},browser:a,bridge:n,callbacks:r,logger:console});let{createSprinkleManagerProxyOverChannel:o}=await import(`./sprinkle-bridge-channel-B_tegUwc.js`);globalThis.__slicc_sprinkleManager=o({instanceId:e.instanceId});let{createPanelRpcClient:s}=await import(`./panel-rpc-uLhnFoXD.js`).then(e=>e.r);A6=s({instanceId:e.instanceId}),globalThis.__slicc_panelRpc=A6;let c=O6.processManager,l=O6.sharedFs;l?k6=x6({transport:t,fs:l,browser:a,processManager:c,logger:console}).stop:console.warn(`[kernel-worker] shared FS unavailable; terminal sessions will fail to open`),e.kernelPort.postMessage({type:`kernel-worker-ready`})}self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-shutdown`&&(k6?.(),k6=null,A6?.dispose(),A6=null,O6?.dispose())});export{vt as i,fK as n,SB as r,s3 as t};
|