pipane 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
- "packageVersion": "0.1.12",
3
- "revision": "628e79f",
2
+ "packageVersion": "0.1.13",
3
+ "revision": "fc6b38d",
4
4
  "developmentCommit": false
5
5
  }
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/device-invite-page-BXdui21Z.js","assets/device-identity-C_w2NbSk.js","assets/rendezvous-trust-api-Bv6fZVJA.js","assets/pairing-page-BUVrsL9A.js","assets/webrtc-frame-transport-Drpqhhdy.js","assets/__vite-browser-external-DGfF_P2w.js","assets/remote-backend-manager-vEOu2dhH.js","assets/backend-protocol-BvNAsFvb.js","assets/ws-agent-adapter-BUykBiJL.js","assets/workspace-backend-client-C2DwlCed.js","assets/main-BOivrw8_.js","assets/app-runtime-Rw-O-AwW.js","assets/backend-landing-page-DnP0b68z.js"])))=>i.map(i=>d[i]);
2
- (function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))a(t);new MutationObserver(t=>{for(const r of t)if(r.type==="childList")for(const i of r.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&a(i)}).observe(document,{childList:!0,subtree:!0});function o(t){const r={};return t.integrity&&(r.integrity=t.integrity),t.referrerPolicy&&(r.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?r.credentials="include":t.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function a(t){if(t.ep)return;t.ep=!0;const r=o(t);fetch(t.href,r)}})();const w="modulepreload",_=function(e){return"/"+e},m={},u=function(n,o,a){let t=Promise.resolve();if(o&&o.length>0){let f=function(s){return Promise.all(s.map(l=>Promise.resolve(l).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),c=i?.nonce||i?.getAttribute("nonce");t=f(o.map(s=>{if(s=_(s),s in m)return;m[s]=!0;const l=s.endsWith(".css"),p=l?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${s}"]${p}`))return;const d=document.createElement("link");if(d.rel=l?"stylesheet":w,l||(d.as="script"),d.crossOrigin="",d.href=s,c&&d.setAttribute("nonce",c),document.head.appendChild(d),l)return new Promise((g,v)=>{d.addEventListener("load",g),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${s}`)))})}))}function r(i){const c=new Event("vite:preloadError",{cancelable:!0});if(c.payload=i,window.dispatchEvent(c),!c.defaultPrevented)throw i}return t.then(i=>{for(const c of i||[])c.status==="rejected"&&r(c.reason);return n().catch(r)})};"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(e=>{for(const n of e)n.unregister()});y();async function y(){if(b(window.location.pathname)){const{initializeDeviceInvitePage:o}=await u(async()=>{const{initializeDeviceInvitePage:a}=await import("./device-invite-page-BXdui21Z.js");return{initializeDeviceInvitePage:a}},__vite__mapDeps([0,1,2]));await o();return}if(k(window.location.pathname)){const{initializePairingPage:o}=await u(async()=>{const{initializePairingPage:a}=await import("./pairing-page-BUVrsL9A.js");return{initializePairingPage:a}},__vite__mapDeps([3,1,2,4,5]));await o();return}const e=L(window.location.pathname);if(e!==void 0||window.location.pathname==="/"&&await E())try{const[{configureAppRuntime:o},{RemoteBackendManager:a},{WorkspaceBackendClient:t},{loadBrowserDeviceIdentity:r}]=await Promise.all([u(()=>import("./app-runtime-Rw-O-AwW.js"),[]),u(()=>import("./remote-backend-manager-vEOu2dhH.js"),__vite__mapDeps([6,7,1,2,4,5,8])),u(()=>import("./workspace-backend-client-C2DwlCed.js"),__vite__mapDeps([9,7])),u(()=>import("./device-identity-C_w2NbSk.js").then(f=>f.d),[])]);if(!await r()){await h();return}const i=new a(window.location.origin),c=await i.initialize();if(c.length===0){await h();return}o({client:new t(c,i,e)})}catch(o){P(o);return}await u(()=>import("./main-BOivrw8_.js"),__vite__mapDeps([10,8,7,5,11,1,2]))}async function h(){const{initializeBackendLandingPage:e}=await u(async()=>{const{initializeBackendLandingPage:n}=await import("./backend-landing-page-DnP0b68z.js");return{initializeBackendLandingPage:n}},__vite__mapDeps([12,7,1,2]));await e()}async function E(){try{const e=await fetch("/health",{cache:"no-store"});if(!e.ok||!e.headers.get("content-type")?.includes("application/json"))return!1;const n=await e.json();return!!n&&typeof n=="object"&&n.ok===!0}catch{return!1}}function P(e){const n=document.getElementById("app")??document.body;n.replaceChildren();const o=document.createElement("main");o.style.cssText="min-height:100vh;display:grid;place-items:center;padding:24px;font-family:ui-sans-serif,system-ui;color:var(--foreground,#111827);background:var(--background,#fff)";const a=document.createElement("section");a.style.cssText="max-width:520px;border:1px solid var(--border,#d1d5db);border-radius:12px;padding:28px";const t=document.createElement("h1");t.textContent="Cannot open backend";const r=document.createElement("p");r.textContent=e instanceof Error?e.message:"This browser is not authorized for the backend.";const i=document.createElement("p");i.textContent="To restore access, run `pipane pair` in the backend terminal and scan the new QR code with this browser.",a.append(t,r,i),o.append(a),n.append(o)}function b(e){return/^\/invite\/[^/]+$/u.test(e)}function k(e){return/^\/pair\/[^/]+$/u.test(e)}function L(e){const n=/^\/backend\/([^/]+)$/u.exec(e);return n?.[1]?decodeURIComponent(n[1]):void 0}export{u as _};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/device-invite-page-BXdui21Z.js","assets/device-identity-C_w2NbSk.js","assets/rendezvous-trust-api-Bv6fZVJA.js","assets/pairing-page-BUVrsL9A.js","assets/webrtc-frame-transport-Drpqhhdy.js","assets/__vite-browser-external-DGfF_P2w.js","assets/remote-backend-manager-9i5f_5_a.js","assets/backend-protocol-BvNAsFvb.js","assets/ws-agent-adapter-C7ujmNSC.js","assets/workspace-backend-client-C2DwlCed.js","assets/main-CcR16Juf.js","assets/app-runtime-Rw-O-AwW.js","assets/backend-landing-page-DnP0b68z.js"])))=>i.map(i=>d[i]);
2
+ (function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))a(t);new MutationObserver(t=>{for(const r of t)if(r.type==="childList")for(const i of r.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&a(i)}).observe(document,{childList:!0,subtree:!0});function o(t){const r={};return t.integrity&&(r.integrity=t.integrity),t.referrerPolicy&&(r.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?r.credentials="include":t.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function a(t){if(t.ep)return;t.ep=!0;const r=o(t);fetch(t.href,r)}})();const w="modulepreload",_=function(e){return"/"+e},m={},u=function(n,o,a){let t=Promise.resolve();if(o&&o.length>0){let f=function(s){return Promise.all(s.map(l=>Promise.resolve(l).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),c=i?.nonce||i?.getAttribute("nonce");t=f(o.map(s=>{if(s=_(s),s in m)return;m[s]=!0;const l=s.endsWith(".css"),p=l?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${s}"]${p}`))return;const d=document.createElement("link");if(d.rel=l?"stylesheet":w,l||(d.as="script"),d.crossOrigin="",d.href=s,c&&d.setAttribute("nonce",c),document.head.appendChild(d),l)return new Promise((g,v)=>{d.addEventListener("load",g),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${s}`)))})}))}function r(i){const c=new Event("vite:preloadError",{cancelable:!0});if(c.payload=i,window.dispatchEvent(c),!c.defaultPrevented)throw i}return t.then(i=>{for(const c of i||[])c.status==="rejected"&&r(c.reason);return n().catch(r)})};"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(e=>{for(const n of e)n.unregister()});y();async function y(){if(b(window.location.pathname)){const{initializeDeviceInvitePage:o}=await u(async()=>{const{initializeDeviceInvitePage:a}=await import("./device-invite-page-BXdui21Z.js");return{initializeDeviceInvitePage:a}},__vite__mapDeps([0,1,2]));await o();return}if(k(window.location.pathname)){const{initializePairingPage:o}=await u(async()=>{const{initializePairingPage:a}=await import("./pairing-page-BUVrsL9A.js");return{initializePairingPage:a}},__vite__mapDeps([3,1,2,4,5]));await o();return}const e=L(window.location.pathname);if(e!==void 0||window.location.pathname==="/"&&await E())try{const[{configureAppRuntime:o},{RemoteBackendManager:a},{WorkspaceBackendClient:t},{loadBrowserDeviceIdentity:r}]=await Promise.all([u(()=>import("./app-runtime-Rw-O-AwW.js"),[]),u(()=>import("./remote-backend-manager-9i5f_5_a.js"),__vite__mapDeps([6,7,1,2,4,5,8])),u(()=>import("./workspace-backend-client-C2DwlCed.js"),__vite__mapDeps([9,7])),u(()=>import("./device-identity-C_w2NbSk.js").then(f=>f.d),[])]);if(!await r()){await h();return}const i=new a(window.location.origin),c=await i.initialize();if(c.length===0){await h();return}o({client:new t(c,i,e)})}catch(o){P(o);return}await u(()=>import("./main-CcR16Juf.js"),__vite__mapDeps([10,8,7,5,11,1,2]))}async function h(){const{initializeBackendLandingPage:e}=await u(async()=>{const{initializeBackendLandingPage:n}=await import("./backend-landing-page-DnP0b68z.js");return{initializeBackendLandingPage:n}},__vite__mapDeps([12,7,1,2]));await e()}async function E(){try{const e=await fetch("/health",{cache:"no-store"});if(!e.ok||!e.headers.get("content-type")?.includes("application/json"))return!1;const n=await e.json();return!!n&&typeof n=="object"&&n.ok===!0}catch{return!1}}function P(e){const n=document.getElementById("app")??document.body;n.replaceChildren();const o=document.createElement("main");o.style.cssText="min-height:100vh;display:grid;place-items:center;padding:24px;font-family:ui-sans-serif,system-ui;color:var(--foreground,#111827);background:var(--background,#fff)";const a=document.createElement("section");a.style.cssText="max-width:520px;border:1px solid var(--border,#d1d5db);border-radius:12px;padding:28px";const t=document.createElement("h1");t.textContent="Cannot open backend";const r=document.createElement("p");r.textContent=e instanceof Error?e.message:"This browser is not authorized for the backend.";const i=document.createElement("p");i.textContent="To restore access, run `pipane pair` in the backend terminal and scan the new QR code with this browser.",a.append(t,r,i),o.append(a),n.append(o)}function b(e){return/^\/invite\/[^/]+$/u.test(e)}function k(e){return/^\/pair\/[^/]+$/u.test(e)}function L(e){const n=/^\/backend\/([^/]+)$/u.exec(e);return n?.[1]?decodeURIComponent(n[1]):void 0}export{u as _};
@@ -1,4 +1,4 @@
1
- var I1=r=>{throw TypeError(r)};var $u=(r,e,t)=>e.has(r)||I1("Cannot "+t);var pr=(r,e,t)=>($u(r,e,"read from private field"),t?t.call(r):e.get(r)),Gs=(r,e,t)=>e.has(r)?I1("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),Hn=(r,e,t,n)=>($u(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),qs=(r,e,t)=>($u(r,e,"access private method"),t);var F1=(r,e,t,n)=>({set _(s){Hn(r,e,s,t)},get _(){return pr(r,e,n)}});import{f as x3,s as w3,W as y3,m as df,g as k3,c as _3}from"./ws-agent-adapter-BUykBiJL.js";import{consumeAppRuntime as E3}from"./app-runtime-Rw-O-AwW.js";import{B as N1}from"./backend-protocol-BvNAsFvb.js";import"./index-CG96lus1.js";import{a as A3}from"./device-identity-C_w2NbSk.js";import{R as S3}from"./rendezvous-trust-api-Bv6fZVJA.js";import"./__vite-browser-external-DGfF_P2w.js";let ff;function Db(){return localStorage.getItem("color-theme")||"gruvbox"}function pf(){return localStorage.getItem("theme")||"dark"}function Pb(){const r=localStorage.getItem("pipane-show-token-usage");return r===null?!0:r==="true"}function Ob(r){r==="default"?document.documentElement.removeAttribute("data-color-theme"):document.documentElement.setAttribute("data-color-theme",r)}function mf(r){const e=r==="dark"||r==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.classList.toggle("dark",e)}function Lb(r){document.documentElement.classList.toggle("hide-token-usage",!r)}function T3(r){ff=r,Ob(Db()),mf(pf()),Lb(Pb()),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{pf()==="system"&&mf("system")}),Bb()}async function Bb(){try{if(!ff)return;const e=(await ff.getLocalSettings())?.settings?.appearance;if(!e)return;if(e.colorTheme&&e.colorTheme!==Db()&&(localStorage.setItem("color-theme",e.colorTheme),Ob(e.colorTheme)),e.darkMode&&e.darkMode!==pf()&&(e.darkMode==="system"?localStorage.removeItem("theme"):localStorage.setItem("theme",e.darkMode),mf(e.darkMode)),typeof e.showTokenUsage=="boolean"){const t=Pb();e.showTokenUsage!==t&&(localStorage.setItem("pipane-show-token-usage",String(e.showTokenUsage)),Lb(e.showTokenUsage))}}catch{}}async function gf(){await Bb()}const $0=globalThis,Mp=$0.ShadowRoot&&($0.ShadyCSS===void 0||$0.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Ip=Symbol(),D1=new WeakMap;let zb=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==Ip)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const t=this.t;if(Mp&&e===void 0){const n=t!==void 0&&t.length===1;n&&(e=D1.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),n&&D1.set(t,e))}return e}toString(){return this.cssText}};const C3=r=>new zb(typeof r=="string"?r:r+"",void 0,Ip),$b=(r,...e)=>{const t=r.length===1?r[0]:e.reduce((n,s,i)=>n+(a=>{if(a._$cssResult$===!0)return a.cssText;if(typeof a=="number")return a;throw Error("Value passed to 'css' function must be a 'css' function result: "+a+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+r[i+1],r[0]);return new zb(t,r,Ip)},R3=(r,e)=>{if(Mp)r.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const t of e){const n=document.createElement("style"),s=$0.litNonce;s!==void 0&&n.setAttribute("nonce",s),n.textContent=t.cssText,r.appendChild(n)}},P1=Mp?r=>r:r=>r instanceof CSSStyleSheet?(e=>{let t="";for(const n of e.cssRules)t+=n.cssText;return C3(t)})(r):r;const{is:M3,defineProperty:I3,getOwnPropertyDescriptor:F3,getOwnPropertyNames:N3,getOwnPropertySymbols:D3,getPrototypeOf:P3}=Object,Hh=globalThis,O1=Hh.trustedTypes,O3=O1?O1.emptyScript:"",L3=Hh.reactiveElementPolyfillSupport,Ol=(r,e)=>r,eh={toAttribute(r,e){switch(e){case Boolean:r=r?O3:null;break;case Object:case Array:r=r==null?r:JSON.stringify(r)}return r},fromAttribute(r,e){let t=r;switch(e){case Boolean:t=r!==null;break;case Number:t=r===null?null:Number(r);break;case Object:case Array:try{t=JSON.parse(r)}catch{t=null}}return t}},Fp=(r,e)=>!M3(r,e),L1={attribute:!0,type:String,converter:eh,reflect:!1,useDefault:!1,hasChanged:Fp};Symbol.metadata??=Symbol("metadata"),Hh.litPropertyMetadata??=new WeakMap;let wo=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=L1){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const n=Symbol(),s=this.getPropertyDescriptor(e,n,t);s!==void 0&&I3(this.prototype,e,s)}}static getPropertyDescriptor(e,t,n){const{get:s,set:i}=F3(this.prototype,e)??{get(){return this[t]},set(a){this[t]=a}};return{get:s,set(a){const o=s?.call(this);i?.call(this,a),this.requestUpdate(e,o,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??L1}static _$Ei(){if(this.hasOwnProperty(Ol("elementProperties")))return;const e=P3(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(Ol("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(Ol("properties"))){const t=this.properties,n=[...N3(t),...D3(t)];for(const s of n)this.createProperty(s,t[s])}const e=this[Symbol.metadata];if(e!==null){const t=litPropertyMetadata.get(e);if(t!==void 0)for(const[n,s]of t)this.elementProperties.set(n,s)}this._$Eh=new Map;for(const[t,n]of this.elementProperties){const s=this._$Eu(t,n);s!==void 0&&this._$Eh.set(s,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const n=new Set(e.flat(1/0).reverse());for(const s of n)t.unshift(P1(s))}else e!==void 0&&t.push(P1(e));return t}static _$Eu(e,t){const n=t.attribute;return n===!1?void 0:typeof n=="string"?n:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const n of t.keys())this.hasOwnProperty(n)&&(e.set(n,this[n]),delete this[n]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return R3(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,n){this._$AK(e,n)}_$ET(e,t){const n=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,n);if(s!==void 0&&n.reflect===!0){const i=(n.converter?.toAttribute!==void 0?n.converter:eh).toAttribute(t,n.type);this._$Em=e,i==null?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null}}_$AK(e,t){const n=this.constructor,s=n._$Eh.get(e);if(s!==void 0&&this._$Em!==s){const i=n.getPropertyOptions(s),a=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:eh;this._$Em=s;const o=a.fromAttribute(t,i.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(e,t,n,s=!1,i){if(e!==void 0){const a=this.constructor;if(s===!1&&(i=this[e]),n??=a.getPropertyOptions(e),!((n.hasChanged??Fp)(i,t)||n.useDefault&&n.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(a._$Eu(e,n))))return;this.C(e,t,n)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(e,t,{useDefault:n,reflect:s,wrapped:i},a){n&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,a??t??this[e]),i!==!0||a!==void 0)||(this._$AL.has(e)||(this.hasUpdated||n||(t=void 0),this._$AL.set(e,t)),s===!0&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[s,i]of this._$Ep)this[s]=i;this._$Ep=void 0}const n=this.constructor.elementProperties;if(n.size>0)for(const[s,i]of n){const{wrapped:a}=i,o=this[s];a!==!0||this._$AL.has(s)||o===void 0||this.C(s,void 0,i,o)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(n=>n.hostUpdate?.()),this.update(t)):this._$EM()}catch(n){throw e=!1,this._$EM(),n}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(e){}firstUpdated(e){}};wo.elementStyles=[],wo.shadowRootOptions={mode:"open"},wo[Ol("elementProperties")]=new Map,wo[Ol("finalized")]=new Map,L3?.({ReactiveElement:wo}),(Hh.reactiveElementVersions??=[]).push("2.1.2");const Np=globalThis,B1=r=>r,th=Np.trustedTypes,z1=th?th.createPolicy("lit-html",{createHTML:r=>r}):void 0,Ub="$lit$",qi=`lit$${Math.random().toFixed(9).slice(2)}$`,Hb="?"+qi,B3=`<${Hb}>`,$a=document,rc=()=>$a.createComment(""),nc=r=>r===null||typeof r!="object"&&typeof r!="function",Dp=Array.isArray,z3=r=>Dp(r)||typeof r?.[Symbol.iterator]=="function",Uu=`[
1
+ var I1=r=>{throw TypeError(r)};var $u=(r,e,t)=>e.has(r)||I1("Cannot "+t);var pr=(r,e,t)=>($u(r,e,"read from private field"),t?t.call(r):e.get(r)),Gs=(r,e,t)=>e.has(r)?I1("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),Hn=(r,e,t,n)=>($u(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),qs=(r,e,t)=>($u(r,e,"access private method"),t);var F1=(r,e,t,n)=>({set _(s){Hn(r,e,s,t)},get _(){return pr(r,e,n)}});import{f as x3,s as w3,W as y3,m as df,g as k3,c as _3}from"./ws-agent-adapter-C7ujmNSC.js";import{consumeAppRuntime as E3}from"./app-runtime-Rw-O-AwW.js";import{B as N1}from"./backend-protocol-BvNAsFvb.js";import"./index-BNFbdYPt.js";import{a as A3}from"./device-identity-C_w2NbSk.js";import{R as S3}from"./rendezvous-trust-api-Bv6fZVJA.js";import"./__vite-browser-external-DGfF_P2w.js";let ff;function Db(){return localStorage.getItem("color-theme")||"gruvbox"}function pf(){return localStorage.getItem("theme")||"dark"}function Pb(){const r=localStorage.getItem("pipane-show-token-usage");return r===null?!0:r==="true"}function Ob(r){r==="default"?document.documentElement.removeAttribute("data-color-theme"):document.documentElement.setAttribute("data-color-theme",r)}function mf(r){const e=r==="dark"||r==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.classList.toggle("dark",e)}function Lb(r){document.documentElement.classList.toggle("hide-token-usage",!r)}function T3(r){ff=r,Ob(Db()),mf(pf()),Lb(Pb()),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{pf()==="system"&&mf("system")}),Bb()}async function Bb(){try{if(!ff)return;const e=(await ff.getLocalSettings())?.settings?.appearance;if(!e)return;if(e.colorTheme&&e.colorTheme!==Db()&&(localStorage.setItem("color-theme",e.colorTheme),Ob(e.colorTheme)),e.darkMode&&e.darkMode!==pf()&&(e.darkMode==="system"?localStorage.removeItem("theme"):localStorage.setItem("theme",e.darkMode),mf(e.darkMode)),typeof e.showTokenUsage=="boolean"){const t=Pb();e.showTokenUsage!==t&&(localStorage.setItem("pipane-show-token-usage",String(e.showTokenUsage)),Lb(e.showTokenUsage))}}catch{}}async function gf(){await Bb()}const $0=globalThis,Mp=$0.ShadowRoot&&($0.ShadyCSS===void 0||$0.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Ip=Symbol(),D1=new WeakMap;let zb=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==Ip)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const t=this.t;if(Mp&&e===void 0){const n=t!==void 0&&t.length===1;n&&(e=D1.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),n&&D1.set(t,e))}return e}toString(){return this.cssText}};const C3=r=>new zb(typeof r=="string"?r:r+"",void 0,Ip),$b=(r,...e)=>{const t=r.length===1?r[0]:e.reduce((n,s,i)=>n+(a=>{if(a._$cssResult$===!0)return a.cssText;if(typeof a=="number")return a;throw Error("Value passed to 'css' function must be a 'css' function result: "+a+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+r[i+1],r[0]);return new zb(t,r,Ip)},R3=(r,e)=>{if(Mp)r.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const t of e){const n=document.createElement("style"),s=$0.litNonce;s!==void 0&&n.setAttribute("nonce",s),n.textContent=t.cssText,r.appendChild(n)}},P1=Mp?r=>r:r=>r instanceof CSSStyleSheet?(e=>{let t="";for(const n of e.cssRules)t+=n.cssText;return C3(t)})(r):r;const{is:M3,defineProperty:I3,getOwnPropertyDescriptor:F3,getOwnPropertyNames:N3,getOwnPropertySymbols:D3,getPrototypeOf:P3}=Object,Hh=globalThis,O1=Hh.trustedTypes,O3=O1?O1.emptyScript:"",L3=Hh.reactiveElementPolyfillSupport,Ol=(r,e)=>r,eh={toAttribute(r,e){switch(e){case Boolean:r=r?O3:null;break;case Object:case Array:r=r==null?r:JSON.stringify(r)}return r},fromAttribute(r,e){let t=r;switch(e){case Boolean:t=r!==null;break;case Number:t=r===null?null:Number(r);break;case Object:case Array:try{t=JSON.parse(r)}catch{t=null}}return t}},Fp=(r,e)=>!M3(r,e),L1={attribute:!0,type:String,converter:eh,reflect:!1,useDefault:!1,hasChanged:Fp};Symbol.metadata??=Symbol("metadata"),Hh.litPropertyMetadata??=new WeakMap;let wo=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=L1){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const n=Symbol(),s=this.getPropertyDescriptor(e,n,t);s!==void 0&&I3(this.prototype,e,s)}}static getPropertyDescriptor(e,t,n){const{get:s,set:i}=F3(this.prototype,e)??{get(){return this[t]},set(a){this[t]=a}};return{get:s,set(a){const o=s?.call(this);i?.call(this,a),this.requestUpdate(e,o,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??L1}static _$Ei(){if(this.hasOwnProperty(Ol("elementProperties")))return;const e=P3(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(Ol("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(Ol("properties"))){const t=this.properties,n=[...N3(t),...D3(t)];for(const s of n)this.createProperty(s,t[s])}const e=this[Symbol.metadata];if(e!==null){const t=litPropertyMetadata.get(e);if(t!==void 0)for(const[n,s]of t)this.elementProperties.set(n,s)}this._$Eh=new Map;for(const[t,n]of this.elementProperties){const s=this._$Eu(t,n);s!==void 0&&this._$Eh.set(s,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const n=new Set(e.flat(1/0).reverse());for(const s of n)t.unshift(P1(s))}else e!==void 0&&t.push(P1(e));return t}static _$Eu(e,t){const n=t.attribute;return n===!1?void 0:typeof n=="string"?n:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const n of t.keys())this.hasOwnProperty(n)&&(e.set(n,this[n]),delete this[n]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return R3(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,n){this._$AK(e,n)}_$ET(e,t){const n=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,n);if(s!==void 0&&n.reflect===!0){const i=(n.converter?.toAttribute!==void 0?n.converter:eh).toAttribute(t,n.type);this._$Em=e,i==null?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null}}_$AK(e,t){const n=this.constructor,s=n._$Eh.get(e);if(s!==void 0&&this._$Em!==s){const i=n.getPropertyOptions(s),a=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:eh;this._$Em=s;const o=a.fromAttribute(t,i.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(e,t,n,s=!1,i){if(e!==void 0){const a=this.constructor;if(s===!1&&(i=this[e]),n??=a.getPropertyOptions(e),!((n.hasChanged??Fp)(i,t)||n.useDefault&&n.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(a._$Eu(e,n))))return;this.C(e,t,n)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(e,t,{useDefault:n,reflect:s,wrapped:i},a){n&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,a??t??this[e]),i!==!0||a!==void 0)||(this._$AL.has(e)||(this.hasUpdated||n||(t=void 0),this._$AL.set(e,t)),s===!0&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[s,i]of this._$Ep)this[s]=i;this._$Ep=void 0}const n=this.constructor.elementProperties;if(n.size>0)for(const[s,i]of n){const{wrapped:a}=i,o=this[s];a!==!0||this._$AL.has(s)||o===void 0||this.C(s,void 0,i,o)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(n=>n.hostUpdate?.()),this.update(t)):this._$EM()}catch(n){throw e=!1,this._$EM(),n}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(e){}firstUpdated(e){}};wo.elementStyles=[],wo.shadowRootOptions={mode:"open"},wo[Ol("elementProperties")]=new Map,wo[Ol("finalized")]=new Map,L3?.({ReactiveElement:wo}),(Hh.reactiveElementVersions??=[]).push("2.1.2");const Np=globalThis,B1=r=>r,th=Np.trustedTypes,z1=th?th.createPolicy("lit-html",{createHTML:r=>r}):void 0,Ub="$lit$",qi=`lit$${Math.random().toFixed(9).slice(2)}$`,Hb="?"+qi,B3=`<${Hb}>`,$a=document,rc=()=>$a.createComment(""),nc=r=>r===null||typeof r!="object"&&typeof r!="function",Dp=Array.isArray,z3=r=>Dp(r)||typeof r?.[Symbol.iterator]=="function",Uu=`[
2
2
  \f\r]`,cl=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,$1=/-->/g,U1=/>/g,ga=RegExp(`>|${Uu}(?:([^\\s"'>=/]+)(${Uu}*=${Uu}*(?:[^
3
3
  \f\r"'\`<>=]|("|')|))|$)`,"g"),H1=/'/g,W1=/"/g,Wb=/^(?:script|style|textarea|title)$/i,$3=r=>(e,...t)=>({_$litType$:r,strings:e,values:t}),fe=$3(1),ws=Symbol.for("lit-noChange"),xt=Symbol.for("lit-nothing"),G1=new WeakMap,Sa=$a.createTreeWalker($a,129);function Gb(r,e){if(!Dp(r)||!r.hasOwnProperty("raw"))throw Error("invalid template strings array");return z1!==void 0?z1.createHTML(e):e}const U3=(r,e)=>{const t=r.length-1,n=[];let s,i=e===2?"<svg>":e===3?"<math>":"",a=cl;for(let o=0;o<t;o++){const l=r[o];let c,h,u=-1,f=0;for(;f<l.length&&(a.lastIndex=f,h=a.exec(l),h!==null);)f=a.lastIndex,a===cl?h[1]==="!--"?a=$1:h[1]!==void 0?a=U1:h[2]!==void 0?(Wb.test(h[2])&&(s=RegExp("</"+h[2],"g")),a=ga):h[3]!==void 0&&(a=ga):a===ga?h[0]===">"?(a=s??cl,u=-1):h[1]===void 0?u=-2:(u=a.lastIndex-h[2].length,c=h[1],a=h[3]===void 0?ga:h[3]==='"'?W1:H1):a===W1||a===H1?a=ga:a===$1||a===U1?a=cl:(a=ga,s=void 0);const d=a===ga&&r[o+1].startsWith("/>")?" ":"";i+=a===cl?l+B3:u>=0?(n.push(c),l.slice(0,u)+Ub+l.slice(u)+qi+d):l+qi+(u===-2?o:d)}return[Gb(r,i+(r[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),n]};let vf=class qb{constructor({strings:e,_$litType$:t},n){let s;this.parts=[];let i=0,a=0;const o=e.length-1,l=this.parts,[c,h]=U3(e,t);if(this.el=qb.createElement(c,n),Sa.currentNode=this.el.content,t===2||t===3){const u=this.el.content.firstChild;u.replaceWith(...u.childNodes)}for(;(s=Sa.nextNode())!==null&&l.length<o;){if(s.nodeType===1){if(s.hasAttributes())for(const u of s.getAttributeNames())if(u.endsWith(Ub)){const f=h[a++],d=s.getAttribute(u).split(qi),m=/([.?@])?(.*)/.exec(f);l.push({type:1,index:i,name:m[2],strings:d,ctor:m[1]==="."?W3:m[1]==="?"?G3:m[1]==="@"?q3:Gh}),s.removeAttribute(u)}else u.startsWith(qi)&&(l.push({type:6,index:i}),s.removeAttribute(u));if(Wb.test(s.tagName)){const u=s.textContent.split(qi),f=u.length-1;if(f>0){s.textContent=th?th.emptyScript:"";for(let d=0;d<f;d++)s.append(u[d],rc()),Sa.nextNode(),l.push({type:2,index:++i});s.append(u[f],rc())}}}else if(s.nodeType===8)if(s.data===Hb)l.push({type:2,index:i});else{let u=-1;for(;(u=s.data.indexOf(qi,u+1))!==-1;)l.push({type:7,index:i}),u+=qi.length-1}i++}}static createElement(e,t){const n=$a.createElement("template");return n.innerHTML=e,n}};function Vo(r,e,t=r,n){if(e===ws)return e;let s=n!==void 0?t._$Co?.[n]:t._$Cl;const i=nc(e)?void 0:e._$litDirective$;return s?.constructor!==i&&(s?._$AO?.(!1),i===void 0?s=void 0:(s=new i(r),s._$AT(r,t,n)),n!==void 0?(t._$Co??=[])[n]=s:t._$Cl=s),s!==void 0&&(e=Vo(r,s._$AS(r,e.values),s,n)),e}class H3{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){const{el:{content:t},parts:n}=this._$AD,s=(e?.creationScope??$a).importNode(t,!0);Sa.currentNode=s;let i=Sa.nextNode(),a=0,o=0,l=n[0];for(;l!==void 0;){if(a===l.index){let c;l.type===2?c=new Wh(i,i.nextSibling,this,e):l.type===1?c=new l.ctor(i,l.name,l.strings,this,e):l.type===6&&(c=new V3(i,this,e)),this._$AV.push(c),l=n[++o]}a!==l?.index&&(i=Sa.nextNode(),a++)}return Sa.currentNode=$a,s}p(e){let t=0;for(const n of this._$AV)n!==void 0&&(n.strings!==void 0?(n._$AI(e,n,t),t+=n.strings.length-2):n._$AI(e[t])),t++}}let Wh=class Vb{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,n,s){this.type=2,this._$AH=xt,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=s,this._$Cv=s?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode;const t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=Vo(this,e,t),nc(e)?e===xt||e==null||e===""?(this._$AH!==xt&&this._$AR(),this._$AH=xt):e!==this._$AH&&e!==ws&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):z3(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==xt&&nc(this._$AH)?this._$AA.nextSibling.data=e:this.T($a.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:n}=e,s=typeof n=="number"?this._$AC(e):(n.el===void 0&&(n.el=vf.createElement(Gb(n.h,n.h[0]),this.options)),n);if(this._$AH?._$AD===s)this._$AH.p(t);else{const i=new H3(s,this),a=i.u(this.options);i.p(t),this.T(a),this._$AH=i}}_$AC(e){let t=G1.get(e.strings);return t===void 0&&G1.set(e.strings,t=new vf(e)),t}k(e){Dp(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let n,s=0;for(const i of e)s===t.length?t.push(n=new Vb(this.O(rc()),this.O(rc()),this,this.options)):n=t[s],n._$AI(i),s++;s<t.length&&(this._$AR(n&&n._$AB.nextSibling,s),t.length=s)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){const n=B1(e).nextSibling;B1(e).remove(),e=n}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},Gh=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,n,s,i){this.type=1,this._$AH=xt,this._$AN=void 0,this.element=e,this.name=t,this._$AM=s,this.options=i,n.length>2||n[0]!==""||n[1]!==""?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=xt}_$AI(e,t=this,n,s){const i=this.strings;let a=!1;if(i===void 0)e=Vo(this,e,t,0),a=!nc(e)||e!==this._$AH&&e!==ws,a&&(this._$AH=e);else{const o=e;let l,c;for(e=i[0],l=0;l<i.length-1;l++)c=Vo(this,o[n+l],t,l),c===ws&&(c=this._$AH[l]),a||=!nc(c)||c!==this._$AH[l],c===xt?e=xt:e!==xt&&(e+=(c??"")+i[l+1]),this._$AH[l]=c}a&&!s&&this.j(e)}j(e){e===xt?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"")}},W3=class extends Gh{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===xt?void 0:e}},G3=class extends Gh{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==xt)}},q3=class extends Gh{constructor(e,t,n,s,i){super(e,t,n,s,i),this.type=5}_$AI(e,t=this){if((e=Vo(this,e,t,0)??xt)===ws)return;const n=this._$AH,s=e===xt&&n!==xt||e.capture!==n.capture||e.once!==n.once||e.passive!==n.passive,i=e!==xt&&(n===xt||s);s&&this.element.removeEventListener(this.name,this,n),i&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}},V3=class{constructor(e,t,n){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=n}get _$AU(){return this._$AM._$AU}_$AI(e){Vo(this,e)}};const j3={I:Wh},X3=Np.litHtmlPolyfillSupport;X3?.(vf,Wh),(Np.litHtmlVersions??=[]).push("3.3.3");const Es=(r,e,t)=>{const n=t?.renderBefore??e;let s=n._$litPart$;if(s===void 0){const i=t?.renderBefore??null;n._$litPart$=s=new Wh(e.insertBefore(rc(),i),i,void 0,t??{})}return s._$AI(r),s};const Pp=globalThis;let Qr=class extends wo{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=Es(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return ws}};Qr._$litElement$=!0,Qr.finalized=!0,Pp.litElementHydrateSupport?.({LitElement:Qr});const K3=Pp.litElementPolyfillSupport;K3?.({LitElement:Qr});(Pp.litElementVersions??=[]).push("4.2.2");const ri={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,ELEMENT:6},Ac=r=>(...e)=>({_$litDirective$:r,values:e});let qh=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,n){this._$Ct=e,this._$AM=t,this._$Ci=n}_$AS(e,t){return this.update(e,t)}update(e,t){return this.render(...t)}};const{I:Y3}=j3,q1=r=>r,jb=r=>r.strings===void 0,V1=()=>document.createComment(""),hl=(r,e,t)=>{const n=r._$AA.parentNode,s=e===void 0?r._$AB:e._$AA;if(t===void 0){const i=n.insertBefore(V1(),s),a=n.insertBefore(V1(),s);t=new Y3(i,a,r,r.options)}else{const i=t._$AB.nextSibling,a=t._$AM,o=a!==r;if(o){let l;t._$AQ?.(r),t._$AM=r,t._$AP!==void 0&&(l=r._$AU)!==a._$AU&&t._$AP(l)}if(i!==s||o){let l=t._$AA;for(;l!==i;){const c=q1(l).nextSibling;q1(n).insertBefore(l,s),l=c}}}return t},va=(r,e,t=r)=>(r._$AI(e,t),r),Z3={},Xb=(r,e=Z3)=>r._$AH=e,J3=r=>r._$AH,Hu=r=>{r._$AR(),r._$AA.remove()};const j1=Ac(class extends qh{constructor(r){if(super(r),r.type!==ri.PROPERTY&&r.type!==ri.ATTRIBUTE&&r.type!==ri.BOOLEAN_ATTRIBUTE)throw Error("The `live` directive is not allowed on child or event bindings");if(!jb(r))throw Error("`live` bindings can only contain a single expression")}render(r){return r}update(r,[e]){if(e===ws||e===xt)return e;const t=r.element,n=r.name;if(r.type===ri.PROPERTY){if(e===t[n])return ws}else if(r.type===ri.BOOLEAN_ATTRIBUTE){if(!!e===t.hasAttribute(n))return ws}else if(r.type===ri.ATTRIBUTE&&t.getAttribute(n)===e+"")return ws;return Xb(r),e}}),Q3=10;class e5{constructor(e=n=>requestAnimationFrame(n),t=n=>cancelAnimationFrame(n)){this.requestFrame=e,this.cancelFrame=t,this.following=!0,this.forceNextScroll=!1,this.programmaticScrollSettling=!1}pinToBottom(){this.following=!0,this.forceNextScroll=!0}pauseForUser(){this.following=!1,this.forceNextScroll=!1,this.pendingFrame!==void 0&&(this.cancelFrame(this.pendingFrame),this.pendingFrame=void 0)}handleScroll(e){this.programmaticScrollSettling||this.forceNextScroll||this.distanceFromBottom(e)<Q3&&(this.following=!0)}scrollToBottomIfNeeded(e){!this.following&&!this.forceNextScroll||this.pendingFrame!==void 0||(this.pendingFrame=this.requestFrame(()=>{if(this.pendingFrame=void 0,!this.following&&!this.forceNextScroll)return;const t=e();t&&(this.programmaticScrollSettling=!0,this.forceNextScroll=!1,t.scrollTop=t.scrollHeight,this.settlingFrame!==void 0&&this.cancelFrame(this.settlingFrame),this.settlingFrame=this.requestFrame(()=>{this.settlingFrame=void 0,this.programmaticScrollSettling=!1}))}))}dispose(){this.pendingFrame!==void 0&&this.cancelFrame(this.pendingFrame),this.settlingFrame!==void 0&&this.cancelFrame(this.settlingFrame),this.pendingFrame=void 0,this.settlingFrame=void 0,this.programmaticScrollSettling=!1}distanceFromBottom(e){return e.scrollHeight-e.scrollTop-e.clientHeight}}const t5={value:"",attachments:[]};function r5(r,e,t){const n=r?`session:${r}`:`virtual:${e}`;return t?`backend:${t}:${n}`:n}class n5{constructor(){this.drafts=new Map}get(e){return this.drafts.get(e)??t5}setValue(e,t){const n=this.get(e);this.set(e,t,n.attachments)}setAttachments(e,t){const n=this.get(e);this.set(e,n.value,t)}clear(e){this.drafts.delete(e)}set(e,t,n){if(!t&&n.length===0){this.clear(e);return}this.drafts.set(e,{value:t,attachments:[...n]})}}function s5(r){return r<1e3?String(r):r<1e4?`${(r/1e3).toFixed(1)}k`:`${Math.round(r/1e3)}k`}function i5(r){return`$${r<.01?r.toFixed(4):r<1?r.toFixed(3):r.toFixed(2)}`}function Kb(r){return r.totalTokens&&r.totalTokens>0?r.totalTokens:(r.input??r.inputTokens??0)+(r.output??r.outputTokens??0)+(r.cacheRead??0)+(r.cacheWrite??0)}function a5(r){return r.role==="assistant"&&r.stopReason!=="aborted"&&r.stopReason!=="error"&&r.usage!==void 0&&Kb(r.usage)>0}function o5(r,e){const t=r.filter(o=>o.role==="assistant").reduce((o,l)=>{const c=l.usage;return c&&(o.input+=c.input??c.inputTokens??0,o.output+=c.output??c.outputTokens??0,o.cacheRead+=c.cacheRead??0,o.cacheWrite+=c.cacheWrite??0,o.cost+=c.cost?.total??c.totalCost??0),o},{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0});if(!!!(t.input||t.output||t.cacheRead||t.cacheWrite||t.cost)&&!(e&&e>0))return;let s=0,i=-1;for(let o=r.length-1;o>=0;o--)if(r[o].role==="compactionSummary"){i=o;break}for(let o=r.length-1;o>i;o--){const l=r[o];if(a5(l)){s=Kb(l.usage);break}}const a=i>=0&&s===0;return{input:t.input,output:t.output,cost:t.cost,costLabel:i5(t.cost),contextPercent:e&&e>0?a?null:Math.round(s/e*100):void 0,contextWindowLabel:e&&e>0?s5(e):void 0}}const Zn=r=>(e,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(r,e)}):customElements.define(r,e)};const l5={attribute:!0,type:String,converter:eh,reflect:!1,hasChanged:Fp},c5=(r=l5,e,t)=>{const{kind:n,metadata:s}=t;let i=globalThis.litPropertyMetadata.get(s);if(i===void 0&&globalThis.litPropertyMetadata.set(s,i=new Map),n==="setter"&&((r=Object.create(r)).wrapped=!0),i.set(t.name,r),n==="accessor"){const{name:a}=t;return{set(o){const l=e.get.call(this);e.set.call(this,o),this.requestUpdate(a,l,r,!0,o)},init(o){return o!==void 0&&this.C(a,void 0,r,o),o}}}if(n==="setter"){const{name:a}=t;return function(o){const l=this[a];e.call(this,o),this.requestUpdate(a,l,r,!0,o)}}throw Error("Unsupported decorator location: "+n)};function Ye(r){return(e,t)=>typeof t=="object"?c5(r,e,t):((n,s,i)=>{const a=s.hasOwnProperty(i);return s.constructor.createProperty(i,n),a?Object.getOwnPropertyDescriptor(s,i):void 0})(r,e,t)}function Kt(r){return Ye({...r,state:!0,attribute:!1})}const X1=(r,e,t)=>{const n=new Map;for(let s=e;s<=t;s++)n.set(r[s],s);return n},U0=Ac(class extends qh{constructor(r){if(super(r),r.type!==ri.CHILD)throw Error("repeat() can only be used in text expressions")}dt(r,e,t){let n;t===void 0?t=e:e!==void 0&&(n=e);const s=[],i=[];let a=0;for(const o of r)s[a]=n?n(o,a):a,i[a]=t(o,a),a++;return{values:i,keys:s}}render(r,e,t){return this.dt(r,e,t).values}update(r,[e,t,n]){const s=J3(r),{values:i,keys:a}=this.dt(e,t,n);if(!Array.isArray(s))return this.ut=a,i;const o=this.ut??=[],l=[];let c,h,u=0,f=s.length-1,d=0,m=i.length-1;for(;u<=f&&d<=m;)if(s[u]===null)u++;else if(s[f]===null)f--;else if(o[u]===a[d])l[d]=va(s[u],i[d]),u++,d++;else if(o[f]===a[m])l[m]=va(s[f],i[m]),f--,m--;else if(o[u]===a[m])l[m]=va(s[u],i[m]),hl(r,l[m+1],s[u]),u++,m--;else if(o[f]===a[d])l[d]=va(s[f],i[d]),hl(r,s[u],s[f]),f--,d++;else if(c===void 0&&(c=X1(a,d,m),h=X1(o,u,f)),c.has(o[u]))if(c.has(o[f])){const p=h.get(a[d]),v=p!==void 0?s[p]:null;if(v===null){const g=hl(r,s[u]);va(g,i[d]),l[d]=g}else l[d]=va(v,i[d]),hl(r,s[u],v),s[p]=null;d++}else Hu(s[f]),f--;else Hu(s[u]),u++;for(;d<=m;){const p=hl(r,l[m+1]);va(p,i[d]),l[d++]=p}for(;u<=f;){const p=s[u++];p!==null&&Hu(p)}return this.ut=a,Xb(r,l),ws}});var h5=Object.defineProperty,u5=Object.getOwnPropertyDescriptor,Lr=(r,e,t,n)=>{for(var s=n>1?void 0:n?u5(e,t):e,i=r.length-1,a;i>=0;i--)(a=r[i])&&(s=(n?a(e,t,s):a(s))||s);return n&&s&&h5(e,t,s),s};const Yb="pipane-pinned-sessions";function d5(){try{const r=localStorage.getItem(Yb);if(r)return new Set(JSON.parse(r))}catch{}return new Set}function K1(r){try{localStorage.setItem(Yb,JSON.stringify([...r]))}catch{}}let Ar=class extends Qr{constructor(){super(...arguments),this.sessionsPerProject=5,this.sessions=[],this.loading=!0,this.showSkeleton=!1,this.searchQuery="",this.expandedGroups=new Set,this.pinnedSessions=d5(),this.showFolderPicker=!1,this.folderPath="~",this.folderDirs=[],this.folderLoading=!1,this.newFolderInputVisible=!1,this.newFolderName="",this.folderCreating=!1,this.folderError="",this._fetchInFlight=!1,this._fetchDirty=!1,this._sessionsChangedDebounceTimer=null,this._skeletonGraceTimer=null}connectedCallback(){super.connectedCallback(),this.prefetchedSessions?(this.sessions=this.prefetchedSessions,this.loading=!1,this.prefetchedSessions=void 0):(this._skeletonGraceTimer=setTimeout(()=>{this.loading&&(this.showSkeleton=!0)},300),this.refreshSessions()),this.agent&&(this._lastObservedSessionStatus=this.agent.sessionStatus,this.unsubSessionChange=this.agent.onSessionChange(()=>{this.mergeOptimisticSessions(),this.requestUpdate(),this.refreshSessions()}),this.unsubSessionsChanged=this.agent.onSessionsChanged(()=>{this.mergeOptimisticSessions(),this.debouncedRefreshSessions()}),this.unsubGlobalStatus=this.agent.onGlobalStatusChange(()=>{this.requestUpdate()}),this.unsubWorkspaceChange=this.agent.onWorkspaceChange?.(()=>{this.requestUpdate(),this.refreshSessions()}),this.unsubStatusChange=this.agent.onStatusChange(()=>{const r=this._lastObservedSessionStatus,e=this.agent.sessionStatus;this._lastObservedSessionStatus=e,e==="attached"&&r!=="attached"&&this.clearSearchFilter()}))}disconnectedCallback(){super.disconnectedCallback(),this.unsubSessionChange?.(),this.unsubSessionsChanged?.(),this.unsubGlobalStatus?.(),this.unsubStatusChange?.(),this.unsubWorkspaceChange?.(),this._sessionsChangedDebounceTimer&&(clearTimeout(this._sessionsChangedDebounceTimer),this._sessionsChangedDebounceTimer=null),this._skeletonGraceTimer&&(clearTimeout(this._skeletonGraceTimer),this._skeletonGraceTimer=null)}mergeOptimisticSessions(){const r=this.agent.optimisticSessions,e=this.agent.virtualSessionInfo,t=[...r];if(e&&t.push(e),t.length===0)return;let n=this.sessions.filter(a=>!a.path.startsWith("__virtual__"));const s=new Set(n.map(a=>this.sessionKey(a)));let i=n.length!==this.sessions.length;for(const a of t){const o=this.sessionKey(a);if(s.has(o)){if(a.cwd){const l=n.find(c=>this.sessionKey(c)===o);l&&!l.cwd&&(l.cwd=a.cwd,i=!0)}}else n=[...n,a],s.add(o),i=!0}i&&(this.sessions=n,this.requestUpdate())}debouncedRefreshSessions(){this._sessionsChangedDebounceTimer&&clearTimeout(this._sessionsChangedDebounceTimer),this._sessionsChangedDebounceTimer=setTimeout(()=>{this._sessionsChangedDebounceTimer=null,this.refreshSessions()},500)}async refreshSessions(){if(this._fetchInFlight){this._fetchDirty=!0;return}this._fetchInFlight=!0,this.sessions.length===0&&(this.loading=!0);try{this.sessions=await this.agent.listSessions()}catch(e){console.error("Failed to load sessions:",e),this.sessions=[]}this.loading=!1,this.showSkeleton=!1,this._skeletonGraceTimer&&(clearTimeout(this._skeletonGraceTimer),this._skeletonGraceTimer=null),this._fetchInFlight=!1,this._fetchDirty&&(this._fetchDirty=!1,this.refreshSessions())}get knownCwds(){const r=new Set;for(const e of this.sessions)e.cwd&&(!this.folderBackendId||e.backendId===this.folderBackendId)&&r.add(e.cwd);return Array.from(r).sort()}sessionKey(r){return r.backendId?`${r.backendId}\0${r.path}`:r.path}groupKey(r,e){return r?`${r}\0${e}`:e}get filteredGroups(){const r=this.searchQuery.toLowerCase().trim();let e=this.sessions;if(r){const s=new Map((this.agent.workspaceBackends??[]).map(i=>[i.backendId,i.name??i.backendId]));e=e.filter(i=>i.name?.toLowerCase().includes(r)||i.firstMessage.toLowerCase().includes(r)||i.cwd.toLowerCase().includes(r)||(i.cwdDisplay?.toLowerCase().includes(r)??!1)||(i.worktreeName??"root").toLowerCase().includes(r)||(i.backendId?s.get(i.backendId)?.toLowerCase().includes(r):!1))}const t=new Map;for(const s of e){const i=s.cwd||"(unknown)",a=this.groupKey(s.backendId,i);t.has(a)||t.set(a,[]),t.get(a).push(s)}const n=[];for(const[s,i]of t){const a=i[0]?.cwd||"(unknown)",o=i[0]?.backendId,l=i[0]?.cwdDisplay||a,c=o&&l.split("/").filter(Boolean).pop()||l;n.push({key:s,backendId:o,cwd:a,displayCwd:l,label:c,sessions:i})}for(const s of n)s.sessions.sort((i,a)=>{const o=this.agent.getSessionStatus(i.path,i.backendId)==="running",l=this.agent.getSessionStatus(a.path,a.backendId)==="running";if(o&&l){const d=this.getSessionDisplayName(i),m=this.getSessionDisplayName(a);return d.localeCompare(m,void 0,{sensitivity:"base"})}if(o)return-1;if(l)return 1;const c=this.pinnedSessions.has(this.sessionKey(i)),h=this.pinnedSessions.has(this.sessionKey(a));if(c&&!h)return-1;if(!c&&h)return 1;const u=i.lastUserPromptTime?new Date(i.lastUserPromptTime).getTime():new Date(i.modified).getTime();return(a.lastUserPromptTime?new Date(a.lastUserPromptTime).getTime():new Date(a.modified).getTime())-u});return n.sort((s,i)=>{const a=l=>{let c=0;for(const h of l.sessions){if(this.agent.getSessionStatus(h.path,h.backendId)==="running")return 1/0;const u=h.lastUserPromptTime?new Date(h.lastUserPromptTime).getTime():new Date(h.modified).getTime();c=Math.max(c,u)}return c},o=a(i)-a(s);return o===0?s.label.localeCompare(i.label,void 0,{sensitivity:"base"}):o}),n}get workspaceHosts(){return(this.agent.workspaceBackends??[]).map(r=>({backendId:r.backendId,name:r.name||`${r.backendId.slice(0,12)}…`,connected:r.connected,reconnecting:r.reconnecting,online:r.online,compatible:r.protocolVersions.includes(N1),error:r.error}))}backendDisplayName(r){return r?this.agent.workspaceBackends?.find(t=>t.backendId===r)?.name||`${r.slice(0,12)}…`:void 0}getSessionDisplayName(r){if(r.name)return r.name;const e=r.firstMessage;return!e||e==="(no messages)"?"New session":e.length>100?e.slice(0,100)+"…":e}formatTime(r){const e=new Date(r),n=new Date().getTime()-e.getTime(),s=Math.floor(n/6e4),i=Math.floor(n/36e5),a=Math.floor(n/864e5);return s<1?"just now":s<60?`${s}m ago`:i<24?`${i}h ago`:a<7?`${a}d ago`:e.toLocaleDateString()}async handleSessionClick(r){if(!(r.id===this.agent?.sessionId&&(!r.backendId||r.backendId===this.agent.activeBackendId))&&!r.path.startsWith("__virtual__")){this.clearSearchFilter(),this.expandedGroups.size>0&&(this.expandedGroups=new Set);try{r.backendId?await this.agent.switchSession(r.path,r.cwd,r.backendId):await this.agent.switchSession(r.path,r.cwd)}catch(e){console.error("Failed to switch session:",e)}}}async handleNewSessionInGroup(r,e){this.clearSearchFilter();try{e?await this.agent.newSession(r,e):await this.agent.newSession(r)}catch(t){console.error("Failed to create new session:",t)}}handleTogglePin(r,e){r.stopPropagation(),r.preventDefault();const t=new Set(this.pinnedSessions),n=this.sessionKey(e);t.has(n)?t.delete(n):t.add(n),this.pinnedSessions=t,K1(t)}async handleDeleteSession(r,e){if(r.stopPropagation(),r.preventDefault(),e.path.startsWith("__virtual__")){e.backendId?this.agent.newSession(void 0,e.backendId):this.agent.newSession();return}const t=e.id===this.agent?.sessionId&&(!e.backendId||e.backendId===this.agent.activeBackendId),n=e.name||e.firstMessage||"this session";if(!confirm(`Delete "${n.slice(0,60)}"?`))return;const s=this.sessionKey(e);if(this.sessions=this.sessions.filter(i=>this.sessionKey(i)!==s),this.pinnedSessions.has(s)){const i=new Set(this.pinnedSessions);i.delete(s),this.pinnedSessions=i,K1(i)}t&&(e.backendId?this.agent.newSession(void 0,e.backendId):this.agent.newSession());try{e.backendId?await this.agent.deleteSession(e.path,e.backendId):await this.agent.deleteSession(e.path)}catch(i){console.error("Failed to delete session:",i),await this.refreshSessions()}}handleSearch(r){this.searchQuery=r.target.value}clearSearchFilter(){this.searchQuery&&(this.searchQuery="")}openFolderPicker(r=this.agent.activeBackendId){this.showFolderPicker=!0,this.folderBackendId=r,this.folderPath="~",this.resetNewFolderInput(),this.folderError="",this.browseTo("~")}handleFolderBackendChange(r){this.folderBackendId=r.currentTarget.value,this.folderPath="~",this.browseTo("~")}closeFolderPicker(){this.showFolderPicker=!1,this.resetNewFolderInput(),this.folderError=""}async browseTo(r){this.folderLoading=!0,this.resetNewFolderInput(),this.folderError="";try{const e=this.folderBackendId?await this.agent.browseDirectory(r,this.folderBackendId):await this.agent.browseDirectory(r);this.folderPath=e.path,this.folderDirs=e.dirs}catch(e){console.error("Failed to browse directory:",e),this.folderDirs=[],this.folderError=e instanceof Error?e.message:"Could not open this folder"}this.folderLoading=!1}beginNewFolder(){this.newFolderInputVisible=!0,this.newFolderName="",this.folderError="",this.updateComplete.then(()=>{this.shadowRoot?.querySelector(".new-folder-row input")?.focus()})}resetNewFolderInput(){this.newFolderInputVisible=!1,this.newFolderName=""}handleNewFolderInput(r){this.newFolderName=r.target.value}handleNewFolderKeydown(r){r.key==="Enter"?(r.preventDefault(),this.handleCreateFolder()):r.key==="Escape"&&this.resetNewFolderInput()}async handleCreateFolder(){const r=this.newFolderName.trim();if(!(!r||this.folderCreating)){this.folderCreating=!0,this.folderError="";try{const e=this.folderBackendId?await this.agent.createDirectory(this.folderPath,r,this.folderBackendId):await this.agent.createDirectory(this.folderPath,r);await this.browseTo(e.path)}catch(e){console.error("Failed to create directory:",e),this.folderError=e instanceof Error?e.message:"Could not create this folder"}finally{this.folderCreating=!1}}}handleFolderInputChange(r){this.folderPath=r.target.value}handleFolderInputKeydown(r){r.key==="Enter"&&this.browseTo(this.folderPath)}handleFolderClick(r){this.folderPath=r.path,this.browseTo(r.path)}handleFolderSelect(){this.showFolderPicker=!1,this.clearSearchFilter(),this.folderBackendId?this.agent.newSession(this.folderPath,this.folderBackendId):this.agent.newSession(this.folderPath)}handleParentFolder(){const r=this.folderPath.replace(/\/[^/]+\/?$/,"")||"/";this.folderPath=r,this.browseTo(r)}render(){const r=this.filteredGroups,e=this.workspaceHosts,t=this.agent?.sessionId,n=this.agent.workspaceBackends!==void 0,s=e.length>1;return fe`
4
4
  <div style="position: relative; height: 100%; display: flex; flex-direction: column;">
@@ -1 +1 @@
1
- import{B as c,e as f,i as w,d as m}from"./backend-protocol-BvNAsFvb.js";import{l as y}from"./device-identity-C_w2NbSk.js";import{R as g}from"./rendezvous-trust-api-Bv6fZVJA.js";import{W as v}from"./webrtc-frame-transport-Drpqhhdy.js";import{W as k}from"./ws-agent-adapter-BUykBiJL.js";import"./__vite-browser-external-DGfF_P2w.js";import"./index-CG96lus1.js";const A=3e4,E=10*6e4;class B extends Error{constructor(e){super(e.message),this.payload=e,this.name="DataChannelBackendApiError"}}class q{constructor(e,t,r=A){this.transport=e,this.backendId=t,this.requestTimeoutMs=r,this.requestId=0,this.pending=new Map,e.onFrame(i=>this.handleFrame(i)),e.onConnectionChange(({connected:i,reconnected:o})=>{if(!(!i||!o))for(const d of this.pending.values())try{this.transport.send(d.encodedFrame)}catch{}})}async getCapabilities(){const e=await this.request("backend.capabilities",{});if(!a(e)||e.backendId!==this.backendId||e.semanticProtocolVersion!==c||!S(e.applicationProtocolVersions)||!l(e.features))throw new Error("Backend returned invalid capabilities");return e}async listSessions(){const e=await this.request("sessions.list",{});if(!Array.isArray(e)||!e.every(T))throw new Error("Backend returned an invalid session list");return e.map(t=>({...t,backendId:this.backendId}))}async deleteSession(e){await this.request("sessions.delete",{sessionPath:e})}async listForkMessages(e){const t=await this.request("sessions.forkMessages",{sessionPath:e});if(!Array.isArray(t)||!t.every(r=>a(r)&&s(r.entryId)&&s(r.text)))throw new Error("Backend returned invalid fork messages");return t}async browseDirectory(e){const t=await this.request("host.browse",{path:e});if(!a(t)||!s(t.path)||!Array.isArray(t.dirs)||!t.dirs.every(r=>a(r)&&s(r.name)&&s(r.path)))throw new Error("Backend returned an invalid directory listing");return t}async createDirectory(e,t){const r=await this.request("host.mkdir",{parentPath:e,name:t});if(!a(r)||!s(r.name)||!s(r.path))throw new Error("Backend returned an invalid created folder");return r}async getRawSession(e){const t=await this.request("sessions.raw",{sessionPath:e});if(!s(t))throw new Error("Backend returned invalid raw session content");return t}async getFileContent(e,t){const r=await this.request("files.read",{sessionPath:e,path:t});if(!a(r)||!s(r.path)||!s(r.content))throw new Error("Backend returned invalid file content");return r}async createFileUpload(e){const t=await this.request("files.upload.create",e);if(!a(t)||!s(t.uploadId)||t.uploadId.length===0)throw new Error("Backend returned an invalid file upload session");return t}async appendFileUpload(e){const t=await this.request("files.upload.append",e);if(!a(t)||!Number.isSafeInteger(t.nextOffset)||t.nextOffset<0)throw new Error("Backend returned an invalid file upload offset");return t}async completeFileUpload(e){const t=await this.request("files.upload.complete",{uploadId:e});if(!a(t)||!s(t.path)||!s(t.fileName)||!s(t.mimeType)||!Number.isSafeInteger(t.size)||t.size<0)throw new Error("Backend returned an invalid uploaded file");return t}async getLocalSettings(){const e=await this.request("settings.get",{});if(!a(e)||!s(e.path)||typeof e.exists!="boolean"||!l(e.errors)||!s(e.formatted)||!("settings"in e))throw new Error("Backend returned invalid local settings");return e}validateLocalSettings(e){return this.settingsMutation("settings.validate",{content:e})}patchLocalSettings(e){return this.settingsMutation("settings.patch",{patch:e})}saveLocalSettings(e){return this.settingsMutation("settings.save",{content:e})}async getUpdates(){const e=await this.request("updates.get",{});if(!a(e)||!s(e.checkedAt)||!Array.isArray(e.notices))throw new Error("Backend returned an invalid update snapshot");return e}async runUpdate(e){const t=await this.request("updates.run",{target:e},E);if(!a(t)||!a(t.result)||!a(t.snapshot))throw new Error("Backend returned an invalid update result");return t}async settingsMutation(e,t){const r=await this.request(e,t);if(!a(r)||typeof r.valid!="boolean"||!l(r.errors)||r.formatted!==void 0&&!s(r.formatted))throw new Error("Backend returned an invalid settings response");return r}request(e,t,r=this.requestTimeoutMs){if(!this.transport.isConnected)return Promise.reject(new Error("Backend transport is not connected"));const i=`api_${++this.requestId}_${crypto.randomUUID()}`;return new Promise((o,d)=>{const h=f({v:c,kind:"request",id:i,method:e,params:t}),p=setTimeout(()=>{this.pending.delete(i),d(new Error(`Backend request timed out: ${e}`))},r);this.pending.set(i,{method:e,encodedFrame:h,resolve:o,reject:d,timer:p});try{this.transport.send(h)}catch(u){clearTimeout(p),this.pending.delete(i),d(u instanceof Error?u:new Error(String(u)))}})}handleFrame(e){if(!w(e))return;const t=m(e);if(!t.ok)return;const r=t.value,i=this.pending.get(r.id);if(i){if(clearTimeout(i.timer),this.pending.delete(r.id),r.method!==i.method){i.reject(new Error(`Backend response method mismatch: expected ${i.method}, received ${r.method}`));return}r.success?i.resolve(r.result):i.reject(new B(r.error))}}}function T(n){return a(n)&&s(n.id)&&s(n.path)&&s(n.cwd)&&s(n.created)&&s(n.modified)&&Number.isSafeInteger(n.messageCount)&&s(n.firstMessage)}function a(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function s(n){return typeof n=="string"}function l(n){return Array.isArray(n)&&n.every(s)}function S(n){return Array.isArray(n)&&n.every(e=>Number.isSafeInteger(e)&&e>0)}class R{constructor(e,t={loadIdentity:()=>y(),createTrustApi:()=>new g(e)}){this.rendezvousUrl=e,this.dependencies=t,this.descriptors=[],this.clients=new Map}async initialize(){return this.identity??=await this.dependencies.loadIdentity(),this.trustApi??=this.dependencies.createTrustApi(),this.descriptors=await this.trustApi.listAuthorizedBackends(this.identity),this.authorizedBackends}get authorizedBackends(){return this.descriptors.map(e=>({...e,protocolVersions:[...e.protocolVersions]}))}getClient(e){const t=this.clients.get(e);if(t)return t;if(!this.identity||!this.trustApi)throw new Error("Remote backend manager is not initialized");const r=this.descriptors.find(o=>o.backendId===e);if(!r)throw new Error("This browser is not authorized for the requested backend");if(r.online&&!r.protocolVersions.includes(c))throw new Error(`Backend does not support semantic protocol v${c}`);const i=this.dependencies.createClient?this.dependencies.createClient(e,this.identity,this.trustApi):this.createClient(e,this.identity,this.trustApi);return this.clients.set(e,i),i}async revokeBackend(e){if(!this.identity||!this.trustApi)throw new Error("Remote backend manager is not initialized");await this.trustApi.revokeBackend(this.identity,e),this.clients.get(e)?.disconnect(),this.clients.delete(e),this.descriptors=this.descriptors.filter(t=>t.backendId!==e)}disconnectAll(){for(const e of this.clients.values())e.disconnect();this.clients.clear()}createClient(e,t,r){const i=new v({rendezvousUrl:this.rendezvousUrl,backendId:e,deviceIdentity:t,authorize:()=>r.createConnectionTicket(t,e)}),o=new q(i,e);return new k({transport:i,api:o})}}export{R as RemoteBackendManager};
1
+ import{B as c,e as f,i as w,d as m}from"./backend-protocol-BvNAsFvb.js";import{l as y}from"./device-identity-C_w2NbSk.js";import{R as g}from"./rendezvous-trust-api-Bv6fZVJA.js";import{W as v}from"./webrtc-frame-transport-Drpqhhdy.js";import{W as k}from"./ws-agent-adapter-C7ujmNSC.js";import"./__vite-browser-external-DGfF_P2w.js";import"./index-BNFbdYPt.js";const A=3e4,E=10*6e4;class B extends Error{constructor(e){super(e.message),this.payload=e,this.name="DataChannelBackendApiError"}}class q{constructor(e,t,r=A){this.transport=e,this.backendId=t,this.requestTimeoutMs=r,this.requestId=0,this.pending=new Map,e.onFrame(i=>this.handleFrame(i)),e.onConnectionChange(({connected:i,reconnected:o})=>{if(!(!i||!o))for(const d of this.pending.values())try{this.transport.send(d.encodedFrame)}catch{}})}async getCapabilities(){const e=await this.request("backend.capabilities",{});if(!a(e)||e.backendId!==this.backendId||e.semanticProtocolVersion!==c||!S(e.applicationProtocolVersions)||!l(e.features))throw new Error("Backend returned invalid capabilities");return e}async listSessions(){const e=await this.request("sessions.list",{});if(!Array.isArray(e)||!e.every(T))throw new Error("Backend returned an invalid session list");return e.map(t=>({...t,backendId:this.backendId}))}async deleteSession(e){await this.request("sessions.delete",{sessionPath:e})}async listForkMessages(e){const t=await this.request("sessions.forkMessages",{sessionPath:e});if(!Array.isArray(t)||!t.every(r=>a(r)&&s(r.entryId)&&s(r.text)))throw new Error("Backend returned invalid fork messages");return t}async browseDirectory(e){const t=await this.request("host.browse",{path:e});if(!a(t)||!s(t.path)||!Array.isArray(t.dirs)||!t.dirs.every(r=>a(r)&&s(r.name)&&s(r.path)))throw new Error("Backend returned an invalid directory listing");return t}async createDirectory(e,t){const r=await this.request("host.mkdir",{parentPath:e,name:t});if(!a(r)||!s(r.name)||!s(r.path))throw new Error("Backend returned an invalid created folder");return r}async getRawSession(e){const t=await this.request("sessions.raw",{sessionPath:e});if(!s(t))throw new Error("Backend returned invalid raw session content");return t}async getFileContent(e,t){const r=await this.request("files.read",{sessionPath:e,path:t});if(!a(r)||!s(r.path)||!s(r.content))throw new Error("Backend returned invalid file content");return r}async createFileUpload(e){const t=await this.request("files.upload.create",e);if(!a(t)||!s(t.uploadId)||t.uploadId.length===0)throw new Error("Backend returned an invalid file upload session");return t}async appendFileUpload(e){const t=await this.request("files.upload.append",e);if(!a(t)||!Number.isSafeInteger(t.nextOffset)||t.nextOffset<0)throw new Error("Backend returned an invalid file upload offset");return t}async completeFileUpload(e){const t=await this.request("files.upload.complete",{uploadId:e});if(!a(t)||!s(t.path)||!s(t.fileName)||!s(t.mimeType)||!Number.isSafeInteger(t.size)||t.size<0)throw new Error("Backend returned an invalid uploaded file");return t}async getLocalSettings(){const e=await this.request("settings.get",{});if(!a(e)||!s(e.path)||typeof e.exists!="boolean"||!l(e.errors)||!s(e.formatted)||!("settings"in e))throw new Error("Backend returned invalid local settings");return e}validateLocalSettings(e){return this.settingsMutation("settings.validate",{content:e})}patchLocalSettings(e){return this.settingsMutation("settings.patch",{patch:e})}saveLocalSettings(e){return this.settingsMutation("settings.save",{content:e})}async getUpdates(){const e=await this.request("updates.get",{});if(!a(e)||!s(e.checkedAt)||!Array.isArray(e.notices))throw new Error("Backend returned an invalid update snapshot");return e}async runUpdate(e){const t=await this.request("updates.run",{target:e},E);if(!a(t)||!a(t.result)||!a(t.snapshot))throw new Error("Backend returned an invalid update result");return t}async settingsMutation(e,t){const r=await this.request(e,t);if(!a(r)||typeof r.valid!="boolean"||!l(r.errors)||r.formatted!==void 0&&!s(r.formatted))throw new Error("Backend returned an invalid settings response");return r}request(e,t,r=this.requestTimeoutMs){if(!this.transport.isConnected)return Promise.reject(new Error("Backend transport is not connected"));const i=`api_${++this.requestId}_${crypto.randomUUID()}`;return new Promise((o,d)=>{const h=f({v:c,kind:"request",id:i,method:e,params:t}),p=setTimeout(()=>{this.pending.delete(i),d(new Error(`Backend request timed out: ${e}`))},r);this.pending.set(i,{method:e,encodedFrame:h,resolve:o,reject:d,timer:p});try{this.transport.send(h)}catch(u){clearTimeout(p),this.pending.delete(i),d(u instanceof Error?u:new Error(String(u)))}})}handleFrame(e){if(!w(e))return;const t=m(e);if(!t.ok)return;const r=t.value,i=this.pending.get(r.id);if(i){if(clearTimeout(i.timer),this.pending.delete(r.id),r.method!==i.method){i.reject(new Error(`Backend response method mismatch: expected ${i.method}, received ${r.method}`));return}r.success?i.resolve(r.result):i.reject(new B(r.error))}}}function T(n){return a(n)&&s(n.id)&&s(n.path)&&s(n.cwd)&&s(n.created)&&s(n.modified)&&Number.isSafeInteger(n.messageCount)&&s(n.firstMessage)}function a(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function s(n){return typeof n=="string"}function l(n){return Array.isArray(n)&&n.every(s)}function S(n){return Array.isArray(n)&&n.every(e=>Number.isSafeInteger(e)&&e>0)}class R{constructor(e,t={loadIdentity:()=>y(),createTrustApi:()=>new g(e)}){this.rendezvousUrl=e,this.dependencies=t,this.descriptors=[],this.clients=new Map}async initialize(){return this.identity??=await this.dependencies.loadIdentity(),this.trustApi??=this.dependencies.createTrustApi(),this.descriptors=await this.trustApi.listAuthorizedBackends(this.identity),this.authorizedBackends}get authorizedBackends(){return this.descriptors.map(e=>({...e,protocolVersions:[...e.protocolVersions]}))}getClient(e){const t=this.clients.get(e);if(t)return t;if(!this.identity||!this.trustApi)throw new Error("Remote backend manager is not initialized");const r=this.descriptors.find(o=>o.backendId===e);if(!r)throw new Error("This browser is not authorized for the requested backend");if(r.online&&!r.protocolVersions.includes(c))throw new Error(`Backend does not support semantic protocol v${c}`);const i=this.dependencies.createClient?this.dependencies.createClient(e,this.identity,this.trustApi):this.createClient(e,this.identity,this.trustApi);return this.clients.set(e,i),i}async revokeBackend(e){if(!this.identity||!this.trustApi)throw new Error("Remote backend manager is not initialized");await this.trustApi.revokeBackend(this.identity,e),this.clients.get(e)?.disconnect(),this.clients.delete(e),this.descriptors=this.descriptors.filter(t=>t.backendId!==e)}disconnectAll(){for(const e of this.clients.values())e.disconnect();this.clients.clear()}createClient(e,t,r){const i=new v({rendezvousUrl:this.rendezvousUrl,backendId:e,deviceIdentity:t,authorize:()=>r.createConnectionTicket(t,e)}),o=new q(i,e);return new k({transport:i,api:o})}}export{R as RemoteBackendManager};
@@ -0,0 +1,6 @@
1
+ import{_ as ie}from"./index-BNFbdYPt.js";import{i as oe}from"./backend-protocol-BvNAsFvb.js";import{D as ae}from"./__vite-browser-external-DGfF_P2w.js";function re(i){const e=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],s=(S,f)=>S>>>f|S<<32-f,t=new TextEncoder().encode(i),n=t.length*8,o=new Uint8Array(Math.ceil((t.length+9)/64)*64);o.set(t),o[t.length]=128;const a=new DataView(o.buffer);a.setUint32(o.length-4,n,!1),n>4294967295&&a.setUint32(o.length-8,Math.floor(n/4294967296),!1);let[r,l,d,_,v,y,w,c]=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];const g=new Int32Array(64);for(let S=0;S<o.length;S+=64){for(let u=0;u<16;u++)g[u]=a.getInt32(S+u*4,!1);for(let u=16;u<64;u++){const q=s(g[u-15],7)^s(g[u-15],18)^g[u-15]>>>3,Q=s(g[u-2],17)^s(g[u-2],19)^g[u-2]>>>10;g[u]=g[u-16]+q+g[u-7]+Q|0}let[f,P,L,N,$,T,F,U]=[r,l,d,_,v,y,w,c];for(let u=0;u<64;u++){const q=s($,6)^s($,11)^s($,25),Q=$&T^~$&F,V=U+q+Q+e[u]+g[u]|0,se=s(f,2)^s(f,13)^s(f,22),te=f&P^f&L^P&L,ne=se+te|0;U=F,F=T,T=$,$=N+V|0,N=L,L=P,P=f,f=V+ne|0}r=r+f|0,l=l+P|0,d=d+L|0,_=_+N|0,v=v+$|0,y=y+T|0,w=w+F|0,c=c+U|0}return[r,l,d,_,v,y,w,c].map(S=>(S>>>0).toString(16).padStart(8,"0")).join("")}async function ce(i){if(typeof globalThis.crypto?.subtle?.digest=="function"){const e=new TextEncoder().encode(i),s=await globalThis.crypto.subtle.digest("SHA-256",e),t=new Uint8Array(s);return Array.from(t).map(n=>n.toString(16).padStart(2,"0")).join("")}if(typeof globalThis.process<"u"){const{createHash:e}=await ie(async()=>{const{createHash:s}=await import("./__vite-browser-external-DGfF_P2w.js").then(t=>t._);return{createHash:s}},[]);return e("sha256").update(i,"utf8").digest("hex")}return re(i)}function he(i,e){let s=i;for(const t of e)s=s.slice(0,t.offset)+t.insert+s.slice(t.offset+t.deleteCount);return s}async function le(i,e,s){if(s.length===0)return{data:i,hash:e};let t=i,n=e,o;for(const r of s){if(o=r,r.op==="full"){t=r.data,n=r.hash;continue}if(r.baseHash!==n)return console.warn("[jsonl-sync] Base hash mismatch, need full sync",{expected:r.baseHash,actual:n}),null;t=he(t,r.patches),n=r.hash}const a=await ce(t);if(a!==n){const r=o?.op==="full"?"[jsonl-sync] Full sync hash mismatch":"[jsonl-sync] Post-patch hash mismatch";return console.error(r,{expected:n,actual:a}),null}return{data:t,hash:n}}const ue=10*6e4,de=ue+9e4,D=1;class J extends Error{constructor(e,s,t){super(`${s}: ${t}`),this.code=e}}function p(i,e,s="invalid_message"){throw new J(s,i,e)}function K(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function m(i,e){return K(i)||p(e,"expected an object"),i}function h(i,e,s=!0){return(typeof i!="string"||!s&&i.length===0)&&p(e,s?"expected a string":"expected a non-empty string"),i}function k(i,e){return i===void 0?void 0:h(i,e)}function b(i,e){return typeof i!="boolean"&&p(e,"expected a boolean"),i}function C(i,e){return(!Number.isSafeInteger(i)||i<0)&&p(e,"expected a non-negative safe integer"),i}function R(i,e){return(typeof i!="number"||!Number.isFinite(i))&&p(e,"expected a finite number"),i}function A(i,e){return Array.isArray(i)||p(e,"expected an array"),i}function H(i,e){return A(i,e).map((s,t)=>h(s,`${e}[${t}]`))}function O(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))h(n,`${e}.${t}`);return s}function Y(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))n!=="running"&&n!=="done"&&p(`${e}.${t}`,"expected 'running' or 'done'");return s}function ge(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))H(n,`${e}.${t}`);return s}function B(i,e){return["off","minimal","low","medium","high","xhigh","max"].includes(String(i))||p(e,"expected a supported thinking level"),i}function pe(i,e){const s=m(i,e);return h(s.provider,`${e}.provider`,!1),h(s.modelId,`${e}.modelId`,!1),s}function W(i,e){const s=m(i,e);h(s.provider,`${e}.provider`,!1);const t=k(s.id,`${e}.id`),n=k(s.modelId,`${e}.modelId`);return!t&&!n&&p(e,"expected id or modelId"),s}function me(i,e){if(i.protocolVersion!==D){const s=i.protocolVersion===void 0?"missing":JSON.stringify(i.protocolVersion);p(`${e}.protocolVersion`,`unsupported protocol version ${s}; expected ${D}`,"unsupported_version")}}function X(i){try{return{ok:!0,value:JSON.parse(i)}}catch(e){return{ok:!1,error:{code:"invalid_json",message:`Invalid JSON: ${e instanceof Error?e.message:String(e)}`,requestId:null,command:"parse"}}}}function Z(i,e,s){const t=K(i)?i:void 0,n=typeof t?.id=="string"?t.id:null,o=typeof t?.type=="string"?t.type:s,a=e instanceof J?e:new J("invalid_message","$",e instanceof Error?e.message:String(e));return{ok:!1,error:{code:a.code,message:a.message,requestId:n,command:o}}}function fe(i,e){A(i,e).forEach((s,t)=>{const n=m(s,`${e}[${t}]`);h(n.name,`${e}[${t}].name`,!1),k(n.description,`${e}[${t}].description`),["extension","prompt","skill"].includes(String(n.source))||p(`${e}[${t}].source`,"expected extension, prompt, or skill"),n.sourceInfo!==void 0&&m(n.sourceInfo,`${e}[${t}].sourceInfo`),k(n.location,`${e}[${t}].location`),k(n.path,`${e}[${t}].path`)})}function _e(i,e){const s=m(i,e);h(s.sessionFile,`${e}.sessionFile`,!1),h(s.sessionId,`${e}.sessionId`,!1);for(const n of["userMessages","assistantMessages","toolCalls","toolResults","totalMessages"])C(s[n],`${e}.${n}`);const t=m(s.tokens,`${e}.tokens`);for(const n of["input","output","cacheRead","cacheWrite","total"])C(t[n],`${e}.tokens.${n}`);if(R(s.cost,`${e}.cost`)<0&&p(`${e}.cost`,"expected a non-negative number"),s.contextUsage!==void 0){const n=m(s.contextUsage,`${e}.contextUsage`);n.tokens!==null&&C(n.tokens,`${e}.contextUsage.tokens`),C(n.contextWindow,`${e}.contextUsage.contextWindow`),n.percent!==null&&R(n.percent,`${e}.contextUsage.percent`)<0&&p(`${e}.contextUsage.percent`,"expected a non-negative number or null")}}function Se(i,e,s){const t=m(e,s);switch(i){case"install_pi":case"subscribe_session":case"steer":case"remove_steering":case"abort":case"set_session_name":break;case"prompt":case"fork_prompt":h(t.newSessionPath,`${s}.newSessionPath`,!1);break;case"hard_kill":b(t.killed,`${s}.killed`),t.reason!==void 0&&t.reason!=="signal_failed"&&t.reason!=="not_attached"&&p(`${s}.reason`,"expected signal_failed or not_attached");break;case"compact":break;case"get_available_models":A(t.models,`${s}.models`).forEach((n,o)=>W(n,`${s}.models[${o}]`));break;case"get_default_model":t.model!==null&&W(t.model,`${s}.model`),B(t.thinkingLevel,`${s}.thinkingLevel`);break;case"get_session_statuses":Y(t.statuses,`${s}.statuses`);break;case"get_session_stats":_e(t,s);break;case"fork":h(t.text,`${s}.text`),b(t.cancelled,`${s}.cancelled`),t.newSessionPath!==null&&h(t.newSessionPath,`${s}.newSessionPath`,!1);break;case"get_commands":fe(t.commands,`${s}.commands`);break;case"reload_processes":C(t.killed,`${s}.killed`),C(t.draining,`${s}.draining`);break}}const ve=new Set(["install_pi","subscribe_session","prompt","steer","remove_steering","abort","hard_kill","compact","get_available_models","get_default_model","get_session_statuses","get_session_stats","fork","fork_prompt","set_session_name","get_commands","reload_processes"]);function ye(i,e){const s=h(i,e,!1);return ve.has(s)||p(e,`unknown response command '${s}'`,"unknown_message"),s}function we(i,e){A(i,e).forEach((s,t)=>{const n=m(s,`${e}[${t}]`);C(n.offset,`${e}[${t}].offset`),C(n.deleteCount,`${e}[${t}].deleteCount`),h(n.insert,`${e}[${t}].insert`)})}function Ce(i){const e=X(i);if(!e.ok)return e;const s=e.value;try{const t=m(s,"$message");me(t,"$message");const n=h(t.type,"$message.type",!1);switch(n){case"response":{if(b(t.success,"$message.success")){h(t.id,"$message.id",!1);const a=ye(t.command,"$message.command");Se(a,t.data,"$message.data")}else t.id!==null&&h(t.id,"$message.id",!1),h(t.command,"$message.command",!1),h(t.error,"$message.error",!1),["invalid_json","invalid_message","unsupported_version","unknown_command","unknown_message","command_failed"].includes(String(t.code))||p("$message.code","expected a protocol error code");break}case"init":Y(t.sessionStatuses,"$message.sessionStatuses"),ge(t.steeringQueues,"$message.steeringQueues"),O(t.providerUsageStatuses,"$message.providerUsageStatuses");break;case"pi_install_required":h(t.command,"$message.command",!1),b(t.installable,"$message.installable"),b(t.installing,"$message.installing"),h(t.message,"$message.message",!1);break;case"session_status_change":h(t.sessionPath,"$message.sessionPath",!1),t.status!=="running"&&t.status!=="done"&&p("$message.status","expected running or done");break;case"provider_usage":O(t.statuses,"$message.statuses");break;case"extension_status":h(t.sessionPath,"$message.sessionPath",!1),O(t.statuses,"$message.statuses");break;case"session_sync":h(t.sessionPath,"$message.sessionPath",!1),C(t.revision,"$message.revision"),h(t.hash,"$message.hash",!1),t.op==="full"?h(t.data,"$message.data"):t.op==="delta"?(h(t.baseHash,"$message.baseHash",!1),we(t.patches,"$message.patches")):p("$message.op","expected full or delta");break;case"control_state":h(t.sessionPath,"$message.sessionPath",!1),t.controlRevision!==void 0&&C(t.controlRevision,"$message.controlRevision"),W(t.model,"$message.model"),B(t.thinkingLevel,"$message.thinkingLevel");break;case"session_attached":h(t.sessionPath,"$message.sessionPath",!1),k(t.cwd,"$message.cwd"),k(t.firstMessage,"$message.firstMessage");break;case"sessions_changed":h(t.file,"$message.file");break;default:p("$message.type",`unknown server message '${n}'`,"unknown_message")}return{ok:!0,value:t}}catch(t){return Z(s,t,"unknown")}}function Pe(i){const e=X(i);if(!e.ok)return e;const s=e.value;try{const t=m(s,"$session");A(t.messages,"$session.messages").forEach((o,a)=>{const r=m(o,`$session.messages[${a}]`);h(r.role,`$session.messages[${a}].role`,!1)}),b(t.isStreaming,"$session.isStreaming"),H(t.pendingToolCalls,"$session.pendingToolCalls");const n=m(t.toolCallTimings,"$session.toolCallTimings");for(const[o,a]of Object.entries(n)){const r=m(a,`$session.toolCallTimings.${o}`);R(r.startedAt,`$session.toolCallTimings.${o}.startedAt`),r.completedAt!==void 0&&R(r.completedAt,`$session.toolCallTimings.${o}.completedAt`)}return t.model!==null&&pe(t.model,"$session.model"),B(t.thinkingLevel,"$session.thinkingLevel"),H(t.steeringQueue,"$session.steeringQueue"),k(t.error,"$session.error"),{ok:!0,value:t}}catch(t){return Z(s,t,"session_sync")}}function $e(i,e){return JSON.stringify({protocolVersion:D,id:e,...i})}function ke(i){throw new Error(`Unhandled protocol variant: ${JSON.stringify(i)}`)}const x=["off","minimal","low","medium","high","xhigh","max"];function E(i){return i?.id??i?.modelId}function j(i,e){const s=E(i),t=E(e);return!!i&&!!e&&!!s&&!!t&&i.provider===e.provider&&s===t}function I(i){const e=E(i);if(!(!i.provider||!e))return{provider:i.provider,modelId:e}}function be(i){if(!i)return!1;if(typeof i.reasoning=="boolean")return i.reasoning;if(i.thinkingLevelMap)return!0;const e=String(i.provider??"").toLowerCase(),s=String(E(i)??"").toLowerCase();return!!(e==="openai-codex"||e==="openai"&&s.startsWith("gpt-5"))}function Le(i){if(!be(i))return["off"];const e=i?.thinkingLevelMap;return x.filter(s=>{const t=e?.[s];return t===null?!1:s==="xhigh"||s==="max"?t!==void 0:!0})}function G(i,e){const s=Le(i);if(s.includes(e))return e;const t=x.indexOf(e);if(t===-1)return s[0]??"off";for(let n=t;n<x.length;n++){const o=x[n];if(s.includes(o))return o}for(let n=t-1;n>=0;n--){const o=x[n];if(s.includes(o))return o}return s[0]??"off"}class xe extends Error{constructor(e,s,t){super(e),this.status=s,this.details=t,this.name="BackendApiError"}}class Ae{constructor(e={}){this.fetch=e.fetch??globalThis.fetch.bind(globalThis)}listSessions(){return this.requestJson("/api/sessions")}async deleteSession(e){await this.requestJson("/api/sessions",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})})}async listForkMessages(e){return(await this.requestJson(`/api/sessions/fork-messages?path=${encodeURIComponent(e)}`)).messages??[]}browseDirectory(e){return this.requestJson(`/api/browse?path=${encodeURIComponent(e)}`)}createDirectory(e,s){return this.requestJson("/api/directories",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentPath:e,name:s})})}async getRawSession(e){const s=await this.fetch(`/api/sessions/raw?path=${encodeURIComponent(e)}`);if(!s.ok)throw await this.toError(s,"Failed to load raw session");return s.text()}getFileContent(e,s){const t=new URLSearchParams({sessionPath:e,path:s});return this.requestJson(`/api/files/content?${t}`,{cache:"no-store"})}createFileUpload(e){return this.requestJson("/api/files/uploads",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}appendFileUpload(e){return this.requestJson(`/api/files/uploads/${encodeURIComponent(e.uploadId)}/chunks`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offset:e.offset,data:e.data})})}completeFileUpload(e){return this.requestJson(`/api/files/uploads/${encodeURIComponent(e)}/complete`,{method:"POST"})}getLocalSettings(){return this.requestJson("/api/settings/local")}validateLocalSettings(e){return this.requestValidation("/api/settings/local/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e})})}patchLocalSettings(e){return this.requestValidation("/api/settings/local",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}saveLocalSettings(e){return this.requestValidation("/api/settings/local",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e})})}getUpdates(){return this.requestJson("/api/updates",{cache:"no-store"})}runUpdate(e){return this.requestJson(`/api/updates/${e}`,{method:"POST",headers:{"X-Pipane-Action":"update"}})}async requestValidation(e,s){const t=await this.fetch(e,s),n=await this.readJson(t);if(!t.ok&&typeof n?.valid!="boolean")throw this.errorFromPayload(t,n,"Settings request failed");return n}async requestJson(e,s){const t=s?await this.fetch(e,s):await this.fetch(e),n=await this.readJson(t);if(!t.ok)throw this.errorFromPayload(t,n,`Backend request failed (${t.status})`);return n}async readJson(e){return e.json().catch(()=>({}))}async toError(e,s){const t=await this.readJson(e);return this.errorFromPayload(e,t,s)}errorFromPayload(e,s,t){const n=Array.isArray(s?.errors)?s.errors.filter(a=>typeof a=="string"):[],o=typeof s?.error=="string"?s.error:n.length>0?n.join(`
2
+ `):t;return new xe(o,e.status,s)}}const ee=[{name:"help",description:"Show this help",source:"builtin"},{name:"new",description:"Start a new session",source:"builtin"},{name:"session",description:"Show session file, messages, tokens, and cost",source:"builtin"},{name:"fork",description:"Fork session from a previous message",source:"builtin"},{name:"compact",description:"Compact conversation history",source:"builtin",argumentHint:"[instructions]",acceptsArguments:!0},{name:"name",description:"Set session display name",source:"builtin",argumentHint:"<name>",acceptsArguments:!0},{name:"reload",description:"Restart all pooled pi RPC processes",source:"builtin"}];function qe(i){const e=ee.map(t=>({...t})),s=new Set(e.map(t=>t.name.toLocaleLowerCase()));for(const t of i){const n=t.name.toLocaleLowerCase();s.has(n)||(s.add(n),e.push({name:t.name,description:t.description??"",source:t.source,acceptsArguments:!0}))}return e}function Te(i,e){const s=i.toLocaleLowerCase(),t=e.toLocaleLowerCase();if(!t)return 0;if(s===t)return 1e5;let n=s.startsWith(t)?5e4:0,o=0,a=-2,r=-1;for(const l of t){const d=s.indexOf(l,o);if(d===-1)return;r===-1&&(r=d);const _=d>0?s[d-1]:"";d===0||_==="-"||_===":"||_==="_"?n+=18:n+=4,d===a+1&&(n+=12),a=d,o=d+1}return n-=r*3,n-=s.length-t.length,n}function Qe(i,e){return i.map((s,t)=>({command:s,index:t,score:Te(s.name,e)})).filter(s=>s.score!==void 0).sort((s,t)=>t.score-s.score||s.index-t.index).map(s=>s.command)}function Oe(i){switch(i){case"builtin":return"Built-in";case"extension":return"Extension";case"prompt":return"Prompt";case"skill":return"Skill"}}const z=1,Fe=1e4;class Ie{constructor(e={}){this.socket=null,this.reconnecting=!1,this.reconnectAttempt=0,this.manuallyClosed=!1,this.decoder=new ae,this.frameListeners=new Set,this.connectionListeners=new Set,this.createWebSocket=e.createWebSocket??(s=>new WebSocket(s)),this.schedule=e.schedule??globalThis.setTimeout.bind(globalThis),this.cancelSchedule=e.cancelSchedule??globalThis.clearTimeout.bind(globalThis),e.socket&&(this.socket=e.socket,this.attachFrameHandler(e.socket))}get isConnected(){return this.socket?.readyState===z}get isReconnecting(){return this.reconnecting}onFrame(e){return this.frameListeners.add(e),()=>this.frameListeners.delete(e)}onConnectionChange(e){return this.connectionListeners.add(e),()=>this.connectionListeners.delete(e)}async connect(e){this.isConnected||(this.endpoint=e,this.manuallyClosed=!1,await this.openSocket(!1))}send(e){if(!this.socket||this.socket.readyState!==z)throw new Error("Backend transport is not connected");this.socket.send(e)}close(e=1e3,s="Client closed"){this.manuallyClosed=!0,this.reconnecting=!1,this.reconnectTimer&&(this.cancelSchedule(this.reconnectTimer),this.reconnectTimer=void 0),this.decoder.reset(),this.socket?.close(e,s)}attachFrameHandler(e){e.onmessage=s=>{try{const t=this.decoder.accept(String(s.data));if(t===void 0)return;for(const n of this.frameListeners)n(t)}catch{e.close(1002,"Invalid carrier frame")}}}emitConnectionChange(e){for(const s of this.connectionListeners)s(e)}openSocket(e){const s=this.endpoint;return s?new Promise((t,n)=>{const o=this.createWebSocket(s);let a=!1,r=!1;this.socket=o,this.attachFrameHandler(o),o.onopen=()=>{this.socket===o&&(a=!0,r=!0,this.reconnecting=!1,this.reconnectAttempt=0,this.emitConnectionChange({connected:!0,reconnected:e}),t())},o.onerror=()=>{!e&&!r&&(r=!0,n(new Error("WebSocket connection failed")))},o.onclose=()=>{if(this.socket===o&&(this.socket=null),this.decoder.reset(),r||(r=!0,n(new Error("WebSocket closed before connecting"))),this.manuallyClosed){a&&this.emitConnectionChange({connected:!1,reconnected:!1});return}(a||e)&&(this.scheduleReconnect(),a&&this.emitConnectionChange({connected:!1,reconnected:!1}))}}):Promise.reject(new Error("Backend transport endpoint is missing"))}scheduleReconnect(){if(this.reconnectTimer||this.manuallyClosed)return;this.reconnecting=!0,this.reconnectAttempt++;const e=Math.min(500*2**(this.reconnectAttempt-1),Fe);this.reconnectTimer=this.schedule(()=>{this.reconnectTimer=void 0,this.openSocket(!0).catch(()=>{})},e)}}const Me="provider-usage";function Re(i){const e=typeof i?.provider=="string"?i.provider.toLowerCase():"";if(e.includes("codex"))return"codex";if(e.includes("anthropic"))return"anthropic"}class je{constructor(e={}){this.sessionsChangedListeners=new Set,this.piInstallRequiredListeners=new Set,this.pendingRequests=new Map,this.requestId=0,this._connectionListeners=new Set,this._state={model:void 0,thinkingLevel:"off",messages:[],isStreaming:!1,error:void 0},this._pendingToolCallIds=new Set,this._toolCallTimings={},this._steeringQueues=new Map,this._compactionQueues=new Map,this._compactingSessions=new Set,this._steeringQueueListeners=new Set,this._extensionStatuses=new Map,this._providerUsageStatuses=new Map,this._extensionStatusListeners=new Set,this._controlRevision=0,this._availableModels=null,this._sessionId="",this._sessionStatus="virtual",this._sessionSubscriptionActive=!0,this._localAssistantMessages=[],this._optimisticSessions=new Map,this._globalSessionStatus=new Map,this._globalStatusListeners=new Set,this._sessionNonce=0,this._pendingNewPrompt=!1,this._startingPrompts=new Map,this._syncJson="",this._syncHash="",this._pendingSessionSyncs=[],this._sessionSyncFlushScheduled=!1,this._sessionSyncFlushInProgress=!1,this._sessionListeners=new Set,this._contentListeners=new Set,this._statusListeners=new Set,this.transport=e.transport??new Ie({socket:e.socket,createWebSocket:e.createWebSocket}),this.api=e.api??new Ae({fetch:e.fetch}),this.requestFrame=e.requestFrame??(s=>requestAnimationFrame(s)),this.transport.onFrame(s=>this.handleMessage(s)),this.transport.onConnectionChange(s=>this.handleTransportConnectionChange(s.connected,s.reconnected))}get state(){return this._state}get sessionId(){return this._sessionId}get sessionFile(){return this._sessionPath}get sessionName(){return this._sessionName}get sessionStatus(){return this._sessionStatus}get isConnected(){return this.transport.isConnected}get isReconnecting(){return this.transport.isReconnecting}onConnectionChange(e){return this._connectionListeners.add(e),()=>this._connectionListeners.delete(e)}emitConnectionChange(e){for(const s of this._connectionListeners)s(e)}get pendingToolCallIds(){return this._pendingToolCallIds}get toolCallTimings(){return this._toolCallTimings}get steeringQueue(){if(!this._sessionPath)return[];const e=this._steeringQueues.get(this._sessionPath)??[],s=this._compactionQueues.get(this._sessionPath)??[];return s.length===0?e:[...e,...s.map(t=>t.text)]}get extensionStatuses(){const e=new Map(this._extensionStatuses),s=Re(this._state.model),t=s?this._providerUsageStatuses.get(s):this._providerUsageStatuses.size===1?this._providerUsageStatuses.values().next().value:void 0;return t&&e.set(Me,t),e}onExtensionStatusChange(e){return this._extensionStatusListeners.add(e),()=>this._extensionStatusListeners.delete(e)}replaceExtensionStatuses(e){const s=new Map;if(e&&typeof e=="object"&&!Array.isArray(e))for(const[t,n]of Object.entries(e))typeof n=="string"&&s.set(t,n);if(!(s.size===this._extensionStatuses.size&&[...s].every(([t,n])=>this._extensionStatuses.get(t)===n))){this._extensionStatuses=s;for(const t of this._extensionStatusListeners)t()}}replaceProviderUsageStatuses(e){const s=new Map;if(e&&typeof e=="object"&&!Array.isArray(e))for(const[t,n]of Object.entries(e))typeof n=="string"&&s.set(t,n);if(!(s.size===this._providerUsageStatuses.size&&[...s].every(([t,n])=>this._providerUsageStatuses.get(t)===n))){this._providerUsageStatuses=s;for(const t of this._extensionStatusListeners)t()}}clearExtensionStatuses(){this.replaceExtensionStatuses({})}getSessionStatus(e){return this._globalSessionStatus.get(e)}onGlobalStatusChange(e){return this._globalStatusListeners.add(e),()=>this._globalStatusListeners.delete(e)}emitGlobalStatusChange(){for(const e of this._globalStatusListeners)e()}setGlobalSessionStatus(e,s){this._globalSessionStatus.set(e,s),s==="running"&&this._startingPrompts.get(e)?.resolveReady(e),this.emitGlobalStatusChange()}setAllSessionStatuses(e){this._globalSessionStatus.clear();for(const[s,t]of Object.entries(e))this._globalSessionStatus.set(s,t);this.emitGlobalStatusChange()}onSteeringQueueChange(e){return this._steeringQueueListeners.add(e),()=>this._steeringQueueListeners.delete(e)}emitSteeringQueueChange(){for(const e of this._steeringQueueListeners)e()}enqueueSteering(e,s){const t=this._steeringQueues.get(e)??[];this._steeringQueues.set(e,[...t,s]),this.emitSteeringQueueChange()}enqueueCompactionPrompt(e,s,t){const n=I(this._state.model);if(!n)throw new Error("BUG: active model has no provider/model ID");const o=this._compactionQueues.get(e)??[];this._compactionQueues.set(e,[...o,{text:s,images:t,model:n,thinkingLevel:this._state.thinkingLevel,controlRevision:this._pendingControl?.revision??this._controlRevision}]),this.emitSteeringQueueChange()}flushCompactionQueue(e){const s=this._compactionQueues.get(e);if(!s?.length)return;this._compactionQueues.delete(e),this.emitSteeringQueueChange();const t=s.map(n=>this.send({type:"prompt",sessionPath:e,message:n.text,model:n.model,thinkingLevel:n.thinkingLevel,controlRevision:n.controlRevision,images:n.images}));Promise.allSettled(t).then(n=>{const o=s.filter((r,l)=>n[l]?.status==="rejected");if(o.length===0)return;const a=this._compactionQueues.get(e)??[];this._compactionQueues.set(e,[...o,...a]),this.emitSteeringQueueChange()})}onSessionChange(e){return this._sessionListeners.add(e),()=>this._sessionListeners.delete(e)}emitSessionChange(){for(const e of this._sessionListeners)e()}onContentChange(e){return this._contentListeners.add(e),()=>this._contentListeners.delete(e)}emitContentChange(){for(const e of this._contentListeners)e()}onStatusChange(e){return this._statusListeners.add(e),()=>this._statusListeners.delete(e)}emitStatusChange(){for(const e of this._statusListeners)e()}onSessionsChanged(e){return this.sessionsChangedListeners.add(e),()=>this.sessionsChangedListeners.delete(e)}onPiInstallRequired(e){return this.piInstallRequiredListeners.add(e),()=>this.piInstallRequiredListeners.delete(e)}emitPiInstallRequired(e){for(const s of this.piInstallRequiredListeners)s(e)}toErrorMessage(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}reportError(e,s="Request failed"){const t=this.toErrorMessage(e);this._state.error=t,this._state.messages=[...this._state.messages,{role:"assistant",content:[{type:"text",text:`⚠️ ${s}: ${t}`}],timestamp:Date.now()}],this.emitStatusChange(),this.emitContentChange()}async connect(e){await this.transport.connect(e),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this.syncStateOnFocus()})}disconnect(){this.transport.close()}async setSessionSubscriptionActive(e){if(e!==this._sessionSubscriptionActive){if(this._sessionSubscriptionActive=e,this._sessionNonce++,this._awaitingFullSync=void 0,this.clearSessionSyncQueue(),!e){await this.subscribeToSession(void 0);return}this._sessionPath&&this._sessionStatus!=="virtual"&&await this.requestFullSessionSync(this._sessionPath)}}getConnectionDiagnostics(){return this.transport.getConnectionDiagnostics?.()??Promise.resolve(void 0)}handleTransportConnectionChange(e,s){e?s?this.onReconnected():this._sessionStatus="virtual":this.handleTransportDisconnected(),this.emitConnectionChange(e)}handleTransportDisconnected(){for(const e of this.pendingRequests.values())e.reject(new Error("Backend transport disconnected"));this.pendingRequests.clear(),this._pendingControl?.phase==="sent"?this.rollbackSentControl(this._pendingControl.revision):this._pendingControl?.phase==="acknowledged"&&(this._pendingControl=void 0)}async onReconnected(){this._sessionSubscriptionActive&&this._sessionPath&&this._sessionStatus!=="virtual"&&(this._awaitingFullSync=void 0,this.requestFullSessionSync(this._sessionPath)),this.refreshSessionStatuses()}async syncStateOnFocus(){this.refreshSessionStatuses(),this._sessionSubscriptionActive&&this._sessionPath&&this._sessionStatus!=="virtual"&&this.subscribeToSession(this._sessionPath),this._sessionStatus==="detached"&&this._state.isStreaming&&(console.log("[ws-adapter] Tab regained focus: clearing stale streaming state"),this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this.emitStatusChange())}async refreshSessionStatuses(){try{const e=await this.send({type:"get_session_statuses"});e?.statuses&&this.setAllSessionStatuses(e.statuses)}catch(e){console.error("Failed to refresh session statuses:",e)}}async subscribeToSession(e){try{await this.send({type:"subscribe_session",sessionPath:e??""})}catch(s){console.error("Failed to subscribe to session:",s)}}async requestFullSessionSync(e){const s={sessionPath:e,sessionNonce:this._sessionNonce};this._awaitingFullSync?.sessionPath===s.sessionPath&&this._awaitingFullSync.sessionNonce===s.sessionNonce||(this._awaitingFullSync=s,this._syncJson="",this._syncHash="",this._syncRevision=void 0,this.clearSessionSyncQueue(),await this.subscribeToSession(e))}handleProtocolError(e){const s=`Protocol error: ${e.message}`;console.error(`[ws-adapter] ${s}`),this._state.error=s,this.emitStatusChange(),e.code==="unsupported_version"&&this.transport.close(1002,"Unsupported protocol version")}handleMessage(e){if(oe(e))return;const s=Ce(e);if(!s.ok){this.handleProtocolError(s.error);return}const t=s.value;switch(t.type){case"response":{if(!t.success&&t.id===null){this._state.error=t.error,this.emitStatusChange();return}if(t.id===null)return;const n=this.pendingRequests.get(t.id);if(!n)return;if(this.pendingRequests.delete(t.id),t.command!==n.command){n.reject(new Error(`Mismatched response for ${n.command}: received ${t.command}`));return}t.success?n.resolve(t.data):(this._state.error=t.error,this.emitStatusChange(),n.reject(new Error(t.error)));return}case"pi_install_required":this.emitPiInstallRequired({command:t.command,installable:t.installable,installing:t.installing,message:t.message});return;case"init":this.setAllSessionStatuses(t.sessionStatuses),this.replaceProviderUsageStatuses(t.providerUsageStatuses),this._steeringQueues.clear();for(const[n,o]of Object.entries(t.steeringQueues))o.length>0&&this._steeringQueues.set(n,[...o]);this.emitSteeringQueueChange();return;case"session_status_change":this.setGlobalSessionStatus(t.sessionPath,t.status);return;case"provider_usage":this.replaceProviderUsageStatuses(t.statuses);return;case"extension_status":t.sessionPath===this._sessionPath&&this.replaceExtensionStatuses(t.statuses);return;case"session_sync":if(t.sessionPath!==this._sessionPath)return;this.enqueueSessionSync({...t,__sessionPath:t.sessionPath,__sessionNonce:this._sessionNonce});return;case"control_state":{if(t.sessionPath!==this._sessionPath)return;this.applyAuthoritativeControlState(t.model,t.thinkingLevel,t.controlRevision)&&this.emitContentChange();return}case"session_attached":{this.setGlobalSessionStatus(t.sessionPath,"running"),t.cwd&&(this._pendingCwd=t.cwd);const n=t.sessionPath===this._sessionPath||this._sessionStatus==="virtual"&&this._pendingNewPrompt;if(n){if(this._sessionStatus==="virtual"){this._sessionPath=t.sessionPath;const a=M.basename(t.sessionPath,".jsonl"),r=a.split("_");this._sessionId=r.length>1?r.slice(1).join("_"):a,this._startingPrompts.get(`virtual:${this._sessionNonce}`)?.resolveReady(t.sessionPath)}this._sessionStatus="attached",this._state.isStreaming=!0,this.requestFullSessionSync(t.sessionPath),this.emitStatusChange()}if(!this._optimisticSessions.has(t.sessionPath)){const o=new Date().toISOString(),a=M.basename(t.sessionPath,".jsonl"),r=a.split("_"),l=r.length>1?r.slice(1).join("_"):a;this._optimisticSessions.set(t.sessionPath,{id:l,path:t.sessionPath,cwd:t.cwd??"",created:o,modified:o,lastUserPromptTime:o,messageCount:1,firstMessage:t.firstMessage??"(new session)"})}n&&this.emitSessionChange();return}case"sessions_changed":for(const n of this.sessionsChangedListeners)n(t.file);return;default:ke(t)}}enqueueSessionSync(e){const s=this._awaitingFullSync!==void 0&&this._awaitingFullSync.sessionPath===e.__sessionPath&&this._awaitingFullSync.sessionNonce===e.__sessionNonce;if(e.op==="full")s&&(this._awaitingFullSync=void 0),this._pendingSessionSyncs=[e];else{if(s)return;this._pendingSessionSyncs.push(e)}this._sessionSyncFlushScheduled||this._sessionSyncFlushInProgress||(this._sessionSyncFlushScheduled=!0,this.requestFrame(()=>{this._sessionSyncFlushScheduled=!1,this.flushSessionSyncQueue()}))}clearSessionSyncQueue(){this._pendingSessionSyncs=[],this._sessionSyncFlushScheduled=!1}async flushSessionSyncQueue(){if(this._sessionSyncFlushInProgress)return;this._sessionSyncFlushInProgress=!0;const e=this._pendingSessionSyncs.splice(0);try{const s=await this.applySessionSyncBatch(e);s&&this.emitSessionSyncChanges(s)}finally{this._sessionSyncFlushInProgress=!1,this._pendingSessionSyncs.length>0&&!this._sessionSyncFlushScheduled&&(this._sessionSyncFlushScheduled=!0,this.requestFrame(()=>{this._sessionSyncFlushScheduled=!1,this.flushSessionSyncQueue()}))}}emitSessionSyncChanges(e){e.steering&&this.emitSteeringQueueChange(),e.content&&this.emitContentChange(),e.status&&this.emitStatusChange()}async applySessionSyncBatch(e){const s=this._sessionPath,t=this._sessionNonce;if(!s||e.length===0||e.some(c=>c.__sessionPath!==s||c.__sessionNonce!==t))return;let n=this._syncRevision;for(const c of e){if(c.op==="full"){n=c.revision;continue}if(n===void 0||c.revision!==n+1){console.error("[ws-adapter] Session revision gap, re-subscribing",{expected:n===void 0?"full snapshot":n+1,actual:c.revision}),this.requestFullSessionSync(s);return}n=c.revision}const o=e.map(c=>c.op==="full"?{op:"full",data:c.data,hash:c.hash}:{op:"delta",patches:c.patches,hash:c.hash,baseHash:c.baseHash});if(o[0]?.op==="delta"&&!this._syncHash){console.warn("[ws-adapter] Ignoring delta while awaiting full sync");return}const a=await le(this._syncJson,this._syncHash,o);if(s!==this._sessionPath||t!==this._sessionNonce)return;if(!a){console.error("[ws-adapter] Sync verification failed, re-subscribing"),this.requestFullSessionSync(s);return}const r=Pe(a.data);if(!r.ok){this.handleProtocolError(r.error);return}const l=r.value;this._syncJson=a.data,this._syncHash=a.hash,this._syncRevision=n;const d=this._state.isStreaming,_=this._sessionStatus,v=this._state.error,y=[...this._steeringQueues.get(s)??[]];this._state.messages=[...l.messages??[],...this._localAssistantMessages],this._state.isStreaming=l.isStreaming??!1,this._sessionStatus!=="virtual"&&(this._sessionStatus=this._state.isStreaming?"attached":"detached"),this._pendingToolCallIds=new Set(l.pendingToolCalls??[]),this._toolCallTimings=l.toolCallTimings??{},this.applyAuthoritativeControlState(l.model,l.thinkingLevel),Array.isArray(l.steeringQueue)&&(l.steeringQueue.length>0?this._steeringQueues.set(s,[...l.steeringQueue]):this._steeringQueues.delete(s)),this._state.error=l.error||void 0;const w=this._steeringQueues.get(s)??[];return{content:!0,status:d!==this._state.isStreaming||_!==this._sessionStatus||v!==this._state.error,steering:y.length!==w.length||y.some((c,g)=>c!==w[g])}}send(e){if(!this.transport.isConnected)return Promise.reject(new Error("Backend transport is not connected"));const s=`req_${++this.requestId}`;return new Promise((t,n)=>{const o=e.type==="compact"?de:e.type==="prompt"||e.type==="fork_prompt"?9e4:3e4,a=setTimeout(()=>{this.pendingRequests.delete(s),n(new Error(`Timeout waiting for response to ${e.type}`))},o);this.pendingRequests.set(s,{command:e.type,resolve:r=>{clearTimeout(a),t(r)},reject:r=>{clearTimeout(a),n(r)}}),this.transport.send($e(e,s))})}async fetchAvailableModels(){const s=(await this.send({type:"get_available_models"}))?.models??[];this._availableModels=s;const t=this.resolveModel(this._state.model);return t&&(this._state.model=t),s}resolveModel(e){if(!e)return;const s=this._availableModels?.find(n=>j(n,e));if(s)return s;const t=I(e);if(t)return{...e,provider:t.provider,id:t.modelId}}markControlPending(){const e=++this._controlRevision;return this._pendingControl={revision:e,sessionNonce:this._sessionNonce,phase:"local"},e}markControlSent(e){this._pendingControl?.revision===e&&this._pendingControl.sessionNonce===this._sessionNonce&&(this._pendingControl.phase="sent")}rollbackSentControl(e){const s=this._pendingControl;if(!s||s.revision!==e||s.phase!=="sent")return;this._pendingControl=void 0;const t=this._lastAuthoritativeControl;t?.sessionNonce===this._sessionNonce&&(this._state.model=t.model,this._state.thinkingLevel=t.thinkingLevel,this.emitContentChange())}rememberAuthoritativeControl(e,s){this._lastAuthoritativeControl={sessionNonce:this._sessionNonce,model:e,thinkingLevel:s}}applyAuthoritativeControlState(e,s,t){const n=this.resolveModel(e),o=s,a=this._pendingControl;if(t!==void 0){if(a){if(a.sessionNonce!==this._sessionNonce||a.revision!==t)return!1;a.phase="acknowledged",a.model=n,a.thinkingLevel=o}return n&&(this._state.model=n),o&&(this._state.thinkingLevel=o),n&&o&&this.rememberAuthoritativeControl(n,o),!!n||!!o}if(a){if(!(a.phase==="acknowledged"&&!!a.model&&j(e,a.model)&&o===a.thinkingLevel))return!1;this._pendingControl=void 0}return n&&(this._state.model=n),o&&(this._state.thinkingLevel=o),n&&o&&this.rememberAuthoritativeControl(n,o),!!n||!!o}async installPi(){await this.send({type:"install_pi"})}async loadDefaultModel(){if(this._state.model)return;const e=await this.send({type:"get_default_model"});this.applyAuthoritativeControlState(e?.model,e?.thinkingLevel)}setCwd(e){this._pendingCwd=e}get cwd(){return this._pendingCwd}createStartingPrompt(e){let s,t;const n={ready:new Promise(o=>{s=o}),resolveReady:o=>s(o),finished:new Promise(o=>{t=o}),resolveFinished:()=>t()};return this._startingPrompts.set(e,n),n}finishStartingPrompt(e,s,t){s.resolveReady(t),s.resolveFinished(),this._startingPrompts.get(e)===s&&this._startingPrompts.delete(e)}async prompt(e,s){let t;if(typeof e=="string"?t=e:Array.isArray(e)?t=e.map(c=>this.extractText(c)).join(`
3
+ `):t=this.extractText(e),this.clearLocalAssistantMessages(),await this.handleSlashCommand(t))return;if(this._sessionPath&&this._compactingSessions.has(this._sessionPath)){this.enqueueCompactionPrompt(this._sessionPath,t,s);return}const o=this._sessionStatus==="virtual"?`virtual:${this._sessionNonce}`:this._sessionPath,a=o?this._startingPrompts.get(o):void 0;if(a){const c=await a.ready;if(c&&this._globalSessionStatus.get(c)==="running"){this.enqueueSteering(c,t),await this.send({type:"steer",sessionPath:c,message:t});return}if(await a.finished,!c)throw new Error("The session failed to start before the queued prompt could be sent");return this.prompt(e,s)}if((this._sessionPath?this._globalSessionStatus.get(this._sessionPath)==="running":!1)&&this._sessionPath){this.enqueueSteering(this._sessionPath,t),await this.send({type:"steer",sessionPath:this._sessionPath,message:t});return}const l=this._state.model;if(!l)throw new Error(`BUG: effective model is undefined when sending prompt. sessionStatus=${this._sessionStatus}, sessionPath=${this._sessionPath}`);const d=I(l);if(!d)throw new Error("BUG: active model has no provider/model ID");const _=this._state.thinkingLevel,v=this._pendingControl?.revision??this._controlRevision;this.markControlSent(v);const y=o??`virtual:${this._sessionNonce}`,w=this.createStartingPrompt(y);if(this._sessionStatus==="virtual"){const c=this._sessionNonce;this._pendingNewPrompt=!0;try{const g=await this.send({type:"prompt",sessionPath:"__new__",cwd:this._pendingCwd,message:t,model:d,thinkingLevel:_,controlRevision:v,images:s});if(this._sessionNonce!==c){console.log("[ws-adapter] Discarding stale prompt response (session changed during await)");return}const S=g?.newSessionPath;if(S&&!this._sessionPath){this._sessionPath=S;const f=M.basename(S,".jsonl"),P=f.split("_");this._sessionId=P.length>1?P.slice(1).join("_"):f,this._sessionStatus="attached",this.requestFullSessionSync(S),this.emitSessionChange(),this.emitStatusChange()}}catch(g){throw this.rollbackSentControl(v),g}finally{this._pendingNewPrompt=!1;const g=this._sessionNonce===c?this._sessionPath:void 0;this.finishStartingPrompt(y,w,g)}return}if(!this._sessionPath)throw new Error("No session loaded");try{await this.send({type:"prompt",sessionPath:this._sessionPath,message:t,model:d,thinkingLevel:_,controlRevision:v,images:s})}catch(c){throw this.rollbackSentControl(v),c}finally{this.finishStartingPrompt(y,w,this._sessionPath)}}extractText(e){if("content"in e){if(typeof e.content=="string")return e.content;if(Array.isArray(e.content))return e.content.filter(s=>s.type==="text").map(s=>s.text).join(`
4
+ `)}return""}async fetchCommands(){try{const e=this._sessionPath?{sessionPath:this._sessionPath}:{cwd:this._pendingCwd};return(await this.send({type:"get_commands",...e}))?.commands??[]}catch{return[]}}clearLocalAssistantMessages(){if(this._localAssistantMessages.length===0)return;const e=new Set(this._localAssistantMessages);this._localAssistantMessages=[],this._state.messages=this._state.messages.filter(s=>!e.has(s)),this.emitContentChange()}appendLocalAssistantMessage(e){const s={role:"assistant",content:[{type:"text",text:e}]};this._localAssistantMessages.push(s),this._state.messages=[...this._state.messages,s],this.emitContentChange()}formatSessionStats(e){const s=o=>o.toLocaleString("en-US"),t=`$${e.cost.toFixed(e.cost<.01?4:e.cost<1?3:2)}`,n=["**Session information**","",`- **File:** \`${e.sessionFile}\``,`- **ID:** \`${e.sessionId}\``,`- **Messages:** ${s(e.totalMessages)} total (${s(e.userMessages)} user, ${s(e.assistantMessages)} assistant)`,`- **Tools:** ${s(e.toolCalls)} calls, ${s(e.toolResults)} results`,`- **Tokens:** ${s(e.tokens.total)} total (${s(e.tokens.input)} input, ${s(e.tokens.output)} output, ${s(e.tokens.cacheRead)} cache read, ${s(e.tokens.cacheWrite)} cache write)`,`- **Cost:** ${t}`];if(e.contextUsage){const o=e.contextUsage.tokens===null?`unknown / ${s(e.contextUsage.contextWindow)}`:`${s(e.contextUsage.tokens)} / ${s(e.contextUsage.contextWindow)}${e.contextUsage.percent===null?"":` (${e.contextUsage.percent}%)`}`;n.push(`- **Context:** ${o}`)}return n.join(`
5
+ `)}async showSessionMessage(){if(!this._sessionPath){this.appendLocalAssistantMessage("No active session yet. Send a message first to create one.");return}const e=await this.send({type:"get_session_stats",sessionPath:this._sessionPath});this.appendLocalAssistantMessage(this.formatSessionStats(e))}async showHelpMessage(){const e=["**Built-in commands:**","","| Command | Description |","|---------|-------------|",...ee.map(a=>{const r=a.argumentHint?` ${a.argumentHint}`:"";return`| \`/${a.name}${r}\` | ${a.description} |`})],s=await this.fetchCommands(),t=s.filter(a=>a.source==="extension"),n=s.filter(a=>a.source==="prompt"),o=s.filter(a=>a.source==="skill");if(t.length>0){e.push("","**Extension commands:**","","| Command | Description |","|---------|-------------|");for(const a of t)e.push(`| \`/${a.name}\` | ${a.description||""} |`)}if(n.length>0){e.push("","**Prompt templates:**","","| Command | Description |","|---------|-------------|");for(const a of n){const r=a.location?` *(${a.location})*`:"";e.push(`| \`/${a.name}\` | ${a.description||""}${r} |`)}}if(o.length>0){e.push("","**Skills:**","","| Command | Description |","|---------|-------------|");for(const a of o){const r=a.location?` *(${a.location})*`:"";e.push(`| \`/${a.name}\` | ${a.description||""}${r} |`)}}e.push("","**Keyboard shortcuts:**","","| Shortcut | Action |","|----------|--------|","| `Enter` | Send message (also works during streaming to steer) |","| `Cmd+Enter` | Fork session and send message in the fork |","| `Shift+Enter` | New line |","| `Escape` | Abort current turn |"),this.appendLocalAssistantMessage(e.join(`
6
+ `))}async handleSlashCommand(e){const s=e.trim();if(!s.startsWith("/"))return!1;if(s==="/help")return await this.showHelpMessage(),!0;if(s==="/new")return await this.newSession(),!0;if(s==="/session")return await this.showSessionMessage(),!0;if(s==="/fork")return window.dispatchEvent(new CustomEvent("pi-fork-request")),!0;if(s==="/compact"||s.startsWith("/compact ")){if(!this._sessionPath)return!0;const t=this._sessionPath,n=s.startsWith("/compact ")?s.slice(9).trim():void 0,o={role:"compactionSummary",summary:"",tokensBefore:0,timestamp:Date.now(),_compacting:!0};this._compactingSessions.add(t),this._state.isStreaming=!0,this._state.messages=[...this._state.messages,o],this.emitStatusChange(),this.emitContentChange();try{await this.send({type:"compact",sessionPath:t,customInstructions:n}),this._sessionPath===t&&await this.subscribeToSession(t)}catch(a){throw this._state.messages=this._state.messages.filter(r=>r!==o),this.emitContentChange(),a}finally{this._compactingSessions.delete(t),this._sessionPath===t&&(this._state.isStreaming=!1,this.emitStatusChange()),this.flushCompactionQueue(t)}return!0}if(s.startsWith("/name ")){const t=s.slice(6).trim();if(!t)return!0;if(!this._sessionPath)return this.appendLocalAssistantMessage("Cannot set name: no active session. Send a message first."),!0;try{await this.send({type:"set_session_name",sessionPath:this._sessionPath,name:t}),this._sessionName=t,this.appendLocalAssistantMessage(`Session renamed to **${t}**`),this.emitSessionChange()}catch(n){this.appendLocalAssistantMessage(`Failed to rename session: ${n?.message||"unknown error"}`)}return!0}if(s==="/reload"){try{const t=await this.send({type:"reload_processes"}),n=t?.killed??0,o=t?.draining??0;this.appendLocalAssistantMessage(`Reload requested: killed ${n} idle process(es), draining ${o} running process(es).`)}catch(t){this.appendLocalAssistantMessage(`Failed to reload pi processes: ${t?.message||"unknown error"}`)}return!0}return!1}abort(){this._sessionPath&&this.send({type:"abort",sessionPath:this._sessionPath}).catch(()=>{})}hardKill(){this._sessionPath&&this.send({type:"hard_kill",sessionPath:this._sessionPath}).catch(()=>{})}steer(e){const s=this.extractText(e);if(!s||!this._sessionPath)return;if(this._compactingSessions.has(this._sessionPath)){this.enqueueCompactionPrompt(this._sessionPath,s,void 0);return}this._globalSessionStatus.get(this._sessionPath)==="running"&&(this.enqueueSteering(this._sessionPath,s),this.send({type:"steer",sessionPath:this._sessionPath,message:s}).catch(console.error))}removeSteering(e){if(!this._sessionPath)return;const s=this._sessionPath,t=this._steeringQueues.get(s)?.length??0;if(e>=t){const n=this._compactionQueues.get(s)??[],o=e-t;if(o<0||o>=n.length)return;const a=n.filter((r,l)=>l!==o);a.length>0?this._compactionQueues.set(s,a):this._compactionQueues.delete(s),this.emitSteeringQueueChange();return}this.send({type:"remove_steering",sessionPath:s,index:e}).catch(console.error)}setModel(e){const s=this.resolveModel(e)??e,t=j(this._state.model,s),n=G(s,this._state.thinkingLevel);t&&n===this._state.thinkingLevel||(this._state.model=s,this._state.thinkingLevel=n,this.markControlPending(),this.emitContentChange())}setThinkingLevel(e){const s=G(this._state.model,e);s!==this._state.thinkingLevel&&(this._state.thinkingLevel=s,this.markControlPending(),this.emitContentChange())}async getForkMessages(){return this._sessionPath?this.listForkMessages(this._sessionPath):[]}listForkMessages(e){return this.api.listForkMessages(e)}browseDirectory(e){return this.api.browseDirectory(e)}createDirectory(e,s){return this.api.createDirectory(e,s)}getRawSession(e){return this.api.getRawSession(e)}getFileContent(e,s){return this.api.getFileContent(e,s)}createFileUpload(e){return this.api.createFileUpload(e)}appendFileUpload(e){return this.api.appendFileUpload(e)}completeFileUpload(e){return this.api.completeFileUpload(e)}getLocalSettings(){return this.api.getLocalSettings()}validateLocalSettings(e){return this.api.validateLocalSettings(e)}patchLocalSettings(e){return this.api.patchLocalSettings(e)}saveLocalSettings(e){return this.api.saveLocalSettings(e)}getUpdates(){return this.api.getUpdates()}runUpdate(e){return this.api.runUpdate(e)}async fork(e){if(!this._sessionPath)throw new Error("No session loaded");const s=await this.send({type:"fork",sessionPath:this._sessionPath,entryId:e});return{text:s?.text??"",cancelled:s?.cancelled??!1,newSessionPath:s?.newSessionPath??null}}async forkAndPrompt(e,s){if(!this._sessionPath||this._sessionStatus==="virtual"){await this.prompt(e,s);return}if(!this._state.model)throw new Error(`BUG: _state.model is undefined when sending fork_prompt. sessionPath=${this._sessionPath}`);const t=I(this._state.model);if(!t)throw new Error("BUG: active model has no provider/model ID");const n=this._pendingControl?.revision??this._controlRevision;this.markControlSent(n);const o=this._sessionNonce;let a;try{a=await this.send({type:"fork_prompt",sessionPath:this._sessionPath,message:e,model:t,thinkingLevel:this._state.thinkingLevel,controlRevision:n,images:s})}catch(r){throw this.rollbackSentControl(n),r}if(this._sessionNonce!==o){console.log("[ws-adapter] Discarding stale fork_prompt response (session changed during await)");return}a?.newSessionPath&&await this.switchSession(a.newSessionPath)}async listSessions(){const e=await this.api.listSessions(),s=new Set(e.map(n=>n.path));for(const[n,o]of this._optimisticSessions)if(s.has(n)){const a=e.find(r=>r.path===n);a&&!a.cwd&&o.cwd?a.cwd=o.cwd:this._optimisticSessions.delete(n)}else e.push(o);const t=this.virtualSessionInfo;return t&&!s.has(t.path)&&e.push(t),e}get optimisticSessions(){return Array.from(this._optimisticSessions.values())}async deleteSession(e){await this.api.deleteSession(e)}async switchSession(e,s){this._sessionSubscriptionActive=!0;const t=++this._sessionNonce;s!==void 0&&(this._pendingCwd=s),this._pendingNewPrompt=!1,this._pendingControl=void 0,this._lastAuthoritativeControl=void 0,this._sessionPath=e,this._localAssistantMessages=[],this.clearExtensionStatuses();const n=M.basename(e,".jsonl"),o=n.split("_");this._sessionId=o.length>1?o.slice(1).join("_"):n,this._sessionStatus="detached",this._state.messages=[],this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this._toolCallTimings={},this._awaitingFullSync=void 0,this._state.error=void 0,await this.requestFullSessionSync(e),!(t!==this._sessionNonce||e!==this._sessionPath)&&(this._globalSessionStatus.get(e)==="running"&&(this._sessionStatus="attached",this._state.isStreaming=!0),this.emitSessionChange(),this.emitStatusChange())}async newSession(e){this._sessionSubscriptionActive=!0,this._sessionNonce++,this._pendingNewPrompt=!1,this._pendingControl=void 0,this._sessionId=typeof crypto.randomUUID=="function"?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16))).map(s=>s.toString(16).padStart(2,"0")).join("").replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/,"$1-$2-$3-$4-$5"),this._sessionPath=void 0,this._sessionName=void 0,this._localAssistantMessages=[],this.clearExtensionStatuses(),this._sessionStatus="virtual",this._pendingCwd=e,this._state.model?this.rememberAuthoritativeControl(this._state.model,this._state.thinkingLevel):this._lastAuthoritativeControl=void 0,this._state.messages=[],this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this._toolCallTimings={},this._syncJson="",this._syncHash="",this._syncRevision=void 0,this._awaitingFullSync=void 0,this.clearSessionSyncQueue(),this._state.error=void 0,this.subscribeToSession(void 0),this.emitSessionChange(),this.emitStatusChange()}get virtualSessionInfo(){if(this._sessionStatus!=="virtual"||!this._pendingCwd)return;const e=new Date().toISOString();return{id:this._sessionId,path:`__virtual__${this._sessionId}`,cwd:this._pendingCwd,created:e,modified:e,lastUserPromptTime:e,messageCount:0,firstMessage:"(new session)"}}}const M={basename(i,e){const s=i.split("/").pop()||i;return e&&s.endsWith(e)?s.slice(0,-e.length):s}};export{je as W,G as c,Qe as f,Le as g,qe as m,Oe as s};
@@ -17,7 +17,7 @@
17
17
  if (colorTheme && colorTheme !== "default") root.setAttribute("data-color-theme", colorTheme);
18
18
  })();
