sliccy 2.48.0 → 2.49.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-f1RkQ2LG.js → adobe-BVYRvXsL.js} +1 -1
- package/dist/ui/assets/{adobe-B5JX3vSF.js → adobe-DOst-H7r.js} +1 -1
- package/dist/ui/assets/{agent-bridge-KerdP1oi.js → agent-bridge-C4zvo9Uu.js} +1 -1
- package/dist/ui/assets/{agent-message-to-chat-rNxH0eRL.js → agent-message-to-chat-CMHJiLMB.js} +1 -1
- package/dist/ui/assets/{anthropic-DqN-XhOb.js → anthropic-CZqomz-1.js} +1 -1
- package/dist/ui/assets/{anthropic-DXIx8WQZ.js → anthropic-CmyipZgN.js} +1 -1
- package/dist/ui/assets/{azure-openai-jVgW-OuR.js → azure-openai-CBaV-VSJ.js} +1 -1
- package/dist/ui/assets/{azure-openai-Bbb6cKeV.js → azure-openai-CJM6ZwXQ.js} +1 -1
- package/dist/ui/assets/{azure-openai-responses-DucvnACK.js → azure-openai-responses-CooQ5Awz.js} +1 -1
- package/dist/ui/assets/{azure-openai-responses-BLClomsm.js → azure-openai-responses-JpSdxXhY.js} +1 -1
- package/dist/ui/assets/{bedrock-camp-BNzU3faS.js → bedrock-camp-B0q-7yNy.js} +2 -2
- package/dist/ui/assets/{bedrock-camp-DAEKkMwP.js → bedrock-camp-W_gIoKyb.js} +3 -3
- package/dist/ui/assets/{cdp-C1_c8-E0.js → cdp-C_HxLMY8.js} +2 -2
- package/dist/ui/assets/cost-command-9CbNoyAQ.js +1 -0
- package/dist/ui/assets/{es-CbuIWQjf.js → es-C_SsgQvK.js} +1 -1
- package/dist/ui/assets/{fs-Ch4z-7e8.js → fs-CxBHreU_.js} +3 -3
- package/dist/ui/assets/{fs-C8QxzFK_.js → fs-llf9MCzR.js} +2 -2
- package/dist/ui/assets/{github-DnfkA3fV.js → github-BPAh8jDL.js} +1 -1
- package/dist/ui/assets/{github-Bm46hrl1.js → github-BuYYHwVD.js} +2 -2
- package/dist/ui/assets/{google-D6ha3Lvd.js → google-Cpy5Sd04.js} +1 -1
- package/dist/ui/assets/{google-DmmMEYi-.js → google-_NgtAdE2.js} +1 -1
- package/dist/ui/assets/{index-BxaasNW5.js → index-DLPF7rO2.js} +6 -6
- package/dist/ui/assets/{kernel-worker-BTAvhT7r.js → kernel-worker-CFHZVECk.js} +82 -88
- package/dist/ui/assets/{local-llm-BQQV1eUs.js → local-llm-DQmN1q4F.js} +1 -1
- package/dist/ui/assets/{local-llm-DQQUPDay.js → local-llm-DRYqjBeF.js} +1 -1
- package/dist/ui/assets/{magick-wasm-Dek2V-_y.js → magick-wasm-Doso8RzK.js} +1 -1
- package/dist/ui/assets/{mistral-BvJc11au.js → mistral-Don9WA_U.js} +1 -1
- package/dist/ui/assets/{mistral-D_QxZUo3.js → mistral-kdNDZsM0.js} +1 -1
- package/dist/ui/assets/{mount-XM0MMGbg.js → mount-D22V7Wmv.js} +2 -2
- package/dist/ui/assets/{mount-CBj4Y0uY.js → mount-cJ7Fh1ww.js} +1 -1
- package/dist/ui/assets/{nuke-command-CKv7dPLq.js → nuke-command-BwPFXzTo.js} +1 -1
- package/dist/ui/assets/{oauth-bootstrap-iOQY9ywE.js → oauth-bootstrap-Cnoncizz.js} +1 -1
- package/dist/ui/assets/{oauth-service-BynE1niO.js → oauth-service-B3UTYTa2.js} +1 -1
- package/dist/ui/assets/offscreen-client-DRUAUGTX.js +1 -0
- package/dist/ui/assets/{onboarding-orchestrator-BTbcOsYi.js → onboarding-orchestrator-DauAN5MT.js} +1 -1
- package/dist/ui/assets/{openai-codex-responses-jw3eMyAW.js → openai-codex-responses-DEFesGuE.js} +1 -1
- package/dist/ui/assets/{openai-codex-responses-ZTcDLOww.js → openai-codex-responses-DchQe0cH.js} +1 -1
- package/dist/ui/assets/{openai-completions-rPhCMQf6.js → openai-completions-Bt4QlIyn.js} +1 -1
- package/dist/ui/assets/{openai-completions-DeKhvKno.js → openai-completions-D49Ptr1B.js} +1 -1
- package/dist/ui/assets/{openai-responses-09Y9u2o-.js → openai-responses-e0RQ8RFv.js} +1 -1
- package/dist/ui/assets/{openai-responses-BYVIjcrN.js → openai-responses-r6y-rY24.js} +1 -1
- package/dist/ui/assets/{openai-responses-shared-BSdTPGXk.js → openai-responses-shared-B-T272Af.js} +1 -1
- package/dist/ui/assets/{openai-responses-shared-Cb6xPI3z.js → openai-responses-shared-BemWgAjZ.js} +1 -1
- package/dist/ui/assets/{provider-settings-YeoYrehC.js → provider-settings-CaxrG5yA.js} +3 -3
- package/dist/ui/assets/{provider-settings-B88plz7u.js → provider-settings-DificpTl.js} +1 -1
- package/dist/ui/assets/{providers-DyuaLPXN.js → providers-ypr6l9lG.js} +1 -1
- package/dist/ui/assets/{spawn-X9L04o6Q.js → spawn-B_aoqz2m.js} +1 -1
- package/dist/ui/assets/{upgrade-detection-Bllbwwis.js → upgrade-detection-CyImEIEC.js} +1 -1
- package/dist/ui/electron-overlay-entry.js +7 -7
- package/dist/ui/index.html +6 -6
- package/dist/ui/packages/webapp/index.html +6 -6
- package/package.json +1 -1
- package/dist/ui/assets/cost-command-DszplwaG.js +0 -1
- package/dist/ui/assets/offscreen-client-Bm3MzxIR.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-DificpTl.js";import{i as A,n as pe,r as me}from"./fs-llf9MCzR.js";import{n as he,t as ge}from"./path-utils-B73K5PBp.js";import{t as _e}from"./mount-id-BBl3dJu8.js";import{a as ve,i as ye,r as be,t as xe}from"./git-config-DZUguBxI.js";import{n as j,t as Se}from"./mime-types-CtECiBq5.js";import{_ as Ce,a as we,c as Te,d as Ee,f as M,g as De,h as N,i as P,l as Oe,m as ke,o as Ae,p as je,r as Me,s as Ne,t as Pe,u as Fe,v as Ie}from"./magick-wasm-DwA3cs4T.js";import{c as Le,o as Re}from"./bedrock-camp-B0q-7yNy.js";import{t as ze}from"./__vite-browser-external-BvI1wG2f.js";import{f as Be}from"./transform-messages-DlZklr1h.js";import{i as Ve}from"./providers-ypr6l9lG.js";import{t as He}from"./local-llm-DQmN1q4F.js";import{a as Ue,i as We,n as Ge,r as Ke}from"./mount-cJ7Fh1ww.js";import{t as qe}from"./remote-cache-BdYCICnT.js";const Je=i(`cdp`);var Ye=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`,Je.info(`Connected`,{url:t}),e()},this.ws.onerror=e=>{clearTimeout(i),this._state===`connecting`&&(Je.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(),Je.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),Je.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;Je.debug(`Response`,{id:e.id,hasError:!!e.error});let n=this.pending.get(e.id);n&&(this.pending.delete(e.id),e.error?(Je.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;Je.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(){Je.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 Xe(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 Ze=`(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:$e()})}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 tt(e){let t={role:Xe(e.role,`unknown`),name:Xe(e.name)},n=Xe(e.value);n!==``&&(t.value=n);let r=Xe(e.description);return r!==``&&(t.description=r),Array.isArray(e.children)&&e.children.length>0&&(t.children=e.children.map(e=>tt(e)).filter(e=>e.role!==`unknown`)),t}function nt(e){return e.headers.get(`x-proxy-error`)===`1`}async function rt(e){let t=`Proxy error ${e.status}`,n;try{n=await e.text()}catch{return t}return it(n,t)}function it(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 at={state:`inactive`,session:null,error:null};function ot(){return{...at,session:at.session?{...at.session}:null}}const st=new Set;function ct(e){return st.add(e),()=>{st.delete(e)}}const lt=new Set([`send_message`,`list_scoops`,`list_tasks`]),ut=`sessions`;function dt(){return new Promise((e,t)=>{let n=indexedDB.open(`browser-coding-agent`,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(ut)||e.createObjectStore(ut,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}var ft=class{db=null;async init(){this.db=await dt()}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(ut,`readwrite`);i.objectStore(ut).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(ut,`readonly`).objectStore(ut).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(ut,`readonly`).objectStore(ut).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(ut,`readwrite`);i.objectStore(ut).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 pt=i(`tool-ui`),mt=new class{pending=new Map;idCounter=0;generateId(){return`tool-ui-${++this.idCounter}-${Date.now().toString(36)}`}register(e,t,n,r){this.pending.set(e,{request:t,resolve:n,reject:r}),pt.info(`Tool UI registered`,{id:e})}async handleAction(e,t){let n=this.pending.get(e);if(!n){pt.warn(`Action for unknown tool UI`,{id:e,action:t.action});return}pt.info(`Tool UI action`,{id:e,action:t.action});try{let e;e=n.request.onAction?await n.request.onAction(t.action,t.data):t,n.resolve(e)}catch(e){n.reject(e instanceof Error?e:Error(String(e)))}finally{this.pending.delete(e)}}cancel(e,t=`cancelled`){let n=this.pending.get(e);n&&(n.reject(Error(t)),this.pending.delete(e),pt.info(`Tool UI cancelled`,{id:e,reason:t}))}cancelAll(e=`cancelled`){let t=this.pending.size;for(let[t,n]of this.pending)n.reject(Error(e));this.pending.clear(),t>0&&pt.info(`All tool UIs cancelled`,{reason:e,count:t})}isPending(e){return this.pending.has(e)}getPendingIds(){return[...this.pending.keys()]}};async function ht(e,t){let n=e.id??mt.generateId(),r,i,a=new Promise((e,t)=>{r=e,i=t});return mt.register(n,e,r,i),t?t({content:[{type:`tool_ui`,requestId:n,html:e.html}]}):pt.warn(`showToolUI called without onUpdate callback — UI may not render`),a.finally(()=>{t&&t({content:[{type:`tool_ui_done`,requestId:n}]})})}const gt=[];function _t(e){return gt.push(e),e}function vt(e){let t=gt.lastIndexOf(e);t!==-1&>.splice(t,1)}function yt(){return gt.length>0?gt[gt.length-1]:null}async function bt(e){let t=yt();return t?ht(e,t.onUpdate):(pt.warn(`showToolUIFromContext called without execution context`),null)}i(`panel-transport`);function xt(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function St(){return{onMessage:e=>{let t=(t,n,r)=>(xt(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(()=>{})}}}var Ct=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||=St(),this._transport}async bind(e,t){this.orchestrator=e,this.browserAPI=t??null,this.transportUnsubscribe?.(),this.transportUnsubscribe=this.setupMessageListener();let n=new ft;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-${wt()}`;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(lt.has(n))return;let i=e.getOrCreateAssistantMsg(t);i.toolCalls||=[],i.toolCalls.push({id:wt(),name:n,input:r}),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:n,toolInput:r})},onToolEnd:(t,n,r,i)=>{if(lt.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=ot(),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-rNxH0eRL.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}-${wt()}`,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-Ci8JPwa_.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`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 mt.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}),mt.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 wt(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}const Tt=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`];function Et(e){return typeof e==`string`&&Tt.includes(e)}var Dt=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 Ot=(e,t,n)=>{let r=e instanceof RegExp?kt(e,n):e,i=t instanceof RegExp?kt(t,n):t,a=r!==null&&i!=null&&At(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)}},kt=(e,t)=>{let n=t.match(e);return n?n[0]:null},At=(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},jt=`\0SLASH`+Math.random()+`\0`,Mt=`\0OPEN`+Math.random()+`\0`,Nt=`\0CLOSE`+Math.random()+`\0`,Pt=`\0COMMA`+Math.random()+`\0`,Ft=`\0PERIOD`+Math.random()+`\0`,It=new RegExp(jt,`g`),Lt=new RegExp(Mt,`g`),Rt=new RegExp(Nt,`g`),zt=new RegExp(Pt,`g`),Bt=new RegExp(Ft,`g`),Vt=/\\\\/g,Ht=/\\{/g,Ut=/\\}/g,Wt=/\\,/g,Gt=/\\\./g;function Kt(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function qt(e){return e.replace(Vt,jt).replace(Ht,Mt).replace(Ut,Nt).replace(Wt,Pt).replace(Gt,Ft)}function Jt(e){return e.replace(It,`\\`).replace(Lt,`{`).replace(Rt,`}`).replace(zt,`,`).replace(Bt,`.`)}function Yt(e){if(!e)return[``];let t=[],n=Ot(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=Yt(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function Xt(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),tn(qt(e),n,!0).map(Jt)}function Zt(e){return`{`+e+`}`}function Qt(e){return/^-?0\d/.test(e)}function $t(e,t){return e<=t}function en(e,t){return e>=t}function tn(e,t,n){let r=[],i=Ot(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?tn(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+Nt+i.post,tn(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=Yt(i.body),d.length===1&&d[0]!==void 0&&(d=tn(d[0],t,!1).map(Zt),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=Kt(d[0]),t=Kt(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.abs(Kt(d[2])):1,i=$t;t<e&&(r*=-1,i=en);let a=d.some(Qt);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,tn(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 nn=e=>{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},rn={"[: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]},an=e=>e.replace(/[[\]\\-]/g,`\\$&`),on=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),sn=e=>e.join(``),cn=(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(rn))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(an(d)+`-`+an(t)):t===d&&r.push(an(t)),d=``,a++;continue}if(e.startsWith(`-]`,a+1)){r.push(an(t+`-`)),a+=2;continue}if(e.startsWith(`-`,a+1)){d=t,a+=2;continue}r.push(an(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[on(r[0].length===2?r[0].slice(-1):r[0]),!1,u-n,!1];let f=`[`+(l?`^`:``)+sn(r)+`]`,p=`[`+(l?``:`^`)+sn(i)+`]`;return[r.length&&i.length?`(`+f+`|`+p+`)`:r.length?f:p,s,u-n,!0]},ln=(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 un;const dn=new Set([`!`,`?`,`+`,`*`,`@`]),fn=e=>dn.has(e),pn=e=>fn(e.type),mn=new Map([[`!`,[`@`]],[`?`,[`?`,`@`]],[`@`,[`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`]]]),hn=new Map([[`!`,[`?`]],[`@`,[`?`]],[`+`,[`?`,`*`]]]),gn=new Map([[`!`,[`?`,`@`]],[`?`,[`?`,`@`]],[`@`,[`?`,`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`,`?`,`*`]]]),_n=new Map([[`!`,new Map([[`!`,`@`]])],[`?`,new Map([[`*`,`*`],[`+`,`*`]])],[`@`,new Map([[`!`,`!`],[`?`,`?`],[`@`,`@`],[`*`,`*`],[`+`,`+`]])],[`+`,new Map([[`?`,`*`],[`*`,`*`]])]]),vn=`(?!\\.)`,yn=new Set([`[`,`.`]),bn=new Set([`..`,`.`]),xn=new Set(`().*{}+?[]^$\\!`),Sn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),Cn=`[^/]`,wn=Cn+`*?`,Tn=Cn+`+?`;let En=0;var Dn=class{type;#e;#t;#n=!1;#r=[];#i;#a;#o;#s=!1;#c;#l;#u=!1;id=++En;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 un&&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 un&&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 un(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&&fn(n)&&e.charAt(u)===`(`&&i<=a){t.push(d),d=``;let a=new un(n,t);u=un.#f(e,a,u,r,i+1),t.push(a);continue}d+=n}return t.push(d),u}let u=n+1,d=new un(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&&fn(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 un(n,d);d.push(o),u=un.#f(e,o,u,r,i+a);continue}if(n===`|`){d.push(p),p=``,f.push(d),d=new un(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,hn)}#m(e,t=mn){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=gn){return!!t.get(this.type)?.includes(e)}#g(e,t){let n=e.#r[0],r=new un(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!!_n.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=_n.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 un(null,void 0,t);return un.#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()),!pn(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`?un.#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&&bn.has(this.#r[0]))){let n=yn,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?vn:``}let a=``;return this.isEnd()&&this.#e.#s&&this.#i?.type===`!`&&(a=`(?:$|\\/)`),[i+r+a,ln(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,ln(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?vn:``)+Tn;else{let n=this.type===`!`?`))`+(this.isStart()&&!t&&!e?vn:``)+wn+`)`:this.type===`@`?`)`:this.type===`?`?`)?`:this.type===`+`&&a?`)`:this.type===`*`&&a?`)?`:`)${this.type}`;o=r+i+n}return[o,ln(i),this.#t=!!this.#t,this.#n]}#x(){if(pn(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+=(xn.has(c)?`\\`:``)+c;continue}if(c===`*`){if(o)continue;o=!0,i+=n&&/^[*]+$/.test(e)?Tn:wn,t=!0;continue}else o=!1;if(c===`\\`){s===e.length-1?i+=`\\\\`:r=!0;continue}if(c===`[`){let[n,r,o,c]=cn(e,s);if(o){i+=n,a||=r,s+=o-1,t||=c;continue}}if(c===`?`){i+=Cn,t=!0;continue}i+=Sn(c)}return[i,ln(e),!!t,a]}};un=Dn;const On=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!1}={})=>n?t?e.replace(/[?*()[\]{}]/g,`[$&]`):e.replace(/[?*()[\]\\{}]/g,`\\$&`):t?e.replace(/[?*()[\]]/g,`[$&]`):e.replace(/[?*()[\]\\]/g,`\\$&`),kn=(e,t,n={})=>(nn(t),!n.nocomment&&t.charAt(0)===`#`?!1:new rr(t,n).match(e)),An=/^\*+([^+@!?\*\[\(]*)$/,jn=e=>t=>!t.startsWith(`.`)&&t.endsWith(e),Mn=e=>t=>t.endsWith(e),Nn=e=>(e=e.toLowerCase(),t=>!t.startsWith(`.`)&&t.toLowerCase().endsWith(e)),Pn=e=>(e=e.toLowerCase(),t=>t.toLowerCase().endsWith(e)),Fn=/^\*+\.\*+$/,In=e=>!e.startsWith(`.`)&&e.includes(`.`),Ln=e=>e!==`.`&&e!==`..`&&e.includes(`.`),Rn=/^\.\*+$/,zn=e=>e!==`.`&&e!==`..`&&e.startsWith(`.`),Bn=/^\*+$/,Vn=e=>e.length!==0&&!e.startsWith(`.`),Hn=e=>e.length!==0&&e!==`.`&&e!==`..`,Un=/^\?+([^+@!?\*\[\(]*)?$/,Wn=([e,t=``])=>{let n=Jn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Gn=([e,t=``])=>{let n=Yn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Kn=([e,t=``])=>{let n=Yn([e]);return t?e=>n(e)&&e.endsWith(t):n},qn=([e,t=``])=>{let n=Jn([e]);return t?e=>n(e)&&e.endsWith(t):n},Jn=([e])=>{let t=e.length;return e=>e.length===t&&!e.startsWith(`.`)},Yn=([e])=>{let t=e.length;return e=>e.length===t&&e!==`.`&&e!==`..`},Xn=typeof process==`object`&&process?{}.__MINIMATCH_TESTING_PLATFORM__||process.platform:`posix`,Zn={win32:{sep:`\\`},posix:{sep:`/`}};kn.sep=Xn===`win32`?Zn.win32.sep:Zn.posix.sep;const Qn=Symbol(`globstar **`);kn.GLOBSTAR=Qn,kn.filter=(e,t={})=>n=>kn(n,e,t);const $n=(e,t={})=>Object.assign({},e,t);kn.defaults=e=>{if(!e||typeof e!=`object`||!Object.keys(e).length)return kn;let t=kn;return Object.assign((n,r,i={})=>t(n,r,$n(e,i)),{Minimatch:class extends t.Minimatch{constructor(t,n={}){super(t,$n(e,n))}static defaults(n){return t.defaults($n(e,n)).Minimatch}},AST:class extends t.AST{constructor(t,n,r={}){super(t,n,$n(e,r))}static fromGlob(n,r={}){return t.AST.fromGlob(n,$n(e,r))}},unescape:(n,r={})=>t.unescape(n,$n(e,r)),escape:(n,r={})=>t.escape(n,$n(e,r)),filter:(n,r={})=>t.filter(n,$n(e,r)),defaults:n=>t.defaults($n(e,n)),makeRe:(n,r={})=>t.makeRe(n,$n(e,r)),braceExpand:(n,r={})=>t.braceExpand(n,$n(e,r)),match:(n,r,i={})=>t.match(n,r,$n(e,i)),sep:t.sep,GLOBSTAR:Qn})};const er=(e,t={})=>(nn(e),t.nobrace||!/\{(?:(?!\{).)*\}/.test(e)?[e]:Xt(e,{max:t.braceExpandMax}));kn.braceExpand=er,kn.makeRe=(e,t={})=>new rr(e,t).makeRe(),kn.match=(e,t,n={})=>{let r=new rr(t,n);return e=e.filter(e=>r.match(e)),r.options.nonull&&!e.length&&e.push(t),e};const tr=/[?*]|[+@!]\(.*?\)|\[|\]/,nr=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`);var rr=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;maxGlobstarRecursion;regexp;constructor(e,t={}){nn(e),t||={},this.options=t,this.maxGlobstarRecursion=t.maxGlobstarRecursion??200,this.pattern=e,this.platform=t.platform||Xn,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]===`?`||!tr.test(e[2]))&&!tr.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(Qn)?this.#e(e,t,n,r,i):this.#n(e,t,n,r,i)}#e(e,t,n,r,i){let a=t.indexOf(Qn,i),o=t.lastIndexOf(Qn),[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===Qn?(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===Qn)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 er(this.pattern,this.options)}parse(e){nn(e);let t=this.options;if(e===`**`)return Qn;if(e===``)return``;let n,r=null;(n=e.match(Bn))?r=t.dot?Hn:Vn:(n=e.match(An))?r=(t.nocase?t.dot?Pn:Nn:t.dot?Mn:jn)(n[1]):(n=e.match(Un))?r=(t.nocase?t.dot?Gn:Wn:t.dot?Kn:qn)(n):(n=e.match(Fn))?r=t.dot?Ln:In:(n=e.match(Rn))&&(r=zn);let i=Dn.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`?nr(e):e===Qn?Qn:e._src});t.forEach((e,r)=>{let i=t[r+1],a=t[r-1];e!==Qn||a===Qn||(a===void 0?i!==void 0&&i!==Qn?t[r+1]=`(?:\\/|`+n+`\\/)?`+i:t[r]=n:i===void 0?t[r-1]=a+`(?:\\/|\\/`+n+`)?`:i!==Qn&&(t[r-1]=a+`(?:\\/|\\/`+n+`\\/)`+i,t[r+1]=Qn))});let i=t.filter(e=>e!==Qn);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 kn.defaults(e).Minimatch}};kn.AST=Dn,kn.Minimatch=rr,kn.escape=On,kn.unescape=ln;const ir={};function ar(){throw Error(`gunzipSync is not available in the browser`)}function or(){throw Error(`gzipSync is not available in the browser`)}var sr=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 sr{};function cr(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 lr(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 ur(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 dr(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 fr(e,t){return ur(e,t,``)}function pr(e,t){return dr(e,t,``)}function mr(e,t){return t.slice(0,hr(e,t))}function hr(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 gr(e){let t;for(t=e.length-1;t>=0&&e[t].match(/\s/);t--);return e.substring(t+1)}function _r(e){let t=e.match(/^\s*/);return t?t[0]:``}const vr=`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}`,yr=RegExp(`[${vr}]+|\\s+|[^${vr}]`,`ug`);new class extends sr{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(yr)||[];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)&&br(n,i,r,e),n=e,r=null,i=null)}),(r||i)&&br(n,i,r,null),e}};function br(e,t,n,r){if(t&&n){let i=_r(t.value),a=gr(t.value),o=_r(n.value),s=gr(n.value);if(e){let r=cr(i,o);e.value=dr(e.value,o,r),t.value=fr(t.value,r),n.value=fr(n.value,r)}if(r){let e=lr(a,s);r.value=ur(r.value,s,e),t.value=pr(t.value,e),n.value=pr(n.value,e)}}else if(n){if(e){let e=_r(n.value);n.value=n.value.substring(e.length)}if(r){let e=_r(r.value);r.value=r.value.substring(e.length)}}else if(e&&r){let n=_r(r.value),i=_r(t.value),a=gr(t.value),o=cr(n,i);t.value=fr(t.value,o);let s=lr(fr(n,o),a);t.value=pr(t.value,s),r.value=ur(r.value,n,s),e.value=dr(e.value,n,n.slice(0,n.length-s.length))}else if(r){let e=_r(r.value),n=mr(gr(t.value),e);t.value=pr(t.value,n)}else if(e){let n=mr(gr(e.value),_r(t.value));t.value=fr(t.value,n)}}new class extends sr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${vr}]+|[^\\S\\n\\r]+|[^${vr}]`,`ug`);return e.match(t)||[]}};const xr=new class extends sr{constructor(){super(...arguments),this.tokenize=Cr}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:$e()})}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 tt(e){let t={role:Xe(e.role,`unknown`),name:Xe(e.name)},n=Xe(e.value);n!==``&&(t.value=n);let r=Xe(e.description);return r!==``&&(t.description=r),Array.isArray(e.children)&&e.children.length>0&&(t.children=e.children.map(e=>tt(e)).filter(e=>e.role!==`unknown`)),t}function nt(e){return e.headers.get(`x-proxy-error`)===`1`}async function rt(e){let t=`Proxy error ${e.status}`,n;try{n=await e.text()}catch{return t}return it(n,t)}function it(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 at={state:`inactive`,session:null,error:null};function ot(){return{...at,session:at.session?{...at.session}:null}}const st=new Set;function ct(e){return st.add(e),()=>{st.delete(e)}}const lt=new Set([`send_message`,`list_scoops`,`list_tasks`]),ut=`sessions`;function dt(){return new Promise((e,t)=>{let n=indexedDB.open(`browser-coding-agent`,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(ut)||e.createObjectStore(ut,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}var ft=class{db=null;async init(){this.db=await dt()}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(ut,`readwrite`);i.objectStore(ut).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(ut,`readonly`).objectStore(ut).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(ut,`readonly`).objectStore(ut).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(ut,`readwrite`);i.objectStore(ut).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 pt=i(`tool-ui`),mt=new class{pending=new Map;idCounter=0;generateId(){return`tool-ui-${++this.idCounter}-${Date.now().toString(36)}`}register(e,t,n,r){this.pending.set(e,{request:t,resolve:n,reject:r}),pt.info(`Tool UI registered`,{id:e})}async handleAction(e,t){let n=this.pending.get(e);if(!n){pt.warn(`Action for unknown tool UI`,{id:e,action:t.action});return}pt.info(`Tool UI action`,{id:e,action:t.action});try{let e;e=n.request.onAction?await n.request.onAction(t.action,t.data):t,n.resolve(e)}catch(e){n.reject(e instanceof Error?e:Error(String(e)))}finally{this.pending.delete(e)}}cancel(e,t=`cancelled`){let n=this.pending.get(e);n&&(n.reject(Error(t)),this.pending.delete(e),pt.info(`Tool UI cancelled`,{id:e,reason:t}))}cancelAll(e=`cancelled`){let t=this.pending.size;for(let[t,n]of this.pending)n.reject(Error(e));this.pending.clear(),t>0&&pt.info(`All tool UIs cancelled`,{reason:e,count:t})}isPending(e){return this.pending.has(e)}getPendingIds(){return[...this.pending.keys()]}};async function ht(e,t){let n=e.id??mt.generateId(),r,i,a=new Promise((e,t)=>{r=e,i=t});return mt.register(n,e,r,i),t?t({content:[{type:`tool_ui`,requestId:n,html:e.html}]}):pt.warn(`showToolUI called without onUpdate callback — UI may not render`),a.finally(()=>{t&&t({content:[{type:`tool_ui_done`,requestId:n}]})})}const gt=[];function _t(e){return gt.push(e),e}function vt(e){let t=gt.lastIndexOf(e);t!==-1&>.splice(t,1)}function yt(){return gt.length>0?gt[gt.length-1]:null}async function bt(e){let t=yt();return t?ht(e,t.onUpdate):(pt.warn(`showToolUIFromContext called without execution context`),null)}i(`panel-transport`);function xt(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function St(){return{onMessage:e=>{let t=(t,n,r)=>(xt(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(()=>{})}}}var Ct=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||=St(),this._transport}async bind(e,t){this.orchestrator=e,this.browserAPI=t??null,this.transportUnsubscribe?.(),this.transportUnsubscribe=this.setupMessageListener();let n=new ft;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-${wt()}`;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(lt.has(n))return;let i=e.getOrCreateAssistantMsg(t);i.toolCalls||=[],i.toolCalls.push({id:wt(),name:n,input:r}),e.emit({type:`agent-event`,scoopJid:t,eventType:`tool_start`,toolName:n,toolInput:r})},onToolEnd:(t,n,r,i)=>{if(lt.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=ot(),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-CMHJiLMB.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}-${wt()}`,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-Ci8JPwa_.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`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 mt.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}),mt.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 wt(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}const Tt=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`];function Et(e){return typeof e==`string`&&Tt.includes(e)}var Dt=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 Ot=(e,t,n)=>{let r=e instanceof RegExp?kt(e,n):e,i=t instanceof RegExp?kt(t,n):t,a=r!==null&&i!=null&&At(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)}},kt=(e,t)=>{let n=t.match(e);return n?n[0]:null},At=(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},jt=`\0SLASH`+Math.random()+`\0`,Mt=`\0OPEN`+Math.random()+`\0`,Nt=`\0CLOSE`+Math.random()+`\0`,Pt=`\0COMMA`+Math.random()+`\0`,Ft=`\0PERIOD`+Math.random()+`\0`,It=new RegExp(jt,`g`),Lt=new RegExp(Mt,`g`),Rt=new RegExp(Nt,`g`),zt=new RegExp(Pt,`g`),Bt=new RegExp(Ft,`g`),Vt=/\\\\/g,Ht=/\\{/g,Ut=/\\}/g,Wt=/\\,/g,Gt=/\\\./g;function Kt(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function qt(e){return e.replace(Vt,jt).replace(Ht,Mt).replace(Ut,Nt).replace(Wt,Pt).replace(Gt,Ft)}function Jt(e){return e.replace(It,`\\`).replace(Lt,`{`).replace(Rt,`}`).replace(zt,`,`).replace(Bt,`.`)}function Yt(e){if(!e)return[``];let t=[],n=Ot(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=Yt(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function Xt(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),tn(qt(e),n,!0).map(Jt)}function Zt(e){return`{`+e+`}`}function Qt(e){return/^-?0\d/.test(e)}function $t(e,t){return e<=t}function en(e,t){return e>=t}function tn(e,t,n){let r=[],i=Ot(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?tn(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+Nt+i.post,tn(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=Yt(i.body),d.length===1&&d[0]!==void 0&&(d=tn(d[0],t,!1).map(Zt),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=Kt(d[0]),t=Kt(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.abs(Kt(d[2])):1,i=$t;t<e&&(r*=-1,i=en);let a=d.some(Qt);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,tn(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 nn=e=>{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},rn={"[: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]},an=e=>e.replace(/[[\]\\-]/g,`\\$&`),on=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),sn=e=>e.join(``),cn=(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(rn))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(an(d)+`-`+an(t)):t===d&&r.push(an(t)),d=``,a++;continue}if(e.startsWith(`-]`,a+1)){r.push(an(t+`-`)),a+=2;continue}if(e.startsWith(`-`,a+1)){d=t,a+=2;continue}r.push(an(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[on(r[0].length===2?r[0].slice(-1):r[0]),!1,u-n,!1];let f=`[`+(l?`^`:``)+sn(r)+`]`,p=`[`+(l?``:`^`)+sn(i)+`]`;return[r.length&&i.length?`(`+f+`|`+p+`)`:r.length?f:p,s,u-n,!0]},ln=(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 un;const dn=new Set([`!`,`?`,`+`,`*`,`@`]),fn=e=>dn.has(e),pn=e=>fn(e.type),mn=new Map([[`!`,[`@`]],[`?`,[`?`,`@`]],[`@`,[`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`]]]),hn=new Map([[`!`,[`?`]],[`@`,[`?`]],[`+`,[`?`,`*`]]]),gn=new Map([[`!`,[`?`,`@`]],[`?`,[`?`,`@`]],[`@`,[`?`,`@`]],[`*`,[`*`,`+`,`?`,`@`]],[`+`,[`+`,`@`,`?`,`*`]]]),_n=new Map([[`!`,new Map([[`!`,`@`]])],[`?`,new Map([[`*`,`*`],[`+`,`*`]])],[`@`,new Map([[`!`,`!`],[`?`,`?`],[`@`,`@`],[`*`,`*`],[`+`,`+`]])],[`+`,new Map([[`?`,`*`],[`*`,`*`]])]]),vn=`(?!\\.)`,yn=new Set([`[`,`.`]),bn=new Set([`..`,`.`]),xn=new Set(`().*{}+?[]^$\\!`),Sn=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),Cn=`[^/]`,wn=Cn+`*?`,Tn=Cn+`+?`;let En=0;var Dn=class{type;#e;#t;#n=!1;#r=[];#i;#a;#o;#s=!1;#c;#l;#u=!1;id=++En;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 un&&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 un&&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 un(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&&fn(n)&&e.charAt(u)===`(`&&i<=a){t.push(d),d=``;let a=new un(n,t);u=un.#f(e,a,u,r,i+1),t.push(a);continue}d+=n}return t.push(d),u}let u=n+1,d=new un(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&&fn(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 un(n,d);d.push(o),u=un.#f(e,o,u,r,i+a);continue}if(n===`|`){d.push(p),p=``,f.push(d),d=new un(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,hn)}#m(e,t=mn){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=gn){return!!t.get(this.type)?.includes(e)}#g(e,t){let n=e.#r[0],r=new un(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!!_n.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=_n.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 un(null,void 0,t);return un.#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()),!pn(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`?un.#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&&bn.has(this.#r[0]))){let n=yn,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?vn:``}let a=``;return this.isEnd()&&this.#e.#s&&this.#i?.type===`!`&&(a=`(?:$|\\/)`),[i+r+a,ln(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,ln(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?vn:``)+Tn;else{let n=this.type===`!`?`))`+(this.isStart()&&!t&&!e?vn:``)+wn+`)`:this.type===`@`?`)`:this.type===`?`?`)?`:this.type===`+`&&a?`)`:this.type===`*`&&a?`)?`:`)${this.type}`;o=r+i+n}return[o,ln(i),this.#t=!!this.#t,this.#n]}#x(){if(pn(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+=(xn.has(c)?`\\`:``)+c;continue}if(c===`*`){if(o)continue;o=!0,i+=n&&/^[*]+$/.test(e)?Tn:wn,t=!0;continue}else o=!1;if(c===`\\`){s===e.length-1?i+=`\\\\`:r=!0;continue}if(c===`[`){let[n,r,o,c]=cn(e,s);if(o){i+=n,a||=r,s+=o-1,t||=c;continue}}if(c===`?`){i+=Cn,t=!0;continue}i+=Sn(c)}return[i,ln(e),!!t,a]}};un=Dn;const On=(e,{windowsPathsNoEscape:t=!1,magicalBraces:n=!1}={})=>n?t?e.replace(/[?*()[\]{}]/g,`[$&]`):e.replace(/[?*()[\]\\{}]/g,`\\$&`):t?e.replace(/[?*()[\]]/g,`[$&]`):e.replace(/[?*()[\]\\]/g,`\\$&`),kn=(e,t,n={})=>(nn(t),!n.nocomment&&t.charAt(0)===`#`?!1:new rr(t,n).match(e)),An=/^\*+([^+@!?\*\[\(]*)$/,jn=e=>t=>!t.startsWith(`.`)&&t.endsWith(e),Mn=e=>t=>t.endsWith(e),Nn=e=>(e=e.toLowerCase(),t=>!t.startsWith(`.`)&&t.toLowerCase().endsWith(e)),Pn=e=>(e=e.toLowerCase(),t=>t.toLowerCase().endsWith(e)),Fn=/^\*+\.\*+$/,In=e=>!e.startsWith(`.`)&&e.includes(`.`),Ln=e=>e!==`.`&&e!==`..`&&e.includes(`.`),Rn=/^\.\*+$/,zn=e=>e!==`.`&&e!==`..`&&e.startsWith(`.`),Bn=/^\*+$/,Vn=e=>e.length!==0&&!e.startsWith(`.`),Hn=e=>e.length!==0&&e!==`.`&&e!==`..`,Un=/^\?+([^+@!?\*\[\(]*)?$/,Wn=([e,t=``])=>{let n=Jn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Gn=([e,t=``])=>{let n=Yn([e]);return t?(t=t.toLowerCase(),e=>n(e)&&e.toLowerCase().endsWith(t)):n},Kn=([e,t=``])=>{let n=Yn([e]);return t?e=>n(e)&&e.endsWith(t):n},qn=([e,t=``])=>{let n=Jn([e]);return t?e=>n(e)&&e.endsWith(t):n},Jn=([e])=>{let t=e.length;return e=>e.length===t&&!e.startsWith(`.`)},Yn=([e])=>{let t=e.length;return e=>e.length===t&&e!==`.`&&e!==`..`},Xn=typeof process==`object`&&process?{}.__MINIMATCH_TESTING_PLATFORM__||process.platform:`posix`,Zn={win32:{sep:`\\`},posix:{sep:`/`}};kn.sep=Xn===`win32`?Zn.win32.sep:Zn.posix.sep;const Qn=Symbol(`globstar **`);kn.GLOBSTAR=Qn,kn.filter=(e,t={})=>n=>kn(n,e,t);const $n=(e,t={})=>Object.assign({},e,t);kn.defaults=e=>{if(!e||typeof e!=`object`||!Object.keys(e).length)return kn;let t=kn;return Object.assign((n,r,i={})=>t(n,r,$n(e,i)),{Minimatch:class extends t.Minimatch{constructor(t,n={}){super(t,$n(e,n))}static defaults(n){return t.defaults($n(e,n)).Minimatch}},AST:class extends t.AST{constructor(t,n,r={}){super(t,n,$n(e,r))}static fromGlob(n,r={}){return t.AST.fromGlob(n,$n(e,r))}},unescape:(n,r={})=>t.unescape(n,$n(e,r)),escape:(n,r={})=>t.escape(n,$n(e,r)),filter:(n,r={})=>t.filter(n,$n(e,r)),defaults:n=>t.defaults($n(e,n)),makeRe:(n,r={})=>t.makeRe(n,$n(e,r)),braceExpand:(n,r={})=>t.braceExpand(n,$n(e,r)),match:(n,r,i={})=>t.match(n,r,$n(e,i)),sep:t.sep,GLOBSTAR:Qn})};const er=(e,t={})=>(nn(e),t.nobrace||!/\{(?:(?!\{).)*\}/.test(e)?[e]:Xt(e,{max:t.braceExpandMax}));kn.braceExpand=er,kn.makeRe=(e,t={})=>new rr(e,t).makeRe(),kn.match=(e,t,n={})=>{let r=new rr(t,n);return e=e.filter(e=>r.match(e)),r.options.nonull&&!e.length&&e.push(t),e};const tr=/[?*]|[+@!]\(.*?\)|\[|\]/,nr=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`);var rr=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;maxGlobstarRecursion;regexp;constructor(e,t={}){nn(e),t||={},this.options=t,this.maxGlobstarRecursion=t.maxGlobstarRecursion??200,this.pattern=e,this.platform=t.platform||Xn,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]===`?`||!tr.test(e[2]))&&!tr.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(Qn)?this.#e(e,t,n,r,i):this.#n(e,t,n,r,i)}#e(e,t,n,r,i){let a=t.indexOf(Qn,i),o=t.lastIndexOf(Qn),[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===Qn?(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===Qn)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 er(this.pattern,this.options)}parse(e){nn(e);let t=this.options;if(e===`**`)return Qn;if(e===``)return``;let n,r=null;(n=e.match(Bn))?r=t.dot?Hn:Vn:(n=e.match(An))?r=(t.nocase?t.dot?Pn:Nn:t.dot?Mn:jn)(n[1]):(n=e.match(Un))?r=(t.nocase?t.dot?Gn:Wn:t.dot?Kn:qn)(n):(n=e.match(Fn))?r=t.dot?Ln:In:(n=e.match(Rn))&&(r=zn);let i=Dn.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`?nr(e):e===Qn?Qn:e._src});t.forEach((e,r)=>{let i=t[r+1],a=t[r-1];e!==Qn||a===Qn||(a===void 0?i!==void 0&&i!==Qn?t[r+1]=`(?:\\/|`+n+`\\/)?`+i:t[r]=n:i===void 0?t[r-1]=a+`(?:\\/|\\/`+n+`)?`:i!==Qn&&(t[r-1]=a+`(?:\\/|\\/`+n+`\\/)`+i,t[r+1]=Qn))});let i=t.filter(e=>e!==Qn);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 kn.defaults(e).Minimatch}};kn.AST=Dn,kn.Minimatch=rr,kn.escape=On,kn.unescape=ln;const ir={};function ar(){throw Error(`gunzipSync is not available in the browser`)}function or(){throw Error(`gzipSync is not available in the browser`)}var sr=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 sr{};function cr(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 lr(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 ur(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 dr(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 fr(e,t){return ur(e,t,``)}function pr(e,t){return dr(e,t,``)}function mr(e,t){return t.slice(0,hr(e,t))}function hr(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 gr(e){let t;for(t=e.length-1;t>=0&&e[t].match(/\s/);t--);return e.substring(t+1)}function _r(e){let t=e.match(/^\s*/);return t?t[0]:``}const vr=`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}`,yr=RegExp(`[${vr}]+|\\s+|[^${vr}]`,`ug`);new class extends sr{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(yr)||[];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)&&br(n,i,r,e),n=e,r=null,i=null)}),(r||i)&&br(n,i,r,null),e}};function br(e,t,n,r){if(t&&n){let i=_r(t.value),a=gr(t.value),o=_r(n.value),s=gr(n.value);if(e){let r=cr(i,o);e.value=dr(e.value,o,r),t.value=fr(t.value,r),n.value=fr(n.value,r)}if(r){let e=lr(a,s);r.value=ur(r.value,s,e),t.value=pr(t.value,e),n.value=pr(n.value,e)}}else if(n){if(e){let e=_r(n.value);n.value=n.value.substring(e.length)}if(r){let e=_r(r.value);r.value=r.value.substring(e.length)}}else if(e&&r){let n=_r(r.value),i=_r(t.value),a=gr(t.value),o=cr(n,i);t.value=fr(t.value,o);let s=lr(fr(n,o),a);t.value=pr(t.value,s),r.value=ur(r.value,n,s),e.value=dr(e.value,n,n.slice(0,n.length-s.length))}else if(r){let e=_r(r.value),n=mr(gr(t.value),e);t.value=pr(t.value,n)}else if(e){let n=mr(gr(e.value),_r(t.value));t.value=fr(t.value,n)}}new class extends sr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${vr}]+|[^\\S\\n\\r]+|[^${vr}]`,`ug`);return e.match(t)||[]}};const xr=new class extends sr{constructor(){super(...arguments),this.tokenize=Cr}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(`
|
|
@@ -3034,7 +3034,7 @@ except BaseException:
|
|
|
3034
3034
|
`,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:we(i)}),c=URL.createObjectURL(s),l=document.createElement(`a`);l.href=c,l.download=P(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
|
|
3035
3035
|
`,exitCode:1};let e=Ie(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(`
|
|
3036
3036
|
`)+`
|
|
3037
|
-
`,stderr:``,exitCode:0}})}let TY=null,EY=null;async function DY(){return TY||=import(`./es-
|
|
3037
|
+
`,stderr:``,exitCode:0}})}let TY=null,EY=null;async function DY(){return TY||=import(`./es-C_SsgQvK.js`),TY}async function OY(){return EY||=import(`./dist-USoe4ZIh.js`),EY}function kY(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 AY(e){let{range:t,rotation:n}=kY(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 jY(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 MY(){return{stdout:`usage: pdftk <input.pdf> <operation> [args...]
|
|
3038
3038
|
|
|
3039
3039
|
Operations:
|
|
3040
3040
|
dump_data Print metadata (page count, title, author, etc.)
|
|
@@ -3273,10 +3273,10 @@ Examples:
|
|
|
3273
3273
|
oauth-token adobe
|
|
3274
3274
|
oauth-token github --scope "repo,models:read"
|
|
3275
3275
|
curl -H "Authorization: Bearer $(oauth-token github)" https://api.github.com/user
|
|
3276
|
-
`}function UZ(){return EM(`oauth-token`,async e=>{let{getOAuthAccountInfo:t,getSelectedProvider:n,getAccounts:r}=await import(`./provider-settings-
|
|
3276
|
+
`}function UZ(){return EM(`oauth-token`,async e=>{let{getOAuthAccountInfo:t,getSelectedProvider:n,getAccounts:r}=await import(`./provider-settings-DificpTl.js`).then(e=>e.l),{getRegisteredProviderConfig:i,getRegisteredProviderIds:a}=await import(`./providers-ypr6l9lG.js`).then(e=>e.r);if(e.includes(`--help`)||e.includes(`-h`))return{stdout:HZ(),stderr:``,exitCode:0};if(e.includes(`--list`))return WZ(r,a,i,t);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
|
|
3277
3277
|
`,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
|
|
3278
3278
|
`,exitCode:1}}else if(e.length>0)c=e[0];else{let e=n(),t=i(e);if(t?.isOAuth&&t.onOAuthLogin)c=e;else if(c=a().find(e=>{let t=i(e);return t?.isOAuth&&t.onOAuthLogin}),!c)return{stdout:``,stderr:`oauth-token: no OAuth providers configured
|
|
3279
|
-
`,exitCode:1}}let u=i(c);if(!u)return{stdout:``,stderr:`oauth-token: unknown provider "${c}"\n`,exitCode:1};if(!u.isOAuth||!u.onOAuthLogin)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{let{createOAuthLauncher:e}=await import(`./oauth-service-
|
|
3279
|
+
`,exitCode:1}}let u=i(c);if(!u)return{stdout:``,stderr:`oauth-token: unknown provider "${c}"\n`,exitCode:1};if(!u.isOAuth||!u.onOAuthLogin)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{let{createOAuthLauncher:e}=await import(`./oauth-service-B3UTYTa2.js`),n=e();await u.onOAuthLogin(n,()=>{},o?{scopes:o}:void 0);let r=t(c);if(r&&r.token){let e=r.maskedValue;return e?{stdout:`${e}\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
|
|
3280
3280
|
`,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}}})}function WZ(e,t,n,r){let i=t().filter(e=>n(e)?.isOAuth);if(i.length===0)return{stdout:`No OAuth providers configured.
|
|
3281
3281
|
`,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(`
|
|
3282
3282
|
`)+`
|
|
@@ -3301,7 +3301,7 @@ Common base URLs:
|
|
|
3301
3301
|
llama.cpp http://localhost:8080/v1
|
|
3302
3302
|
vLLM http://localhost:8000/v1
|
|
3303
3303
|
Jan http://localhost:1337/v1
|
|
3304
|
-
`}function fQ(){return EM(uQ,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:dQ(),stderr:``,exitCode:0};let{getApiKeyForProvider:t,getRawApiKeyForProvider:n,getBaseUrlForProvider:r,addAccount:i}=await import(`./provider-settings-
|
|
3304
|
+
`}function fQ(){return EM(uQ,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:dQ(),stderr:``,exitCode:0};let{getApiKeyForProvider:t,getRawApiKeyForProvider:n,getBaseUrlForProvider:r,addAccount:i}=await import(`./provider-settings-DificpTl.js`).then(e=>e.l),{verifyConnection:a}=await import(`./local-llm-DQmN1q4F.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(uQ);if(!s)return{stdout:``,stderr:`Local LLM is not configured. Open Settings → Providers → Local LLM and set a base URL.
|
|
3305
3305
|
`,exitCode:1};let c=await a(s,t(uQ)??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(`
|
|
3306
3306
|
`)+`
|
|
3307
3307
|
`,exitCode:1}}return o===`discover`?(i(uQ,n(uQ)??``,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(`
|
|
@@ -3378,7 +3378,7 @@ Examples:
|
|
|
3378
3378
|
oauth-domain add adobe '*.da.live'
|
|
3379
3379
|
oauth-domain list adobe
|
|
3380
3380
|
oauth-domain remove adobe admin.da.live
|
|
3381
|
-
`}function wQ(){return EM(`oauth-domain`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return{stdout:CQ(),stderr:``,exitCode:0};let{getExtraOAuthDomains:t,setExtraOAuthDomains:n,getAllExtraOAuthDomains:r}=await import(`./provider-settings-
|
|
3381
|
+
`}function wQ(){return EM(`oauth-domain`,async e=>{if(e.length===0||e.includes(`--help`)||e.includes(`-h`))return{stdout:CQ(),stderr:``,exitCode:0};let{getExtraOAuthDomains:t,setExtraOAuthDomains:n,getAllExtraOAuthDomains:r}=await import(`./provider-settings-DificpTl.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(`
|
|
3382
3382
|
`)+`
|
|
3383
3383
|
`,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)
|
|
3384
3384
|
`,stderr:``,exitCode:0}:{stdout:n.map(([e,t])=>`${e}: ${t.join(`, `)}`).join(`
|
|
@@ -3493,13 +3493,7 @@ Examples:
|
|
|
3493
3493
|
|
|
3494
3494
|
Plays a notification chime sound.
|
|
3495
3495
|
Alias for: afplay /shared/sounds/chime.mp3
|
|
3496
|
-
`,stderr:``,exitCode:0}:v$(`/shared/sounds/chime.mp3`,1,1,t))}function x$()
|
|
3497
|
-
|
|
3498
|
-
Toggle debug tabs (Terminal, Memory) in extension mode.
|
|
3499
|
-
Without arguments, shows current state.
|
|
3500
|
-
`,stderr:``,exitCode:0};let t=e[0]?.toLowerCase();if(t!==`on`&&t!==`off`&&t!==void 0)return{stdout:``,stderr:`debug: unknown argument '${t}' (use 'on' or 'off')\n`,exitCode:1};if(!t)try{let e=localStorage.getItem(`slicc-hidden-tabs`);return{stdout:`Debug tabs: ${(e?JSON.parse(e):[`terminal`,`memory`]).includes(`terminal`)?`off`:`on`}\n`,stderr:``,exitCode:0}}catch{return{stdout:`Debug tabs: off
|
|
3501
|
-
`,stderr:``,exitCode:0}}let n=t===`on`,r=window.__slicc_debug_tabs;if(r)return r(n),{stdout:`Debug tabs ${n?`enabled`:`hidden`}\n`,stderr:``,exitCode:0};try{return chrome.runtime.sendMessage({source:`offscreen`,payload:{type:`debug-tabs`,show:n}}),{stdout:`Debug tabs ${n?`enabled`:`hidden`}\n`,stderr:``,exitCode:0}}catch{return{stdout:``,stderr:`debug: failed to send toggle message
|
|
3502
|
-
`,exitCode:1}}})}const S$=`/.cache/artificial-analysis.json`;async function C$(e,t=!1){if(e&&!t)try{let t=await e.readFile(S$),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=PK(),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(S$,JSON.stringify(t))}catch{}}return s}function w$(e){return e.toLowerCase().replace(/\./g,`-`).replace(/-\d{8}$/,``).replace(/-\d{4}$/,``)}function T$(e,t){let n=e.toLowerCase(),r=t.find(e=>e.slug===n);if(r)return r;let i=w$(e),a=t.find(e=>w$(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 E$(){return`models - list available LLM models
|
|
3496
|
+
`,stderr:``,exitCode:0}:v$(`/shared/sounds/chime.mp3`,1,1,t))}const x$=`/.cache/artificial-analysis.json`;async function S$(e,t=!1){if(e&&!t)try{let t=await e.readFile(x$),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=PK(),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(x$,JSON.stringify(t))}catch{}}return s}function C$(e){return e.toLowerCase().replace(/\./g,`-`).replace(/-\d{8}$/,``).replace(/-\d{4}$/,``)}function w$(e,t){let n=e.toLowerCase(),r=t.find(e=>e.slug===n);if(r)return r;let i=C$(e),a=t.find(e=>C$(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 T$(){return`models - list available LLM models
|
|
3503
3497
|
|
|
3504
3498
|
Usage: models [options]
|
|
3505
3499
|
|
|
@@ -3511,37 +3505,37 @@ Options:
|
|
|
3511
3505
|
--refresh Force re-fetch benchmark data from Artificial Analysis
|
|
3512
3506
|
--no-benchmarks Skip benchmark data enrichment (faster, works offline)
|
|
3513
3507
|
-h, --help Show this help message
|
|
3514
|
-
`}function
|
|
3508
|
+
`}function E$(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`.replace(`.0M`,`M`):e>=1e3?`${(e/1e3).toFixed(0)}K`:`${e}`}function D$(e){return`$${e.toFixed(2)}`}const O$=/\b(embedding|embed|tts|whisper|dall-e|image-gen|audio|vision-preview)\b/i;function k$(e){let t=`${e.id} ${e.name??``}`;return!O$.test(t)}function A$(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 j$(e){let t=new Map;for(let n of e){let e=A$(n.id);t.has(e)||t.set(e,n)}return[...t.values()]}function M$(e,t,n,r,i){let a=i?w$(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 N$(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=`${D$(e.cost.input)} / ${D$(e.cost.output)}`,a=`${E$(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(`
|
|
3515
3509
|
`)+`
|
|
3516
|
-
`}function
|
|
3517
|
-
`,exitCode:1};let v;f||(v=await
|
|
3510
|
+
`}function P$(e){return EM(`models`,async t=>{let{getAccounts:n,getAvailableProviders:r,getProviderConfig:i,getProviderModels:a,getSelectedProvider:o,getSelectedModelId:s}=await import(`./provider-settings-DificpTl.js`).then(e=>e.l);if(t.includes(`--help`)||t.includes(`-h`))return{stdout:T$(),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.
|
|
3511
|
+
`,exitCode:1};let v;f||(v=await S$(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(k$);if(t.length===0){if(!l)return{stdout:``,stderr:`No models available for provider ${e}.\n`,exitCode:1};continue}let n=t.map(t=>M$(t,e,g,h,v)).sort((e,t)=>t.cost.input-e.cost.input);if(u||(n=j$(n)),b.push(...n),!c){let t=i(e);x.push(N$(t.name,e,n,!!v))}}return c?{stdout:JSON.stringify(b,null,2)+`
|
|
3518
3512
|
`,stderr:``,exitCode:0}:(!u&&!c&&x.push(`Showing latest versions only. Use --all-versions to see all.
|
|
3519
3513
|
`),{stdout:x.join(`
|
|
3520
|
-
`),stderr:``,exitCode:0})})}var
|
|
3514
|
+
`),stderr:``,exitCode:0})})}var F$=n({createCostCommand:()=>W$,registerSessionCostsProvider:()=>L$});let I$=null;function L$(e){I$=e}function R$(){return`cost - show session cost breakdown
|
|
3521
3515
|
|
|
3522
3516
|
Usage: cost [options]
|
|
3523
3517
|
|
|
3524
3518
|
Options:
|
|
3525
3519
|
--json Output as JSON (for programmatic use)
|
|
3526
3520
|
-h, --help Show this help message
|
|
3527
|
-
`}function
|
|
3528
|
-
`);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=
|
|
3521
|
+
`}function z$(e){let t=e/1e6;return t<.01?`<0.01`:t.toFixed(2)}function B$(e){return`$${e.toFixed(2)}`}function V$(e,t){if(!t||t===0)return`-`;let n=t/(1e3*60*60);return n===0?`-`:`$${(e/n).toFixed(2)}`}function H$(e,t){return e.length<=t?e:e.slice(0,t-3)+`...`}function U$(e){let t=[];t.push(`Session Cost Breakdown:
|
|
3522
|
+
`);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=H$(n.model,18).padEnd(18),l=`${z$(n.usage.input).padStart(5)} / ${z$(n.usage.output).padStart(5)}`.padEnd(15),u=`${z$(n.usage.cacheRead).padStart(5)} / ${z$(n.usage.cacheWrite).padStart(5)}`.padEnd(15),d=B$(n.usage.cost.total).padStart(10),f=V$(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=`${z$(i).padStart(5)} / ${z$(a).padStart(5)}`.padEnd(15),f=`${z$(o).padStart(5)} / ${z$(s).padStart(5)}`.padEnd(15),p=B$(c).padStart(10),m=``.padStart(10);return t.push(` ${l}${u}${d}${f}${p}${m}`),t.join(`
|
|
3529
3523
|
`)+`
|
|
3530
|
-
`}function
|
|
3531
|
-
`,exitCode:1};let t=await
|
|
3524
|
+
`}function W$(){return EM(`cost`,async e=>{if(e.includes(`--help`)||e.includes(`-h`))return{stdout:R$(),stderr:``,exitCode:0};if(!I$)return{stdout:``,stderr:`Cost data not available.
|
|
3525
|
+
`,exitCode:1};let t=await I$();return t.length===0?{stdout:`No session cost data yet.
|
|
3532
3526
|
`,stderr:``,exitCode:0}:e.includes(`--json`)?{stdout:JSON.stringify(t,null,2)+`
|
|
3533
|
-
`,stderr:``,exitCode:0}:{stdout:
|
|
3527
|
+
`,stderr:``,exitCode:0}:{stdout:U$(t),stderr:``,exitCode:0}})}const G$=[`slicc:welcome-flow-fired`,`slicc.trayJoinUrl`,`slicc.trayWorkerBaseUrl`];function K$(){return EM(`nuke`,async e=>e.includes(`--help`)||e.includes(`-h`)?{stdout:`Usage: nuke <launch-code>
|
|
3534
3528
|
|
|
3535
3529
|
Completely reset the environment by deleting all local data and reloading.
|
|
3536
3530
|
Destroys the file system, chat history, and scoops database.
|
|
3537
3531
|
Requires the secret launch code to proceed.
|
|
3538
|
-
`,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{}
|
|
3532
|
+
`,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{}q$(G$)})(),{stdout:`Nuking everything…
|
|
3539
3533
|
`,stderr:``,exitCode:0}):{stdout:``,stderr:`⚠️ WARNING: this will reset the entire environment, file system, chats, and scoops.
|
|
3540
3534
|
Run nuke again with the secret launch code to proceed.
|
|
3541
|
-
`,exitCode:1})}function
|
|
3535
|
+
`,exitCode:1})}function q$(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 J$=i(`agent-command`);function Y$(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(!Et(t))return{help:!1,error:`agent: ${s} must be one of: ${Tt.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=X$(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 X$(e){return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}function Z$(e,t){return e.startsWith(`/`)?he(e):he(`${t.length>0?t:`/`}/${e}`)}function Q$(e){return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0)}function $$(e){return e==null?`
|
|
3542
3536
|
`:e.replace(/\n+$/,``)+`
|
|
3543
|
-
`}function
|
|
3544
|
-
`}function
|
|
3537
|
+
`}function e1(e){return e==null||e===``?``:e.replace(/\n+$/,``)+`
|
|
3538
|
+
`}function t1(){let e=globalThis.__slicc_agent;if(!(!e||typeof e.spawn!=`function`))return e}function n1(e={}){let{getParentJid:t}=e;return EM(`agent`,async(e,n)=>{let r=Y$(e);if(r.help)return{stdout:`usage: agent <cwd> <allowed-commands> <prompt>
|
|
3545
3539
|
|
|
3546
3540
|
Spawns a sub-scoop, feeds it a task, blocks until the agent loop completes,
|
|
3547
3541
|
then prints the scoop's final message on stdout.
|
|
@@ -3587,12 +3581,12 @@ Examples:
|
|
|
3587
3581
|
agent --thinking high . "*" "design a careful plan first"
|
|
3588
3582
|
agent --read-only /workspace/,/shared/assets/ . "*" "review the docs"
|
|
3589
3583
|
`,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
|
|
3590
|
-
`,exitCode:1};let a=
|
|
3591
|
-
`,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
|
|
3592
|
-
`,exitCode:1};let r=
|
|
3593
|
-
`,exitCode:2};let a=
|
|
3584
|
+
`,exitCode:1};let a=Z$(i,n.cwd),o=Q$(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=t1();if(!l)return{stdout:``,stderr:`agent: orchestrator bridge not available
|
|
3585
|
+
`,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:$$(n),stderr:``,exitCode:0}:{stdout:``,stderr:e1(n),exitCode:t}}catch(e){let t=e instanceof Error?e.message:String(e);return J$.error(`agent bridge threw`,e),{stdout:``,stderr:`${t}\n`,exitCode:1}}})}const r1=[`pid`,`ppid`,`kind`,`stat`,`start`,`scoop`,`command`],i1=[`pid`,`ppid`,`stat`,`start`,`scoop`,`command`],a1={running:`R`,pending:`S`,exited:`Z`,killed:`K`};function o1(e={}){return EM(`ps`,async t=>{if(t.includes(`--help`)||t.includes(`-h`))return v1();let n=e.processManager??s1();if(!n)return{stdout:``,stderr:`ps: no process manager available in this runtime
|
|
3586
|
+
`,exitCode:1};let r=i1,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
|
|
3587
|
+
`,exitCode:2};let a=c1(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?_1(s):s.map(e=>({proc:e,depth:0}))).map(({proc:e,depth:t})=>d1(e,r,t,i));return{stdout:[l1(r),...c].join(`
|
|
3594
3588
|
`)+`
|
|
3595
|
-
`,stderr:``,exitCode:0}})}function
|
|
3589
|
+
`,stderr:``,exitCode:0}})}function s1(){let e=globalThis.__slicc_pm;return e instanceof Object&&typeof e.list==`function`?e:null}function c1(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(!r1.includes(e))return Error(`unknown column '${e}'; supported: ${r1.join(`, `)}`);n.push(e)}return n}function l1(e){return e.map(e=>u1(e)).join(` `)}function u1(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 d1(e,t,n,r){return t.map(t=>f1(e,t,n,r)).join(` `)}function f1(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 a1[e.status];case`start`:return p1(e.startedAt);case`scoop`:return m1(e).padEnd(10);case`command`:return h1(e,n,r)}}function p1(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 m1(e){return e.owner.kind===`cone`?`cone`:e.owner.kind===`system`?`system`:e.owner.scoopJid?.slice(0,10)??`scoop`}function h1(e,t,n){let r=n&&t>0?` `.repeat(t-1)+`└─ `:``,i=e.argv.length===0?`[${e.kind}]`:e.argv.map(g1).join(` `);return r+(i.length>80?i.slice(0,79)+`…`:i)}function g1(e){return e===``?`''`:/^[A-Za-z0-9_./:=@%+-]+$/.test(e)?e:e.includes(`"`)&&!e.includes(`'`)?`'${e}'`:`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function _1(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 v1(){return{stdout:`Usage: ps [-a] [-T] [-o col[,col…]]
|
|
3596
3590
|
|
|
3597
3591
|
List processes tracked by the kernel.
|
|
3598
3592
|
|
|
@@ -3622,12 +3616,12 @@ Examples:
|
|
|
3622
3616
|
ps -T live tree
|
|
3623
3617
|
ps -a -T full tree
|
|
3624
3618
|
ps -o pid,kind,stat just three columns
|
|
3625
|
-
`,stderr:``,exitCode:0}}const
|
|
3619
|
+
`,stderr:``,exitCode:0}}const y1=new Set([`SIGINT`,`SIGTERM`,`SIGKILL`,`SIGSTOP`,`SIGCONT`]);function b1(e={}){return EM(`kill`,async t=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return w1();let n=e.processManager??x1();if(!n)return{stdout:``,stderr:`kill: no process manager available in this runtime
|
|
3626
3620
|
`,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
|
|
3627
|
-
`,exitCode:2};let i=
|
|
3628
|
-
`,exitCode:2};if(!
|
|
3621
|
+
`,exitCode:2};let i=S1(n);if(i instanceof Error)return{stdout:``,stderr:`kill: ${i.message}\n`,exitCode:2};r=i;continue}if(n.startsWith(`-`)){let e=C1(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
|
|
3622
|
+
`,exitCode:2};if(!y1.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(`
|
|
3629
3623
|
`)+`
|
|
3630
|
-
`:``,exitCode:+!a}})}function
|
|
3624
|
+
`:``,exitCode:+!a}})}function x1(){let e=globalThis.__slicc_pm;return e instanceof Object&&typeof e.signal==`function`?e:null}function S1(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 C1(e){return e===`-9`?`SIGKILL`:S1(e.slice(1))}function w1(){return{stdout:`Usage: kill [-s SIGNAL | -INT | -TERM | -KILL | -STOP | -CONT | -9] PID [PID …]
|
|
3631
3625
|
|
|
3632
3626
|
Send a signal to one or more processes tracked by the kernel.
|
|
3633
3627
|
|
|
@@ -3649,11 +3643,11 @@ Examples:
|
|
|
3649
3643
|
kill -INT 1024 1025 SIGINT both
|
|
3650
3644
|
kill -STOP 1024 pause; \`kill -CONT 1024\` resumes
|
|
3651
3645
|
kill -s SIGKILL 1024 explicit signal name
|
|
3652
|
-
`,stderr:``,exitCode:0}}function
|
|
3653
|
-
`}function
|
|
3646
|
+
`,stderr:``,exitCode:0}}function T1(e={}){let t=[nJ({getJshCommands:e.getJshCommands}),dJ(),HY(e.browserAPI,e.fs),wY(),mJ(e),qQ(),lZ(),WY(`sqlite3`),WY(`sqllite`),bY(),IY(`python3`),IY(`python`),fZ(),xZ(),OZ(),jZ(),VZ(),NY(`pdftk`),NY(`pdf`),aJ(`convert`),aJ(`magick`),WQ({fs:e.fs,scriptCatalog:e.scriptCatalog}),KY(),YY(),UZ(),wQ(),fQ(),SQ(),zQ({fs:e.fs}),QQ(),s$(),c$(),l$(`xclip`),l$(`xsel`),m$(),y$(),b$(),P$(e.fs),W$(),K$(),n1({getParentJid:e.getParentJid}),o1({processManager:e.processManager}),b1({processManager:e.processManager})];return e.fs&&t.push(...oq.map(t=>$q(t,e.browserAPI,e.fs))),t}const E1=`https://wry-manatee-359.convex.site/api/v1`,D1=`https://api.tessl.io`,O1=`/workspace/skills`,k1=`application/vnd.github.v3+json`,A1=`https://www.sliccy.com/skills/catalog.json`;function j1(e){if(!(!e||!e.trim()))return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function M1(e){if(!e)return!1;let t=e.trim().toLowerCase();return t===`true`||t===`1`||t===`yes`}function N1(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:M1(e.installAll)},affinity:{apps:j1(e.apps),tasks:j1(e.tasks),role:j1(e.role),purpose:j1(e.purpose)},priority:n}})}const P1={apps:3,tasks:2,role:1,purpose:1};function F1(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*P1.apps,r.push(`apps(${i.join(`, `)})`));let a=(e.affinity.tasks??[]).filter(e=>t.tasks.includes(e));return a.length&&(n+=a.length*P1.tasks,r.push(`tasks(${a.join(`, `)})`)),(e.affinity.role??[]).includes(t.role)&&(n+=P1.role,r.push(`role(${t.role})`)),(e.affinity.purpose??[]).includes(t.purpose)&&(n+=P1.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 I1(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 L1(e){let t=new Set;try{let n=await e.readDir(O1);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 R1;function z1(){return R1||=A.create({dbName:`slicc-fs-global`}),R1}async function B1(){try{return(await(await z1()).readTextFile(`/workspace/.git/github-token`)).trim()||void 0}catch{return}}function V1(e,t=k1){let n={Accept:t,"User-Agent":`slicc-upskill`};return e&&(n.Authorization=`Bearer ${e}`),n}async function H1(e){let t=await B1();return{hasToken:!!t,request:(n,r=k1)=>e(n,{headers:V1(t,r)})}}function U1(e,t){if(!e)return;let n=t.toLowerCase();for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}function W1(e){let t=xK(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 G1(e,t,n){let r=W1(e.body),i=r?` GitHub said: ${r}`:``,a=U1(e.headers,`retry-after`),o=U1(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 K1(){return`Discovery roots: /workspace/skills plus accessible **/.agents/skills/* and **/.claude/skills/* anywhere in the VFS.
|
|
3647
|
+
`}function q1(e){switch(e){case`native`:return`native`;case`agents`:return`.agents`;case`claude`:return`.claude`}}function J1(e,t){let n=`${t}:\n\n`;n+=` NAME SOURCE DESCRIPTION
|
|
3654
3648
|
`,n+=` ─────────────────────────────────────────────────────────────
|
|
3655
|
-
`;for(let t of e){let e=t.description||``;n+=` ${t.name.padEnd(20)} ${
|
|
3656
|
-
`;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function
|
|
3649
|
+
`;for(let t of e){let e=t.description||``;n+=` ${t.name.padEnd(20)} ${q1(t.source).padEnd(9)} ${e}\n`}return n+=`\n${K1()}`,n}function Y1(e){let t=`Skill: ${e.name}\n`;if(t+=`Description: ${e.description||`(none)`}\n`,t+=`Source: ${q1(e.source)}\n`,t+=`Source root: ${e.sourceRoot}\n`,e.skillFilePath&&(t+=`Instructions: ${e.skillFilePath}\n`),e.shadowedPaths?.length){t+=`Shadowed paths:
|
|
3650
|
+
`;for(let n of e.shadowedPaths)t+=` - ${n}\n`}return t}function X1(){return{stdout:`usage: upskill <command> [options]
|
|
3657
3651
|
|
|
3658
3652
|
Install skills from GitHub repositories, ClawHub, or Tessl registry.
|
|
3659
3653
|
|
|
@@ -3666,7 +3660,7 @@ Commands:
|
|
|
3666
3660
|
<clawhub-url> Install skill from ClawHub URL
|
|
3667
3661
|
tessl:<name> Install skill from Tessl registry
|
|
3668
3662
|
|
|
3669
|
-
${
|
|
3663
|
+
${K1()}
|
|
3670
3664
|
GitHub Installation:
|
|
3671
3665
|
upskill owner/repo List available skills in repo
|
|
3672
3666
|
upskill owner/repo --skill name Install specific skill
|
|
@@ -3706,29 +3700,29 @@ Examples:
|
|
|
3706
3700
|
upskill aemcoder/skills@fix/stateless-tab-targeting --all
|
|
3707
3701
|
upskill https://clawhub.ai/arun-8687/tavily-search
|
|
3708
3702
|
upskill tessl:postgres-pro
|
|
3709
|
-
`,stderr:``,exitCode:0}}async function
|
|
3703
|
+
`,stderr:``,exitCode:0}}async function Z1(e,t){let n=await t(`${E1}/search?q=${encodeURIComponent(e)}`,{headers:{Accept:`application/json`}});if(n.status!==200)throw Error(`ClawHub returned HTTP ${n.status}`);let r=SK(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 Q1(e){let t=e.match(/github\.com\/([^\/?#]+)\/([^\/?#]+)/);return t?{owner:t[1],repo:t[2].replace(/\.git$/,``)}:null}async function $1(e,t){let n=await t(`${D1}/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=SK(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=Q1(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 e0(e,t,n=1){let[r,i]=await Promise.allSettled([Z1(e,t),$1(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
|
|
3710
3704
|
`),{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+=`
|
|
3711
3705
|
`}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:
|
|
3712
3706
|
`,a.length>0&&(h+=` From ClawHub: upskill clawhub:<slug>
|
|
3713
3707
|
`),o.length>0&&(h+=` From Tessl: upskill <owner/repo> --skill <name>
|
|
3714
|
-
`),{stdout:h,stderr:``,exitCode:0}}async function n0(e,t,n,r=!1,i){try{let a=`${k1}/${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=`${D1}/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=az(o);l||=CK(s.body);let u;try{u=sZ(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=r0(u,i);return await d0(),{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 r0(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=i0(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 i0(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 a0(e,t){let n=await t(`${O1}/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=SK(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=$1(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 o0(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`?o0(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=az(i);o||=CK(a.body);try{return{status:`ok`,files:sZ(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function s0(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 c0(e,t,n,r,i,a){if(i){let n=await o0(e,t,i,a);if(n.status===`ok`){let e=s0(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(K1(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=SK(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 l0(e,t,n,r,i,a,o=!1,s,c){try{let l=`${k1}/${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 o0(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=s0(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 h0(),await p0(),{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: ${K1(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=SK(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(K1(n,`${e}/${t}/${o.path}`,a.hasToken));let s=az(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(K1(l,`${e}/${t}/${o.path}`,a.hasToken));let u=SK(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 d0(),{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 u0(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 d0(){await h0(),await p0()}async function f0(e,t,n,r,i=!1){let a=`${k1}/${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 p0(){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 m0(e){let t=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return t?{owner:t[1],repo:t[2],branch:t[3]}:null}async function h0(){try{let e=globalThis.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}function g0(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 _0(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=g0(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=g0(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(j1,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return P1(SK(e.body).data)})(),R1(e)]);o=n,s=r}catch(e){return i(`catalog-fetch`,[`upskill: failed to fetch skill catalog from ${j1}: ${e instanceof Error?e.message:String(e)}`])}let c=I1(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 o0(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=s0(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 f0(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 f0(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 d0();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 v0(e,t,n){if(n){let n=await _0(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.
|
|
3708
|
+
`),{stdout:h,stderr:``,exitCode:0}}async function t0(e,t,n,r=!1,i){try{let a=`${O1}/${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=`${E1}/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=az(o);l||=CK(s.body);let u;try{u=sZ(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=n0(u,i);return await u0(),{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 n0(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=r0(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 r0(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 i0(e,t){let n=await t(`${D1}/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=SK(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=Q1(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 a0(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`?a0(e,t,n,`master`):{status:`not_found`};if(a.status!==200)return{status:`error`,message:`codeload returned HTTP ${a.status}`};let o=az(i);o||=CK(a.body);try{return{status:`ok`,files:sZ(o)}}catch(e){return{status:`error`,message:`failed to unzip: ${e instanceof Error?e.message:String(e)}`}}}function o0(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 s0(e,t,n,r,i,a){if(i){let n=await a0(e,t,i,a);if(n.status===`ok`){let e=o0(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(G1(l,`${e}/${t}${r?`/${r}`:``}`,n.hasToken));let u=SK(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 c0(e,t,n,r,i,a,o=!1,s,c){try{let l=`${O1}/${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 a0(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=o0(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 m0(),await f0(),{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: ${G1(f,`${e}/${t}/${n}`,a.hasToken)}\n`,exitCode:1};let p=SK(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(G1(n,`${e}/${t}/${o.path}`,a.hasToken));let s=az(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(G1(l,`${e}/${t}/${o.path}`,a.hasToken));let u=SK(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 u0(),{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 l0(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 u0(){await m0(),await f0()}async function d0(e,t,n,r,i=!1){let a=`${O1}/${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 f0(){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 p0(e){let t=e.match(/^([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(?:@([a-zA-Z0-9_./\-]+))?$/);return t?{owner:t[1],repo:t[2],branch:t[3]}:null}async function m0(){try{let e=globalThis.__slicc_sprinkleManager;e&&typeof e.openNewAutoOpenSprinkles==`function`&&await e.openNewAutoOpenSprinkles()}catch{}}function h0(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 g0(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=h0(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=h0(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(A1,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return N1(SK(e.body).data)})(),L1(e)]);o=n,s=r}catch(e){return i(`catalog-fetch`,[`upskill: failed to fetch skill catalog from ${A1}: ${e instanceof Error?e.message:String(e)}`])}let c=F1(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 a0(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=o0(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 d0(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 d0(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 u0();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 _0(e,t,n){if(n){let n=await g0(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.
|
|
3715
3709
|
`,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.
|
|
3716
3710
|
`,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.
|
|
3717
|
-
`,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(
|
|
3711
|
+
`,exitCode:1};let i,a;try{let[n,r]=await Promise.all([(async()=>{let e=await t(A1,{headers:{Accept:`application/json`}});if(e.status!==200)throw Error(`HTTP ${e.status}`);return N1(SK(e.body).data)})(),L1(e)]);i=n,a=r}catch(e){return{stdout:``,stderr:`upskill: failed to fetch skill catalog from ${A1}: ${e instanceof Error?e.message:String(e)}\n`,exitCode:1}}let o=F1(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.
|
|
3718
3712
|
`,stderr:``,exitCode:0};let s=`Recommended skills for you:
|
|
3719
3713
|
|
|
3720
|
-
`,c=0;for(let e of o){c++;let t=
|
|
3721
|
-
`,{stdout:s,stderr:``,exitCode:0}}function
|
|
3714
|
+
`,c=0;for(let e of o){c++;let t=I1(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
|
|
3715
|
+
`,{stdout:s,stderr:``,exitCode:0}}function v0(e,t){return EM(`upskill`,async(n,r)=>{if(n.length===0||n.includes(`--help`)||n.includes(`-h`))return X1();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 _0(e,t,n.includes(`--install`));else if(r===`list`){let t=await(await Promise.resolve().then(()=>z2)).discoverSkills(e);return t.length===0?{stdout:`No discoverable local skills found.\n\n${K1()}`,stderr:``,exitCode:0}:{stdout:J1(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(()=>z2);if(r===`info`){let n=await i.getSkillInfo(e,t);return n?{stdout:Y1(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+`
|
|
3722
3716
|
`,stderr:``,exitCode:0}}}else if(r===`--skill`)i.push(n[++p]);else if(r===`--path`||r===`-p`)a=n[++p];else if(r===`--list`)o=!0;else if(r===`--all`)s=!0;else if(r===`--force`)c=!0;else if(r===`--branch`||r===`-b`){let e=n[p+1];if(!e||e.startsWith(`-`))return{stdout:``,stderr:`upskill: --branch requires a value
|
|
3723
|
-
`,exitCode:1};u=n[++p]}else r.startsWith(`-`)||(l=r);p++}if(d)return
|
|
3724
|
-
`,exitCode:1};let r=await
|
|
3717
|
+
`,exitCode:1};u=n[++p]}else r.startsWith(`-`)||(l=r);p++}if(d)return e0(d,t,f);if(!l)return X1();let m=l0(l);if(m){let n=r.getRegisteredCommands?.()??[];return t0(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
|
|
3718
|
+
`,exitCode:1};let r=await i0(n,t);if(`error`in r)return{stdout:``,stderr:`upskill: ${r.error}\n`,exitCode:1};let i=await H1(t);return c0(r.owner,r.repo,r.skillPath,r.skillName,e,i,c,t)}let h=p0(l);if(h){let{owner:n,repo:r}=h,d=u??h.branch,f=await H1(t),p=await s0(n,r,f,a,t,d);if(p.error)return{stdout:``,stderr:`upskill: failed to list skills: ${p.error}\n`,exitCode:1};if(p.skills.length===0)return{stdout:`No skills found in ${n}/${r}${a?`/`+a:``}\n`,stderr:``,exitCode:0};if(o){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let m=p.skills;if(i.length>0){m=p.skills.filter(e=>i.includes(e.name));for(let e of i)if(!p.skills.find(t=>t.name===e))return{stdout:``,stderr:`upskill: skill "${e}" not found in ${n}/${r}\n`,exitCode:1}}else if(!s){let e=`Available skills in ${n}/${r}:\n\n`;for(let t of p.skills)e+=` ${t.name.padEnd(30)} ${t.path}\n`;return e+=`\nFound ${p.skills.length} skill(s)\n`,e+=`\nTo install specific skills: upskill ${l} --skill <name>\n`,e+=`To install all: upskill ${l} --all\n`,{stdout:e,stderr:``,exitCode:0}}let g=``,_=``,v=0,y=m.length,b=Date.now();if(y>1){let i=await a0(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=o0(i.files);for(let t=0;t<m.length;t++){let i=m[t],o=await d0(i.path,i.name,a,e,c),s=t+1,l=((Date.now()-b)/1e3).toFixed(1),u=(Date.now()-b)/s,d=Math.round((y-s)*u/1e3),f=s<y?` (~${d}s remaining)`:``;o.ok?(g+=`[${s}/${y}] Installed "${i.name}" from ${n}/${r} (${l}s)${f}\n`,v++):(g+=`[${s}/${y}] Failed "${i.name}": ${o.error}${f}\n`,_+=`upskill: ${o.error}\n`)}}else for(let i of m){let a=await c0(n,r,i.path,i.name,e,f,c,t,d);a.exitCode===0?(g+=a.stdout,v++):_+=a.stderr}let x=((Date.now()-b)/1e3).toFixed(1);return v>0&&(g+=`\nInstalled ${v} skill(s)${y>1?` in ${x}s`:``}\n`,await u0()),{stdout:g,stderr:_,exitCode:+!!_}}return{stdout:``,stderr:`upskill: unrecognized source "${l}"\n\nExpected: owner/repo, clawhub:<slug>, tessl:<name>, or https://clawhub.ai/user/skill\n`,exitCode:1}})}function y0(e){return EM(`skill`,async(t,n)=>{if(t.length===0||t.includes(`--help`)||t.includes(`-h`))return{stdout:`usage: skill <command> [options]
|
|
3725
3719
|
|
|
3726
3720
|
Commands:
|
|
3727
3721
|
list List discoverable skills
|
|
3728
3722
|
info <name> Show details about a skill
|
|
3729
3723
|
read <name> Read the SKILL.md instructions
|
|
3730
3724
|
|
|
3731
|
-
${
|
|
3725
|
+
${K1()}
|
|
3732
3726
|
For installing skills from registries or GitHub, use 'upskill':
|
|
3733
3727
|
upskill search "query" Search ClawHub + Tessl
|
|
3734
3728
|
upskill owner/repo --list List skills in GitHub repo
|
|
@@ -3739,18 +3733,18 @@ Examples:
|
|
|
3739
3733
|
skill list
|
|
3740
3734
|
skill info bluebubbles
|
|
3741
3735
|
skill read bluebubbles
|
|
3742
|
-
`,stderr:``,exitCode:0};let r=t[0],i=await Promise.resolve().then(()=>
|
|
3743
|
-
`,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:
|
|
3736
|
+
`,stderr:``,exitCode:0};let r=t[0],i=await Promise.resolve().then(()=>z2);try{switch(r){case`list`:{let t=await i.discoverSkills(e);return t.length===0?{stdout:`No discoverable skills found.\n\n${K1()}Install skills with: upskill owner/repo --all\n`,stderr:``,exitCode:0}:{stdout:J1(t,`Discoverable skills`),stderr:``,exitCode:0}}case`info`:{let n=t[1];if(!n)return{stdout:``,stderr:`skill: info requires a skill name
|
|
3737
|
+
`,exitCode:1};let r=await i.getSkillInfo(e,n);return r?{stdout:Y1(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
|
|
3744
3738
|
`,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+`
|
|
3745
|
-
`,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
|
|
3739
|
+
`,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 b0(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 x0=class{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=b0(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=yt();if(!n){let t=await S0(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 $R.create({mountId:_e(),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=_e(),i=new qe({mountId:r,ttlMs:3e4}),a=new Ue({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchS3??Ke(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=_e(),i=new qe({mountId:r,ttlMs:3e4}),a=new We({source:t.source,profile:n,cache:i,maxBodyBytes:t.maxBodyMb?t.maxBodyMb*1024*1024:void 0,mountId:r,signedFetch:this.signedFetchDa??Ge()});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=b0(e);if(n.positional.length===0)return{stdout:``,stderr:`mount unmount: path required
|
|
3746
3740
|
`,exitCode:1};let r=this.resolvePath(n.positional[0],t);try{let e,t;if(n.clearCache){let{getAllMountEntries:n}=await Promise.resolve().then(()=>RR),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-BdYCICnT.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
|
|
3747
3741
|
`,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(`
|
|
3748
3742
|
`)+`
|
|
3749
|
-
`,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=
|
|
3743
|
+
`,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=b0(e);if(n.positional.length===0)return{stdout:``,stderr:`mount refresh: path required
|
|
3750
3744
|
`,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(`
|
|
3751
3745
|
`)+`
|
|
3752
|
-
`,stderr:``,exitCode:0}}};async function
|
|
3753
|
-
`).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 A0(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 j0(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||!A0(n.hostname,a)?!1:o?M0(n.pathname+n.search,o):!0}catch{return!1}}function M0(e,t){let n=`^`+t.replace(/[.+^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`.*`)+`$`;return new RegExp(n).test(e)}function N0(e,t){try{let n=new URL(t);return e.filter(e=>A0(n.hostname,e.hostnamePattern)?e.matchPatterns.length>0?e.matchPatterns.some(e=>j0(t,e)):!0:!1)}catch{return[]}}var P0=n({ScriptCatalog:()=>V0});const F0=[`/workspace`,`/shared`];function I0(e){return new Map(e)}function L0(e){return e.map(e=>({...e,matchPatterns:[...e.matchPatterns]}))}function R0(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 z0(e){return(R0(e)?.listMounts?.().length??0)>0}function B0(e){return e?(R0(e)?.listMounts?.()??[]).some(e=>F0.some(t=>e===t||e.startsWith(t+`/`))):!1}var V0=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 F0)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 I0(await this.loadJshCommands())}async getJshCommandNames(){return[...(await this.getJshCommands()).keys()]}async getBshEntries(){return this.bshFs?L0(await this.loadBshEntries()):[]}async findMatchingBshScripts(e){return this.bshFs?L0(N0(await this.loadBshEntries(),e)):[]}shouldCacheJsh(){return!!this.watcher&&!z0(this.jshFs)}shouldCacheBsh(){return!!this.watcher&&!!this.bshFs&&!B0(this.bshFs)}async loadJshCommands(){let e=this.shouldCacheJsh();if(e&&this.jshCache)return this.jshCache;if(!this.jshInflight){let t=this.jshGeneration,n=VQ(this.jshFs).then(n=>{let r=I0(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=E0(this.bshFs).then(n=>{let r=L0(n);return e&&this.bshGeneration===t&&(this.bshCache=r),r}).finally(()=>{this.bshInflight===n&&(this.bshInflight=null)});this.bshInflight=n}return this.bshInflight}};function H0(e){return e&&typeof e.getWatcher==`function`?e.getWatcher?.()??null:e&&typeof e.getUnderlyingFS==`function`?H0(e.getUnderlyingFS?.()):null}var U0=class{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 sz(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 qK({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new S0({fs:e.fs,isScoop:e.isScoop});let r=e.jshDiscoveryFs??e.fs,i=e.bshDiscoveryFs??e.fs,a=H0(r)??H0(i);this.scriptCatalog=e.scriptCatalog??new V0({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=E1({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=PK(),u=[o,c,b0(e.fs),y0(e.fs,l),...s].filter(e=>this.isCommandAllowed(e.name)),d=[...yM(),...bM()],f=this.allowedCommands?d.filter(e=>this.isCommandAllowed(e)):void 0;if(this.bash=new NR({fs:this.vfsAdapter,cwd:t,env:n,fetch:l,commands:f,customCommands:u}),this.allowedCommands!==null){let e=this.bash;for(let t of bM())this.isCommandAllowed(t)||e.commands.delete(t)}let p=u.map(e=>e.name),m=f??[...yM(),...bM()];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 fY(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 pY(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 EM(`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 EM(`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?w0(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 pY(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 W0(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 G0=class extends U0{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-CeGiW_7a.js`),{FitAddon:r}=await import(`./addon-fit-DYt1qsAX.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
|
|
3746
|
+
`,stderr:``,exitCode:0}}};async function S0(e){let t=`pendingMount:term:${e}`,n;try{n=await YR(t)}catch{return null}if(!n)return null;try{await XR(n)}catch{return null}return $R.fromHandle(n,{mountId:_e()})}function C0(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 w0=[`/workspace`,`/shared`];async function T0(e){let t=[],n=new Set;for(let r of w0)await e.exists(r)&&await E0(e,r,t,n);return t}async function E0(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=D0(i);if(!t)continue;let a=await e.readFile(i,{encoding:`utf-8`}),o=O0(typeof a==`string`?a:new TextDecoder().decode(a));n.push({path:i,hostnamePattern:t,matchPatterns:o})}}function D0(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 O0(e){let t=e.split(`
|
|
3747
|
+
`).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 k0(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 A0(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||!k0(n.hostname,a)?!1:o?j0(n.pathname+n.search,o):!0}catch{return!1}}function j0(e,t){let n=`^`+t.replace(/[.+^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`.*`)+`$`;return new RegExp(n).test(e)}function M0(e,t){try{let n=new URL(t);return e.filter(e=>k0(n.hostname,e.hostnamePattern)?e.matchPatterns.length>0?e.matchPatterns.some(e=>A0(t,e)):!0:!1)}catch{return[]}}var N0=n({ScriptCatalog:()=>B0});const P0=[`/workspace`,`/shared`];function F0(e){return new Map(e)}function I0(e){return e.map(e=>({...e,matchPatterns:[...e.matchPatterns]}))}function L0(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 R0(e){return(L0(e)?.listMounts?.().length??0)>0}function z0(e){return e?(L0(e)?.listMounts?.()??[]).some(e=>P0.some(t=>e===t||e.startsWith(t+`/`))):!1}var B0=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 P0)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 F0(await this.loadJshCommands())}async getJshCommandNames(){return[...(await this.getJshCommands()).keys()]}async getBshEntries(){return this.bshFs?I0(await this.loadBshEntries()):[]}async findMatchingBshScripts(e){return this.bshFs?I0(M0(await this.loadBshEntries(),e)):[]}shouldCacheJsh(){return!!this.watcher&&!R0(this.jshFs)}shouldCacheBsh(){return!!this.watcher&&!!this.bshFs&&!z0(this.bshFs)}async loadJshCommands(){let e=this.shouldCacheJsh();if(e&&this.jshCache)return this.jshCache;if(!this.jshInflight){let t=this.jshGeneration,n=VQ(this.jshFs).then(n=>{let r=F0(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=T0(this.bshFs).then(n=>{let r=I0(n);return e&&this.bshGeneration===t&&(this.bshCache=r),r}).finally(()=>{this.bshInflight===n&&(this.bshInflight=null)});this.bshInflight=n}return this.bshInflight}};function V0(e){return e&&typeof e.getWatcher==`function`?e.getWatcher?.()??null:e&&typeof e.getUnderlyingFS==`function`?V0(e.getUnderlyingFS?.()):null}var H0=class{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 sz(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 qK({fs:e.fs,authorName:n.GIT_AUTHOR_NAME??`User`,authorEmail:n.GIT_AUTHOR_EMAIL??`user@example.com`}),this.mountCommands=new x0({fs:e.fs,isScoop:e.isScoop});let r=e.jshDiscoveryFs??e.fs,i=e.bshDiscoveryFs??e.fs,a=V0(r)??V0(i);this.scriptCatalog=e.scriptCatalog??new B0({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=T1({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=PK(),u=[o,c,y0(e.fs),v0(e.fs,l),...s].filter(e=>this.isCommandAllowed(e.name)),d=[...yM(),...bM()],f=this.allowedCommands?d.filter(e=>this.isCommandAllowed(e)):void 0;if(this.bash=new NR({fs:this.vfsAdapter,cwd:t,env:n,fetch:l,commands:f,customCommands:u}),this.allowedCommands!==null){let e=this.bash;for(let t of bM())this.isCommandAllowed(t)||e.commands.delete(t)}let p=u.map(e=>e.name),m=f??[...yM(),...bM()];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 fY(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 pY(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 EM(`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 EM(`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?C0(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 pY(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 U0(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 W0=class extends H0{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-CeGiW_7a.js`),{FitAddon:r}=await import(`./addon-fit-DYt1qsAX.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
|
|
3754
3748
|
`),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
|
|
3755
3749
|
`,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(`
|
|
3756
3750
|
`).entries()){if(e+n.length>=this.cursorPos)return t;e+=n.length+1}return 0}positionTerminalCursor(){let e=this.currentLine.split(`
|
|
@@ -3765,9 +3759,9 @@ Examples:
|
|
|
3765
3759
|
`,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(`
|
|
3766
3760
|
`).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(`
|
|
3767
3761
|
`);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+`
|
|
3768
|
-
`+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=`${
|
|
3762
|
+
`+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=`${U0(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=U0(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 G0=i(`tool:fs`);function K0(e){return[q0(e),J0(e),Y0(e)]}function q0(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;G0.debug(`Read`,{path:n,offset:r,limit:i});try{let t=(await e.readTextFile(n)).split(`
|
|
3769
3763
|
`),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(`
|
|
3770
|
-
`)}}catch(e){let t=e instanceof Error?e.message:String(e);return
|
|
3764
|
+
`)}}catch(e){let t=e instanceof Error?e.message:String(e);return G0.error(`Read failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function J0(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;G0.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 G0.error(`Write failed`,{path:n,error:t}),{content:t,isError:!0}}}}}function Y0(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;G0.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 G0.error(`Edit failed`,{path:n,error:t}),{content:t,isError:!0}}}}}const X0=i(`tool:bash`),Z0=/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)*(?:command\s+)?(?:grep|egrep|fgrep|rg)\b/;function Q0(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 $0(e,t,n){return t!==1||n.trim()?!1:Z0.test(Q0(e))}function e2(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;X0.debug(`Execute`,{command:r});try{let t=await e.executeCommand(r,n);X0.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&&!$0(r,t.exitCode,t.stderr)}}catch(e){let t=e instanceof Error?e.message:String(e);return X0.error(`Error`,{command:r,error:t}),{content:`Shell error: ${t}`,isError:!0}}}}}i(`tool:search`);var t2="# 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: `x-slicc` response header on main-frame document responses → `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",n2='# 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.\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\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` code blocks in chat that hydrate into sandboxed widgets. Ephemeral, lick-only (no state). Cone may write these directly. Use for pickers, calculators, quick charts:\n\n```shtml\n<button onclick="slicc.lick(\'choose\', { 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\nThe best flavor of ice cream is lobster, nobody likes chocolate, and mixing bacon with ice cream is a crime against humanity.\n',r2=`<html lang="en">
|
|
3771
3765
|
<head>
|
|
3772
3766
|
<title>Connect an LLM</title>
|
|
3773
3767
|
<meta charset="utf-8" />
|
|
@@ -4242,7 +4236,7 @@ Examples:
|
|
|
4242
4236
|
<\/script>
|
|
4243
4237
|
</body>
|
|
4244
4238
|
</html>
|
|
4245
|
-
`,
|
|
4239
|
+
`,i2=`<!DOCTYPE html>
|
|
4246
4240
|
<html lang="en">
|
|
4247
4241
|
<head>
|
|
4248
4242
|
<title>Welcome</title>
|
|
@@ -4862,7 +4856,7 @@ Examples:
|
|
|
4862
4856
|
<\/script>
|
|
4863
4857
|
</body>
|
|
4864
4858
|
</html>
|
|
4865
|
-
`,
|
|
4859
|
+
`,a2=`---
|
|
4866
4860
|
name: automation
|
|
4867
4861
|
description: |
|
|
4868
4862
|
Use this when setting up event-driven automation in SLICC — webhooks, cron
|
|
@@ -4940,7 +4934,7 @@ Events include the change type (\`create\`, \`modify\`, \`delete\`) and the file
|
|
|
4940
4934
|
- 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\`.
|
|
4941
4935
|
- 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.
|
|
4942
4936
|
- Don't fan a single trigger out to multiple scoops by registering N near-identical entries. Register once, let the receiving scoop dispatch.
|
|
4943
|
-
`,
|
|
4937
|
+
`,o2=`---
|
|
4944
4938
|
name: delegation
|
|
4945
4939
|
description: |
|
|
4946
4940
|
Use this when deciding whether to do work yourself or delegate to a scoop, when
|
|
@@ -5190,7 +5184,7 @@ scoop_scoop({ name: "architect", model: "claude-opus-4-6", prompt: "Design the n
|
|
|
5190
5184
|
## Browser tabs
|
|
5191
5185
|
|
|
5192
5186
|
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.
|
|
5193
|
-
`,
|
|
5187
|
+
`,s2=`---
|
|
5194
5188
|
name: dips
|
|
5195
5189
|
description: |
|
|
5196
5190
|
Use this whenever a response could benefit from richer visualization, guided
|
|
@@ -5332,7 +5326,7 @@ slicc.lick({ action: 'sort-complete', algorithm: algo, comparisons: n });
|
|
|
5332
5326
|
\`\`\`
|
|
5333
5327
|
|
|
5334
5328
|
The agent receives the lick as a structured message and can respond with prose, another dip, or spawn a scoop.
|
|
5335
|
-
`,
|
|
5329
|
+
`,c2=`# Dip patterns
|
|
5336
5330
|
|
|
5337
5331
|
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.
|
|
5338
5332
|
|
|
@@ -5498,7 +5492,7 @@ N sliders → proportional stacked bar → over/under budget indicator.
|
|
|
5498
5492
|
Textarea input → parsed recursive DOM tree with collapse/expand.
|
|
5499
5493
|
|
|
5500
5494
|
**Use for**: JSON explorers, config viewers, log parsers, schema inspectors, AST browsers.
|
|
5501
|
-
`,
|
|
5495
|
+
`,l2=`---
|
|
5502
5496
|
name: handoff
|
|
5503
5497
|
description: |
|
|
5504
5498
|
Use this when you receive a Navigate Event lick — emitted whenever the user
|
|
@@ -5574,7 +5568,7 @@ Use this shtml block verbatim, substituting the origin URL and header value. Kee
|
|
|
5574
5568
|
- Do not fetch the origin URL until the user has accepted. Even a \`HEAD\` request is too eager — the origin may use fetch-beacon side effects.
|
|
5575
5569
|
- Do not execute the header value as a shell command. It is instruction text or a pointer, not code.
|
|
5576
5570
|
- Do not render more than one approval card for a single navigate event. If you already showed the card, wait for the user.
|
|
5577
|
-
`,
|
|
5571
|
+
`,u2=`---
|
|
5578
5572
|
name: mount
|
|
5579
5573
|
description: |
|
|
5580
5574
|
Use this whenever the user asks to mount anything — local folders, S3
|
|
@@ -5716,7 +5710,7 @@ For DA specifically: the \`/list\` endpoint doesn't include file sizes, so \`ls
|
|
|
5716
5710
|
- Don't try to \`cd\` into a remote mount before mounting; \`bash\`'s working directory is independent of mount setup.
|
|
5717
5711
|
- 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.
|
|
5718
5712
|
- 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.
|
|
5719
|
-
`,
|
|
5713
|
+
`,d2=`---
|
|
5720
5714
|
name: playwright-cli
|
|
5721
5715
|
description: |
|
|
5722
5716
|
Use this whenever the user asks to browse, navigate, click, fill a form,
|
|
@@ -5971,7 +5965,7 @@ echo 'Page.navigate {"url":"https://example.com"}' \\
|
|
|
5971
5965
|
\`\`\`
|
|
5972
5966
|
|
|
5973
5967
|
Run \`websocat --help\` for the full flag list. Use this only when \`playwright-cli\` has no wrapper for the CDP method you need.
|
|
5974
|
-
`,p2="---\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",m2='---\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\', 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\\",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({action: \'refresh\', data: {...}})` — send a lick event to the cone (cone routes to the right scoop).\n- `slicc.on(\'update\', function(data) {...})` — receive data sent via `sprinkle send`.\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',h2=`# Lucide Icons Example
|
|
5968
|
+
`,f2="---\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",p2='---\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\', 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\\",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({action: \'refresh\', data: {...}})` — send a lick event to the cone (cone routes to the right scoop).\n- `slicc.on(\'update\', function(data) {...})` — receive data sent via `sprinkle send`.\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',m2=`# Lucide Icons Example
|
|
5975
5969
|
|
|
5976
5970
|
This shows how to use Lucide icons in inline sprinkles instead of emojis.
|
|
5977
5971
|
|
|
@@ -6081,7 +6075,7 @@ This shows how to use Lucide icons in inline sprinkles instead of emojis.
|
|
|
6081
6075
|
**UI**: \`settings\`, \`menu\`, \`more-vertical\`, \`more-horizontal\`, \`eye\`, \`eye-off\`, \`lock\`, \`unlock\`
|
|
6082
6076
|
|
|
6083
6077
|
Browse all icons at [lucide.dev/icons](https://lucide.dev/icons)
|
|
6084
|
-
`,
|
|
6078
|
+
`,h2=`# Sprinkle Component Reference
|
|
6085
6079
|
|
|
6086
6080
|
Use these CSS classes in \`.shtml\` sprinkles. Do NOT write custom CSS — these components cover all common UI patterns.
|
|
6087
6081
|
|
|
@@ -6873,7 +6867,7 @@ background: color-mix(in srgb, var(--s2-accent) 6%, transparent); /* blue tint *
|
|
|
6873
6867
|
| \`--s2-spacing-400\` | 24px |
|
|
6874
6868
|
| \`--s2-spacing-500\` | 32px |
|
|
6875
6869
|
| \`--s2-spacing-600\` | 40px |
|
|
6876
|
-
`,
|
|
6870
|
+
`,g2='---\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',_2=`---
|
|
6877
6871
|
name: welcome
|
|
6878
6872
|
description: |
|
|
6879
6873
|
Use this when you receive a \`[Sprinkle Event: welcome]\` lick with
|
|
@@ -6929,10 +6923,10 @@ Your one and only job is to send a single short reply (≤ 6 sentences total) th
|
|
|
6929
6923
|
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\`.
|
|
6930
6924
|
|
|
6931
6925
|
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.
|
|
6932
|
-
`,
|
|
6926
|
+
`,v2=`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 y2=`/workspace/skills`,b2=`SKILL.md`,x2=[`native`,`agents`,`claude`],S2=new Map([[`.agents`,`agents`],[`.claude`,`claude`]]),C2=new Set([`.git`,`.slicc`]),w2=[`mkdir`,`mount`,`rename`,`rm`,`unmount`,`writeFile`],T2=new WeakMap,E2=new WeakSet;async function D2(e,t=y2){let n=await A2(e,t),r=await O2(e);return[...x2.flatMap(e=>(e===`native`?n:r.filter(t=>t.source===e)).sort((e,t)=>e.path.localeCompare(t.path)))]}async function O2(e){M2(e);let t=e,n=T2.get(t);if(n)return n.map(e=>({...e}));let r=await j2(e);return T2.set(t,r),r.map(e=>({...e}))}function k2(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 A2(e,t){let n=await P2(e,t),r=[];for(let i of n){if(i.type!==`directory`)continue;let n=`${t}/${i.name}`,a=`${n}/${b2}`;await N2(e,a)&&r.push({source:`native`,sourceRoot:t,path:n,skillFilePath:a})}return r}async function j2(e){let t=[],n=new Set,r=[`/`];for(let i=0;i<r.length;i+=1){let a=r[i],o=await P2(e,a);for(let i of o){if(i.type!==`directory`)continue;let o=a===`/`?`/${i.name}`:`${a}/${i.name}`,s=S2.get(i.name);if(s){let r=`${o}/skills`,i=await P2(e,r);for(let a of i){if(a.type!==`directory`)continue;let i=`${r}/${a.name}`,o=`${i}/${b2}`;!await N2(e,o)||n.has(i)||(n.add(i),t.push({source:s,sourceRoot:r,path:i,skillFilePath:o}))}}C2.has(i.name)||r.push(o)}}return t}function M2(e){let t=e;if(E2.has(t))return;E2.add(t);let n=e;for(let r of w2){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 T2.delete(t),r}}catch{}}}async function N2(e,t){try{return await e.stat(t),!0}catch{return!1}}async function P2(e,t){try{return[...await e.readDir(t)].sort((e,t)=>e.name.localeCompare(t.name))}catch{return[]}}async function F2(e,t=`/workspace/skills`){let n=await D2(e,t),r=[];for(let t of n){let n=t.path.split(`/`).pop()??t.path,i=``;if(t.skillFilePath)try{i=R2(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}=k2(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 I2(e,t,n=`/workspace/skills`){return(await F2(e,n)).find(e=>e.name===t)||null}async function L2(e,t,n=`/workspace/skills`){let r=await I2(e,t,n);if(!r?.skillFilePath)return null;try{return await e.readTextFile(r.skillFilePath)}catch{return null}}function R2(e){let t=e.replace(/^\uFEFF/,``).replace(/\r\n?/g,`
|
|
6933
6927
|
`).trimStart().match(/^---\s*\n([\s\S]*?)\n---/);if(!t)return null;for(let e of t[1].split(`
|
|
6934
|
-
`)){let t=e.match(/^description:\s*(.*)$/);if(t)return t[1].trim()}return null}var
|
|
6935
|
-
`)){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
|
|
6928
|
+
`)){let t=e.match(/^description:\s*(.*)$/);if(t)return t[1].trim()}return null}var z2=n({MAX_SKILL_ARCHIVE_SIZE_BYTES:()=>MAX_SKILL_ARCHIVE_SIZE_BYTES,SKILLS_DIR:()=>O1,SKILL_ARCHIVE_EXTENSION:()=>SKILL_ARCHIVE_EXTENSION,SKILL_FILE:()=>b2,WORKSPACE_SKILLS_PATH:()=>y2,discoverSkills:()=>F2,getSkillInfo:()=>I2,readSkillInstructions:()=>L2});const B2=i(`skills`),V2=Object.assign({"/packages/vfs-root/AGENTS.md":t2,"/packages/vfs-root/CLAUDE.md":t2,"/packages/vfs-root/shared/CLAUDE.md":n2,"/packages/vfs-root/shared/sprinkles/welcome/connect-llm.shtml":r2,"/packages/vfs-root/shared/sprinkles/welcome/welcome.shtml":i2,"/packages/vfs-root/workspace/skills/automation/SKILL.md":a2,"/packages/vfs-root/workspace/skills/delegation/SKILL.md":o2,"/packages/vfs-root/workspace/skills/dips/SKILL.md":s2,"/packages/vfs-root/workspace/skills/dips/patterns.md":c2,"/packages/vfs-root/workspace/skills/handoff/SKILL.md":l2,"/packages/vfs-root/workspace/skills/mount/SKILL.md":u2,"/packages/vfs-root/workspace/skills/playwright-cli/SKILL.md":d2,"/packages/vfs-root/workspace/skills/skill-authoring/SKILL.md":f2,"/packages/vfs-root/workspace/skills/sprinkles/SKILL.md":p2,"/packages/vfs-root/workspace/skills/sprinkles/icon-example.md":m2,"/packages/vfs-root/workspace/skills/sprinkles/style-guide.md":h2,"/packages/vfs-root/workspace/skills/upgrade/SKILL.md":g2,"/packages/vfs-root/workspace/skills/welcome/SKILL.md":_2}),H2=Object.assign({"/packages/vfs-root/shared/sounds/chime.mp3":v2});function U2(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 W2(){let e={};for(let[t,n]of Object.entries(V2))e[t]=n;for(let[t,n]of Object.entries(H2))e[t]=U2(n);return e}function G2(e){let t=new Map;for(let n of e){if(t.has(n.metadata.name)){B2.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 K2(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(`
|
|
6929
|
+
`)){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 q2(e,t){let n=await J2(e,t),r=await Y2(e,t),i=n.filter(e=>e.source===`native`),a=n.filter(e=>e.source!==`native`),o=G2([...i,...r,...a]);return B2.info(`Skills loaded`,{count:o.length,dir:t}),o}async function J2(e,t){let n=await F2(e,t),r=[];for(let t of n)if(t.skillFilePath)try{let{metadata:n,body:i}=K2(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}),B2.debug(`Loaded discovered skill`,{name:a,path:t.skillFilePath,source:t.source})}catch{B2.debug(`Failed to load discovered skill`,{name:t.name,path:t.skillFilePath})}return r}async function Y2(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}=K2(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}),B2.debug(`Loaded standalone skill`,{name:s,path:r})}catch{}}}catch{B2.debug(`Standalone skills directory not found`,{dir:t})}return n}function X2(e){return e.length===0?``:`
|
|
6936
6930
|
---
|
|
6937
6931
|
AVAILABLE SKILLS
|
|
6938
6932
|
|
|
@@ -6941,10 +6935,10 @@ The following skills are available. To use a skill, first read its full instruct
|
|
|
6941
6935
|
|
|
6942
6936
|
${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(`
|
|
6943
6937
|
`)}
|
|
6944
|
-
---`}async function
|
|
6945
|
-
`)}`}}}),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:[...Tt],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(!Et(l))return{content:`Invalid thinking level "${l}". Must be one of: ${Tt.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(
|
|
6946
|
-
`)}}}),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}=n4(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 t4.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),t4.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 i4=new Map;function a4(){return new Date().toISOString().slice(0,10)}function o4(){try{let e=globalThis.localStorage;return!e||typeof e.getItem!=`function`||typeof e.setItem!=`function`?null:e}catch{return null}}function s4(e){let t=a4(),n=o4(),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=i4.get(e);if(i&&i.date===t)return i.uuid;let a=crypto.randomUUID();return i4.set(e,{uuid:a,date:t}),a}async function c4(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 l4(e,t){let n=s4(t??e.jid);return e.isCone?n:`${n}/${await c4(e.folder,n)}`}const u4=i(`secret-env`);function d4(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}async function f4(){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&&d4(e.name)&&(r[e.name]=e.maskedValue);Object.keys(r).length>0&&u4.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 u4.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&&d4(e.name)&&(n[e.name]=e.maskedValue);return Object.keys(n).length>0&&u4.info(`Loaded masked secrets into shell env`,{count:Object.keys(n).length}),n}catch(e){return u4.debug(`Could not fetch masked secrets (server may be unavailable)`,{error:e instanceof Error?e.message:String(e)}),{}}}const p4=i(`scoop-context`);function m4(e,t){return!t.reasoning||e===void 0?`off`:e===`xhigh`&&!Be(t).includes(`xhigh`)?`high`:e}function h4(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 g4(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 _4(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 v4(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 y4=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`);p4.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 Q2(this.fs,this.skillsDir);let n=this.skillsFs??this.fs,r=await f4();this.shell=new G0({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}),p4.info(`WasmShell initialized`,{folder:this.scoop.folder});let i=await J2(n,this.skillsDir),a=r4({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=[...q0(this.fs),t2(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()){p4.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,p4.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:m.length,droppedOrphans:e.messages.length-m.length}))}catch(e){p4.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 l4(this.scoop,this.coneJid),g=(e,t,n)=>e.provider===`adobe`?Le(e,t,{...n,headers:{...n?.headers,"X-Session-Id":h}}):Le(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=m4(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`),p4.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);p4.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){p4.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(g4(t)){p4.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(_4(t)&&n<3){let e=c*2**(n-1);if(p4.warn(`Retryable agent error, will retry`,{folder:this.scoop.folder,error:t,attempt:n,maxRetries:3,delayMs:e}),await v4(e,a)||this.disposed)return;continue}if(p4.error(`Agent error`,{folder:this.scoop.folder,error:t,attempt:n,isRetryable:_4(t)}),n===3)break;if(await v4(c*2**(n-1),a)||this.disposed)return}}if(l&&!this.disposed&&!a.aborted){let e=l.message;p4.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=m4(t,e),p4.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 J2(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,p4.info(`Skills reloaded`,{folder:this.scoop.folder,skillCount:e.length})}setThinkingLevel(e){if(!this.agent)return`off`;let t=m4(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(`
|
|
6947
|
-
`),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&&
|
|
6938
|
+
---`}async function Z2(e,t=`/workspace/skills`){let n=W2();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),B2.info(`Created default file`,{path:s})}}}const Q2=new Set([`/shared/sprinkles/welcome/welcome.shtml`,`/shared/sprinkles/welcome/connect-llm.shtml`]);async function $2(e){let t=W2();for(let[n,r]of Object.entries(t)){let t=n.slice(18);if(!t.startsWith(`/shared/`))continue;let i=Q2.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),B2.info(i?`Refreshed bundled shared file`:`Created default shared file`,{path:t})}}const e4=i(`scoop-management-tools`);function t4(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 n4(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),e4.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),e4.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(`
|
|
6939
|
+
`)}`}}}),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:[...Tt],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(!Et(l))return{content:`Invalid thinking level "${l}". Must be one of: ${Tt.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(e4.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 e4.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),e4.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}=t4(t,i);return n.length===0?{content:`No matching scoops found. Unknown: ${r.join(`, `)}`,isError:!0}:(u(n.map(e=>e.jid)),e4.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}=t4(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);e4.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(`
|
|
6940
|
+
`)}}}),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}=t4(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 e4.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),e4.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 r4=new Map;function i4(){return new Date().toISOString().slice(0,10)}function a4(){try{let e=globalThis.localStorage;return!e||typeof e.getItem!=`function`||typeof e.setItem!=`function`?null:e}catch{return null}}function o4(e){let t=i4(),n=a4(),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=r4.get(e);if(i&&i.date===t)return i.uuid;let a=crypto.randomUUID();return r4.set(e,{uuid:a,date:t}),a}async function s4(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 c4(e,t){let n=o4(t??e.jid);return e.isCone?n:`${n}/${await s4(e.folder,n)}`}const l4=i(`secret-env`);function u4(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}async function d4(){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&&u4(e.name)&&(r[e.name]=e.maskedValue);Object.keys(r).length>0&&l4.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 l4.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&&u4(e.name)&&(n[e.name]=e.maskedValue);return Object.keys(n).length>0&&l4.info(`Loaded masked secrets into shell env`,{count:Object.keys(n).length}),n}catch(e){return l4.debug(`Could not fetch masked secrets (server may be unavailable)`,{error:e instanceof Error?e.message:String(e)}),{}}}const f4=i(`scoop-context`);function p4(e,t){return!t.reasoning||e===void 0?`off`:e===`xhigh`&&!Be(t).includes(`xhigh`)?`high`:e}function m4(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 h4(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 g4(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 _4(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 v4=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`);f4.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 Z2(this.fs,this.skillsDir);let n=this.skillsFs??this.fs,r=await d4();this.shell=new W0({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}),f4.info(`WasmShell initialized`,{folder:this.scoop.folder});let i=await q2(n,this.skillsDir),a=n4({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=[...K0(this.fs),e2(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()){f4.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,f4.info(`Restored agent session`,{folder:this.scoop.folder,messageCount:m.length,droppedOrphans:e.messages.length-m.length}))}catch(e){f4.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 c4(this.scoop,this.coneJid),g=(e,t,n)=>e.provider===`adobe`?Le(e,t,{...n,headers:{...n?.headers,"X-Session-Id":h}}):Le(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=p4(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`),f4.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);f4.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){f4.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(h4(t)){f4.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(g4(t)&&n<3){let e=c*2**(n-1);if(f4.warn(`Retryable agent error, will retry`,{folder:this.scoop.folder,error:t,attempt:n,maxRetries:3,delayMs:e}),await _4(e,a)||this.disposed)return;continue}if(f4.error(`Agent error`,{folder:this.scoop.folder,error:t,attempt:n,isRetryable:g4(t)}),n===3)break;if(await _4(c*2**(n-1),a)||this.disposed)return}}if(l&&!this.disposed&&!a.aborted){let e=l.message;f4.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=p4(t,e),f4.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 q2(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,f4.info(`Skills reloaded`,{folder:this.scoop.folder,skillCount:e.length})}setThinkingLevel(e){if(!this.agent)return`off`;let t=p4(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(`
|
|
6941
|
+
`),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&&m4(n)){this.recoverFromImageError(t);break}if(!this.isRecovering&&Re(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=>{f4.error(`Failed to save agent session`,{folder:this.scoop.folder,error:e instanceof Error?e.message:String(e)})});break}}}recoverFromOverflow(e){if(this.agent){f4.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++,f4.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=>{f4.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){f4.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){f4.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=>{f4.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){f4.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
|
|
6948
6942
|
|
|
6949
6943
|
${this.scoop.isCone?`Role: Cone (main orchestrator)`:`Scoop: ${this.scoop.name}`}
|
|
6950
6944
|
Folder: ${this.scoop.folder}
|
|
@@ -6955,7 +6949,7 @@ Created: ${new Date().toISOString()}
|
|
|
6955
6949
|
|
|
6956
6950
|
## Context
|
|
6957
6951
|
(Add important context here)
|
|
6958
|
-
`;try{await this.fs.writeFile(t,e)}catch(e){if(e?.code===`EACCES`)
|
|
6952
|
+
`;try{await this.fs.writeFile(t,e)}catch(e){if(e?.code===`EACCES`)f4.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}
|
|
6959
6953
|
|
|
6960
6954
|
You are ${r}, ${this.scoop.isCone?`the main assistant (cone)`:`a scoop assistant`} in SLICC (Self-Licking Ice Cream Cone).
|
|
6961
6955
|
|
|
@@ -7023,26 +7017,26 @@ ${e}
|
|
|
7023
7017
|
---
|
|
7024
7018
|
${this.scoop.isCone?`CONE`:`SCOOP`} MEMORY (${this.scoop.name}):
|
|
7025
7019
|
${t}
|
|
7026
|
-
---`);let a=
|
|
7027
|
-
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}let
|
|
7020
|
+
---`);let a=X2(n);return a&&(i+=a),i}};const y4=i(`scheduler`);var b4=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(),y4.info(`Scheduler started`))}stop(){this.pollInterval&&=(clearInterval(this.pollInterval),null),this.running=!1,y4.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),y4.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),y4.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),y4.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){y4.warn(`Task scoop not found`,{taskId:e.id,groupFolder:e.groupFolder});return}y4.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),y4.info(`Task completed`,{id:e.id})}catch(t){y4.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}},x4=n({LickManager:()=>C4,buildActiveLicksError:()=>w4,getLickManager:()=>E4});const S4=i(`lick-manager`);var C4=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);S4.info(`Loaded webhooks`,{count:this.webhooks.size});let t=await l();for(let e of t)this.crontasks.set(e.id,e);S4.info(`Loaded crontasks`,{count:this.crontasks.size}),this.cronInterval=setInterval(()=>this.runCronScheduler(),6e4),S4.info(`Cron scheduler started`)}dispose(){this.cronInterval&&=(clearInterval(this.cronInterval),null)}setEventHandler(e){this.eventHandler=e}emitEvent(e){S4.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),S4.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),S4.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){S4.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){S4.debug(`Webhook event dropped by filter`,{webhookId:e,name:r.name});return}typeof t==`object`&&t&&(i=t)}catch(t){S4.error(`Webhook filter error`,{webhookId:e,error:t instanceof Error?t.message:String(t)})}S4.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),S4.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),S4.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){S4.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){S4.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};S4.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 w4(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(`
|
|
7021
|
+
`);return Error(`Cannot remove scoop '${e}': it has ${r.join(` and `)}. Unregister them first:\n${i}`)}let T4=null;function E4(){return T4||=new C4,T4}const $=i(`orchestrator`),D4=`/shared/scoop-notifications`,O4=1e3;function k4(e){let t=e.replace(/\r\n?/g,`
|
|
7028
7022
|
`);if(t.length===0)return 0;let n=1;for(let e=0;e<t.length;e++)t[e]===`
|
|
7029
7023
|
`&&n++;return t.endsWith(`
|
|
7030
|
-
`)?n-1:n}var
|
|
7024
|
+
`)?n-1:n}var A4=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 A.create({dbName:`slicc-fs`}),this.sessionStore=new te,this.fsWatcher=new pe,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 b4({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);L$(()=>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 $2(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(`
|
|
7031
7025
|
`)?``:`
|
|
7032
7026
|
`}\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)}}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)+`
|
|
7033
|
-
... (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=
|
|
7034
|
-
`)}formatScoopCompletionFallbackNotification(e,t,n,r){return[`[@${e} completed]`,`VFS path: unavailable`,`Artifact persistence error: ${r}`,`Total lines: ${t}`,`Preview (up to ${
|
|
7027
|
+
... (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=k4(t),i=t.slice(0,O4),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(D4,{recursive:!0}),await this.pruneScoopCompletionArtifacts(199);let n=new Date().toISOString().replace(/[:.]/g,`-`),r=Math.random().toString(36).slice(2,8),i=`${D4}/${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(D4)}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=`${D4}/${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 ${O4} chars):`,r].join(`
|
|
7028
|
+
`)}formatScoopCompletionFallbackNotification(e,t,n,r){return[`[@${e} completed]`,`VFS path: unavailable`,`Artifact persistence error: ${r}`,`Total lines: ${t}`,`Preview (up to ${O4} chars):`,n].join(`
|
|
7035
7029
|
`)}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)+`
|
|
7036
7030
|
... (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)+`
|
|
7037
7031
|
... (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(`
|
|
7038
|
-
`),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=T4(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 A.create({dbName:`slicc-fs`,wipe:!0}),this.fsWatcher&&this.sharedFs.setWatcher(this.fsWatcher),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await Q2(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){$.info(`handleMessage`,{id:e.id,chatJid:e.chatJid,sender:e.senderName,channel:e.channel,contentPreview:e.content.slice(0,80)}),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 me(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 y4(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(`
|
|
7039
|
-
`),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 M4=i(`agent-bridge`);function N4(e,t,n=null,r={}){let i=r.generateName??R4,a=r.generateUid??F4,o=r.resolveModel??B4;function s(){for(let t=0;t<8;t++){let t=i(),n=`agent_${z4(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&&Et(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&&!Et(u))return{finalText:`agent: invalid thinking level: ${String(u)} (one of: ${Tt.join(`, `)})`,exitCode:1};let d=u??l(r.parentJid)??void 0,f=s(),p=`agent-${f}`,m=`agent_${z4(f)}`,h=`/scoops/${p}`,g=V4(r.cwd),_={visiblePaths:H4(r),writablePaths:U4([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??W4(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??W4(e),exitCode:1}}finally{S();try{await e.unregisterScoop(m)}catch(e){M4.warn(`unregisterScoop failed`,{jid:m,error:W4(e)})}try{await t.rm(h,{recursive:!0})}catch(e){G4(e,`ENOENT`)||M4.warn(`scratch folder cleanup failed`,{folder:p,error:W4(e)})}if(n)try{await n.delete(m)}catch(e){M4.warn(`sessionStore.delete failed`,{jid:m,error:W4(e)})}}}return{spawn:u}}function P4(e,t,n=null,r={}){let i=N4(e,t,n,r);return globalThis.__slicc_agent=i,M4.info(`agent bridge published on globalThis.__slicc_agent`),i}function F4(){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 I4=`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(`.`),L4=`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 R4(){return`${I4[Math.floor(Math.random()*I4.length)]}-${L4[Math.floor(Math.random()*L4.length)]}`}function z4(e){return e.replace(/-/g,`_`)}function B4(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 V4(e){let t=he(e);return t.endsWith(`/`)?t:`${t}/`}function H4(e){if(e.visiblePaths!==void 0)return e.visiblePaths.map(V4);let t=[`/workspace/`];return e.invokingCwd&&e.invokingCwd.length>0&&t.push(V4(e.invokingCwd)),U4(t)}function U4(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function W4(e){return e instanceof Error?e.message:String(e)}function G4(e,t){if(typeof e!=`object`||!e)return!1;let n=e.code;return typeof n==`string`&&n===t}var K4=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=J4(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=Y4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);return q4.map(e=>({name:e,kind:`file`,size:this.fileSize(n,e),lastModified:this.fileMtime(n)}))}throw new LR(`ENOTDIR`,`not a directory`,e)}async readFile(e){this.assertOpen(e);let t=J4(e);if(t.length!==2)throw new LR(`EISDIR`,`is a directory`,e);let n=Y4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!q4.includes(r))throw new LR(`ENOENT`,`no such file or directory`,e);let i=this.renderProcFile(n,r);return new TextEncoder().encode(i)}async writeFile(e){throw new LR(`EACCES`,`read-only filesystem`,e)}async stat(e){this.assertOpen(e);let t=J4(e);if(t.length===0)return{kind:`directory`,size:0,mtime:0};if(t.length===1){let n=Y4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);return{kind:`directory`,size:0,mtime:this.fileMtime(n)}}if(t.length===2){let n=Y4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!q4.includes(r))throw new LR(`ENOENT`,`no such file or directory`,e);return{kind:`file`,size:this.fileSize(n,r),mtime:this.fileMtime(n)}}throw new LR(`ENOENT`,`no such file or directory`,e)}async mkdir(e){throw new LR(`EACCES`,`read-only filesystem`,e)}async remove(e){throw new LR(`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 LR(`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 n3(t);let n=this.pm.get(e);switch(t){case`status`:return X4(n);case`cmdline`:return Z4(n);case`cwd`:return Q4(n);case`stat`:return $4(n)}}};const q4=[`status`,`cmdline`,`cwd`,`stat`];function J4(e){return e.replace(/^\/+/,``).replace(/\/+$/,``).split(`/`).filter(Boolean)}function Y4(e){let t=Number.parseInt(e,10);return!Number.isFinite(t)||String(t)!==e?null:t}function X4(e){let t=[`Name:\t${e.kind}`,`Pid:\t${e.pid}`,`PPid:\t${e.ppid}`,`State:\t${e3(e.status)} (${e.status})`,`Owner:\t${t3(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(`
|
|
7032
|
+
`),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=w4(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 A.create({dbName:`slicc-fs`,wipe:!0}),this.fsWatcher&&this.sharedFs.setWatcher(this.fsWatcher),await this.ensureRootStructure(),await this.ensureGlobalMemory(),await Z2(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){$.info(`handleMessage`,{id:e.id,chatJid:e.chatJid,sender:e.senderName,channel:e.channel,contentPreview:e.content.slice(0,80)}),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 me(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 v4(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(`
|
|
7033
|
+
`),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 j4=i(`agent-bridge`);function M4(e,t,n=null,r={}){let i=r.generateName??L4,a=r.generateUid??P4,o=r.resolveModel??z4;function s(){for(let t=0;t<8;t++){let t=i(),n=`agent_${R4(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&&Et(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&&!Et(u))return{finalText:`agent: invalid thinking level: ${String(u)} (one of: ${Tt.join(`, `)})`,exitCode:1};let d=u??l(r.parentJid)??void 0,f=s(),p=`agent-${f}`,m=`agent_${R4(f)}`,h=`/scoops/${p}`,g=B4(r.cwd),_={visiblePaths:V4(r),writablePaths:H4([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??U4(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??U4(e),exitCode:1}}finally{S();try{await e.unregisterScoop(m)}catch(e){j4.warn(`unregisterScoop failed`,{jid:m,error:U4(e)})}try{await t.rm(h,{recursive:!0})}catch(e){W4(e,`ENOENT`)||j4.warn(`scratch folder cleanup failed`,{folder:p,error:U4(e)})}if(n)try{await n.delete(m)}catch(e){j4.warn(`sessionStore.delete failed`,{jid:m,error:U4(e)})}}}return{spawn:u}}function N4(e,t,n=null,r={}){let i=M4(e,t,n,r);return globalThis.__slicc_agent=i,j4.info(`agent bridge published on globalThis.__slicc_agent`),i}function P4(){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 F4=`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(`.`),I4=`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 L4(){return`${F4[Math.floor(Math.random()*F4.length)]}-${I4[Math.floor(Math.random()*I4.length)]}`}function R4(e){return e.replace(/-/g,`_`)}function z4(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 B4(e){let t=he(e);return t.endsWith(`/`)?t:`${t}/`}function V4(e){if(e.visiblePaths!==void 0)return e.visiblePaths.map(B4);let t=[`/workspace/`];return e.invokingCwd&&e.invokingCwd.length>0&&t.push(B4(e.invokingCwd)),H4(t)}function H4(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function U4(e){return e instanceof Error?e.message:String(e)}function W4(e,t){if(typeof e!=`object`||!e)return!1;let n=e.code;return typeof n==`string`&&n===t}var G4=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=q4(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=J4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);return K4.map(e=>({name:e,kind:`file`,size:this.fileSize(n,e),lastModified:this.fileMtime(n)}))}throw new LR(`ENOTDIR`,`not a directory`,e)}async readFile(e){this.assertOpen(e);let t=q4(e);if(t.length!==2)throw new LR(`EISDIR`,`is a directory`,e);let n=J4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!K4.includes(r))throw new LR(`ENOENT`,`no such file or directory`,e);let i=this.renderProcFile(n,r);return new TextEncoder().encode(i)}async writeFile(e){throw new LR(`EACCES`,`read-only filesystem`,e)}async stat(e){this.assertOpen(e);let t=q4(e);if(t.length===0)return{kind:`directory`,size:0,mtime:0};if(t.length===1){let n=J4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);return{kind:`directory`,size:0,mtime:this.fileMtime(n)}}if(t.length===2){let n=J4(t[0]);if(n===null||!this.pidExists(n))throw new LR(`ENOENT`,`no such file or directory`,e);let r=t[1];if(!K4.includes(r))throw new LR(`ENOENT`,`no such file or directory`,e);return{kind:`file`,size:this.fileSize(n,r),mtime:this.fileMtime(n)}}throw new LR(`ENOENT`,`no such file or directory`,e)}async mkdir(e){throw new LR(`EACCES`,`read-only filesystem`,e)}async remove(e){throw new LR(`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 LR(`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 t3(t);let n=this.pm.get(e);switch(t){case`status`:return Y4(n);case`cmdline`:return X4(n);case`cwd`:return Z4(n);case`stat`:return Q4(n)}}};const K4=[`status`,`cmdline`,`cwd`,`stat`];function q4(e){return e.replace(/^\/+/,``).replace(/\/+$/,``).split(`/`).filter(Boolean)}function J4(e){let t=Number.parseInt(e,10);return!Number.isFinite(t)||String(t)!==e?null:t}function Y4(e){let t=[`Name:\t${e.kind}`,`Pid:\t${e.pid}`,`PPid:\t${e.ppid}`,`State:\t${$4(e.status)} (${e.status})`,`Owner:\t${e3(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(`
|
|
7040
7034
|
`)+`
|
|
7041
|
-
`}function
|
|
7042
|
-
`}function
|
|
7043
|
-
`}function
|
|
7035
|
+
`}function X4(e){return e.argv.join(`\0`)+`\0`}function Z4(e){return e.cwd+`
|
|
7036
|
+
`}function Q4(e){return[e.pid,`(${e.kind})`,$4(e.status),e.ppid,e.exitCode??`-`,e.startedAt,e.finishedAt??`-`].join(` `)+`
|
|
7037
|
+
`}function $4(e){switch(e){case`running`:return`R`;case`pending`:return`S`;case`exited`:return`Z`;case`killed`:return`K`}}function e3(e){return e.owner.kind===`cone`?`cone`:e.owner.kind===`system`?`system`:e.owner.scoopJid?`scoop/${e.owner.scoopJid}`:`scoop`}function t3(e){switch(e){case`status`:return[`Name: kernel-host`,`Pid: 1`,`PPid: 0`,`State: R (running)`,`Owner: system`].join(`
|
|
7044
7038
|
`)+`
|
|
7045
7039
|
`;case`cmdline`:return`kernel-host\0`;case`cwd`:return`/
|
|
7046
7040
|
`;case`stat`:return`1 (kernel-host) R 0 - 0 -
|
|
7047
|
-
`}}var
|
|
7048
|
-
`)}function c3(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=s3(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\`\`\``}}function l3(e,{orchestrator:t,log:n}){let r=c3(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 u3(e){let{container:t,browser:n,bridge:r,callbacks:i,skipConeBootstrap:a=!1}=e,o=e.logger??console,s=new bJ,c=new j4(t,{...i,getBrowserAPI:()=>n});c.setProcessManager(s),globalThis.__slicc_pm=s,await r.bind(c,n);let l=ct(()=>r.emitTrayRuntimeStatus()),u=D(()=>r.emitTrayRuntimeStatus());await c.init();let d=c.getSharedFS();if(d?P4(c,d,c.getSessionStore()):o.warn(`AgentBridge not published — orchestrator.getSharedFS() returned null`),d)try{await d.mountInternal(`/proc`,new K4(s))}catch(e){o.warn(`Failed to mount /proc`,e)}let{registerSessionCostsProvider:f}=await Promise.resolve().then(()=>I$);f(()=>c.getSessionCosts());let{getLickManager:p}=await Promise.resolve().then(()=>S4),m=p();await m.init(),c.setLickManager(m);let h=e.lickEventHandler??l3,g={orchestrator:c,lickManager:m,log:o};m.setEventHandler(e=>h(e,g)),globalThis.__slicc_lickManager=m,d&&(async()=>{try{let{getAllMountEntries:e}=await Promise.resolve().then(()=>RR),{recoverMounts:t}=await Promise.resolve().then(()=>r3),n=await e();if(n.length===0)return;let{needsRecovery:r}=await t(n,d,o);if(r.length===0)return;m.emitEvent({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:r}})}catch(e){o.warn(`mount recovery failed`,e)}})(),a||c.getScoops().some(e=>e.isCone)||await c.registerScoop({jid:`cone_${Date.now()}`,name:`Cone`,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()}),d&&(async()=>{try{let{detectUpgrade:e,recordVersionSeen:t}=await import(`./upgrade-detection-Bllbwwis.js`),n=await e();if(!n.isUpgrade||n.lastSeen===null)return;m.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){o.warn(`Upgrade detection failed`,e)}})();let _=null,v=null;if(d)try{let{BshWatchdog:e}=await import(`./bsh-watchdog-DEvn8Q9x.js`),{ScriptCatalog:t}=await Promise.resolve().then(()=>P0),r=new t({jshFs:d,bshFs:d,watcher:d.getWatcher()}),i=new e({browserAPI:n,scriptCatalog:r,fs:d});i.start(),_=()=>i.stop(),v=()=>r.dispose()}catch(e){o.warn(`Failed to start BSH watchdog`,e)}let y=!1;return{orchestrator:c,browser:n,bridge:r,lickManager:m,sharedFs:d??null,processManager:s,async dispose(){if(!y){if(y=!0,l?.(),u?.(),_?.(),v?.(),d)try{await d.unmountInternal(`/proc`)}catch{}d3({processManager:s,lickManager:m})}}}}function d3(e){let t=globalThis;t.__slicc_pm===e.processManager&&delete t.__slicc_pm,t.__slicc_lickManager===e.lickManager&&delete t.__slicc_lickManager}function f3(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 p3(e){let t=f3(e);return{onMessage:e=>t.onMessage(e),send:e=>{t.send({source:`offscreen`,payload:e})}}}var m3=class extends JK{constructor(e){let t=f3(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})}})}},h3=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(!g3(e)||e.source!==`panel`)return;let t=e.payload;v3(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=_3(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 g3(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function _3(e){switch(e){case`SIGINT`:return 130;case`SIGTERM`:return 143;case`SIGKILL`:return 137;case`SIGSTOP`:case`SIGCONT`:return 130}}function v3(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 y3(e){let{transport:t,fs:n,browser:r,processManager:i}=e,a=new h3({transport:t,processManager:i,createShell:(e,t)=>new U0({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 b3(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 x3=`x-bypass-llm-proxy`;function S3(e,t){return t?(n,r)=>{if(!C3(n,t))return e(n,r);let i=new Headers(r?.headers);return i.has(x3)||i.set(x3,`1`),e(n,{...r,headers:i})}:e}function C3(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 w3(){let e=globalThis.fetch;if(!e)return;let t=typeof self<`u`&&self.location?self.location.origin:void 0;globalThis.fetch=S3(e.bind(globalThis),t)}function T3(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 E3=null,D3=null,O3=null;const k3=b3(e=>A3(e));self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-init`&&k3.handle(e.data)});async function A3(e){w3(),T3(e.localStorageSeed??{}),await Ve();let t=p3(e.kernelPort),n=new Ct(t),r=Ct.createCallbacks(n),i=new m3(e.cdpPort);await i.connect();let a=new et(i);E3=await u3({container:{},browser:a,bridge:n,callbacks:r,logger:console});let{createSprinkleManagerProxyOverChannel:o}=await import(`./sprinkle-bridge-channel-DhKQ_srk.js`);globalThis.__slicc_sprinkleManager=o({instanceId:e.instanceId});let{createPanelRpcClient:s}=await Promise.resolve().then(()=>ZK);O3=s({instanceId:e.instanceId}),globalThis.__slicc_panelRpc=O3;let c=E3.processManager,l=E3.sharedFs;l?D3=y3({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`&&(D3?.(),D3=null,O3?.dispose(),O3=null,E3?.dispose())});export{yK as a,KR as c,HR as d,LR as f,lt as h,nq as i,GR as l,_t as m,lQ as n,AB as o,vt as p,tQ as r,$R as s,cQ as t,UR as u};
|
|
7041
|
+
`}}var n3=n({formatMountRecoveryPrompt:()=>o3,mdInlineCode:()=>a3,recoverMounts:()=>r3,shellQuote:()=>i3});async function r3(e,t,n){let r=[],i=[];for(let a of e){let{targetPath:e,descriptor:o}=a;if(o.kind===`local`){let a=await GR(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=$R.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 qe({mountId:o.mountId,ttlMs:3e4}),a=new Ue({source:o.source,profile:o.profile,cache:i,mountId:o.mountId,signedFetch:Ke(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 qe({mountId:o.mountId,ttlMs:3e4}),a=new We({source:o.source,profile:o.profile,cache:i,mountId:o.mountId,signedFetch:Ge()});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 i3(e){return`'${e.replace(/'/g,`'\\''`)}'`}function a3(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 o3(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 ${a3(t)})`:``;return`- ${a3(e)}${n}`}),i=r.map(({path:e})=>` mount ${i3(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 ${i3(n)}`,a=`mount --source ${i3(t)}${i} ${i3(e)}`;return`- ${a3(e)} (${a3(t)}, profile ${a3(n)}) — ${r}\n Retry: ${a3(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(`
|
|
7042
|
+
`)}function s3(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=o3(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\`\`\``}}function c3(e,{orchestrator:t,log:n}){let r=s3(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 l3(e){let{container:t,browser:n,bridge:r,callbacks:i,skipConeBootstrap:a=!1}=e,o=e.logger??console,s=new bJ,c=new A4(t,{...i,getBrowserAPI:()=>n});c.setProcessManager(s),globalThis.__slicc_pm=s,await r.bind(c,n);let l=ct(()=>r.emitTrayRuntimeStatus()),u=D(()=>r.emitTrayRuntimeStatus());await c.init();let d=c.getSharedFS();if(d?N4(c,d,c.getSessionStore()):o.warn(`AgentBridge not published — orchestrator.getSharedFS() returned null`),d)try{await d.mountInternal(`/proc`,new G4(s))}catch(e){o.warn(`Failed to mount /proc`,e)}let{registerSessionCostsProvider:f}=await Promise.resolve().then(()=>F$);f(()=>c.getSessionCosts());let{getLickManager:p}=await Promise.resolve().then(()=>x4),m=p();await m.init(),c.setLickManager(m);let h=e.lickEventHandler??c3,g={orchestrator:c,lickManager:m,log:o};m.setEventHandler(e=>h(e,g)),globalThis.__slicc_lickManager=m,d&&(async()=>{try{let{getAllMountEntries:e}=await Promise.resolve().then(()=>RR),{recoverMounts:t}=await Promise.resolve().then(()=>n3),n=await e();if(n.length===0)return;let{needsRecovery:r}=await t(n,d,o);if(r.length===0)return;m.emitEvent({type:`session-reload`,targetScoop:void 0,timestamp:new Date().toISOString(),body:{reason:`mount-recovery`,mounts:r}})}catch(e){o.warn(`mount recovery failed`,e)}})(),a||c.getScoops().some(e=>e.isCone)||await c.registerScoop({jid:`cone_${Date.now()}`,name:`Cone`,folder:`cone`,isCone:!0,type:`cone`,requiresTrigger:!1,assistantLabel:`sliccy`,addedAt:new Date().toISOString()}),d&&(async()=>{try{let{detectUpgrade:e,recordVersionSeen:t}=await import(`./upgrade-detection-CyImEIEC.js`),n=await e();if(!n.isUpgrade||n.lastSeen===null)return;m.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){o.warn(`Upgrade detection failed`,e)}})();let _=null,v=null;if(d)try{let{BshWatchdog:e}=await import(`./bsh-watchdog-DEvn8Q9x.js`),{ScriptCatalog:t}=await Promise.resolve().then(()=>N0),r=new t({jshFs:d,bshFs:d,watcher:d.getWatcher()}),i=new e({browserAPI:n,scriptCatalog:r,fs:d});i.start(),_=()=>i.stop(),v=()=>r.dispose()}catch(e){o.warn(`Failed to start BSH watchdog`,e)}let y=!1;return{orchestrator:c,browser:n,bridge:r,lickManager:m,sharedFs:d??null,processManager:s,async dispose(){if(!y){if(y=!0,l?.(),u?.(),_?.(),v?.(),d)try{await d.unmountInternal(`/proc`)}catch{}u3({processManager:s,lickManager:m})}}}}function u3(e){let t=globalThis;t.__slicc_pm===e.processManager&&delete t.__slicc_pm,t.__slicc_lickManager===e.lickManager&&delete t.__slicc_lickManager}function d3(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 f3(e){let t=d3(e);return{onMessage:e=>t.onMessage(e),send:e=>{t.send({source:`offscreen`,payload:e})}}}var p3=class extends JK{constructor(e){let t=d3(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})}})}},m3=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(!h3(e)||e.source!==`panel`)return;let t=e.payload;_3(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=g3(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 h3(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}function g3(e){switch(e){case`SIGINT`:return 130;case`SIGTERM`:return 143;case`SIGKILL`:return 137;case`SIGSTOP`:case`SIGCONT`:return 130}}function _3(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 v3(e){let{transport:t,fs:n,browser:r,processManager:i}=e,a=new m3({transport:t,processManager:i,createShell:(e,t)=>new H0({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 y3(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 b3=`x-bypass-llm-proxy`;function x3(e,t){return t?(n,r)=>{if(!S3(n,t))return e(n,r);let i=new Headers(r?.headers);return i.has(b3)||i.set(b3,`1`),e(n,{...r,headers:i})}:e}function S3(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 C3(){let e=globalThis.fetch;if(!e)return;let t=typeof self<`u`&&self.location?self.location.origin:void 0;globalThis.fetch=x3(e.bind(globalThis),t)}function w3(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 T3=null,E3=null,D3=null;const O3=y3(e=>k3(e));self.addEventListener(`message`,e=>{e.data?.type===`kernel-worker-init`&&O3.handle(e.data)});async function k3(e){C3(),w3(e.localStorageSeed??{}),await Ve();let t=f3(e.kernelPort),n=new Ct(t),r=Ct.createCallbacks(n),i=new p3(e.cdpPort);await i.connect();let a=new et(i);T3=await l3({container:{},browser:a,bridge:n,callbacks:r,logger:console});let{createSprinkleManagerProxyOverChannel:o}=await import(`./sprinkle-bridge-channel-DhKQ_srk.js`);globalThis.__slicc_sprinkleManager=o({instanceId:e.instanceId});let{createPanelRpcClient:s}=await Promise.resolve().then(()=>ZK);D3=s({instanceId:e.instanceId}),globalThis.__slicc_panelRpc=D3;let c=T3.processManager,l=T3.sharedFs;l?E3=v3({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`&&(E3?.(),E3=null,D3?.dispose(),D3=null,T3?.dispose())});export{yK as a,KR as c,HR as d,LR as f,lt as h,nq as i,GR as l,_t as m,lQ as n,AB as o,vt as p,tQ as r,$R as s,cQ as t,UR as u};
|