19
19
  </script>
20
- <script type="module" crossorigin src="/assets/index-CG96lus1.js"></script>
20
+ <script type="module" crossorigin src="/assets/index-BNFbdYPt.js"></script>
21
21
  <link rel="stylesheet" crossorigin href="/assets/index-VW8gJNOU.css">
22
22
  </head>
23
23
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipane",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "A clean web interface for the pi coding agent — chat UI with real-time tool calls, streaming output, session management, and model picker",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,6 +0,0 @@
1
- import{_ as ie}from"./index-CG96lus1.js";import{i as oe}from"./backend-protocol-BvNAsFvb.js";import{D as ae}from"./__vite-browser-external-DGfF_P2w.js";function re(i){const e=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],s=(S,f)=>S>>>f|S<<32-f,t=new TextEncoder().encode(i),n=t.length*8,o=new Uint8Array(Math.ceil((t.length+9)/64)*64);o.set(t),o[t.length]=128;const a=new DataView(o.buffer);a.setUint32(o.length-4,n,!1),n>4294967295&&a.setUint32(o.length-8,Math.floor(n/4294967296),!1);let[r,l,u,_,y,v,w,c]=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];const g=new Int32Array(64);for(let S=0;S<o.length;S+=64){for(let d=0;d<16;d++)g[d]=a.getInt32(S+d*4,!1);for(let d=16;d<64;d++){const U=s(g[d-15],7)^s(g[d-15],18)^g[d-15]>>>3,q=s(g[d-2],17)^s(g[d-2],19)^g[d-2]>>>10;g[d]=g[d-16]+U+g[d-7]+q|0}let[f,$,L,N,P,T,F,R]=[r,l,u,_,y,v,w,c];for(let d=0;d<64;d++){const U=s(P,6)^s(P,11)^s(P,25),q=P&T^~P&F,V=R+U+q+e[d]+g[d]|0,se=s(f,2)^s(f,13)^s(f,22),te=f&$^f&L^$&L,ne=se+te|0;R=F,F=T,T=P,P=N+V|0,N=L,L=$,$=f,f=V+ne|0}r=r+f|0,l=l+$|0,u=u+L|0,_=_+N|0,y=y+P|0,v=v+T|0,w=w+F|0,c=c+R|0}return[r,l,u,_,y,v,w,c].map(S=>(S>>>0).toString(16).padStart(8,"0")).join("")}async function ce(i){if(typeof globalThis.crypto?.subtle?.digest=="function"){const e=new TextEncoder().encode(i),s=await globalThis.crypto.subtle.digest("SHA-256",e),t=new Uint8Array(s);return Array.from(t).map(n=>n.toString(16).padStart(2,"0")).join("")}if(typeof globalThis.process<"u"){const{createHash:e}=await ie(async()=>{const{createHash:s}=await import("./__vite-browser-external-DGfF_P2w.js").then(t=>t._);return{createHash:s}},[]);return e("sha256").update(i,"utf8").digest("hex")}return re(i)}function he(i,e){let s=i;for(const t of e)s=s.slice(0,t.offset)+t.insert+s.slice(t.offset+t.deleteCount);return s}async function le(i,e,s){if(s.length===0)return{data:i,hash:e};let t=i,n=e,o;for(const r of s){if(o=r,r.op==="full"){t=r.data,n=r.hash;continue}if(r.baseHash!==n)return console.warn("[jsonl-sync] Base hash mismatch, need full sync",{expected:r.baseHash,actual:n}),null;t=he(t,r.patches),n=r.hash}const a=await ce(t);if(a!==n){const r=o?.op==="full"?"[jsonl-sync] Full sync hash mismatch":"[jsonl-sync] Post-patch hash mismatch";return console.error(r,{expected:n,actual:a}),null}return{data:t,hash:n}}const de=10*6e4,ue=de+9e4,J=1;class Q extends Error{constructor(e,s,t){super(`${s}: ${t}`),this.code=e}}function p(i,e,s="invalid_message"){throw new Q(s,i,e)}function K(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function m(i,e){return K(i)||p(e,"expected an object"),i}function h(i,e,s=!0){return(typeof i!="string"||!s&&i.length===0)&&p(e,s?"expected a string":"expected a non-empty string"),i}function k(i,e){return i===void 0?void 0:h(i,e)}function b(i,e){return typeof i!="boolean"&&p(e,"expected a boolean"),i}function C(i,e){return(!Number.isSafeInteger(i)||i<0)&&p(e,"expected a non-negative safe integer"),i}function M(i,e){return(typeof i!="number"||!Number.isFinite(i))&&p(e,"expected a finite number"),i}function A(i,e){return Array.isArray(i)||p(e,"expected an array"),i}function H(i,e){return A(i,e).map((s,t)=>h(s,`${e}[${t}]`))}function O(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))h(n,`${e}.${t}`);return s}function Y(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))n!=="running"&&n!=="done"&&p(`${e}.${t}`,"expected 'running' or 'done'");return s}function ge(i,e){const s=m(i,e);for(const[t,n]of Object.entries(s))H(n,`${e}.${t}`);return s}function B(i,e){return["off","minimal","low","medium","high","xhigh","max"].includes(String(i))||p(e,"expected a supported thinking level"),i}function pe(i,e){const s=m(i,e);return h(s.provider,`${e}.provider`,!1),h(s.modelId,`${e}.modelId`,!1),s}function W(i,e){const s=m(i,e);h(s.provider,`${e}.provider`,!1);const t=k(s.id,`${e}.id`),n=k(s.modelId,`${e}.modelId`);return!t&&!n&&p(e,"expected id or modelId"),s}function me(i,e){if(i.protocolVersion!==J){const s=i.protocolVersion===void 0?"missing":JSON.stringify(i.protocolVersion);p(`${e}.protocolVersion`,`unsupported protocol version ${s}; expected ${J}`,"unsupported_version")}}function X(i){try{return{ok:!0,value:JSON.parse(i)}}catch(e){return{ok:!1,error:{code:"invalid_json",message:`Invalid JSON: ${e instanceof Error?e.message:String(e)}`,requestId:null,command:"parse"}}}}function Z(i,e,s){const t=K(i)?i:void 0,n=typeof t?.id=="string"?t.id:null,o=typeof t?.type=="string"?t.type:s,a=e instanceof Q?e:new Q("invalid_message","$",e instanceof Error?e.message:String(e));return{ok:!1,error:{code:a.code,message:a.message,requestId:n,command:o}}}function fe(i,e){A(i,e).forEach((s,t)=>{const n=m(s,`${e}[${t}]`);h(n.name,`${e}[${t}].name`,!1),k(n.description,`${e}[${t}].description`),["extension","prompt","skill"].includes(String(n.source))||p(`${e}[${t}].source`,"expected extension, prompt, or skill"),n.sourceInfo!==void 0&&m(n.sourceInfo,`${e}[${t}].sourceInfo`),k(n.location,`${e}[${t}].location`),k(n.path,`${e}[${t}].path`)})}function _e(i,e){const s=m(i,e);h(s.sessionFile,`${e}.sessionFile`,!1),h(s.sessionId,`${e}.sessionId`,!1);for(const n of["userMessages","assistantMessages","toolCalls","toolResults","totalMessages"])C(s[n],`${e}.${n}`);const t=m(s.tokens,`${e}.tokens`);for(const n of["input","output","cacheRead","cacheWrite","total"])C(t[n],`${e}.tokens.${n}`);if(M(s.cost,`${e}.cost`)<0&&p(`${e}.cost`,"expected a non-negative number"),s.contextUsage!==void 0){const n=m(s.contextUsage,`${e}.contextUsage`);n.tokens!==null&&C(n.tokens,`${e}.contextUsage.tokens`),C(n.contextWindow,`${e}.contextUsage.contextWindow`),n.percent!==null&&M(n.percent,`${e}.contextUsage.percent`)<0&&p(`${e}.contextUsage.percent`,"expected a non-negative number or null")}}function Se(i,e,s){const t=m(e,s);switch(i){case"install_pi":case"subscribe_session":case"steer":case"remove_steering":case"abort":case"set_session_name":break;case"prompt":case"fork_prompt":h(t.newSessionPath,`${s}.newSessionPath`,!1);break;case"hard_kill":b(t.killed,`${s}.killed`),t.reason!==void 0&&t.reason!=="signal_failed"&&t.reason!=="not_attached"&&p(`${s}.reason`,"expected signal_failed or not_attached");break;case"compact":break;case"get_available_models":A(t.models,`${s}.models`).forEach((n,o)=>W(n,`${s}.models[${o}]`));break;case"get_default_model":t.model!==null&&W(t.model,`${s}.model`),B(t.thinkingLevel,`${s}.thinkingLevel`);break;case"get_session_statuses":Y(t.statuses,`${s}.statuses`);break;case"get_session_stats":_e(t,s);break;case"fork":h(t.text,`${s}.text`),b(t.cancelled,`${s}.cancelled`),t.newSessionPath!==null&&h(t.newSessionPath,`${s}.newSessionPath`,!1);break;case"get_commands":fe(t.commands,`${s}.commands`);break;case"reload_processes":C(t.killed,`${s}.killed`),C(t.draining,`${s}.draining`);break}}const ye=new Set(["install_pi","subscribe_session","prompt","steer","remove_steering","abort","hard_kill","compact","get_available_models","get_default_model","get_session_statuses","get_session_stats","fork","fork_prompt","set_session_name","get_commands","reload_processes"]);function ve(i,e){const s=h(i,e,!1);return ye.has(s)||p(e,`unknown response command '${s}'`,"unknown_message"),s}function we(i,e){A(i,e).forEach((s,t)=>{const n=m(s,`${e}[${t}]`);C(n.offset,`${e}[${t}].offset`),C(n.deleteCount,`${e}[${t}].deleteCount`),h(n.insert,`${e}[${t}].insert`)})}function Ce(i){const e=X(i);if(!e.ok)return e;const s=e.value;try{const t=m(s,"$message");me(t,"$message");const n=h(t.type,"$message.type",!1);switch(n){case"response":{if(b(t.success,"$message.success")){h(t.id,"$message.id",!1);const a=ve(t.command,"$message.command");Se(a,t.data,"$message.data")}else t.id!==null&&h(t.id,"$message.id",!1),h(t.command,"$message.command",!1),h(t.error,"$message.error",!1),["invalid_json","invalid_message","unsupported_version","unknown_command","unknown_message","command_failed"].includes(String(t.code))||p("$message.code","expected a protocol error code");break}case"init":Y(t.sessionStatuses,"$message.sessionStatuses"),ge(t.steeringQueues,"$message.steeringQueues"),O(t.providerUsageStatuses,"$message.providerUsageStatuses");break;case"pi_install_required":h(t.command,"$message.command",!1),b(t.installable,"$message.installable"),b(t.installing,"$message.installing"),h(t.message,"$message.message",!1);break;case"session_status_change":h(t.sessionPath,"$message.sessionPath",!1),t.status!=="running"&&t.status!=="done"&&p("$message.status","expected running or done");break;case"provider_usage":O(t.statuses,"$message.statuses");break;case"extension_status":h(t.sessionPath,"$message.sessionPath",!1),O(t.statuses,"$message.statuses");break;case"session_sync":h(t.sessionPath,"$message.sessionPath",!1),C(t.revision,"$message.revision"),h(t.hash,"$message.hash",!1),t.op==="full"?h(t.data,"$message.data"):t.op==="delta"?(h(t.baseHash,"$message.baseHash",!1),we(t.patches,"$message.patches")):p("$message.op","expected full or delta");break;case"control_state":h(t.sessionPath,"$message.sessionPath",!1),t.controlRevision!==void 0&&C(t.controlRevision,"$message.controlRevision"),W(t.model,"$message.model"),B(t.thinkingLevel,"$message.thinkingLevel");break;case"session_attached":h(t.sessionPath,"$message.sessionPath",!1),k(t.cwd,"$message.cwd"),k(t.firstMessage,"$message.firstMessage");break;case"sessions_changed":h(t.file,"$message.file");break;default:p("$message.type",`unknown server message '${n}'`,"unknown_message")}return{ok:!0,value:t}}catch(t){return Z(s,t,"unknown")}}function $e(i){const e=X(i);if(!e.ok)return e;const s=e.value;try{const t=m(s,"$session");A(t.messages,"$session.messages").forEach((o,a)=>{const r=m(o,`$session.messages[${a}]`);h(r.role,`$session.messages[${a}].role`,!1)}),b(t.isStreaming,"$session.isStreaming"),H(t.pendingToolCalls,"$session.pendingToolCalls");const n=m(t.toolCallTimings,"$session.toolCallTimings");for(const[o,a]of Object.entries(n)){const r=m(a,`$session.toolCallTimings.${o}`);M(r.startedAt,`$session.toolCallTimings.${o}.startedAt`),r.completedAt!==void 0&&M(r.completedAt,`$session.toolCallTimings.${o}.completedAt`)}return t.model!==null&&pe(t.model,"$session.model"),B(t.thinkingLevel,"$session.thinkingLevel"),H(t.steeringQueue,"$session.steeringQueue"),k(t.error,"$session.error"),{ok:!0,value:t}}catch(t){return Z(s,t,"session_sync")}}function Pe(i,e){return JSON.stringify({protocolVersion:J,id:e,...i})}function ke(i){throw new Error(`Unhandled protocol variant: ${JSON.stringify(i)}`)}const x=["off","minimal","low","medium","high","xhigh","max"];function E(i){return i?.id??i?.modelId}function j(i,e){const s=E(i),t=E(e);return!!i&&!!e&&!!s&&!!t&&i.provider===e.provider&&s===t}function D(i){const e=E(i);if(!(!i.provider||!e))return{provider:i.provider,modelId:e}}function be(i){if(!i)return!1;if(typeof i.reasoning=="boolean")return i.reasoning;if(i.thinkingLevelMap)return!0;const e=String(i.provider??"").toLowerCase(),s=String(E(i)??"").toLowerCase();return!!(e==="openai-codex"||e==="openai"&&s.startsWith("gpt-5"))}function Le(i){if(!be(i))return["off"];const e=i?.thinkingLevelMap;return x.filter(s=>{const t=e?.[s];return t===null?!1:s==="xhigh"||s==="max"?t!==void 0:!0})}function G(i,e){const s=Le(i);if(s.includes(e))return e;const t=x.indexOf(e);if(t===-1)return s[0]??"off";for(let n=t;n<x.length;n++){const o=x[n];if(s.includes(o))return o}for(let n=t-1;n>=0;n--){const o=x[n];if(s.includes(o))return o}return s[0]??"off"}class xe extends Error{constructor(e,s,t){super(e),this.status=s,this.details=t,this.name="BackendApiError"}}class Ae{constructor(e={}){this.fetch=e.fetch??globalThis.fetch.bind(globalThis)}listSessions(){return this.requestJson("/api/sessions")}async deleteSession(e){await this.requestJson("/api/sessions",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})})}async listForkMessages(e){return(await this.requestJson(`/api/sessions/fork-messages?path=${encodeURIComponent(e)}`)).messages??[]}browseDirectory(e){return this.requestJson(`/api/browse?path=${encodeURIComponent(e)}`)}createDirectory(e,s){return this.requestJson("/api/directories",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentPath:e,name:s})})}async getRawSession(e){const s=await this.fetch(`/api/sessions/raw?path=${encodeURIComponent(e)}`);if(!s.ok)throw await this.toError(s,"Failed to load raw session");return s.text()}getFileContent(e,s){const t=new URLSearchParams({sessionPath:e,path:s});return this.requestJson(`/api/files/content?${t}`,{cache:"no-store"})}createFileUpload(e){return this.requestJson("/api/files/uploads",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}appendFileUpload(e){return this.requestJson(`/api/files/uploads/${encodeURIComponent(e.uploadId)}/chunks`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offset:e.offset,data:e.data})})}completeFileUpload(e){return this.requestJson(`/api/files/uploads/${encodeURIComponent(e)}/complete`,{method:"POST"})}getLocalSettings(){return this.requestJson("/api/settings/local")}validateLocalSettings(e){return this.requestValidation("/api/settings/local/validate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e})})}patchLocalSettings(e){return this.requestValidation("/api/settings/local",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}saveLocalSettings(e){return this.requestValidation("/api/settings/local",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e})})}getUpdates(){return this.requestJson("/api/updates",{cache:"no-store"})}runUpdate(e){return this.requestJson(`/api/updates/${e}`,{method:"POST",headers:{"X-Pipane-Action":"update"}})}async requestValidation(e,s){const t=await this.fetch(e,s),n=await this.readJson(t);if(!t.ok&&typeof n?.valid!="boolean")throw this.errorFromPayload(t,n,"Settings request failed");return n}async requestJson(e,s){const t=s?await this.fetch(e,s):await this.fetch(e),n=await this.readJson(t);if(!t.ok)throw this.errorFromPayload(t,n,`Backend request failed (${t.status})`);return n}async readJson(e){return e.json().catch(()=>({}))}async toError(e,s){const t=await this.readJson(e);return this.errorFromPayload(e,t,s)}errorFromPayload(e,s,t){const n=Array.isArray(s?.errors)?s.errors.filter(a=>typeof a=="string"):[],o=typeof s?.error=="string"?s.error:n.length>0?n.join(`
2
- `):t;return new xe(o,e.status,s)}}const ee=[{name:"help",description:"Show this help",source:"builtin"},{name:"new",description:"Start a new session",source:"builtin"},{name:"session",description:"Show session file, messages, tokens, and cost",source:"builtin"},{name:"fork",description:"Fork session from a previous message",source:"builtin"},{name:"compact",description:"Compact conversation history",source:"builtin",argumentHint:"[instructions]",acceptsArguments:!0},{name:"name",description:"Set session display name",source:"builtin",argumentHint:"<name>",acceptsArguments:!0},{name:"reload",description:"Restart all pooled pi RPC processes",source:"builtin"}];function qe(i){const e=ee.map(t=>({...t})),s=new Set(e.map(t=>t.name.toLocaleLowerCase()));for(const t of i){const n=t.name.toLocaleLowerCase();s.has(n)||(s.add(n),e.push({name:t.name,description:t.description??"",source:t.source,acceptsArguments:!0}))}return e}function Te(i,e){const s=i.toLocaleLowerCase(),t=e.toLocaleLowerCase();if(!t)return 0;if(s===t)return 1e5;let n=s.startsWith(t)?5e4:0,o=0,a=-2,r=-1;for(const l of t){const u=s.indexOf(l,o);if(u===-1)return;r===-1&&(r=u);const _=u>0?s[u-1]:"";u===0||_==="-"||_===":"||_==="_"?n+=18:n+=4,u===a+1&&(n+=12),a=u,o=u+1}return n-=r*3,n-=s.length-t.length,n}function Oe(i,e){return i.map((s,t)=>({command:s,index:t,score:Te(s.name,e)})).filter(s=>s.score!==void 0).sort((s,t)=>t.score-s.score||s.index-t.index).map(s=>s.command)}function je(i){switch(i){case"builtin":return"Built-in";case"extension":return"Extension";case"prompt":return"Prompt";case"skill":return"Skill"}}const z=1,Fe=1e4;class Ie{constructor(e={}){this.socket=null,this.reconnecting=!1,this.reconnectAttempt=0,this.manuallyClosed=!1,this.decoder=new ae,this.frameListeners=new Set,this.connectionListeners=new Set,this.createWebSocket=e.createWebSocket??(s=>new WebSocket(s)),this.schedule=e.schedule??globalThis.setTimeout.bind(globalThis),this.cancelSchedule=e.cancelSchedule??globalThis.clearTimeout.bind(globalThis),e.socket&&(this.socket=e.socket,this.attachFrameHandler(e.socket))}get isConnected(){return this.socket?.readyState===z}get isReconnecting(){return this.reconnecting}onFrame(e){return this.frameListeners.add(e),()=>this.frameListeners.delete(e)}onConnectionChange(e){return this.connectionListeners.add(e),()=>this.connectionListeners.delete(e)}async connect(e){this.isConnected||(this.endpoint=e,this.manuallyClosed=!1,await this.openSocket(!1))}send(e){if(!this.socket||this.socket.readyState!==z)throw new Error("Backend transport is not connected");this.socket.send(e)}close(e=1e3,s="Client closed"){this.manuallyClosed=!0,this.reconnecting=!1,this.reconnectTimer&&(this.cancelSchedule(this.reconnectTimer),this.reconnectTimer=void 0),this.decoder.reset(),this.socket?.close(e,s)}attachFrameHandler(e){e.onmessage=s=>{try{const t=this.decoder.accept(String(s.data));if(t===void 0)return;for(const n of this.frameListeners)n(t)}catch{e.close(1002,"Invalid carrier frame")}}}emitConnectionChange(e){for(const s of this.connectionListeners)s(e)}openSocket(e){const s=this.endpoint;return s?new Promise((t,n)=>{const o=this.createWebSocket(s);let a=!1,r=!1;this.socket=o,this.attachFrameHandler(o),o.onopen=()=>{this.socket===o&&(a=!0,r=!0,this.reconnecting=!1,this.reconnectAttempt=0,this.emitConnectionChange({connected:!0,reconnected:e}),t())},o.onerror=()=>{!e&&!r&&(r=!0,n(new Error("WebSocket connection failed")))},o.onclose=()=>{if(this.socket===o&&(this.socket=null),this.decoder.reset(),r||(r=!0,n(new Error("WebSocket closed before connecting"))),this.manuallyClosed){a&&this.emitConnectionChange({connected:!1,reconnected:!1});return}(a||e)&&(this.scheduleReconnect(),a&&this.emitConnectionChange({connected:!1,reconnected:!1}))}}):Promise.reject(new Error("Backend transport endpoint is missing"))}scheduleReconnect(){if(this.reconnectTimer||this.manuallyClosed)return;this.reconnecting=!0,this.reconnectAttempt++;const e=Math.min(500*2**(this.reconnectAttempt-1),Fe);this.reconnectTimer=this.schedule(()=>{this.reconnectTimer=void 0,this.openSocket(!0).catch(()=>{})},e)}}const Me="provider-usage";function Ee(i){const e=typeof i?.provider=="string"?i.provider.toLowerCase():"";if(e.includes("codex"))return"codex";if(e.includes("anthropic"))return"anthropic"}class De{constructor(e={}){this.sessionsChangedListeners=new Set,this.piInstallRequiredListeners=new Set,this.pendingRequests=new Map,this.requestId=0,this._connectionListeners=new Set,this._state={model:void 0,thinkingLevel:"off",messages:[],isStreaming:!1,error:void 0},this._pendingToolCallIds=new Set,this._toolCallTimings={},this._steeringQueues=new Map,this._steeringQueueListeners=new Set,this._extensionStatuses=new Map,this._providerUsageStatuses=new Map,this._extensionStatusListeners=new Set,this._controlRevision=0,this._availableModels=null,this._sessionId="",this._sessionStatus="virtual",this._sessionSubscriptionActive=!0,this._localAssistantMessages=[],this._optimisticSessions=new Map,this._globalSessionStatus=new Map,this._globalStatusListeners=new Set,this._sessionNonce=0,this._pendingNewPrompt=!1,this._startingPrompts=new Map,this._syncJson="",this._syncHash="",this._pendingSessionSyncs=[],this._sessionSyncFlushScheduled=!1,this._sessionSyncFlushInProgress=!1,this._sessionListeners=new Set,this._contentListeners=new Set,this._statusListeners=new Set,this.transport=e.transport??new Ie({socket:e.socket,createWebSocket:e.createWebSocket}),this.api=e.api??new Ae({fetch:e.fetch}),this.requestFrame=e.requestFrame??(s=>requestAnimationFrame(s)),this.transport.onFrame(s=>this.handleMessage(s)),this.transport.onConnectionChange(s=>this.handleTransportConnectionChange(s.connected,s.reconnected))}get state(){return this._state}get sessionId(){return this._sessionId}get sessionFile(){return this._sessionPath}get sessionName(){return this._sessionName}get sessionStatus(){return this._sessionStatus}get isConnected(){return this.transport.isConnected}get isReconnecting(){return this.transport.isReconnecting}onConnectionChange(e){return this._connectionListeners.add(e),()=>this._connectionListeners.delete(e)}emitConnectionChange(e){for(const s of this._connectionListeners)s(e)}get pendingToolCallIds(){return this._pendingToolCallIds}get toolCallTimings(){return this._toolCallTimings}get steeringQueue(){return this._sessionPath?this._steeringQueues.get(this._sessionPath)??[]:[]}get extensionStatuses(){const e=new Map(this._extensionStatuses),s=Ee(this._state.model),t=s?this._providerUsageStatuses.get(s):this._providerUsageStatuses.size===1?this._providerUsageStatuses.values().next().value:void 0;return t&&e.set(Me,t),e}onExtensionStatusChange(e){return this._extensionStatusListeners.add(e),()=>this._extensionStatusListeners.delete(e)}replaceExtensionStatuses(e){const s=new Map;if(e&&typeof e=="object"&&!Array.isArray(e))for(const[t,n]of Object.entries(e))typeof n=="string"&&s.set(t,n);if(!(s.size===this._extensionStatuses.size&&[...s].every(([t,n])=>this._extensionStatuses.get(t)===n))){this._extensionStatuses=s;for(const t of this._extensionStatusListeners)t()}}replaceProviderUsageStatuses(e){const s=new Map;if(e&&typeof e=="object"&&!Array.isArray(e))for(const[t,n]of Object.entries(e))typeof n=="string"&&s.set(t,n);if(!(s.size===this._providerUsageStatuses.size&&[...s].every(([t,n])=>this._providerUsageStatuses.get(t)===n))){this._providerUsageStatuses=s;for(const t of this._extensionStatusListeners)t()}}clearExtensionStatuses(){this.replaceExtensionStatuses({})}getSessionStatus(e){return this._globalSessionStatus.get(e)}onGlobalStatusChange(e){return this._globalStatusListeners.add(e),()=>this._globalStatusListeners.delete(e)}emitGlobalStatusChange(){for(const e of this._globalStatusListeners)e()}setGlobalSessionStatus(e,s){this._globalSessionStatus.set(e,s),s==="running"&&this._startingPrompts.get(e)?.resolveReady(e),this.emitGlobalStatusChange()}setAllSessionStatuses(e){this._globalSessionStatus.clear();for(const[s,t]of Object.entries(e))this._globalSessionStatus.set(s,t);this.emitGlobalStatusChange()}onSteeringQueueChange(e){return this._steeringQueueListeners.add(e),()=>this._steeringQueueListeners.delete(e)}emitSteeringQueueChange(){for(const e of this._steeringQueueListeners)e()}enqueueSteering(e,s){const t=this._steeringQueues.get(e)??[];this._steeringQueues.set(e,[...t,s]),this.emitSteeringQueueChange()}onSessionChange(e){return this._sessionListeners.add(e),()=>this._sessionListeners.delete(e)}emitSessionChange(){for(const e of this._sessionListeners)e()}onContentChange(e){return this._contentListeners.add(e),()=>this._contentListeners.delete(e)}emitContentChange(){for(const e of this._contentListeners)e()}onStatusChange(e){return this._statusListeners.add(e),()=>this._statusListeners.delete(e)}emitStatusChange(){for(const e of this._statusListeners)e()}onSessionsChanged(e){return this.sessionsChangedListeners.add(e),()=>this.sessionsChangedListeners.delete(e)}onPiInstallRequired(e){return this.piInstallRequiredListeners.add(e),()=>this.piInstallRequiredListeners.delete(e)}emitPiInstallRequired(e){for(const s of this.piInstallRequiredListeners)s(e)}toErrorMessage(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}reportError(e,s="Request failed"){const t=this.toErrorMessage(e);this._state.error=t,this._state.messages=[...this._state.messages,{role:"assistant",content:[{type:"text",text:`⚠️ ${s}: ${t}`}],timestamp:Date.now()}],this.emitStatusChange(),this.emitContentChange()}async connect(e){await this.transport.connect(e),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this.syncStateOnFocus()})}disconnect(){this.transport.close()}async setSessionSubscriptionActive(e){if(e!==this._sessionSubscriptionActive){if(this._sessionSubscriptionActive=e,this._sessionNonce++,this._awaitingFullSync=void 0,this.clearSessionSyncQueue(),!e){await this.subscribeToSession(void 0);return}this._sessionPath&&this._sessionStatus!=="virtual"&&await this.requestFullSessionSync(this._sessionPath)}}getConnectionDiagnostics(){return this.transport.getConnectionDiagnostics?.()??Promise.resolve(void 0)}handleTransportConnectionChange(e,s){e?s?this.onReconnected():this._sessionStatus="virtual":this.handleTransportDisconnected(),this.emitConnectionChange(e)}handleTransportDisconnected(){for(const e of this.pendingRequests.values())e.reject(new Error("Backend transport disconnected"));this.pendingRequests.clear(),this._pendingControl?.phase==="sent"?this.rollbackSentControl(this._pendingControl.revision):this._pendingControl?.phase==="acknowledged"&&(this._pendingControl=void 0)}async onReconnected(){this._sessionSubscriptionActive&&this._sessionPath&&this._sessionStatus!=="virtual"&&(this._awaitingFullSync=void 0,this.requestFullSessionSync(this._sessionPath)),this.refreshSessionStatuses()}async syncStateOnFocus(){this.refreshSessionStatuses(),this._sessionSubscriptionActive&&this._sessionPath&&this._sessionStatus!=="virtual"&&this.subscribeToSession(this._sessionPath),this._sessionStatus==="detached"&&this._state.isStreaming&&(console.log("[ws-adapter] Tab regained focus: clearing stale streaming state"),this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this.emitStatusChange())}async refreshSessionStatuses(){try{const e=await this.send({type:"get_session_statuses"});e?.statuses&&this.setAllSessionStatuses(e.statuses)}catch(e){console.error("Failed to refresh session statuses:",e)}}async subscribeToSession(e){try{await this.send({type:"subscribe_session",sessionPath:e??""})}catch(s){console.error("Failed to subscribe to session:",s)}}async requestFullSessionSync(e){const s={sessionPath:e,sessionNonce:this._sessionNonce};this._awaitingFullSync?.sessionPath===s.sessionPath&&this._awaitingFullSync.sessionNonce===s.sessionNonce||(this._awaitingFullSync=s,this._syncJson="",this._syncHash="",this._syncRevision=void 0,this.clearSessionSyncQueue(),await this.subscribeToSession(e))}handleProtocolError(e){const s=`Protocol error: ${e.message}`;console.error(`[ws-adapter] ${s}`),this._state.error=s,this.emitStatusChange(),e.code==="unsupported_version"&&this.transport.close(1002,"Unsupported protocol version")}handleMessage(e){if(oe(e))return;const s=Ce(e);if(!s.ok){this.handleProtocolError(s.error);return}const t=s.value;switch(t.type){case"response":{if(!t.success&&t.id===null){this._state.error=t.error,this.emitStatusChange();return}if(t.id===null)return;const n=this.pendingRequests.get(t.id);if(!n)return;if(this.pendingRequests.delete(t.id),t.command!==n.command){n.reject(new Error(`Mismatched response for ${n.command}: received ${t.command}`));return}t.success?n.resolve(t.data):(this._state.error=t.error,this.emitStatusChange(),n.reject(new Error(t.error)));return}case"pi_install_required":this.emitPiInstallRequired({command:t.command,installable:t.installable,installing:t.installing,message:t.message});return;case"init":this.setAllSessionStatuses(t.sessionStatuses),this.replaceProviderUsageStatuses(t.providerUsageStatuses),this._steeringQueues.clear();for(const[n,o]of Object.entries(t.steeringQueues))o.length>0&&this._steeringQueues.set(n,[...o]);this.emitSteeringQueueChange();return;case"session_status_change":this.setGlobalSessionStatus(t.sessionPath,t.status);return;case"provider_usage":this.replaceProviderUsageStatuses(t.statuses);return;case"extension_status":t.sessionPath===this._sessionPath&&this.replaceExtensionStatuses(t.statuses);return;case"session_sync":if(t.sessionPath!==this._sessionPath)return;this.enqueueSessionSync({...t,__sessionPath:t.sessionPath,__sessionNonce:this._sessionNonce});return;case"control_state":{if(t.sessionPath!==this._sessionPath)return;this.applyAuthoritativeControlState(t.model,t.thinkingLevel,t.controlRevision)&&this.emitContentChange();return}case"session_attached":{this.setGlobalSessionStatus(t.sessionPath,"running"),t.cwd&&(this._pendingCwd=t.cwd);const n=t.sessionPath===this._sessionPath||this._sessionStatus==="virtual"&&this._pendingNewPrompt;if(n){if(this._sessionStatus==="virtual"){this._sessionPath=t.sessionPath;const a=I.basename(t.sessionPath,".jsonl"),r=a.split("_");this._sessionId=r.length>1?r.slice(1).join("_"):a,this._startingPrompts.get(`virtual:${this._sessionNonce}`)?.resolveReady(t.sessionPath)}this._sessionStatus="attached",this._state.isStreaming=!0,this.requestFullSessionSync(t.sessionPath),this.emitStatusChange()}if(!this._optimisticSessions.has(t.sessionPath)){const o=new Date().toISOString(),a=I.basename(t.sessionPath,".jsonl"),r=a.split("_"),l=r.length>1?r.slice(1).join("_"):a;this._optimisticSessions.set(t.sessionPath,{id:l,path:t.sessionPath,cwd:t.cwd??"",created:o,modified:o,lastUserPromptTime:o,messageCount:1,firstMessage:t.firstMessage??"(new session)"})}n&&this.emitSessionChange();return}case"sessions_changed":for(const n of this.sessionsChangedListeners)n(t.file);return;default:ke(t)}}enqueueSessionSync(e){const s=this._awaitingFullSync!==void 0&&this._awaitingFullSync.sessionPath===e.__sessionPath&&this._awaitingFullSync.sessionNonce===e.__sessionNonce;if(e.op==="full")s&&(this._awaitingFullSync=void 0),this._pendingSessionSyncs=[e];else{if(s)return;this._pendingSessionSyncs.push(e)}this._sessionSyncFlushScheduled||this._sessionSyncFlushInProgress||(this._sessionSyncFlushScheduled=!0,this.requestFrame(()=>{this._sessionSyncFlushScheduled=!1,this.flushSessionSyncQueue()}))}clearSessionSyncQueue(){this._pendingSessionSyncs=[],this._sessionSyncFlushScheduled=!1}async flushSessionSyncQueue(){if(this._sessionSyncFlushInProgress)return;this._sessionSyncFlushInProgress=!0;const e=this._pendingSessionSyncs.splice(0);try{const s=await this.applySessionSyncBatch(e);s&&this.emitSessionSyncChanges(s)}finally{this._sessionSyncFlushInProgress=!1,this._pendingSessionSyncs.length>0&&!this._sessionSyncFlushScheduled&&(this._sessionSyncFlushScheduled=!0,this.requestFrame(()=>{this._sessionSyncFlushScheduled=!1,this.flushSessionSyncQueue()}))}}emitSessionSyncChanges(e){e.steering&&this.emitSteeringQueueChange(),e.content&&this.emitContentChange(),e.status&&this.emitStatusChange()}async applySessionSyncBatch(e){const s=this._sessionPath,t=this._sessionNonce;if(!s||e.length===0||e.some(c=>c.__sessionPath!==s||c.__sessionNonce!==t))return;let n=this._syncRevision;for(const c of e){if(c.op==="full"){n=c.revision;continue}if(n===void 0||c.revision!==n+1){console.error("[ws-adapter] Session revision gap, re-subscribing",{expected:n===void 0?"full snapshot":n+1,actual:c.revision}),this.requestFullSessionSync(s);return}n=c.revision}const o=e.map(c=>c.op==="full"?{op:"full",data:c.data,hash:c.hash}:{op:"delta",patches:c.patches,hash:c.hash,baseHash:c.baseHash});if(o[0]?.op==="delta"&&!this._syncHash){console.warn("[ws-adapter] Ignoring delta while awaiting full sync");return}const a=await le(this._syncJson,this._syncHash,o);if(s!==this._sessionPath||t!==this._sessionNonce)return;if(!a){console.error("[ws-adapter] Sync verification failed, re-subscribing"),this.requestFullSessionSync(s);return}const r=$e(a.data);if(!r.ok){this.handleProtocolError(r.error);return}const l=r.value;this._syncJson=a.data,this._syncHash=a.hash,this._syncRevision=n;const u=this._state.isStreaming,_=this._sessionStatus,y=this._state.error,v=[...this._steeringQueues.get(s)??[]];this._state.messages=[...l.messages??[],...this._localAssistantMessages],this._state.isStreaming=l.isStreaming??!1,this._sessionStatus!=="virtual"&&(this._sessionStatus=this._state.isStreaming?"attached":"detached"),this._pendingToolCallIds=new Set(l.pendingToolCalls??[]),this._toolCallTimings=l.toolCallTimings??{},this.applyAuthoritativeControlState(l.model,l.thinkingLevel),Array.isArray(l.steeringQueue)&&(l.steeringQueue.length>0?this._steeringQueues.set(s,[...l.steeringQueue]):this._steeringQueues.delete(s)),this._state.error=l.error||void 0;const w=this._steeringQueues.get(s)??[];return{content:!0,status:u!==this._state.isStreaming||_!==this._sessionStatus||y!==this._state.error,steering:v.length!==w.length||v.some((c,g)=>c!==w[g])}}send(e){if(!this.transport.isConnected)return Promise.reject(new Error("Backend transport is not connected"));const s=`req_${++this.requestId}`;return new Promise((t,n)=>{const o=e.type==="compact"?ue:e.type==="prompt"||e.type==="fork_prompt"?9e4:3e4,a=setTimeout(()=>{this.pendingRequests.delete(s),n(new Error(`Timeout waiting for response to ${e.type}`))},o);this.pendingRequests.set(s,{command:e.type,resolve:r=>{clearTimeout(a),t(r)},reject:r=>{clearTimeout(a),n(r)}}),this.transport.send(Pe(e,s))})}async fetchAvailableModels(){const s=(await this.send({type:"get_available_models"}))?.models??[];this._availableModels=s;const t=this.resolveModel(this._state.model);return t&&(this._state.model=t),s}resolveModel(e){if(!e)return;const s=this._availableModels?.find(n=>j(n,e));if(s)return s;const t=D(e);if(t)return{...e,provider:t.provider,id:t.modelId}}markControlPending(){const e=++this._controlRevision;return this._pendingControl={revision:e,sessionNonce:this._sessionNonce,phase:"local"},e}markControlSent(e){this._pendingControl?.revision===e&&this._pendingControl.sessionNonce===this._sessionNonce&&(this._pendingControl.phase="sent")}rollbackSentControl(e){const s=this._pendingControl;if(!s||s.revision!==e||s.phase!=="sent")return;this._pendingControl=void 0;const t=this._lastAuthoritativeControl;t?.sessionNonce===this._sessionNonce&&(this._state.model=t.model,this._state.thinkingLevel=t.thinkingLevel,this.emitContentChange())}rememberAuthoritativeControl(e,s){this._lastAuthoritativeControl={sessionNonce:this._sessionNonce,model:e,thinkingLevel:s}}applyAuthoritativeControlState(e,s,t){const n=this.resolveModel(e),o=s,a=this._pendingControl;if(t!==void 0){if(a){if(a.sessionNonce!==this._sessionNonce||a.revision!==t)return!1;a.phase="acknowledged",a.model=n,a.thinkingLevel=o}return n&&(this._state.model=n),o&&(this._state.thinkingLevel=o),n&&o&&this.rememberAuthoritativeControl(n,o),!!n||!!o}if(a){if(!(a.phase==="acknowledged"&&!!a.model&&j(e,a.model)&&o===a.thinkingLevel))return!1;this._pendingControl=void 0}return n&&(this._state.model=n),o&&(this._state.thinkingLevel=o),n&&o&&this.rememberAuthoritativeControl(n,o),!!n||!!o}async installPi(){await this.send({type:"install_pi"})}async loadDefaultModel(){if(this._state.model)return;const e=await this.send({type:"get_default_model"});this.applyAuthoritativeControlState(e?.model,e?.thinkingLevel)}setCwd(e){this._pendingCwd=e}get cwd(){return this._pendingCwd}createStartingPrompt(e){let s,t;const n={ready:new Promise(o=>{s=o}),resolveReady:o=>s(o),finished:new Promise(o=>{t=o}),resolveFinished:()=>t()};return this._startingPrompts.set(e,n),n}finishStartingPrompt(e,s,t){s.resolveReady(t),s.resolveFinished(),this._startingPrompts.get(e)===s&&this._startingPrompts.delete(e)}async prompt(e,s){let t;if(typeof e=="string"?t=e:Array.isArray(e)?t=e.map(c=>this.extractText(c)).join(`
3
- `):t=this.extractText(e),this.clearLocalAssistantMessages(),await this.handleSlashCommand(t))return;const o=this._sessionStatus==="virtual"?`virtual:${this._sessionNonce}`:this._sessionPath,a=o?this._startingPrompts.get(o):void 0;if(a){const c=await a.ready;if(c&&this._globalSessionStatus.get(c)==="running"){this.enqueueSteering(c,t),await this.send({type:"steer",sessionPath:c,message:t});return}if(await a.finished,!c)throw new Error("The session failed to start before the queued prompt could be sent");return this.prompt(e,s)}if((this._sessionPath?this._globalSessionStatus.get(this._sessionPath)==="running":!1)&&this._sessionPath){this.enqueueSteering(this._sessionPath,t),await this.send({type:"steer",sessionPath:this._sessionPath,message:t});return}const l=this._state.model;if(!l)throw new Error(`BUG: effective model is undefined when sending prompt. sessionStatus=${this._sessionStatus}, sessionPath=${this._sessionPath}`);const u=D(l);if(!u)throw new Error("BUG: active model has no provider/model ID");const _=this._state.thinkingLevel,y=this._pendingControl?.revision??this._controlRevision;this.markControlSent(y);const v=o??`virtual:${this._sessionNonce}`,w=this.createStartingPrompt(v);if(this._sessionStatus==="virtual"){const c=this._sessionNonce;this._pendingNewPrompt=!0;try{const g=await this.send({type:"prompt",sessionPath:"__new__",cwd:this._pendingCwd,message:t,model:u,thinkingLevel:_,controlRevision:y,images:s});if(this._sessionNonce!==c){console.log("[ws-adapter] Discarding stale prompt response (session changed during await)");return}const S=g?.newSessionPath;if(S&&!this._sessionPath){this._sessionPath=S;const f=I.basename(S,".jsonl"),$=f.split("_");this._sessionId=$.length>1?$.slice(1).join("_"):f,this._sessionStatus="attached",this.requestFullSessionSync(S),this.emitSessionChange(),this.emitStatusChange()}}catch(g){throw this.rollbackSentControl(y),g}finally{this._pendingNewPrompt=!1;const g=this._sessionNonce===c?this._sessionPath:void 0;this.finishStartingPrompt(v,w,g)}return}if(!this._sessionPath)throw new Error("No session loaded");try{await this.send({type:"prompt",sessionPath:this._sessionPath,message:t,model:u,thinkingLevel:_,controlRevision:y,images:s})}catch(c){throw this.rollbackSentControl(y),c}finally{this.finishStartingPrompt(v,w,this._sessionPath)}}extractText(e){if("content"in e){if(typeof e.content=="string")return e.content;if(Array.isArray(e.content))return e.content.filter(s=>s.type==="text").map(s=>s.text).join(`
4
- `)}return""}async fetchCommands(){try{const e=this._sessionPath?{sessionPath:this._sessionPath}:{cwd:this._pendingCwd};return(await this.send({type:"get_commands",...e}))?.commands??[]}catch{return[]}}clearLocalAssistantMessages(){if(this._localAssistantMessages.length===0)return;const e=new Set(this._localAssistantMessages);this._localAssistantMessages=[],this._state.messages=this._state.messages.filter(s=>!e.has(s)),this.emitContentChange()}appendLocalAssistantMessage(e){const s={role:"assistant",content:[{type:"text",text:e}]};this._localAssistantMessages.push(s),this._state.messages=[...this._state.messages,s],this.emitContentChange()}formatSessionStats(e){const s=o=>o.toLocaleString("en-US"),t=`$${e.cost.toFixed(e.cost<.01?4:e.cost<1?3:2)}`,n=["**Session information**","",`- **File:** \`${e.sessionFile}\``,`- **ID:** \`${e.sessionId}\``,`- **Messages:** ${s(e.totalMessages)} total (${s(e.userMessages)} user, ${s(e.assistantMessages)} assistant)`,`- **Tools:** ${s(e.toolCalls)} calls, ${s(e.toolResults)} results`,`- **Tokens:** ${s(e.tokens.total)} total (${s(e.tokens.input)} input, ${s(e.tokens.output)} output, ${s(e.tokens.cacheRead)} cache read, ${s(e.tokens.cacheWrite)} cache write)`,`- **Cost:** ${t}`];if(e.contextUsage){const o=e.contextUsage.tokens===null?`unknown / ${s(e.contextUsage.contextWindow)}`:`${s(e.contextUsage.tokens)} / ${s(e.contextUsage.contextWindow)}${e.contextUsage.percent===null?"":` (${e.contextUsage.percent}%)`}`;n.push(`- **Context:** ${o}`)}return n.join(`
5
- `)}async showSessionMessage(){if(!this._sessionPath){this.appendLocalAssistantMessage("No active session yet. Send a message first to create one.");return}const e=await this.send({type:"get_session_stats",sessionPath:this._sessionPath});this.appendLocalAssistantMessage(this.formatSessionStats(e))}async showHelpMessage(){const e=["**Built-in commands:**","","| Command | Description |","|---------|-------------|",...ee.map(a=>{const r=a.argumentHint?` ${a.argumentHint}`:"";return`| \`/${a.name}${r}\` | ${a.description} |`})],s=await this.fetchCommands(),t=s.filter(a=>a.source==="extension"),n=s.filter(a=>a.source==="prompt"),o=s.filter(a=>a.source==="skill");if(t.length>0){e.push("","**Extension commands:**","","| Command | Description |","|---------|-------------|");for(const a of t)e.push(`| \`/${a.name}\` | ${a.description||""} |`)}if(n.length>0){e.push("","**Prompt templates:**","","| Command | Description |","|---------|-------------|");for(const a of n){const r=a.location?` *(${a.location})*`:"";e.push(`| \`/${a.name}\` | ${a.description||""}${r} |`)}}if(o.length>0){e.push("","**Skills:**","","| Command | Description |","|---------|-------------|");for(const a of o){const r=a.location?` *(${a.location})*`:"";e.push(`| \`/${a.name}\` | ${a.description||""}${r} |`)}}e.push("","**Keyboard shortcuts:**","","| Shortcut | Action |","|----------|--------|","| `Enter` | Send message (also works during streaming to steer) |","| `Cmd+Enter` | Fork session and send message in the fork |","| `Shift+Enter` | New line |","| `Escape` | Abort current turn |"),this.appendLocalAssistantMessage(e.join(`
6
- `))}async handleSlashCommand(e){const s=e.trim();if(!s.startsWith("/"))return!1;if(s==="/help")return await this.showHelpMessage(),!0;if(s==="/new")return await this.newSession(),!0;if(s==="/session")return await this.showSessionMessage(),!0;if(s==="/fork")return window.dispatchEvent(new CustomEvent("pi-fork-request")),!0;if(s==="/compact"||s.startsWith("/compact ")){if(!this._sessionPath)return!0;const t=s.startsWith("/compact ")?s.slice(9).trim():void 0,n={role:"compactionSummary",summary:"",tokensBefore:0,timestamp:Date.now(),_compacting:!0};this._state.isStreaming=!0,this._state.messages=[...this._state.messages,n],this.emitStatusChange(),this.emitContentChange();try{await this.send({type:"compact",sessionPath:this._sessionPath,customInstructions:t})}catch(o){throw this._state.messages=this._state.messages.filter(a=>a!==n),this.emitContentChange(),o}finally{this._state.isStreaming=!1,this.emitStatusChange()}return await this.subscribeToSession(this._sessionPath),!0}if(s.startsWith("/name ")){const t=s.slice(6).trim();if(!t)return!0;if(!this._sessionPath)return this.appendLocalAssistantMessage("Cannot set name: no active session. Send a message first."),!0;try{await this.send({type:"set_session_name",sessionPath:this._sessionPath,name:t}),this._sessionName=t,this.appendLocalAssistantMessage(`Session renamed to **${t}**`),this.emitSessionChange()}catch(n){this.appendLocalAssistantMessage(`Failed to rename session: ${n?.message||"unknown error"}`)}return!0}if(s==="/reload"){try{const t=await this.send({type:"reload_processes"}),n=t?.killed??0,o=t?.draining??0;this.appendLocalAssistantMessage(`Reload requested: killed ${n} idle process(es), draining ${o} running process(es).`)}catch(t){this.appendLocalAssistantMessage(`Failed to reload pi processes: ${t?.message||"unknown error"}`)}return!0}return!1}abort(){this._sessionPath&&this.send({type:"abort",sessionPath:this._sessionPath}).catch(()=>{})}hardKill(){this._sessionPath&&this.send({type:"hard_kill",sessionPath:this._sessionPath}).catch(()=>{})}steer(e){const s=this.extractText(e);!s||!this._sessionPath||!(this._globalSessionStatus.get(this._sessionPath)==="running")||(this.enqueueSteering(this._sessionPath,s),this.send({type:"steer",sessionPath:this._sessionPath,message:s}).catch(console.error))}removeSteering(e){this._sessionPath&&this.send({type:"remove_steering",sessionPath:this._sessionPath,index:e}).catch(console.error)}setModel(e){const s=this.resolveModel(e)??e,t=j(this._state.model,s),n=G(s,this._state.thinkingLevel);t&&n===this._state.thinkingLevel||(this._state.model=s,this._state.thinkingLevel=n,this.markControlPending(),this.emitContentChange())}setThinkingLevel(e){const s=G(this._state.model,e);s!==this._state.thinkingLevel&&(this._state.thinkingLevel=s,this.markControlPending(),this.emitContentChange())}async getForkMessages(){return this._sessionPath?this.listForkMessages(this._sessionPath):[]}listForkMessages(e){return this.api.listForkMessages(e)}browseDirectory(e){return this.api.browseDirectory(e)}createDirectory(e,s){return this.api.createDirectory(e,s)}getRawSession(e){return this.api.getRawSession(e)}getFileContent(e,s){return this.api.getFileContent(e,s)}createFileUpload(e){return this.api.createFileUpload(e)}appendFileUpload(e){return this.api.appendFileUpload(e)}completeFileUpload(e){return this.api.completeFileUpload(e)}getLocalSettings(){return this.api.getLocalSettings()}validateLocalSettings(e){return this.api.validateLocalSettings(e)}patchLocalSettings(e){return this.api.patchLocalSettings(e)}saveLocalSettings(e){return this.api.saveLocalSettings(e)}getUpdates(){return this.api.getUpdates()}runUpdate(e){return this.api.runUpdate(e)}async fork(e){if(!this._sessionPath)throw new Error("No session loaded");const s=await this.send({type:"fork",sessionPath:this._sessionPath,entryId:e});return{text:s?.text??"",cancelled:s?.cancelled??!1,newSessionPath:s?.newSessionPath??null}}async forkAndPrompt(e,s){if(!this._sessionPath||this._sessionStatus==="virtual"){await this.prompt(e,s);return}if(!this._state.model)throw new Error(`BUG: _state.model is undefined when sending fork_prompt. sessionPath=${this._sessionPath}`);const t=D(this._state.model);if(!t)throw new Error("BUG: active model has no provider/model ID");const n=this._pendingControl?.revision??this._controlRevision;this.markControlSent(n);const o=this._sessionNonce;let a;try{a=await this.send({type:"fork_prompt",sessionPath:this._sessionPath,message:e,model:t,thinkingLevel:this._state.thinkingLevel,controlRevision:n,images:s})}catch(r){throw this.rollbackSentControl(n),r}if(this._sessionNonce!==o){console.log("[ws-adapter] Discarding stale fork_prompt response (session changed during await)");return}a?.newSessionPath&&await this.switchSession(a.newSessionPath)}async listSessions(){const e=await this.api.listSessions(),s=new Set(e.map(n=>n.path));for(const[n,o]of this._optimisticSessions)if(s.has(n)){const a=e.find(r=>r.path===n);a&&!a.cwd&&o.cwd?a.cwd=o.cwd:this._optimisticSessions.delete(n)}else e.push(o);const t=this.virtualSessionInfo;return t&&!s.has(t.path)&&e.push(t),e}get optimisticSessions(){return Array.from(this._optimisticSessions.values())}async deleteSession(e){await this.api.deleteSession(e)}async switchSession(e,s){this._sessionSubscriptionActive=!0;const t=++this._sessionNonce;s!==void 0&&(this._pendingCwd=s),this._pendingNewPrompt=!1,this._pendingControl=void 0,this._lastAuthoritativeControl=void 0,this._sessionPath=e,this._localAssistantMessages=[],this.clearExtensionStatuses();const n=I.basename(e,".jsonl"),o=n.split("_");this._sessionId=o.length>1?o.slice(1).join("_"):n,this._sessionStatus="detached",this._state.messages=[],this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this._toolCallTimings={},this._awaitingFullSync=void 0,this._state.error=void 0,await this.requestFullSessionSync(e),!(t!==this._sessionNonce||e!==this._sessionPath)&&(this._globalSessionStatus.get(e)==="running"&&(this._sessionStatus="attached",this._state.isStreaming=!0),this.emitSessionChange(),this.emitStatusChange())}async newSession(e){this._sessionSubscriptionActive=!0,this._sessionNonce++,this._pendingNewPrompt=!1,this._pendingControl=void 0,this._sessionId=typeof crypto.randomUUID=="function"?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16))).map(s=>s.toString(16).padStart(2,"0")).join("").replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/,"$1-$2-$3-$4-$5"),this._sessionPath=void 0,this._sessionName=void 0,this._localAssistantMessages=[],this.clearExtensionStatuses(),this._sessionStatus="virtual",this._pendingCwd=e,this._state.model?this.rememberAuthoritativeControl(this._state.model,this._state.thinkingLevel):this._lastAuthoritativeControl=void 0,this._state.messages=[],this._state.isStreaming=!1,this._pendingToolCallIds.clear(),this._toolCallTimings={},this._syncJson="",this._syncHash="",this._syncRevision=void 0,this._awaitingFullSync=void 0,this.clearSessionSyncQueue(),this._state.error=void 0,this.subscribeToSession(void 0),this.emitSessionChange(),this.emitStatusChange()}get virtualSessionInfo(){if(this._sessionStatus!=="virtual"||!this._pendingCwd)return;const e=new Date().toISOString();return{id:this._sessionId,path:`__virtual__${this._sessionId}`,cwd:this._pendingCwd,created:e,modified:e,lastUserPromptTime:e,messageCount:0,firstMessage:"(new session)"}}}const I={basename(i,e){const s=i.split("/").pop()||i;return e&&s.endsWith(e)?s.slice(0,-e.length):s}};export{De as W,G as c,Oe as f,Le as g,qe as m,je as s};